{
  "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/pipes.ts", "../../src/html/html.ts", "../../src/html/template.ts", "../../src/templates/accessorParser.ts", "../../src/templates/tokenizer.ts", "../../src/templates/parseTemplate.ts", "../../src/templates/NodeTemplate.ts", "../../src/html/TableRenderer.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 pipes\r\n * Data transformation functions (pipes) for use in template expressions.\r\n * Pipes transform values for display, like formatting dates, currencies, or text.\r\n *\r\n * Locale-aware pipes (currency, date, daysAgo, pieces) use the i18n system\r\n * for formatting and translations. Call `setLocale()` before using these pipes.\r\n *\r\n * Pipes can be chained in templates: `{{value | uppercase | shorten:20}}`\r\n *\r\n * @example\r\n * // In templates\r\n * <span>{{user.name | uppercase}}</span>\r\n * <span>{{price | currency}}</span>\r\n * <span>{{createdAt | daysAgo}}</span>\r\n *\r\n * @example\r\n * // Programmatic usage\r\n * import { applyPipes, defaultPipes } from 'relaxjs';\r\n * const result = applyPipes('hello world', ['uppercase', 'shorten:8']);\r\n * // Returns: 'HELLO...'\r\n */\r\n\r\nimport { getCurrentLocale, t } from './i18n/i18n';\r\n\r\n/**\r\n * Type definition for pipe transformation functions.\r\n * Pipes take a value and optional arguments, returning a transformed value.\r\n *\r\n * @example\r\n * // Define a custom pipe\r\n * const reversePipe: PipeFunction = (value: string) => {\r\n *     return value.split('').reverse().join('');\r\n * };\r\n */\r\nexport type PipeFunction = (value: any, ...args: any[]) => any;\r\n\r\n\r\n//  =============================== Text manipulation pipes  ===========================\r\n\r\n\r\n\r\n/**\r\n * Converts a string to uppercase\r\n * @param value The string to convert\r\n * @returns The uppercase string\r\n */\r\nexport function uppercasePipe(value: string): string {\r\n    return String(value).toUpperCase();\r\n}\r\n\r\n/**\r\n * Converts a string to uppercase\r\n * @param value The string to convert\r\n * @returns The uppercase string\r\n */\r\nexport function trimPipe(value: string): string {\r\n    return String(value).trimEnd().trimStart();\r\n}\r\n\r\n\r\n/**\r\n * Converts a string to lowercase\r\n * @param value The string to convert\r\n * @returns The lowercase string\r\n */\r\nexport function lowercasePipe(value: string): string {\r\n    return String(value).toLowerCase();\r\n}\r\n\r\n/**\r\n * Capitalizes the first character of a string\r\n * @param value The string to capitalize\r\n * @returns The capitalized string\r\n */\r\nexport function capitalizePipe(value: string): string {\r\n    const str = String(value);\r\n    return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * Shortens a string to a specified length and adds ellipsis.\r\n * @param value The string to shorten\r\n * @param length Maximum length including ellipsis\r\n * @returns The shortened string with ellipsis if needed\r\n */\r\nexport function shortenPipe(value: string, length: string): string {\r\n    const str = String(value);\r\n    const maxLength = parseInt(length, 10);\r\n    return str.length > maxLength\r\n        ? str.substring(0, maxLength - 3) + '...'\r\n        : str;\r\n}\r\n\r\n// Formatting pipes\r\n/**\r\n * Formats a number as currency using the current locale.\r\n * Uses the i18n system's current locale for formatting.\r\n *\r\n * @param value The number to format\r\n * @param currency Currency code (defaults to USD)\r\n * @returns Formatted currency string\r\n *\r\n * @example\r\n * // In template: {{price | currency}} or {{price | currency:EUR}}\r\n * currencyPipe(1234.56);        // \"$1,234.56\" (en) or \"1 234,56 $\" (sv)\r\n * currencyPipe(1234.56, 'SEK'); // \"SEK 1,234.56\" (en) or \"1 234,56 kr\" (sv)\r\n */\r\nexport function currencyPipe(value: number, currency: string = 'USD'): string {\r\n    const locale = getCurrentLocale();\r\n    return new Intl.NumberFormat(locale, {\r\n        style: 'currency',\r\n        currency\r\n    }).format(value);\r\n}\r\n\r\n/**\r\n * Formats a date value according to the specified format.\r\n * Uses the i18n system's current locale for formatting.\r\n *\r\n * @param value Date value (string, number, or Date object)\r\n * @param format Format type: 'short', 'long', or default (ISO)\r\n * @returns Formatted date string\r\n *\r\n * @example\r\n * // In template: {{date | date:short}} or {{date | date:long}}\r\n * datePipe(new Date(), 'short'); // \"1/15/2024\" (en) or \"2024-01-15\" (sv)\r\n * datePipe(new Date(), 'long');  // \"Monday, January 15, 2024\" (en) or \"m\u00E5ndag 15 januari 2024\" (sv)\r\n */\r\nexport function datePipe(value: string | number | Date, format?: string): string {\r\n    const date = new Date(value);\r\n    const locale = getCurrentLocale();\r\n    if (format === 'short') {\r\n        return date.toLocaleDateString(locale);\r\n    } else if (format === 'long') {\r\n        return date.toLocaleDateString(locale, {\r\n            weekday: 'long',\r\n            year: 'numeric',\r\n            month: 'long',\r\n            day: 'numeric'\r\n        });\r\n    }\r\n    return date.toISOString();\r\n}\r\n\r\n/**\r\n * Prints today, yesterday or X days ago.\r\n * Uses the i18n system for translations (requires pipes namespace loaded).\r\n *\r\n * @param value Date value (string, number, or Date object)\r\n * @returns Formatted relative date string\r\n *\r\n * @example\r\n * // In template: {{createdAt | daysAgo}}\r\n * // English: \"today\", \"yesterday\", \"3 days ago\"\r\n * // Swedish: \"idag\", \"ig\u00E5r\", \"3 dagar sedan\"\r\n */\r\nexport function daysAgoPipe(value: string | number | Date): string {\r\n    if (!value) {\r\n        return 'n/a';\r\n    }\r\n\r\n    const inputDate = new Date(value);\r\n    const today = new Date();\r\n\r\n    // Normalize times to midnight to compare only dates\r\n    inputDate.setHours(0, 0, 0, 0);\r\n    today.setHours(0, 0, 0, 0);\r\n\r\n    const diffTime = today.getTime() - inputDate.getTime();\r\n    const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24));\r\n\r\n    if (diffDays === 0) return t('r-pipes:today');\r\n    if (diffDays === 1) return t('r-pipes:yesterday');\r\n    return t('r-pipes:daysAgo', { count: diffDays });\r\n}\r\n\r\n/**\r\n * Formats a count as pieces/items.\r\n * Uses the i18n system for translations (requires pipes namespace loaded).\r\n *\r\n * @param value Count value\r\n * @returns Formatted piece count string\r\n *\r\n * @example\r\n * // In template: {{quantity | pieces}}\r\n * // English: \"none\", \"one\", \"3 pcs\"\r\n * // Swedish: \"inga\", \"en\", \"3 st\"\r\n */\r\nexport function piecesPipe(value: string | number): string {\r\n    if (value === null || value === undefined) {\r\n        return 'n/a';\r\n    }\r\n\r\n    const count = Number(value);\r\n    return t('r-pipes:pieces', { count });\r\n}\r\n\r\n\r\n\r\n//  =============================== Array operation pipes  ===========================\r\n\r\n\r\n\r\n/**\r\n * Joins array elements with the specified separator\r\n * @param value Array to join\r\n * @param separator Character(s) to use between elements (defaults to comma)\r\n * @returns Joined string or original value if not an array\r\n */\r\nexport function joinPipe(value: any[], separator: string = ','): string | any {\r\n    if (!Array.isArray(value)) return value;\r\n    return value.join(separator);\r\n}\r\n\r\n/**\r\n * Returns the first element of an array\r\n * @param value Array to extract from\r\n * @returns First element or empty string if array is empty/invalid\r\n */\r\nexport function firstPipe(value: any[]): any {\r\n    if (!Array.isArray(value) || value.length === 0) return '';\r\n    return value[0];\r\n}\r\n\r\n/**\r\n * Returns the last element of an array\r\n * @param value Array to extract from\r\n * @returns Last element or empty string if array is empty/invalid\r\n */\r\nexport function lastPipe(value: any[]): any {\r\n    if (!Array.isArray(value) || value.length === 0) return '';\r\n    return value[value.length - 1];\r\n}\r\n\r\n// Object operation pipes\r\n/**\r\n * Returns the keys of an object\r\n * @param value Object to extract keys from\r\n * @returns Array of object keys or empty array if not an object\r\n */\r\nexport function keysPipe(value: object): string[] {\r\n    if (typeof value !== 'object' || value === null) return [];\r\n    return Object.keys(value);\r\n}\r\n\r\n// Conditional pipes\r\n/**\r\n * Returns a default value if the input is falsy\r\n * @param value Input value to check\r\n * @param defaultValue Value to return if input is falsy\r\n * @returns Original value or default value\r\n */\r\nexport function defaultPipe(value: any, defaultValue: string): any {\r\n    return value || defaultValue;\r\n}\r\n\r\n/**\r\n * Implements ternary operator as a pipe\r\n * @param value Condition to evaluate\r\n * @param trueValue Value to return if condition is truthy\r\n * @param falseValue Value to return if condition is falsy\r\n * @returns Selected value based on condition\r\n */\r\nexport function ternaryPipe(value: any, trueValue: string, falseValue: string): string {\r\n    return value ? trueValue : falseValue;\r\n}\r\n\r\n\r\n\r\n//  =============================== Pipe registry and application  ===========================\r\n\r\n\r\n/**\r\n * Interface for a collection of pipe functions.\r\n * Use this to look up pipes by name for template processing.\r\n *\r\n * @example\r\n * // Check if a pipe exists before using\r\n * if (registry.has('currency')) {\r\n *     const formatted = registry.get('currency')(price);\r\n * }\r\n */\r\nexport interface PipeRegistry {\r\n    /**\r\n     * Looks up a pipe by name, returning null if not found.\r\n     */\r\n    lookup(name: string): PipeFunction | null;\r\n\r\n    /**\r\n     * Gets a pipe by name, throwing if not found.\r\n     */\r\n    get(name: string): PipeFunction;\r\n\r\n    /**\r\n     * Checks if a pipe with the given name exists.\r\n     */\r\n    has(name: string): boolean;\r\n}\r\n\r\n\r\n/**\r\n * Creates a new pipe registry with all built-in pipes registered.\r\n * Built-in pipes include:\r\n *\r\n * **Text:** uppercase, lowercase, capitalize, trim, shorten\r\n * **Formatting:** currency, date, daysAgo, pieces\r\n * **Arrays:** join, first, last\r\n * **Objects:** keys\r\n * **Conditionals:** default, ternary\r\n *\r\n * @returns A new pipe registry instance\r\n *\r\n * @example\r\n * const registry = createPipeRegistry();\r\n * const upperPipe = registry.get('uppercase');\r\n * console.log(upperPipe('hello')); // 'HELLO'\r\n */\r\nexport function createPipeRegistry(): PipeRegistry {\r\n    const pipes = new Map<string, PipeFunction>();\r\n\r\n    // Text manipulation\r\n    pipes.set('uppercase', uppercasePipe);\r\n    pipes.set('lowercase', lowercasePipe);\r\n    pipes.set('capitalize', capitalizePipe);\r\n    pipes.set('trim', trimPipe);\r\n    pipes.set('shorten', shortenPipe);\r\n\r\n    // Formatting\r\n    pipes.set('currency', currencyPipe);\r\n    pipes.set('date', datePipe);\r\n    pipes.set('daysAgo', daysAgoPipe);\r\n    pipes.set('pieces', piecesPipe);\r\n\r\n    // Array operations\r\n    pipes.set('join', joinPipe);\r\n    pipes.set('first', firstPipe);\r\n    pipes.set('last', lastPipe);\r\n\r\n    // Object operations\r\n    pipes.set('keys', keysPipe);\r\n\r\n    // Conditional formatting\r\n    pipes.set('default', defaultPipe);\r\n    pipes.set('ternary', ternaryPipe);\r\n\r\n    return {\r\n        lookup(name) {\r\n            return pipes.get(name) ?? null;\r\n        },\r\n        get(name) {\r\n            var pipe = pipes.get(name);\r\n            if (!pipe) {\r\n                throw Error(\"Pipe '\" + name + \"' not found.\");\r\n            }\r\n            return pipe;\r\n        },\r\n        has(name) {\r\n            return pipes.has(name);\r\n        },\r\n    };\r\n}\r\n\r\n/**\r\n * Default pipe registry instance with all built-in pipes.\r\n * Used by template engines unless a custom registry is provided.\r\n *\r\n * @example\r\n * import { defaultPipes } from 'relaxjs';\r\n *\r\n * if (defaultPipes.has('uppercase')) {\r\n *     const result = defaultPipes.get('uppercase')('hello');\r\n * }\r\n */\r\nexport const defaultPipes = createPipeRegistry();\r\n\r\n/**\r\n * Applies a series of pipes to a value sequentially.\r\n * Each pipe transforms the output of the previous pipe.\r\n *\r\n * Pipe arguments are specified after a colon: `shorten:20`\r\n *\r\n * @param value - Initial value to transform\r\n * @param pipes - Array of pipe strings (name and optional arguments separated by ':')\r\n * @param registry - Optional custom pipe registry (uses defaultPipes if not provided)\r\n * @returns The transformed value after applying all pipes\r\n *\r\n * @example\r\n * // Apply single pipe\r\n * applyPipes('hello', ['uppercase']); // 'HELLO'\r\n *\r\n * @example\r\n * // Chain multiple pipes\r\n * applyPipes('hello world', ['uppercase', 'shorten:8']); // 'HELLO...'\r\n *\r\n * @example\r\n * // With pipe arguments\r\n * applyPipes(1234.56, ['currency']); // '$1,234.56'\r\n */\r\nexport function applyPipes(\r\n    value: any,\r\n    pipes: string[],\r\n    registry: PipeRegistry = defaultPipes\r\n): any {\r\n\r\n    return pipes.reduce((currentValue, pipe) => {\r\n        const [pipeName, ...args] = pipe.split(':').map((p) => p.trim());\r\n\r\n        if (!registry.has(pipeName)) {\r\n            return `[Pipe ${pipeName} not found]`;\r\n        }\r\n\r\n        try {\r\n            return registry.get(pipeName)(currentValue, ...args);\r\n        } catch (error) {\r\n            return `[Pipe ${pipeName}, value: ${value}, error: ${error}]`;\r\n        }\r\n    }, value);\r\n}", "/**\r\n * @module html\r\n * HTML template engine with update capabilities.\r\n * Creates templates that can be re-rendered with new data without recreating DOM nodes.\r\n */\r\n\r\nimport { defaultPipes } from \"../pipes\";\r\n\r\nconst pipes = defaultPipes;\r\n\r\ninterface Binding {\r\n  originalValue?: unknown;\r\n  setter: (instance: unknown) => void;\r\n}\r\n\r\n/**\r\n * Result of rendering a template.\r\n * Provides the DOM fragment and an update function for re-rendering.\r\n */\r\nexport interface RenderTemplate {\r\n  /** The rendered DOM fragment */\r\n  fragment: DocumentFragment;\r\n  /** Updates the DOM with new data without recreating elements */\r\n  update(context: any): void;\r\n}\r\n\r\n/**\r\n * Creates an updateable HTML template using tagged template literals.\r\n * Returns an object with the fragment and an update method for efficient re-rendering.\r\n *\r\n * Supports:\r\n * - Template literal substitutions (`${}`)\r\n * - Mustache-style bindings (`{{property}}`)\r\n * - Pipe transformations (`{{value|uppercase}}`)\r\n * - Event handler binding\r\n *\r\n * @param templateStrings - The static parts of the template literal\r\n * @param substitutions - The dynamic values interpolated into the template\r\n * @returns A function that takes context and returns a RenderTemplate\r\n *\r\n * @example\r\n * // Create and render a template\r\n * const template = html`\r\n *     <div class=\"user\">\r\n *         <h2>{{name}}</h2>\r\n *         <p>{{email}}</p>\r\n *         <span>{{createdAt|daysAgo}}</span>\r\n *     </div>\r\n * `;\r\n *\r\n * const result = template({ name: 'John', email: 'john@example.com', createdAt: new Date() });\r\n * container.appendChild(result.fragment);\r\n *\r\n * // Later, update with new data\r\n * result.update({ name: 'Jane', email: 'jane@example.com', createdAt: new Date() });\r\n *\r\n * @example\r\n * // With event handlers\r\n * const row = html`\r\n *     <tr>\r\n *         <td>{{name}}</td>\r\n *         <td><button onclick=${function() { this.edit(this.id) }}>Edit</button></td>\r\n *     </tr>\r\n * `;\r\n */\r\nexport function html(\r\n  templateStrings: TemplateStringsArray,\r\n  ...substitutions: any[]\r\n): (context: any) => RenderTemplate {\r\n  // Preprocess template strings\r\n  const template = document.createElement(\"template\");\r\n  const resolvedTemplate = resolveTemplate(templateStrings);\r\n  template.innerHTML = resolvedTemplate;\r\n  const bindings: Binding[] = [];\r\n\r\n  const walker = document.createTreeWalker(\r\n    template.content,\r\n    NodeFilter.SHOW_ALL\r\n  );\r\n  let node: Node | null;\r\n\r\n  while ((node = walker.nextNode())) {\r\n    if (node.nodeType === Node.ELEMENT_NODE) {\r\n      const element = node as HTMLElement;\r\n      processElement(element, substitutions, bindings);\r\n      if (customElements.get(element.tagName.toLowerCase())) {\r\n        customElements.upgrade(element);\r\n      }\r\n    } else if (node.nodeType === Node.TEXT_NODE) {\r\n      const myNode = node;\r\n      const text = myNode.textContent!;\r\n      const result = parseTemplate(text, substitutions);\r\n      if (result) {\r\n        const hasSubstitutions = /\u20AC\u20AC\\d+\u20AC\u20AC/.test(text);\r\n        if (hasSubstitutions) {\r\n          let startMarker: Comment | null = null;\r\n          let endMarker: Comment | null = null;\r\n          let insertedNodes: Node[] = [];\r\n          bindings.push({\r\n            originalValue: text,\r\n            setter(instance) {\r\n              var value = result(instance);\r\n              if (!startMarker) {\r\n                startMarker = document.createComment('');\r\n                endMarker = document.createComment('');\r\n                myNode.parentNode?.replaceChild(endMarker, myNode);\r\n                endMarker.parentNode?.insertBefore(startMarker, endMarker);\r\n              }\r\n              insertedNodes.forEach(n => n.parentNode?.removeChild(n));\r\n              insertedNodes = [];\r\n              const temp = document.createElement('template');\r\n              temp.innerHTML = value;\r\n              const nodes = Array.from(temp.content.childNodes);\r\n              const parent = endMarker!.parentNode!;\r\n              nodes.forEach(n => {\r\n                parent.insertBefore(n, endMarker);\r\n                insertedNodes.push(n);\r\n              });\r\n            },\r\n          });\r\n        } else {\r\n          bindings.push({\r\n            originalValue: text,\r\n            setter(instance) {\r\n              var value = result(instance);\r\n              myNode.textContent = value;\r\n            },\r\n          });\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  // Return a function for binding\r\n  return function bind(context: any): RenderTemplate {\r\n    bindings.forEach((x) => {\r\n      x.setter(context);\r\n    });\r\n\r\n    return {\r\n      fragment: template.content,\r\n      update(context: any) {\r\n        bindings.forEach((x) => {\r\n          x.setter(context);\r\n        });\r\n      },\r\n    };\r\n  };\r\n}\r\n\r\nfunction resolveTemplate(templateStrings: TemplateStringsArray): string {\r\n  return templateStrings.raw\r\n    .map((str, i) =>\r\n      i < templateStrings.raw.length - 1 ? `${str}\u20AC\u20AC${i}\u20AC\u20AC` : str\r\n    )\r\n    .join(\"\");\r\n}\r\n\r\nfunction processElement(\r\n  element: HTMLElement,\r\n  substitutions: any[],\r\n  bindings: Binding[]\r\n) {\r\n  const attrBindings: Binding[] = [];\r\n\r\n  for (const attr of Array.from(element.attributes)) {\r\n    var attrValue = attr.value;\r\n    if (attrValue == \"\") {\r\n      continue;\r\n    }\r\n\r\n    const regex = /\u20AC\u20AC(\\d+)\u20AC\u20AC/;\r\n    const match = attrValue.match(regex);\r\n    if (match) {\r\n      const index = parseInt(match[1], 10);\r\n      const func = substitutions[index];\r\n      if (typeof func === \"function\") {\r\n        attrBindings.push({\r\n          setter(instance) {\r\n            const boundFunction = func.bind(instance);\r\n            element.removeAttribute(attr.name);\r\n            (element as any)[attr.name] = boundFunction;\r\n          },\r\n        });\r\n\r\n        continue;\r\n      }\r\n    }\r\n\r\n    var attributeCallback = parseTemplate(attrValue, substitutions);\r\n    if (attributeCallback == null) {\r\n      continue;\r\n    }\r\n\r\n    attrBindings.push({\r\n      originalValue: attrValue,\r\n      setter(instance) {\r\n        const value = attributeCallback!(instance) ?? attrValue;\r\n        if (attr.name in element) {\r\n          (element as any)[attr.name] = value;\r\n        } else {\r\n          attr.value = value;\r\n        }\r\n      },\r\n    });\r\n  }\r\n\r\n  if (attrBindings.length > 0) {\r\n    bindings.push({\r\n      originalValue: element.tagName,\r\n      setter(instance) {\r\n        attrBindings.forEach((attrBinding) => attrBinding.setter(instance));\r\n      },\r\n    });\r\n  }\r\n}\r\n\r\ntype TemplateCallback = (instance: any) => string;\r\n\r\n\r\n/**\r\n * Parse arguments for function calls in mustache expressions\r\n * Handles dot notation like row.id and nested properties\r\n */\r\nfunction parseArguments(argsStr: string, instance: any): any[] {\r\n  return argsStr.split(',').map(arg => {\r\n    arg = arg.trim();\r\n\r\n    if ((arg.startsWith('\"') && arg.endsWith('\"')) ||\r\n        (arg.startsWith(\"'\") && arg.endsWith(\"'\"))) {\r\n      return arg.slice(1, -1);\r\n    }\r\n\r\n    if (!isNaN(Number(arg))) {\r\n      return Number(arg);\r\n    }\r\n\r\n    if (arg.includes('.')) {\r\n      const parts = arg.split('.');\r\n      let value = instance;\r\n      for (const part of parts) {\r\n        if (value === undefined || value === null) return undefined;\r\n        value = value[part];\r\n      }\r\n      return value;\r\n    }\r\n\r\n    // Handle simple variable references\r\n    return instance[arg];\r\n  });\r\n}\r\n\r\n\r\nfunction parseTemplate(\r\n  template: string,\r\n  substitutions: any[]\r\n): TemplateCallback | null {\r\n  const regex = /\u20AC\u20AC(\\d+)\u20AC\u20AC|{{\\s*([^|]+?)(?:\\|([\\w|]+))?\\s*}}/g;\r\n  let lastIndex = 0;\r\n  let match;\r\n\r\n  const textBindings: TemplateCallback[] = [];\r\n  while ((match = regex.exec(template)) !== null) {\r\n    var value = template.slice(lastIndex, match.index);\r\n    if (value.length > 0) {\r\n      textBindings.push((_instance) => {\r\n        return value;\r\n      });\r\n    }\r\n\r\n    // ${}\r\n    if (match[1]) {\r\n      const index = parseInt(match[1], 10);\r\n      const sub = substitutions[index];\r\n      if (!sub) {\r\n        continue;\r\n      }\r\n\r\n      if (typeof sub === \"function\") {\r\n        const func = sub as Function;\r\n        textBindings.push((instance) => {\r\n          var result = func.apply(instance);\r\n          return result;\r\n        });\r\n      } else {\r\n        if (sub && sub.length > 0) {\r\n          textBindings.push((instance) => {\r\n            return sub;\r\n          });\r\n        }\r\n      }\r\n    } else if (match[2]) {\r\n      // {{mustache|pipes}} case\r\n      const mustacheName = match[2].trim();\r\n      const argsStr = match[3] ? match[3].trim() : null;\r\n      const matchingPipes = match[4]\r\n        ? match[4].split(\"|\").map((pipe) => pipe.trim())\r\n        : [];\r\n\r\n      textBindings.push((instance) => {\r\n        var value = instance[mustacheName];\r\n\r\n        if (typeof value === \"function\") {\r\n          if (argsStr) {\r\n            const args = parseArguments(argsStr, instance);\r\n            value = value.apply(instance, args);\r\n          } else {\r\n            value = value.call(instance);\r\n          }\r\n        }\r\n\r\n        matchingPipes.forEach((pipe) => {\r\n          value = pipes.get(pipe)(value);\r\n        });\r\n        return value;\r\n      });\r\n    }\r\n\r\n    lastIndex = regex.lastIndex;\r\n  }\r\n\r\n  if (textBindings.length == 0) {\r\n    return null;\r\n  }\r\n\r\n  var val = template.slice(lastIndex);\r\n  if (val.length > 0) {\r\n    textBindings.push((_) => {\r\n      return val;\r\n    });\r\n  }\r\n  return (instance) => {\r\n    var result = \"\";\r\n    textBindings.forEach((binding) => {\r\n      var value = binding(instance);\r\n      result += value;\r\n    });\r\n\r\n    return result;\r\n  };\r\n}\r\n", "/**\r\n * @module template\r\n * DOM-based template engine with reactive rendering capabilities.\r\n *\r\n * Compiles HTML templates with mustache-style expressions into efficient\r\n * render functions that update the DOM when data changes.\r\n *\r\n * **Features:**\r\n * - Text interpolation: `{{name}}`, `{{user.profile.email}}`\r\n * - Attribute binding: `<div class=\"{{className}}\">`\r\n * - Pipes: `{{price | currency}}`, `{{name | uppercase | shorten:20}}`\r\n * - Function calls: `{{formatDate(createdAt)}}`, `{{add(5, 3)}}`\r\n * - Array indexing: `{{items[0]}}`, `{{users[1].name}}`\r\n * - Conditionals: `<div if=\"isVisible\">`, `<div unless=\"isHidden\">`\r\n * - Loops: `<li loop=\"item in items\">{{item.name}}</li>`\r\n *\r\n * @example\r\n * // Basic usage\r\n * import { compileTemplate } from './m';\r\n *\r\n * const { content, render } = compileTemplate(`\r\n *     <div class=\"card\">\r\n *         <h2>{{title}}</h2>\r\n *         <p>{{description}}</p>\r\n *     </div>\r\n * `);\r\n *\r\n * render({ title: 'Hello', description: 'World' });\r\n * document.body.appendChild(content);\r\n *\r\n * @example\r\n * // With pipes and functions\r\n * import { createPipeRegistry } from '../pipes';\r\n *\r\n * const pipeRegistry = createPipeRegistry();\r\n * const { content, render } = compileTemplate(`\r\n *     <span>{{user.name | uppercase}}</span>\r\n *     <span>{{formatDate(user.createdAt)}}</span>\r\n * `, { strict: false, pipeRegistry });\r\n *\r\n * render(\r\n *     { user: { name: 'john', createdAt: new Date() } },\r\n *     { formatDate: (d) => d.toLocaleDateString() }\r\n * );\r\n *\r\n * @example\r\n * // With loops and conditionals\r\n * const { content, render } = compileTemplate(`\r\n *     <ul>\r\n *         <li loop=\"item in items\" if=\"item.visible\">\r\n *             {{item.name}}: {{item.price | currency}}\r\n *         </li>\r\n *     </ul>\r\n * `);\r\n *\r\n * render({ items: [\r\n *     { name: 'Apple', price: 1.5, visible: true },\r\n *     { name: 'Hidden', price: 0, visible: false }\r\n * ]});\r\n */\r\n\r\nimport { PipeRegistry, defaultPipes, applyPipes } from '../pipes';\r\n\r\n/**\r\n * Configuration options for the template engine.\r\n *\r\n * @example\r\n * const config: EngineConfig = {\r\n *     strict: true,\r\n *     onError: (msg) => console.error(msg),\r\n *     pipeRegistry: createPipeRegistry()\r\n * };\r\n */\r\nexport interface EngineConfig {\r\n    /** When true, throws errors for missing paths/functions. When false, returns empty string. */\r\n    strict: boolean;\r\n    /** Optional callback invoked when errors occur, receives formatted error message. */\r\n    onError?: (msg: string) => void;\r\n    /** Custom pipe registry for transformations. Defaults to built-in pipes. */\r\n    pipeRegistry?: PipeRegistry;\r\n}\r\n\r\nexport type Path = string;\r\nexport type TemplateValue = string | number | boolean | null | undefined;\r\n\r\n/**\r\n * Data context object passed to render function.\r\n * Contains the data values that expressions resolve against.\r\n *\r\n * @example\r\n * const ctx: Context = {\r\n *     user: { name: 'John', age: 30 },\r\n *     items: ['a', 'b', 'c'],\r\n *     isActive: true\r\n * };\r\n *\r\n * @internal\r\n */\r\nexport interface Context {\r\n    [key: string]: ContextValue;\r\n}\r\n\r\n/**\r\n * Functions context object passed as second argument to render.\r\n * Contains callable functions that can be invoked from templates.\r\n *\r\n * @example\r\n * const fns: FunctionsContext = {\r\n *     formatDate: (d) => d.toLocaleDateString(),\r\n *     add: (a, b) => a + b,\r\n *     greet: (name) => `Hello, ${name}!`\r\n * };\r\n *\r\n * @internal\r\n */\r\nexport interface FunctionsContext {\r\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n    [key: string]: (...args: any[]) => any;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport type ContextValue = TemplateValue | any[] | Context | ((...args: any[]) => any);\r\n\r\nexport type Getter = (ctx: Context, path: Path, debugInfo?: string) => TemplateValue;\r\nexport type Setter = (ctx: Context, fns?: FunctionsContext) => void;\r\nexport type Patcher = (node: Node, get: Getter, config: EngineConfig) => Setter | void;\r\nexport type ExpressionFn = (ctx: Context, fns?: FunctionsContext) => TemplateValue;\r\n\r\ninterface ParsedExpression {\r\n    type: 'path' | 'function';\r\n    path?: string;\r\n    fnName?: string;\r\n    fnArgs?: string[];\r\n    pipes: string[];\r\n}\r\n\r\nfunction parseExpression(expr: string): ParsedExpression {\r\n    const pipesSplit = expr.split('|').map(s => s.trim());\r\n    const mainExpr = pipesSplit[0];\r\n    const pipes = pipesSplit.slice(1);\r\n\r\n    // Check if it's a function call: functionName(args)\r\n    const fnMatch = mainExpr.match(/^(\\w+)\\s*\\((.*)\\)$/);\r\n    if (fnMatch) {\r\n        const [, fnName, argsStr] = fnMatch;\r\n        const fnArgs = argsStr\r\n            ? argsStr.split(',').map(a => a.trim())\r\n            : [];\r\n        return { type: 'function', fnName, fnArgs, pipes };\r\n    }\r\n\r\n    return { type: 'path', path: mainExpr, pipes };\r\n}\r\n\r\n// Resolve a path with support for array indexing: items[0].name\r\nfunction resolvePath(ctx: ContextValue, path: string): ContextValue {\r\n    // Handle array indexing by converting items[0] to items.0\r\n    const normalizedPath = path.replace(/\\[(\\d+)\\]/g, '.$1');\r\n    const segments = normalizedPath.split('.');\r\n    let current = ctx;\r\n\r\n    for (const key of segments) {\r\n        if (current && typeof current === 'object' && key in current) {\r\n            current = (current as Record<string, ContextValue>)[key];\r\n        } else {\r\n            return undefined;\r\n        }\r\n    }\r\n\r\n    return current;\r\n}\r\n  \r\n  function handleError(config: EngineConfig, message: string, context: string, shouldThrow = false): void {\r\n    const formattedMessage = `[template error] ${message} (at ${context})`;\r\n\r\n    if (window.relaxDebug?.templates) console.warn(formattedMessage);\r\n    if (config.onError) config.onError(formattedMessage);\r\n    if (config.strict || shouldThrow) throw new Error(formattedMessage);\r\n  }\r\n  \r\nfunction createGetter(config: EngineConfig): Getter {\r\n    return function get(ctx: ContextValue, path: Path, debugInfo = ''): TemplateValue {\r\n        try {\r\n            const current = resolvePath(ctx, path);\r\n\r\n            if (current === undefined) {\r\n                handleError(config, `Cannot resolve \"${path}\"`, debugInfo);\r\n                return '';\r\n            }\r\n\r\n            // Return primitive values as-is for conditional checks\r\n            if (current === null) {\r\n                return '';\r\n            } else if (Array.isArray(current)) {\r\n                return current.length > 0 ? JSON.stringify(current) : '';\r\n            } else if (typeof current === 'object') {\r\n                return JSON.stringify(current);\r\n            } else {\r\n                return current as TemplateValue;\r\n            }\r\n        } catch (err) {\r\n            const errorMessage = err instanceof Error ? err.message : String(err);\r\n            handleError(config, `Exception resolving \"${path}\": ${errorMessage}`, debugInfo, true);\r\n            return '';\r\n        }\r\n    };\r\n}\r\n\r\nfunction evaluateExpression(\r\n    parsed: ParsedExpression,\r\n    ctx: Context,\r\n    fns: FunctionsContext | undefined,\r\n    config: EngineConfig,\r\n    debugInfo: string\r\n): TemplateValue {\r\n    let value: TemplateValue;\r\n    const registry = config.pipeRegistry ?? defaultPipes;\r\n\r\n    if (parsed.type === 'function') {\r\n        const fn = fns?.[parsed.fnName!];\r\n        if (typeof fn !== 'function') {\r\n            handleError(config, `Function \"${parsed.fnName}\" not found`, debugInfo);\r\n            return '';\r\n        }\r\n\r\n        // Resolve function arguments - could be literals or paths\r\n        const resolvedArgs = (parsed.fnArgs ?? []).map(arg => {\r\n            // String literal\r\n            if ((arg.startsWith('\"') && arg.endsWith('\"')) ||\r\n                (arg.startsWith(\"'\") && arg.endsWith(\"'\"))) {\r\n                return arg.slice(1, -1);\r\n            }\r\n            // Number literal\r\n            if (!isNaN(Number(arg))) {\r\n                return Number(arg);\r\n            }\r\n            // Path reference - resolve from context\r\n            const resolved = resolvePath(ctx, arg);\r\n            return resolved;\r\n        });\r\n\r\n        try {\r\n            value = fn(...resolvedArgs) as TemplateValue;\r\n        } catch (err) {\r\n            const errorMessage = err instanceof Error ? err.message : String(err);\r\n            handleError(config, `Error calling \"${parsed.fnName}\": ${errorMessage}`, debugInfo);\r\n            return '';\r\n        }\r\n    } else {\r\n        // Path resolution\r\n        const resolved = resolvePath(ctx, parsed.path!);\r\n        if (resolved === undefined) {\r\n            handleError(config, `Cannot resolve \"${parsed.path}\"`, debugInfo);\r\n            return '';\r\n        }\r\n        if (resolved === null) {\r\n            value = '';\r\n        } else if (typeof resolved === 'object') {\r\n            value = JSON.stringify(resolved);\r\n        } else {\r\n            value = resolved as TemplateValue;\r\n        }\r\n    }\r\n\r\n    // Apply pipes if any\r\n    if (parsed.pipes.length > 0) {\r\n        value = applyPipes(value, parsed.pipes, registry);\r\n    }\r\n\r\n    return value;\r\n}\r\n  \r\ninterface InterpolationPart {\r\n    /** Set for a `{{expr}}` segment, null for surrounding literal text. */\r\n    parsed: ParsedExpression | null;\r\n    literal: string;\r\n}\r\n\r\nconst expressionCache = new Map<string, InterpolationPart[]>();\r\n\r\n/**\r\n * Splits interpolated text into the literal and `{{expr}}` segments it is made\r\n * of, so both can be re-joined on every render. Text and attributes share the\r\n * parse result, which is memoized because loops recompile a clone per item.\r\n */\r\nfunction splitInterpolation(raw: string): InterpolationPart[] {\r\n    let parts = expressionCache.get(raw);\r\n    if (!parts) {\r\n        parts = raw\r\n            .split(/(\\{\\{.*?\\}\\})/)\r\n            .filter(part => part !== '')\r\n            .map(part => part.startsWith('{{') && part.endsWith('}}')\r\n                ? { parsed: parseExpression(part.slice(2, -2).trim()), literal: '' }\r\n                : { parsed: null, literal: part });\r\n        expressionCache.set(raw, parts);\r\n    }\r\n    return parts;\r\n}\r\n\r\nfunction composeParts(\r\n    parts: InterpolationPart[],\r\n    ctx: Context,\r\n    fns: FunctionsContext | undefined,\r\n    config: EngineConfig,\r\n    debugInfo: string\r\n): string {\r\n    return parts\r\n        .map(({ parsed, literal }) => parsed\r\n            ? String(evaluateExpression(parsed, ctx, fns, config, debugInfo))\r\n            : literal)\r\n        .join('');\r\n}\r\n\r\nfunction textNodePatcher(node: Node, _get: Getter, config: EngineConfig): Setter | void {\r\n    if (node.nodeType !== Node.TEXT_NODE || !node.textContent?.includes('{{')) return;\r\n\r\n    const raw = node.textContent;\r\n    const parts = splitInterpolation(raw);\r\n    const debugInfo = `TextNode: \"${raw}\"`;\r\n\r\n    return (ctx: Context, fns?: FunctionsContext) => {\r\n        (node as Text).textContent = composeParts(parts, ctx, fns, config, debugInfo);\r\n    };\r\n}\r\n  \r\n/**\r\n * Attributes whose content attribute does not stay in sync with the live\r\n * property the user actually sees. Setting `value`/`checked`/`selected` via\r\n * `setAttribute` only writes the *default* (`defaultValue`/`defaultChecked`),\r\n * so a form control that is cleared and repopulated programmatically would\r\n * keep showing stale data. For these we write the property directly.\r\n */\r\nconst liveValueAttributes = ['value', 'checked', 'selected'];\r\n\r\n/**\r\n * Resolves `{{expr}}` inside element attributes and keeps them updated on\r\n * every render. An attribute may mix literal text with any number of\r\n * expressions, as in `class=\"finding {{severity}}\"`.\r\n *\r\n * Three binding modes, chosen by the attribute and the resolved value:\r\n * - `value`/`checked`/`selected` are written to the matching DOM *property*,\r\n *   because the content attribute only seeds the default and would not\r\n *   reflect a programmatic clear-and-repopulate.\r\n * - A boolean value is applied with `toggleAttribute`, so `disabled=\"{{busy}}\"`\r\n *   adds the attribute when `true` and removes it when `false` (a plain\r\n *   `setAttribute` would leave `disabled=\"false\"`, which is still disabled).\r\n * - Everything else is a normal string `setAttribute`.\r\n *\r\n * @example\r\n * // Property binding keeps the input in sync after a reset\r\n * compileTemplate('<input value=\"{{name}}\">');\r\n *\r\n * @example\r\n * // Boolean binding toggles the attribute on and off. Only a whole-value\r\n * // expression can do this; \"busy {{flag}}\" is always a string.\r\n * compileTemplate('<button disabled=\"{{busy}}\">Save</button>');\r\n *\r\n * @example\r\n * // Literals and expressions compose into one string\r\n * compileTemplate('<img src=\"/avatars/{{user.id}}.png\">');\r\n */\r\nfunction attributeInterpolationPatcher(node: Node, _get: Getter, config: EngineConfig): Setter | void {\r\n    if (node.nodeType !== Node.ELEMENT_NODE) return;\r\n\r\n    const element = node as Element;\r\n    const setters: Setter[] = [];\r\n\r\n    // Use Array.from to safely iterate over NamedNodeMap\r\n    const attributes = Array.from(element.attributes);\r\n    for (const attr of attributes) {\r\n        if (!attr.value.includes('{{')) continue;\r\n\r\n        const parts = splitInterpolation(attr.value);\r\n        if (!parts.some(part => part.parsed)) continue;\r\n\r\n        const name = attr.name;\r\n        const wholeValue = parts.length === 1 ? parts[0].parsed : null;\r\n        const debugInfo = `Attribute: ${name} on <${element.tagName.toLowerCase()}>`;\r\n\r\n        setters.push((ctx: Context, fns?: FunctionsContext) => {\r\n            const value = wholeValue\r\n                ? evaluateExpression(wholeValue, ctx, fns, config, debugInfo)\r\n                : composeParts(parts, ctx, fns, config, debugInfo);\r\n\r\n            if (liveValueAttributes.includes(name) && name in element) {\r\n                (element as unknown as Record<string, unknown>)[name] = value;\r\n            } else if (typeof value === 'boolean') {\r\n                element.toggleAttribute(name, value);\r\n            } else {\r\n                element.setAttribute(name, String(value));\r\n            }\r\n        });\r\n    }\r\n\r\n    if (setters.length > 0) {\r\n        return (ctx: Context, fns?: FunctionsContext) => setters.forEach(fn => fn(ctx, fns));\r\n    }\r\n}\r\n\r\n/**\r\n * Binds event handlers declared with `r-<event>=\"handler(args)\"`, for example\r\n * `r-click`, `r-change`, or `r-keypress`. The part after `r-` is treated as a\r\n * DOM event name and is only wired when the element actually supports it\r\n * (checked via the matching `on<event>` property); an unrecognised name is\r\n * reported as an error.\r\n *\r\n * The handler name is resolved from the functions context passed to `render`.\r\n * Arguments are resolved against the current data context, so inside a loop\r\n * the iteration alias (`row`) and its nested values can be passed straight to\r\n * the handler. The literal `event` resolves to the native DOM event.\r\n *\r\n * Listeners are attached once per element. Each render only refreshes the data\r\n * the listeners close over, so handlers keep working as loops reuse, add, or\r\n * remove rows.\r\n */\r\nfunction eventPatcher(node: Node, _get: Getter, config: EngineConfig): Setter | void {\r\n    if (node.nodeType !== Node.ELEMENT_NODE) return;\r\n\r\n    const element = node as Element;\r\n    const tag = element.tagName.toLowerCase();\r\n    const rAttributes = Array.from(element.attributes).filter(attr => attr.name.startsWith('r-'));\r\n    if (rAttributes.length === 0) return;\r\n\r\n    const updaters: Setter[] = [];\r\n\r\n    for (const attr of rAttributes) {\r\n        const eventName = attr.name.slice(2);\r\n        const expr = attr.value;\r\n        const debugInfo = `${attr.name}=\"${expr}\" on <${tag}>`;\r\n        element.removeAttribute(attr.name);\r\n\r\n        if (!(`on${eventName}` in element)) {\r\n            handleError(config, `\"${attr.name}\" is not a known event for <${tag}>`, debugInfo);\r\n            continue;\r\n        }\r\n\r\n        const parsed = parseExpression(expr);\r\n        if (parsed.type !== 'function') {\r\n            handleError(config, `${attr.name} must be a function call, got \"${expr}\"`, debugInfo);\r\n            continue;\r\n        }\r\n\r\n        let currentCtx: Context | null = null;\r\n        let currentFns: FunctionsContext | undefined = undefined;\r\n\r\n        element.addEventListener(eventName, (event) => {\r\n            if (!currentCtx) return;\r\n            const ctxWithEvent = { ...currentCtx, event } as unknown as Context;\r\n            evaluateExpression(parsed, ctxWithEvent, currentFns, config, debugInfo);\r\n        });\r\n\r\n        updaters.push((ctx: Context, fns?: FunctionsContext) => {\r\n            currentCtx = ctx;\r\n            currentFns = fns;\r\n        });\r\n    }\r\n\r\n    if (updaters.length > 0) {\r\n        return (ctx: Context, fns?: FunctionsContext) => updaters.forEach(fn => fn(ctx, fns));\r\n    }\r\n}\r\n\r\nconst structuralAttributes = ['loop', 'if', 'unless'];\r\n\r\n/** One rendered copy of a structural element, kept so the next render can re-use it. */\r\ninterface Instance {\r\n    element: Element;\r\n    render: (ctx: Context, fns?: FunctionsContext) => void;\r\n}\r\n\r\n/**\r\n * Takes full ownership of any element carrying `loop`, `if` or `unless`,\r\n * including an element carrying several of them at once. The element is\r\n * replaced by a comment placeholder, and every render decides which copies\r\n * belong after that placeholder. Content patchers and child traversal are\r\n * skipped for such an element; its copies are compiled on their own.\r\n *\r\n * `if` and `unless` combine: the element renders when the `if` holds and the\r\n * `unless` does not. On a looping element the condition is evaluated per item\r\n * against that item's context, so an item that fails it produces no element.\r\n *\r\n * Rendering order for a new copy:\r\n *\r\n * 1. Clone from template (detached, attributes still contain mustache)\r\n * 2. Compile the clone, creating setters for mustache in attributes/text\r\n * 3. Render, resolving mustache against the iteration context\r\n * 4. Insert into DOM. Custom elements upgrade with final attribute values\r\n *\r\n * Steps 2-3 MUST happen before step 4. If we insert first, the browser\r\n * upgrades custom elements immediately (connectedCallback fires) while\r\n * attributes still contain raw \"{{expr}}\" strings.\r\n *\r\n * Copies already in the DOM are re-rendered in place. The most recently\r\n * removed copy is kept, so hiding and re-showing an element, or a list that\r\n * shrinks and grows again, skips the clone + compile.\r\n */\r\nfunction structuralPatcher(node: Node, get: Getter, config: EngineConfig): Setter | void {\r\n    if (node.nodeType !== Node.ELEMENT_NODE) return;\r\n\r\n    const element = node as Element;\r\n    const loopDef = element.getAttribute('loop');\r\n    const ifExpr = element.getAttribute('if');\r\n    const unlessExpr = element.getAttribute('unless');\r\n    if (loopDef === null && ifExpr === null && unlessExpr === null) return;\r\n\r\n    const tag = element.tagName.toLowerCase();\r\n    let alias = '';\r\n    let source = '';\r\n\r\n    if (loopDef !== null) {\r\n        const match = loopDef.match(/(\\w+)\\s+in\\s+(.+)/);\r\n        if (!match) {\r\n            handleError(config, `Invalid loop syntax: \"${loopDef}\"`, `Element: <${tag}>`);\r\n            return;\r\n        }\r\n        [, alias, source] = match;\r\n    }\r\n\r\n    const template = element.cloneNode(true) as Element;\r\n    structuralAttributes.forEach(name => template.removeAttribute(name));\r\n\r\n    const placeholder = document.createComment(\r\n        loopDef !== null\r\n            ? `loop: ${loopDef}`\r\n            : ifExpr !== null\r\n                ? `if: ${ifExpr}`\r\n                : `unless: ${unlessExpr}`\r\n    );\r\n    const parent = element.parentNode!;\r\n    parent.insertBefore(placeholder, element);\r\n    element.remove();\r\n\r\n    const isVisible = (candidate: Context): boolean => {\r\n        if (ifExpr !== null && !get(candidate, ifExpr, `if=\"${ifExpr}\"`)) return false;\r\n        if (unlessExpr !== null && get(candidate, unlessExpr, `unless=\"${unlessExpr}\"`)) return false;\r\n        return true;\r\n    };\r\n\r\n    /** The contexts to render one copy for, or null when the loop source is unusable. */\r\n    const contextsToRender = (ctx: Context): Context[] | null => {\r\n        if (loopDef === null) return isVisible(ctx) ? [ctx] : [];\r\n\r\n        const items = resolvePath(ctx, source);\r\n\r\n        if (items === undefined) {\r\n            handleError(config, `Cannot resolve \"${source}\"`, `Loop source: \"${loopDef}\"`);\r\n            return null;\r\n        }\r\n\r\n        if (!Array.isArray(items)) {\r\n            handleError(config, `\"${source}\" is not an array in loop: \"${loopDef}\"`, `Element: <${tag}>`);\r\n            return null;\r\n        }\r\n\r\n        return items\r\n            .map(item => ({ ...ctx, [alias]: item }) as Context)\r\n            .filter(isVisible);\r\n    };\r\n\r\n    let instances: Instance[] = [];\r\n    let spare: Instance | null = null;\r\n\r\n    return (ctx: Context, fns?: FunctionsContext) => {\r\n        const contexts = contextsToRender(ctx);\r\n        if (!contexts) return;\r\n\r\n        const reuseCount = Math.min(instances.length, contexts.length);\r\n\r\n        // Re-render copies that are already in the DOM\r\n        for (let i = 0; i < reuseCount; i++) {\r\n            instances[i].render(contexts[i], fns);\r\n        }\r\n\r\n        // Remove excess copies, keeping the last one for re-use\r\n        for (let i = instances.length - 1; i >= contexts.length; i--) {\r\n            instances[i].element.remove();\r\n            spare = instances[i];\r\n        }\r\n\r\n        // Create missing copies via DocumentFragment for batch insertion\r\n        if (contexts.length > reuseCount) {\r\n            const fragment = document.createDocumentFragment();\r\n            const added: Instance[] = [];\r\n\r\n            for (let i = reuseCount; i < contexts.length; i++) {\r\n                let instance = spare;\r\n                spare = null;\r\n                if (!instance) {\r\n                    // 1-2. Clone (detached, no connectedCallback yet) and compile\r\n                    const clone = template.cloneNode(true) as Element;\r\n                    instance = { element: clone, render: compileDOM(clone, config) };\r\n                }\r\n\r\n                // 3. Render while detached; resolves mustache\r\n                instance.render(contexts[i], fns);\r\n\r\n                fragment.appendChild(instance.element);\r\n                added.push(instance);\r\n            }\r\n\r\n            // 4. Batch-insert into live DOM. Custom elements upgrade with final values\r\n            const insertAfter = reuseCount > 0 ? instances[reuseCount - 1].element : placeholder;\r\n            parent.insertBefore(fragment, insertAfter.nextSibling);\r\n\r\n            instances = instances.slice(0, reuseCount).concat(added);\r\n        } else {\r\n            instances.length = contexts.length;\r\n        }\r\n    };\r\n}\r\n\r\n/** Content patchers resolve mustache expressions and bind `r-<event>` handlers. */\r\nconst contentPatchers: Patcher[] = [\r\n    textNodePatcher,\r\n    attributeInterpolationPatcher,\r\n    eventPatcher,\r\n];\r\n\r\n/**\r\n * Walks the DOM tree and collects setters from patchers.\r\n *\r\n * Processing order per node:\r\n * 1. Try the structural patcher. If it matches, it owns the node (skip steps 2-3)\r\n * 2. Run content patchers (text interpolation, attribute interpolation)\r\n * 3. Recurse into child nodes\r\n */\r\nfunction compileDOM(root: Node, config: EngineConfig): (ctx: Context, fns?: FunctionsContext) => void {\r\n    const setters: Setter[] = [];\r\n    const get = createGetter(config);\r\n\r\n    function processNode(node: Node) {\r\n        // Structural directives own the node; they clone + compileDOM internally\r\n        const structural = structuralPatcher(node, get, config);\r\n        if (structural) {\r\n            setters.push(structural);\r\n            return;\r\n        }\r\n\r\n        // Content patchers: resolve {{expr}} in text and attributes\r\n        for (const patch of contentPatchers) {\r\n            const setter = patch(node, get, config);\r\n            if (setter) setters.push(setter);\r\n        }\r\n\r\n        for (const child of Array.from(node.childNodes)) {\r\n            processNode(child);\r\n        }\r\n    }\r\n\r\n    processNode(root);\r\n\r\n    // Return memoized render function\r\n    let lastCtx: Context | null = null;\r\n    let lastFns: FunctionsContext | undefined = undefined;\r\n    return (ctx: Context, fns?: FunctionsContext) => {\r\n        // Only re-render if context has changed\r\n        if (lastCtx !== ctx || lastFns !== fns) {\r\n            setters.forEach(fn => fn(ctx, fns));\r\n            lastCtx = ctx;\r\n            lastFns = fns;\r\n        }\r\n    };\r\n}\r\n\r\n/**\r\n * Result of compiling a template.\r\n * Contains the DOM content and a render function for updating it with data.\r\n */\r\nexport interface CompiledTemplate {\r\n    /** The compiled DOM element containing the template structure. */\r\n    content: DocumentFragment | HTMLElement;\r\n    /**\r\n     * Updates the DOM with the provided data context.\r\n     * Memoized: only re-renders when context object reference changes.\r\n     * @param ctx - Data context with values for template expressions\r\n     * @param fns - Optional functions context for callable expressions\r\n     */\r\n    render: (ctx: Context, fns?: FunctionsContext) => void;\r\n}\r\n\r\n/**\r\n * Compiles an HTML template string into a reusable render function.\r\n *\r\n * The template supports mustache-style expressions `{{expression}}` for:\r\n * - Path resolution: `{{user.name}}`, `{{items[0].title}}`\r\n * - Pipes: `{{value | uppercase}}`, `{{price | currency}}`\r\n * - Function calls: `{{formatDate(createdAt)}}`, `{{add(a, b)}}`\r\n *\r\n * Directive attributes for control flow:\r\n * - `if=\"condition\"` - Renders element only when condition is truthy\r\n * - `unless=\"condition\"` - Renders element only when condition is falsy\r\n * - `loop=\"item in items\"` - Repeats element for each array item\r\n * - `r-<event>=\"handler(args)\"` - Calls a function from the functions context\r\n *   on the named DOM event (`r-click`, `r-change`, `r-keypress`, ...);\r\n *   arguments resolve against the current data context\r\n *\r\n * @param templateStr - HTML template string with mustache expressions\r\n * @param config - Optional engine configuration\r\n * @returns Compiled template with content and render function\r\n *\r\n * @example\r\n * // Simple data binding\r\n * const { content, render } = compileTemplate('<h1>{{title}}</h1>');\r\n * render({ title: 'Hello World' });\r\n * document.body.appendChild(content);\r\n *\r\n * @example\r\n * // Re-rendering with new data\r\n * const { content, render } = compileTemplate('<span>Count: {{count}}</span>');\r\n * render({ count: 0 });\r\n * render({ count: 1 }); // DOM updates automatically\r\n *\r\n * @example\r\n * // With strict mode and error handling\r\n * const { render } = compileTemplate('{{missing}}', {\r\n *     strict: true,\r\n *     onError: (msg) => console.error(msg)\r\n * });\r\n * render({}); // Throws error for missing path\r\n *\r\n * @example\r\n * // Event handling in loops with r-<event>\r\n * const tpl = compileTemplate(`\r\n *     <ul>\r\n *         <li loop=\"row in rows\">\r\n *             {{row.name}}\r\n *             <button r-click=\"removeRow(row)\">x</button>\r\n *         </li>\r\n *     </ul>\r\n * `);\r\n *\r\n * // The handler is looked up in the functions context passed to render.\r\n * tpl.render(\r\n *     { rows: [{ id: 1, name: 'Apple' }] },\r\n *     { removeRow: (row) => console.log('remove', row.id) }\r\n * );\r\n * document.body.appendChild(tpl.content);\r\n */\r\nexport function compileTemplate(templateStr: string, config: EngineConfig = { strict: false }): CompiledTemplate {\r\n    const parser = new DOMParser();\r\n    const doc = parser.parseFromString(`<template><div>${templateStr}</div></template>`, 'text/html');\r\n    const content = doc.querySelector('template')!.content.firstElementChild as HTMLElement;\r\n    const render = compileDOM(content, config);\r\n\r\n    return { content, render };\r\n}", "/**\r\n * Represents a single step in a property access path\r\n * Can be either a property name or an array index access\r\n * @example { type: \"property\", key: \"user\" }\r\n * @example { type: \"index\", key: \"0\" }\r\n */\r\ntype PathSegment = {\r\n  type: \"property\" | \"index\";\r\n  key: string;\r\n};\r\n\r\n/**\r\n * Represents the result of parsing a dot-notation string into path segments\r\n * Used internally by the parser to break down property access chains including arrays\r\n * @example [{ type: \"property\", key: \"users\" }, { type: \"index\", key: \"0\" }, { type: \"property\", key: \"name\" }] for \"users[0].name\"\r\n */\r\ntype PropertyPath = PathSegment[];\r\n\r\n/**\r\n * Function type that accesses nested properties safely from a record\r\n * Returns undefined if any property in the chain is missing or null/undefined\r\n * @example\r\n * const accessor = createAccessor(\"user.name\");\r\n * const result = accessor(data); // string | undefined\r\n */\r\ntype PropertyAccessor<T = unknown> = (\r\n  record: Record<string, any>\r\n) => T | undefined;\r\n\r\n/**\r\n * Parser configuration options for customizing dot-notation parsing behavior\r\n * Used to modify how the parser handles property paths and edge cases\r\n * @example { delimiter: \".\", escapeChar: \"\\\\\" }\r\n */\r\ninterface ParserOptions {\r\n  delimiter?: string;\r\n  escapeChar?: string;\r\n}\r\n\r\n/**\r\n * Parses a dot-notation string with array support into path segments\r\n * Handles escaped delimiters, array indices, and validates input format\r\n * @param notation - Notation string with dots and brackets (e.g., \"users[0].profile.name\")\r\n * @param options - Parser configuration options\r\n * @returns Array of path segments for property and array access\r\n * @example\r\n * parsePath(\"user.profile.name\") // [{ type: \"property\", key: \"user\" }, { type: \"property\", key: \"profile\" }, { type: \"property\", key: \"name\" }]\r\n * parsePath(\"users[0].name\") // [{ type: \"property\", key: \"users\" }, { type: \"index\", key: \"0\" }, { type: \"property\", key: \"name\" }]\r\n * parsePath(\"data\\\\.file[1]\", { escapeChar: \"\\\\\" }) // [{ type: \"property\", key: \"data.file\" }, { type: \"index\", key: \"1\" }]\r\n */\r\nfunction parsePath(\r\n  notation: string,\r\n  options: ParserOptions = {}\r\n): PropertyPath {\r\n  const { delimiter = \".\", escapeChar = \"\\\\\" } = options;\r\n\r\n  if (!notation || typeof notation !== \"string\") {\r\n    throw new Error(\"Notation must be a non-empty string\");\r\n  }\r\n\r\n  const segments: PathSegment[] = [];\r\n  let current = \"\";\r\n  let i = 0;\r\n  let inBrackets = false;\r\n  let bracketContent = \"\";\r\n\r\n  while (i < notation.length) {\r\n    const char = notation[i];\r\n    const currentInDelimLength = notation.substring(i, delimiter.length + i);\r\n    const nextChar = notation[i + 1];\r\n    const nextInDelimLength = notation.substring(i + 1, delimiter.length + i + 1);\r\n\r\n    if (\r\n      char === escapeChar &&\r\n      (nextInDelimLength === delimiter || nextChar === \"[\" || nextChar === \"]\")\r\n    ) {\r\n      if (inBrackets) {\r\n        bracketContent += nextChar;\r\n      } else {\r\n        current += nextChar;\r\n      }\r\n      i += 2;\r\n    } else if (char === \"[\" && !inBrackets) {\r\n      if (current) {\r\n        segments.push({ type: \"property\", key: current });\r\n        current = \"\";\r\n      }\r\n      inBrackets = true;\r\n      bracketContent = \"\";\r\n      i++;\r\n    } else if (char === \"]\" && inBrackets) {\r\n      if (!/^\\d+$/.test(bracketContent.trim())) {\r\n        throw new Error(\r\n          `Invalid array index: [${bracketContent}]. Only numeric indices are supported.`\r\n        );\r\n      }\r\n      segments.push({ type: \"index\", key: bracketContent.trim() });\r\n      inBrackets = false;\r\n      bracketContent = \"\";\r\n      i++;\r\n    } else if (currentInDelimLength === delimiter && !inBrackets) {\r\n      if (current) {\r\n        segments.push({ type: \"property\", key: current });\r\n        current = \"\";\r\n      }\r\n      i += delimiter.length;\r\n    } else if (inBrackets) {\r\n      bracketContent += char;\r\n      i++;\r\n    } else {\r\n      current += char;\r\n      i++;\r\n    }\r\n  }\r\n\r\n  if (inBrackets) {\r\n    throw new Error(\"Unclosed bracket in notation\");\r\n  }\r\n\r\n  if (current) {\r\n    segments.push({ type: \"property\", key: current });\r\n  }\r\n\r\n  if (segments.length === 0) {\r\n    throw new Error(\r\n      \"Invalid notation: must contain at least one property or index\"\r\n    );\r\n  }\r\n\r\n  return segments;\r\n}\r\n\r\n/**\r\n * Creates an accessor function from a parsed property path with array support\r\n * The returned function safely navigates nested objects and arrays using the parsed path\r\n * @param path - Array of path segments to access in sequence\r\n * @returns Function that takes a record and returns the nested value or undefined\r\n * @example\r\n * const path = [{ type: \"property\", key: \"users\" }, { type: \"index\", key: \"0\" }, { type: \"property\", key: \"name\" }];\r\n * const accessor = createAccessorFromPath(path);\r\n * accessor({ users: [{ name: \"John\" }] }) // \"John\"\r\n */\r\nfunction createAccessorFromPath<T = unknown>(\r\n  path: PropertyPath\r\n): PropertyAccessor<T> {\r\n  return (record: Record<string, any>): T | undefined => {\r\n    let current: any = record;\r\n\r\n    for (const segment of path) {\r\n      if (current == null) {\r\n        return undefined;\r\n      }\r\n\r\n      if (segment.type === \"property\") {\r\n        if (typeof current !== \"object\") {\r\n          return undefined;\r\n        }\r\n        current = current[segment.key];\r\n      } else if (segment.type === \"index\") {\r\n        if (!Array.isArray(current)) {\r\n          return undefined;\r\n        }\r\n        const index = parseInt(segment.key, 10);\r\n        if (index < 0 || index >= current.length) {\r\n          return undefined;\r\n        }\r\n        current = current[index];\r\n      }\r\n    }\r\n\r\n    return current as T;\r\n  };\r\n}\r\n\r\n/**\r\n * Main parser function that creates an accessor from notation string with array support\r\n * Combines path parsing and accessor creation into a single operation\r\n * @param notation - Notation string with dots and brackets (e.g., \"users[0].profile.name\")\r\n * @param options - Parser configuration options\r\n * @returns Accessor function for the specified property path\r\n * @example\r\n * const accessor = createAccessor(\"user.profile.name\");\r\n * const name = accessor(userData); // safely gets nested property\r\n *\r\n * const arrayAccessor = createAccessor(\"users[0].name\");\r\n * const userName = arrayAccessor(data); // safely accesses array elements\r\n *\r\n * const complexAccessor = createAccessor(\"items[2].meta\\\\.data.values[1]\", { escapeChar: \"\\\\\" });\r\n * const value = complexAccessor(response); // handles escaped dots and nested arrays\r\n */\r\nfunction createAccessor<T = unknown>(\r\n  notation: string,\r\n  options: ParserOptions = {}\r\n): PropertyAccessor<T> {\r\n  const path = parsePath(notation, options);\r\n  return createAccessorFromPath<T>(path);\r\n}\r\n\r\n/**\r\n * Utility function to test if a property path exists in a record (with array support)\r\n * Useful for validation before attempting to access nested properties or array elements\r\n * @param notation - Notation string with dots and brackets to test\r\n * @param record - Record to test against\r\n * @param options - Parser configuration options\r\n * @returns Boolean indicating if the complete path exists\r\n * @example\r\n * hasProperty(\"user.name\", data) // true if data.user.name exists\r\n * hasProperty(\"users[0].name\", data) // true if data.users[0].name exists\r\n * hasProperty(\"missing.path\", data) // false if any part is undefined\r\n */\r\nfunction hasProperty(\r\n  notation: string,\r\n  record: Record<string, any>,\r\n  options: ParserOptions = {}\r\n): boolean {\r\n  const accessor = createAccessor(notation, options);\r\n  return accessor(record) !== undefined;\r\n}\r\n\r\nexport {\r\n  createAccessor,\r\n  createAccessorFromPath,\r\n  parsePath,\r\n  hasProperty,\r\n  type PropertyAccessor,\r\n  type PropertyPath,\r\n  type PathSegment,\r\n  type ParserOptions,\r\n};\r\n", "/**\r\n * Represents different token types that can be identified by the tokenizer\r\n * @example\r\n * // Use to classify what kind of syntax element was found\r\n * const tokenType = TokenType.Constant;\r\n */\r\nexport enum TokenType {\r\n  Constant = 0,\r\n  FunctionCall = 1,\r\n  Variable = 2,\r\n  Pipe = 3,\r\n}\r\n\r\n/**\r\n * Represents a token with its type and value\r\n * @example\r\n * // Creating a token for a number constant\r\n * const token: Token = { type: TokenType.Constant, value: '42' };\r\n */\r\nexport interface Token {\r\n  type: TokenType;\r\n  value: string;\r\n}\r\n\r\n/**\r\n * Tokenizes an input string into constants, function calls, and variables\r\n * @example\r\n * // Basic usage\r\n * const tokens = tokenize('myVar.property + func(42)');\r\n * \r\n * @example\r\n * // Handling complex expressions\r\n * const tokens = tokenize('math.sin(angle) + \"hello\".length');\r\n * \r\n * @example\r\n * // Handling pipes\r\n * const tokens = tokenize('input | transform | display');\r\n */\r\nexport function tokenize(input: string): Token[] {\r\n  const tokens: Token[] = [];\r\n  let i = 0;\r\n\r\n  while (i < input.length) {\r\n    let char = input[i];\r\n\r\n    // Skip whitespace\r\n    if (/\\s/.test(char)) {\r\n      i++;\r\n      continue;\r\n    }\r\n\r\n    // Handle pipe operator (\"|\")\r\n    if (char === '|') {\r\n      i++;\r\n\r\n      // Skip whitespace after pipe\r\n      while (i < input.length && /\\s/.test(input[i])) {\r\n        i++;\r\n      }\r\n\r\n      // Capture the pipe target (everything up to the next whitespace or special character)\r\n      let pipeTarget = '';\r\n      while (i < input.length && !/[\\s\\(\\)\\[\\]\\{\\}\\|\\+\\-\\*\\/\\=\\;\\,\\.]/.test(input[i])) {\r\n        pipeTarget += input[i];\r\n        i++;\r\n      }\r\n\r\n      tokens.push({ type: TokenType.Pipe, value: pipeTarget });\r\n      continue;\r\n    }\r\n\r\n    // Handle string constants\r\n    if (char === '\"' || char === \"'\") {\r\n      const quote = char;\r\n      let value = quote;\r\n      i++;\r\n\r\n      while (i < input.length && input[i] !== quote) {\r\n        // Handle escaped quotes\r\n        if (input[i] === '\\\\' && i + 1 < input.length && input[i + 1] === quote) {\r\n          value += '\\\\' + quote;\r\n          i += 2;\r\n        } else {\r\n          value += input[i];\r\n          i++;\r\n        }\r\n      }\r\n\r\n      if (i < input.length) {\r\n        value += quote;\r\n        i++;\r\n      }\r\n\r\n      tokens.push({ type: TokenType.Constant, value });\r\n      continue;\r\n    }\r\n\r\n    // Handle numeric constants\r\n    if (/[0-9]/.test(char)) {\r\n      let value = '';\r\n      let hasDecimal = false;\r\n\r\n      while (i < input.length && (/[0-9]/.test(input[i]) || (input[i] === '.' && !hasDecimal))) {\r\n        if (input[i] === '.') {\r\n          hasDecimal = true;\r\n        }\r\n        value += input[i];\r\n        i++;\r\n      }\r\n\r\n      tokens.push({ type: TokenType.Constant, value });\r\n      continue;\r\n    }\r\n\r\n    // Handle identifiers (variables and function calls with property/array access)\r\n    if (/[a-zA-Z_$]/.test(char)) {\r\n      let value = '';\r\n      let isFunctionCall = false;\r\n\r\n      // Capture identifier, including dots and bracket access\r\n      while (i < input.length) {\r\n        if (/[a-zA-Z0-9_$.]/.test(input[i])) {\r\n          value += input[i];\r\n          i++;\r\n        } else if (input[i] === '[') {\r\n          // Include array index expression like [0] or ['key']\r\n          let bracketCount = 1;\r\n          value += input[i++];\r\n          while (i < input.length && bracketCount > 0) {\r\n            if (input[i] === '[') bracketCount++;\r\n            if (input[i] === ']') bracketCount--;\r\n            value += input[i++];\r\n          }\r\n        } else {\r\n          break;\r\n        }\r\n      }\r\n\r\n      // Skip whitespace to check for function call\r\n      let wsCount = 0;\r\n      while (i < input.length && /\\s/.test(input[i])) {\r\n        wsCount++;\r\n        i++;\r\n      }\r\n\r\n      // Check if this is a function call\r\n      if (i < input.length && input[i] === '(') {\r\n        isFunctionCall = true;\r\n\r\n        value += '(';\r\n        i++;\r\n\r\n        let parenCount = 1;\r\n        while (i < input.length && parenCount > 0) {\r\n          if (input[i] === '(') parenCount++;\r\n          if (input[i] === ')') parenCount--;\r\n          value += input[i++];\r\n        }\r\n      } else {\r\n        // Restore skipped whitespace\r\n        i -= wsCount;\r\n      }\r\n\r\n      const lastToken = tokens[tokens.length - 1];\r\n      const isDotAfterConstant = input[i - value.length - 1] === '.' && lastToken?.type === TokenType.Constant;\r\n\r\n      tokens.push({\r\n        type: isFunctionCall || isDotAfterConstant ? TokenType.FunctionCall : TokenType.Variable,\r\n        value\r\n      });\r\n      continue;\r\n    }\r\n\r\n    // Handle operators and other characters\r\n    i++;\r\n  }\r\n\r\n  return tokens;\r\n}\r\n\r\n\r\n\r\n\r\n\r\n/** Functions */\r\n\r\nexport type ArgToken =\r\n  | { type: 'number'; value: number }\r\n  | { type: 'string'; value: string }\r\n  | { type: 'identifier'; value: string };\r\n\r\nexport function tokenizeArgs(input: string): ArgToken[] {\r\n  const tokens: ArgToken[] = [];\r\n\r\n  const start = input.indexOf('(');\r\n  const end = input.lastIndexOf(')');\r\n  if (start === -1 || end === -1 || end <= start) {\r\n    throw new Error('Invalid function call syntax');\r\n  }\r\n\r\n  const argsStr = input.slice(start + 1, end);\r\n  let i = 0;\r\n\r\n  while (i < argsStr.length) {\r\n    const char = argsStr[i];\r\n\r\n    if (/\\s/.test(char)) {\r\n      i++;\r\n      continue;\r\n    }\r\n\r\n    if (char === '\"' || char === \"'\") {\r\n      const quoteType = char;\r\n      let value = '';\r\n      i++;\r\n      while (i < argsStr.length && argsStr[i] !== quoteType) {\r\n        if (argsStr[i] === '\\\\') {\r\n          i++;\r\n          if (i < argsStr.length) {\r\n            value += argsStr[i];\r\n          }\r\n        } else {\r\n          value += argsStr[i];\r\n        }\r\n        i++;\r\n      }\r\n      if (i >= argsStr.length) {\r\n        throw new Error('Unterminated string in arguments');\r\n      }\r\n\r\n      i++; // skip closing quote\r\n      tokens.push({ type: 'string', value });\r\n      continue;\r\n    }\r\n\r\n\r\n    if (/[0-9]/.test(char)) {\r\n      let numStr = '';\r\n      while (i < argsStr.length && /[0-9.]/.test(argsStr[i])) {\r\n        numStr += argsStr[i];\r\n        i++;\r\n      }\r\n      tokens.push({ type: 'number', value: parseFloat(numStr) });\r\n      continue;\r\n    }\r\n\r\n    if (/[a-zA-Z_]/.test(char)) {\r\n      let ident = '';\r\n      while (i < argsStr.length && /[a-zA-Z0-9_\\.]/.test(argsStr[i])) {\r\n        ident += argsStr[i];\r\n        i++;\r\n      }\r\n      tokens.push({ type: 'identifier', value: ident });\r\n      continue;\r\n    }\r\n\r\n    if (char === ',') {\r\n      i++;\r\n      continue;\r\n    }\r\n\r\n    throw new Error(`Unexpected character in arguments: ${char}`);\r\n  }\r\n\r\n  return tokens;\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n/** For STRING/MUSTACHE */\r\n\r\nexport type MustacheTokenType = 'string' | 'mustache';\r\n\r\n/**\r\n * Represents a token extracted from a template string\r\n * @typedef {Object} MustahceToken\r\n * @property {MustacheTokenType} type - Either 'string' for plain text or 'mustache' for mustache expressions\r\n * @property {string} value - The actual content of the token\r\n */\r\nexport interface MustacheToken {\r\n  type: MustacheTokenType;\r\n  value: string;\r\n}\r\n\r\n/**\r\n * Tokenizes a template string into an array of string and mustache tokens\r\n * @param {string} template - The template string containing text and mustache expressions\r\n * @returns {MustacheToken[]} An array of tokens representing the parsed template\r\n *\r\n * @example\r\n * // Returns tokens for a simple greeting template\r\n * tokenizeTemplate(\"Hello, {{name}}!\");\r\n * // [\r\n * //   { type: 'string', value: 'Hello, ' },\r\n * //   { type: 'mustache', value: '{{name}}' },\r\n * //   { type: 'string', value: '!' }\r\n * // ]\r\n */\r\nexport function tokenizeMustache(template: string): MustacheToken[] {\r\n  const tokens: MustacheToken[] = [];\r\n  let currentIndex = 0;\r\n\r\n  while (currentIndex < template.length) {\r\n    const openTagIndex = template.indexOf('{{', currentIndex);\r\n\r\n    if (openTagIndex === -1) {\r\n      tokens.push(createStringToken(template.slice(currentIndex)));\r\n      break;\r\n    }\r\n\r\n    if (openTagIndex > currentIndex) {\r\n      tokens.push(createStringToken(template.slice(currentIndex, openTagIndex)));\r\n    }\r\n\r\n    const { value: mustache, endIndex, balanced } = extractMustache(template, openTagIndex);\r\n    if (!balanced) {\r\n      throw new Error(`Unclosed mustache tag starting at index ${openTagIndex}, template: ${template}`);\r\n    }\r\n    tokens.push(createMustacheToken(mustache));\r\n    currentIndex = endIndex;\r\n  }\r\n\r\n  return tokens;\r\n}\r\n\r\nfunction createStringToken(value: string): MustacheToken {\r\n  return { type: 'string', value };\r\n}\r\n\r\nfunction createMustacheToken(value: string): MustacheToken {\r\n  return { type: 'mustache', value };\r\n}\r\n\r\nfunction extractMustache(template: string, startIndex: number): {\r\n  value: string;\r\n  endIndex: number;\r\n  balanced: boolean;\r\n} {\r\n  const open = '{{';\r\n  const close = '}}';\r\n  let i = startIndex + open.length;\r\n  let depth = 1;\r\n\r\n  while (i < template.length && depth > 0) {\r\n    if (template.slice(i, i + open.length) === open) {\r\n      depth++;\r\n      i += open.length;\r\n    } else if (template.slice(i, i + close.length) === close) {\r\n      depth--;\r\n      i += close.length;\r\n    } else {\r\n      i++;\r\n    }\r\n  }\r\n\r\n  const balanced = depth === 0;\r\n  const endIndex = balanced ? i : template.length;\r\n  const value = template.slice(startIndex, endIndex);\r\n\r\n  return { value, endIndex, balanced };\r\n}\r\n", "import { defaultPipes, PipeFunction, PipeRegistry } from \"../pipes\";\r\nimport { createAccessor } from \"./accessorParser\";\r\nimport {\r\n  MustacheToken,\r\n  Token,\r\n  tokenize,\r\n  tokenizeArgs,\r\n  tokenizeMustache,\r\n  TokenType,\r\n} from \"./tokenizer\";\r\n\r\nexport type RenderTemplate = (data: Record<string, any>, component?: any) => string;\r\ntype ResolveValue = (data: Record<string, any>, component?: any) => any;\r\ntype ResolveFunctionValue = (data: Record<string, any>, component: any) => any;\r\ntype RenderPart = (data: Record<string, any>, component: any) => string;\r\n\r\nexport interface TemplateParserOptions {\r\n  pipeRegistry?: PipeRegistry;\r\n}\r\n\r\ninterface ExpressionChain {\r\n  source: ResolveValue;\r\n  pipes: PipeFunction[];\r\n}\r\n\r\nexport function compileMustard(template: string, options?: TemplateParserOptions): RenderTemplate {\r\n  const segments: RenderPart[] = tokenizeMustache(template).map(token =>\r\n    token.type === \"string\"\r\n      ? (_data, _component) => token.value\r\n      : compileExpression(token, options)\r\n  );\r\n\r\n  return (data, component) => segments.map(fn => fn(data, component)).join(\"\");\r\n}\r\n\r\nfunction compileExpression(token: MustacheToken, options?: TemplateParserOptions): RenderPart {\r\n  const tokens = tokenize(token.value);\r\n  const chain = buildExpressionChain(tokens, token.value, options?.pipeRegistry);\r\n  return renderFromChain(chain);\r\n}\r\n\r\nfunction buildExpressionChain(\r\n  tokens: Token[],\r\n  sourceText: string,\r\n  pipeRegistry?: PipeRegistry\r\n): ExpressionChain {\r\n  let chain: ExpressionChain | null = null;\r\n  if (!pipeRegistry){\r\n    pipeRegistry = defaultPipes;\r\n  }\r\n\r\n  for (const token of tokens) {\r\n    switch (token.type) {\r\n      case TokenType.Constant:\r\n        throw Error(`Constants not supported: ${token.value}`);\r\n\r\n      case TokenType.Variable: {\r\n        const accessor = createAccessor(token.value);\r\n        chain = { source: accessor, pipes: [] };\r\n        break;\r\n      }\r\n\r\n      case TokenType.FunctionCall: {\r\n        const func = resolveFunction(token.value);\r\n        chain = {\r\n          source: func,\r\n          pipes: []\r\n        };\r\n        break;\r\n      }\r\n\r\n      case TokenType.Pipe: {\r\n        if (!chain) throw Error(`Pipe '${token.value}' has no input expression in: ${sourceText}`);\r\n        if (!token.value || token.value === ''){\r\n          throw Error('Pipe symbol was provided, but no pipes. Template: ' + sourceText);\r\n        }\r\n\r\n        const [pipeName, ...args] = token.value.split(':').map((p) => p.trim());\r\n        const pipe = pipeRegistry.lookup(pipeName);\r\n        if (!pipe) throw Error(`Pipe not found: ${pipeName}`);\r\n        chain.pipes.push(value => pipe(value, args));\r\n        break;\r\n      }\r\n    }\r\n  }\r\n\r\n  if (!chain) throw Error(`Invalid expression: ${sourceText}`);\r\n  return chain;\r\n}\r\n\r\nfunction renderFromChain(chain: ExpressionChain): RenderPart {\r\n  return (data, component) => {\r\n    const initial = chain.source(data, component);\r\n    const result = chain.pipes.reduce((acc, fn) => fn(acc), initial);\r\n    return result != null ? result.toString() : \"\";\r\n  };\r\n}\r\n\r\nfunction resolveFunction(expression: string): ResolveFunctionValue {\r\n  const pos = expression.indexOf(\"(\");\r\n  if (pos === -1) throw Error(`Invalid function: ${expression}`);\r\n\r\n  const args = tokenizeArgs(expression);\r\n  const resolvedArgs: ((data: Record<string, any>) => any)[] = args.map(arg => {\r\n    if (arg.type === \"number\" || arg.type === \"string\") return () => arg.value;\r\n    if (arg.type === \"identifier\") return data => createAccessor(arg.value)(data);\r\n    throw Error(`Unsupported argument type: ${(arg as any).type}`);\r\n  });\r\n\r\n  const name = expression.substring(0, pos);\r\n  const fnAccessor = createAccessor(name);\r\n\r\n  return (data, component) => {\r\n    if (!component) throw Error(`Component context is required for calling '${name}'`);\r\n    const fn = fnAccessor(component);\r\n    if (typeof fn !== \"function\") throw Error(`Resolved '${name}' is not a function`);\r\n    const evaluatedArgs = resolvedArgs.map(argFn => argFn(data));\r\n    return fn.apply(component, evaluatedArgs);\r\n  };\r\n}\r\n", "import { compileMustard } from \"./parseTemplate\";\r\nimport { ArgToken, tokenizeArgs } from \"./tokenizer\";\r\n\r\ntype RawBinding =\r\n  | {\r\n    type: 'text';\r\n    path: number[];\r\n    func: (context: Record<string, any>, component: Record<string, any>, node: Node) => void;\r\n  }\r\n  | {\r\n    type: 'attribute';\r\n    path: number[];\r\n    name: string;\r\n    func: (context: Record<string, any>, component: Record<string, any>, element: HTMLElement) => void;\r\n  };\r\n\r\n/** @internal */\r\ntype ClickBinding = {\r\n  path: number[];\r\n  methodName: string;\r\n  argTokens: ArgToken[];\r\n};\r\n\r\n/** @internal */\r\ntype BoundBinding =\r\n  | {\r\n    type: 'text';\r\n    node: Node;\r\n    func: (context: Record<string, any>, node: Node) => void;\r\n  }\r\n  | {\r\n    type: 'attribute';\r\n    element: HTMLElement;\r\n    name: string;\r\n    func: (context: Record<string, any>, element: HTMLElement) => void;\r\n  };\r\n\r\nexport class BoundNode {\r\n  constructor(\r\n    private readonly root: HTMLElement,\r\n    private readonly bindings: BoundBinding[],\r\n    private readonly clickBindings: ClickBinding[],\r\n    private readonly component?: Record<string, any>\r\n  ) { }\r\n\r\n  render(data: Record<string, any>): HTMLElement {\r\n    for (const binding of this.bindings) {\r\n      if (binding.type === 'text') {\r\n        binding.func(data, binding.node);\r\n      } else {\r\n        binding.func(data, binding.element);\r\n      }\r\n    }\r\n\r\n    for (const click of this.clickBindings) {\r\n      const node = this.getNodeAtPath(this.root, click.path);\r\n      const method = this.component?.[click.methodName];\r\n\r\n      if (node instanceof HTMLElement && typeof method === 'function') {\r\n        node.onclick = (evt: Event) => {\r\n          const args = click.argTokens.map(token => {\r\n            if (token.type === 'number' || token.type === 'string') {\r\n              return token.value;\r\n            }\r\n            if (token.type === 'identifier') {\r\n              if (token.value === 'event') {\r\n                return evt;\r\n              }\r\n\r\n              const parts = token.value.split('.');\r\n              return parts.reduce((obj, key) => obj?.[key], data);\r\n            }\r\n          });\r\n          method.apply(this.component, args);\r\n        };\r\n      }\r\n    }\r\n\r\n    return this.root;\r\n  }\r\n\r\n  private getNodeAtPath(root: Node, path: number[]): Node {\r\n    return path.reduce((node, index) => node.childNodes[index], root);\r\n  }\r\n}\r\n\r\nexport function createBluePrint(html: string): Blueprint {\r\n  var bp = new Blueprint(html);\r\n  return bp;\r\n}\r\n\r\nexport class Blueprint {\r\n  private readonly template: HTMLTemplateElement;\r\n  private readonly bindings: RawBinding[];\r\n  private readonly clickBindings: ClickBinding[];\r\n\r\n  constructor(htmlOrTemplate: string | HTMLTemplateElement) {\r\n    if (typeof htmlOrTemplate === 'string') {\r\n      const trimmed = htmlOrTemplate.trim();\r\n      if (trimmed.startsWith('<template')) {\r\n        const wrapper = document.createElement('div');\r\n        wrapper.innerHTML = trimmed;\r\n        const found = wrapper.querySelector('template');\r\n        if (!found) throw new Error('Could not find <template> in input string');\r\n        this.template = found;\r\n      } else {\r\n        this.template = document.createElement('template');\r\n        this.template.innerHTML = trimmed;\r\n      }\r\n    } else {\r\n      this.template = htmlOrTemplate;\r\n    }\r\n\r\n    const rootElement = this.getRootElement();\r\n    this.bindings = this.collectBindings(rootElement);\r\n    this.clickBindings = this.collectClickBindings(rootElement);\r\n  }\r\n\r\n  createInstance(component?: Record<string, any>): BoundNode {\r\n    const rootClone = this.getRootElement().cloneNode(true) as HTMLElement;\r\n    const componentOrEmpty = component ?? {};\r\n\r\n    const boundBindings: BoundBinding[] = this.bindings.map(binding => {\r\n      const node = this.getNodeAtPath(rootClone, binding.path);\r\n      if (binding.type === 'text') {\r\n        return {\r\n          type: 'text',\r\n          node,\r\n          func: (data, node) => binding.func(data, componentOrEmpty, node)\r\n        };\r\n      } else {\r\n        return {\r\n          type: 'attribute',\r\n          element: node as HTMLElement,\r\n          name: binding.name,\r\n          func: (data, node) => binding.func(data, componentOrEmpty, node)\r\n        };\r\n      }\r\n    });\r\n\r\n    return new BoundNode(rootClone, boundBindings, this.clickBindings, component);\r\n  }\r\n\r\n  private getRootElement(): HTMLElement {\r\n    const el = Array.from(this.template.content.childNodes).find(\r\n      node => node.nodeType === Node.ELEMENT_NODE\r\n    );\r\n    if (!(el instanceof HTMLElement)) {\r\n      throw new Error('Template must contain a single root element');\r\n    }\r\n    return el;\r\n  }\r\n\r\n  private collectBindings(root: HTMLElement): RawBinding[] {\r\n    const bindings: RawBinding[] = [];\r\n\r\n    const walk = (node: Node, path: number[] = []) => {\r\n      if (node.nodeType === Node.TEXT_NODE && node.textContent) {\r\n        if (node.textContent.match(/\\{\\{\\s*(.*?)\\s*\\}\\}/g)) {\r\n          const func = compileMustard(node.textContent);\r\n          bindings.push({\r\n            type: 'text',\r\n            path: [...path],\r\n            func: (data, component, targetNode) => {\r\n              targetNode.textContent = func(data, component);\r\n            }\r\n          });\r\n        }\r\n      }\r\n\r\n      if (node.nodeType === Node.ELEMENT_NODE) {\r\n        const element = node as HTMLElement;\r\n\r\n        if (element.tagName === 'TEMPLATE') return;\r\n\r\n        for (let i = 0; i < element.attributes.length; i++) {\r\n          const attr = element.attributes[i];\r\n          if (attr.value.match(/\\{\\{\\s*(.*?)\\s*\\}\\}/g)) {\r\n            const func = compileMustard(attr.value);\r\n            bindings.push({\r\n              type: 'attribute',\r\n              path: [...path],\r\n              name: attr.name,\r\n              func: (data, component, el) => {\r\n                el.setAttribute(attr.name, func(data, component));\r\n              }\r\n            });\r\n          }\r\n        }\r\n\r\n        Array.from(node.childNodes).forEach((child, index) => {\r\n          walk(child, [...path, index]);\r\n        });\r\n      }\r\n    };\r\n\r\n    walk(root);\r\n    return bindings;\r\n  }\r\n\r\n  private collectClickBindings(root: Node): ClickBinding[] {\r\n    const bindings: ClickBinding[] = [];\r\n\r\n    const walk = (node: Node, path: number[] = []) => {\r\n      if (node.nodeType === Node.ELEMENT_NODE) {\r\n        const element = node as HTMLElement;\r\n        const clickAttr = element.getAttribute('click');\r\n        if (clickAttr?.trim()) {\r\n          const trimmed = clickAttr.trim();\r\n\r\n          const match = trimmed.match(/^([a-zA-Z_$][\\w$]*)\\s*\\((.*)\\)$/);\r\n          if (match) {\r\n            const methodName = match[1];\r\n            const argTokens = tokenizeArgs(trimmed);\r\n            bindings.push({ path: [...path], methodName, argTokens });\r\n          } else {\r\n            // No parentheses, treat as method with no args\r\n            bindings.push({ path: [...path], methodName: trimmed, argTokens: [] });\r\n          }\r\n        }\r\n\r\n        Array.from(node.childNodes).forEach((child, index) => {\r\n          walk(child, [...path, index]);\r\n        });\r\n      }\r\n    };\r\n\r\n    walk(root);\r\n    return bindings;\r\n  }\r\n\r\n  private getNodeAtPath(root: Node, path: number[]): Node {\r\n    return path.reduce((node, index) => node.childNodes[index], root);\r\n  }\r\n}\r\n", "export class TableRenderer {\r\n  private table: HTMLTableElement;\r\n  private template: HTMLTemplateElement;\r\n  private component: HTMLElement;\r\n  private dataMap = new Map<string, Record<string, any>>();\r\n  private rowMap = new Map<string, HTMLTableRowElement>();\r\n\r\n  public IdColumn: string;\r\n\r\n  constructor(\r\n    table: HTMLTableElement,\r\n    template: HTMLTemplateElement,\r\n    idColumn: string,\r\n    component: HTMLElement\r\n  ) {\r\n    this.table = table;\r\n    this.template = template;\r\n    this.IdColumn = idColumn;\r\n    this.component = component;\r\n  }\r\n\r\n  public render(data: Record<string, any>[]) {\r\n    this.clearRows();\r\n    for (const item of data) {\r\n      this.renderRow(item);\r\n    }\r\n  }\r\n\r\n  private clearRows(): void {\r\n    this.table.tBodies[0].innerHTML = '';\r\n    this.dataMap.clear();\r\n    this.rowMap.clear();\r\n  }\r\n\r\n  private renderRow(data: Record<string, any>): void {\r\n    const id = data[this.IdColumn];\r\n    if (id === undefined || id === null) {\r\n      throw new Error(`Missing IdColumn '${this.IdColumn}' in data`);\r\n    }\r\n\r\n    const row = this.template.content.firstElementChild?.cloneNode(true) as HTMLTableRowElement;\r\n    if (!row) throw new Error(\"Template must have a <tr> as its first child\");\r\n\r\n    this.populateRow(row, data);\r\n    this.attachEventHandlers(row, data);\r\n\r\n    this.table.tBodies[0].appendChild(row);\r\n    this.dataMap.set(id, data);\r\n    this.rowMap.set(id, row);\r\n  }\r\n\r\n  private populateRow(row: HTMLTableRowElement, data: Record<string, any>): void {\r\n    const cells = row.querySelectorAll('[data-field]');\r\n    cells.forEach((cell) => {\r\n      const field = (cell as HTMLElement).dataset.field;\r\n      if (field && field in data) {\r\n        cell.textContent = String(data[field]);\r\n      }\r\n    });\r\n  }\r\n\r\n  private attachEventHandlers(row: HTMLElement, data: Record<string, any>): void {\r\n    const interactiveElements = row.querySelectorAll('[onclick]');\r\n    interactiveElements.forEach((el) => {\r\n      const element = el as HTMLElement;\r\n      const handlerAttr = element.getAttribute('onclick');\r\n      if (!handlerAttr) return;\r\n\r\n      const match = handlerAttr.match(/^(\\w+)(\\(([^)]*)\\))?$/);\r\n      if (!match) return;\r\n\r\n      const [, methodName, , argStr] = match;\r\n      const args = argStr ? argStr.split(',').map(s => s.trim().replace(/^['\"]|['\"]$/g, '')) : [];\r\n\r\n      if (typeof (this.component as any)[methodName] === 'function') {\r\n        element.removeAttribute('onclick');\r\n        element.addEventListener('click', (event) => {\r\n          (this.component as any)[methodName](...args, data, event);\r\n        });\r\n      }\r\n    });\r\n  }\r\n\r\n  public update(data: Record<string, any>) {\r\n    const id = data[this.IdColumn];\r\n    if (id === undefined || id === null) {\r\n      throw new Error(`Missing IdColumn '${this.IdColumn}' in update data`);\r\n    }\r\n\r\n    const row = this.rowMap.get(id);\r\n    if (!row) {\r\n      this.renderRow(data);\r\n    } else {\r\n      this.populateRow(row, data);\r\n      this.attachEventHandlers(row, data);\r\n      this.dataMap.set(id, data);\r\n    }\r\n  }\r\n}\r\n\r\nexport class SortChangeEvent extends CustomEvent<SortColumn[]> {\r\n  constructor(sortColumns: SortColumn[]) {\r\n    super('sortchange', {\r\n      detail: sortColumns,\r\n      bubbles: true,\r\n      composed: true,\r\n    });\r\n  }\r\n}\r\n\r\n\r\n/** @internal */\r\ntype SortDirection = 'asc' | 'desc';\r\nexport type SortColumn = { column: string; direction: SortDirection };\r\n\r\nexport class TableSorter {\r\n  private table: HTMLTableElement;\r\n  private sortColumns: SortColumn[] = [];\r\n  private component: HTMLElement;\r\n\r\n  constructor(table: HTMLTableElement, component: HTMLElement) {\r\n    this.table = table;\r\n    this.component = component;\r\n    this.setupListeners();\r\n  }\r\n\r\n  private setupListeners() {\r\n    const headers = this.table.tHead?.querySelectorAll('th[name]');\r\n    headers?.forEach((th) => {\r\n      th.addEventListener('click', () => {\r\n        const column = th.getAttribute('name')!;\r\n        this.toggle(column);\r\n        this.updateSortIndicators();\r\n        this.emit();\r\n      });\r\n    });\r\n  }\r\n\r\n  private toggle(column: string) {\r\n    const index = this.sortColumns.findIndex(c => c.column === column);\r\n\r\n    if (index === -1) {\r\n      this.sortColumns.push({ column, direction: 'asc' });\r\n    } else if (this.sortColumns[index].direction === 'asc') {\r\n      this.sortColumns[index].direction = 'desc';\r\n    } else {\r\n      this.sortColumns.splice(index, 1);\r\n    }\r\n  }\r\n\r\n  private emit() {\r\n    const event = new SortChangeEvent(this.sortColumns);\r\n        this.component.dispatchEvent(event);\r\n  }\r\n\r\n   private updateSortIndicators() {\r\n    const headers = this.table.tHead?.querySelectorAll('th[name]');\r\n    headers?.forEach((el) => {\r\n      const th = el as HTMLElement;\r\n      // Remove existing indicators\r\n      const existingIndicator = th.querySelector('.sort-indicator') as HTMLElement;\r\n      if (existingIndicator) {\r\n        th.removeChild(existingIndicator);\r\n      }\r\n\r\n      // Get column name and find if it's sorted\r\n      const column = th.getAttribute('name')!;\r\n      const sortInfo = this.sortColumns.find(c => c.column === column);\r\n      \r\n      if (sortInfo) {\r\n        // Create indicator element\r\n        const indicator = document.createElement('span');\r\n        indicator.className = 'sort-indicator';\r\n        indicator.textContent = sortInfo.direction === 'asc' ? '\u2191' : '\u2193';\r\n        \r\n        // Style for right alignment\r\n        indicator.style.float = 'right';\r\n        indicator.style.marginLeft = '5px';\r\n        \r\n        // Append to header\r\n        th.appendChild(indicator);\r\n      }\r\n      \r\n      // Ensure header is positioned relatively for absolute positioning if needed\r\n      if (!th.style.position) {\r\n        th.style.position = 'relative';\r\n      }\r\n    });\r\n  }\r\n\r\n  public getSortColumns(): SortColumn[] {\r\n    return [...this.sortColumns];\r\n  }\r\n\r\n  public clear() {\r\n    this.sortColumns = [];\r\n    this.updateSortIndicators();\r\n    this.emit();\r\n  }\r\n}\r\n\r\ndeclare global {\r\n  interface HTMLTableElementEventMap extends HTMLElementEventMap {\r\n    'sortchange': SortChangeEvent;\r\n  }\r\n\r\n  interface HTMLTableElement {\r\n    addEventListener<K extends keyof HTMLTableElementEventMap>(\r\n      type: K,\r\n      listener: (this: HTMLTableElement, ev: HTMLTableElementEventMap[K]) => any,\r\n      options?: boolean | AddEventListenerOptions\r\n    ): void;\r\n  }\r\n}"],
  "mappings": "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",
  "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", "uppercasePipe", "value", "trimPipe", "lowercasePipe", "capitalizePipe", "str", "shortenPipe", "length", "maxLength", "currencyPipe", "currency", "locale", "getCurrentLocale", "datePipe", "format", "date", "daysAgoPipe", "inputDate", "today", "diffTime", "diffDays", "t", "piecesPipe", "count", "joinPipe", "separator", "firstPipe", "lastPipe", "keysPipe", "defaultPipe", "defaultValue", "ternaryPipe", "trueValue", "falseValue", "createPipeRegistry", "pipes", "name", "pipe", "defaultPipes", "applyPipes", "registry", "currentValue", "pipeName", "args", "p", "error", "pipes", "defaultPipes", "html", "templateStrings", "substitutions", "template", "resolvedTemplate", "resolveTemplate", "bindings", "walker", "node", "element", "processElement", "myNode", "text", "result", "parseTemplate", "startMarker", "endMarker", "insertedNodes", "instance", "value", "n", "temp", "nodes", "parent", "context", "x", "str", "i", "attrBindings", "attr", "attrValue", "regex", "match", "index", "func", "boundFunction", "attributeCallback", "attrBinding", "parseArguments", "argsStr", "arg", "parts", "part", "lastIndex", "textBindings", "_instance", "sub", "mustacheName", "matchingPipes", "pipe", "args", "val", "_", "binding", "parseExpression", "expr", "pipesSplit", "mainExpr", "pipes", "fnMatch", "fnName", "argsStr", "fnArgs", "a", "resolvePath", "ctx", "path", "segments", "current", "key", "handleError", "config", "message", "context", "shouldThrow", "formattedMessage", "createGetter", "debugInfo", "err", "errorMessage", "evaluateExpression", "parsed", "fns", "value", "registry", "defaultPipes", "fn", "resolvedArgs", "arg", "resolved", "applyPipes", "expressionCache", "splitInterpolation", "raw", "parts", "part", "composeParts", "literal", "textNodePatcher", "node", "_get", "liveValueAttributes", "attributeInterpolationPatcher", "element", "setters", "attributes", "attr", "name", "wholeValue", "eventPatcher", "tag", "rAttributes", "updaters", "eventName", "currentCtx", "currentFns", "event", "ctxWithEvent", "structuralAttributes", "structuralPatcher", "get", "loopDef", "ifExpr", "unlessExpr", "alias", "source", "match", "template", "placeholder", "parent", "isVisible", "candidate", "contextsToRender", "items", "item", "instances", "spare", "contexts", "reuseCount", "i", "fragment", "added", "instance", "clone", "compileDOM", "insertAfter", "contentPatchers", "root", "processNode", "structural", "patch", "setter", "child", "lastCtx", "lastFns", "compileTemplate", "templateStr", "content", "render", "parsePath", "notation", "options", "delimiter", "escapeChar", "segments", "current", "i", "inBrackets", "bracketContent", "char", "currentInDelimLength", "nextChar", "nextInDelimLength", "createAccessorFromPath", "path", "record", "segment", "index", "createAccessor", "tokenize", "input", "tokens", "i", "char", "pipeTarget", "quote", "value", "hasDecimal", "isFunctionCall", "bracketCount", "wsCount", "parenCount", "lastToken", "isDotAfterConstant", "tokenizeArgs", "start", "end", "argsStr", "quoteType", "numStr", "ident", "tokenizeMustache", "template", "currentIndex", "openTagIndex", "createStringToken", "mustache", "endIndex", "balanced", "extractMustache", "createMustacheToken", "startIndex", "open", "close", "depth", "compileMustard", "template", "options", "segments", "tokenizeMustache", "token", "_data", "_component", "compileExpression", "data", "component", "fn", "tokens", "tokenize", "chain", "buildExpressionChain", "renderFromChain", "sourceText", "pipeRegistry", "defaultPipes", "createAccessor", "resolveFunction", "pipeName", "args", "p", "pipe", "value", "initial", "result", "acc", "expression", "pos", "resolvedArgs", "tokenizeArgs", "arg", "name", "fnAccessor", "evaluatedArgs", "argFn", "BoundNode", "root", "bindings", "clickBindings", "component", "data", "binding", "click", "node", "method", "evt", "args", "token", "obj", "key", "path", "index", "createBluePrint", "html", "bp", "Blueprint", "htmlOrTemplate", "trimmed", "wrapper", "found", "rootElement", "rootClone", "componentOrEmpty", "boundBindings", "el", "walk", "func", "compileMustard", "targetNode", "element", "attr", "child", "clickAttr", "match", "methodName", "argTokens", "tokenizeArgs", "TableRenderer", "table", "template", "idColumn", "component", "data", "item", "id", "row", "cell", "field", "el", "element", "handlerAttr", "match", "methodName", "argStr", "args", "s", "event", "SortChangeEvent", "sortColumns", "TableSorter", "th", "column", "index", "c", "existingIndicator", "sortInfo", "indicator"]
}
