@lionrapid/core 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/browser/auto-init.d.ts +8 -3
  2. package/dist/browser/auto-init.d.ts.map +1 -1
  3. package/dist/browser/auto-init.js +34 -26
  4. package/dist/browser/auto-init.js.map +1 -1
  5. package/dist/browser/lionrapid.auto.dev.js +267 -24
  6. package/dist/browser/lionrapid.auto.dev.js.map +2 -2
  7. package/dist/browser/lionrapid.auto.js +267 -24
  8. package/dist/browser/lionrapid.auto.js.map +2 -2
  9. package/dist/browser/lionrapid.auto.min.js +4 -4
  10. package/dist/browser/lionrapid.auto.min.js.map +3 -3
  11. package/dist/browser/lionrapid.esm.js +241 -2
  12. package/dist/browser/lionrapid.esm.js.map +2 -2
  13. package/dist/browser/lionrapid.esm.min.js +3 -3
  14. package/dist/browser/lionrapid.esm.min.js.map +3 -3
  15. package/dist/browser/lionrapid.iife.dev.js +241 -2
  16. package/dist/browser/lionrapid.iife.dev.js.map +2 -2
  17. package/dist/browser/lionrapid.iife.js +241 -2
  18. package/dist/browser/lionrapid.iife.js.map +2 -2
  19. package/dist/browser/lionrapid.iife.min.js +3 -3
  20. package/dist/browser/lionrapid.iife.min.js.map +3 -3
  21. package/dist/browser/lionrapid.umd.js +241 -2
  22. package/dist/browser/lionrapid.umd.js.map +2 -2
  23. package/dist/browser/lionrapid.umd.min.js +3 -3
  24. package/dist/browser/lionrapid.umd.min.js.map +3 -3
  25. package/dist/browser/storage/cache-storage-repository.d.ts +65 -0
  26. package/dist/browser/storage/cache-storage-repository.d.ts.map +1 -1
  27. package/dist/browser/storage/cache-storage-repository.js +77 -7
  28. package/dist/browser/storage/cache-storage-repository.js.map +1 -1
  29. package/dist/browser/storage/localstorage-repository.d.ts +62 -0
  30. package/dist/browser/storage/localstorage-repository.d.ts.map +1 -1
  31. package/dist/browser/storage/localstorage-repository.js +71 -4
  32. package/dist/browser/storage/localstorage-repository.js.map +1 -1
  33. package/dist/config/repository.config.d.ts +17 -0
  34. package/dist/config/repository.config.d.ts.map +1 -1
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/repositories/network-repository.d.ts +42 -1
  39. package/dist/repositories/network-repository.d.ts.map +1 -1
  40. package/dist/repositories/network-repository.js +161 -1
  41. package/dist/repositories/network-repository.js.map +1 -1
  42. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/browser/index.ts", "../../src/config/logger.config.ts", "../../src/utils/logger.ts", "../../src/utils/locale.ts", "../../src/base/event-emitter.ts", "../../src/handlers/handler-chain.ts", "../../src/utils/namespace-utils.ts", "../../src/utils/context-utils.ts", "../../src/utils/translation-value-utils.ts", "../../src/utils/translation-flow.ts", "../../src/handlers/sync-storage-handler.ts", "../../src/handlers/async-storage-handler.ts", "../../src/errors/translation-errors.ts", "../../src/handlers/network-handler.ts", "../../src/content/canonical-tag.ts", "../../src/content/parser/MarkupParser.ts", "../../src/content/sanitizer/HTMLSanitizer.ts", "../../src/content/serializer/HTMLSerializer.ts", "../../src/cache/CacheManager.ts", "../../src/lionRapid.ts", "../../src/repositories/memory-repository.ts", "../../src/repositories/static-repository.ts", "../../src/sync/missing-translation-queue.ts", "../../src/builder.ts", "../../src/repositories/network-repository.ts", "../../src/browser/exclude-filter.ts", "../../src/browser/markup-parser.ts", "../../src/browser/md5.ts", "../../src/browser/block-extractor.ts", "../../src/browser/attribute-extractor.ts", "../../src/browser/dom-observer.ts", "../../src/browser/auto-translator.ts", "../../src/browser/language-switcher.ts", "../../src/browser/storage/localstorage-repository.ts", "../../src/browser/storage/cache-storage-repository.ts", "../../src/browser/auto-init.ts"],
4
- "sourcesContent": ["/**\n * Browser Bundle Entry Point\n * Auto-init bundle for non-developer usage with script tag\n *\n * Usage:\n * <script\n * src=\"https://cdn.lionrapid.com/lionrapid.min.js\"\n * data-api-key=\"pk_live_xxx\"\n * ></script>\n */\n\n// Core exports for advanced usage\nexport { LionRapidBuilder } from '../builder.js';\nexport { LionRapidCore } from '../lionRapid.js';\nexport { MemoryRepository, NetworkRepository } from '../repositories/index.js';\n\n// Browser-specific exports\nexport { AutoTranslator } from './auto-translator.js';\nexport type { AutoTranslatorConfig } from './auto-translator.js';\n\nexport { LanguageSwitcher } from './language-switcher.js';\nexport type { Language, SwitcherStyle } from './language-switcher.js';\n\nexport { BlockExtractor } from './block-extractor.js';\nexport type { ExtractedBlock } from './block-extractor.js';\n\nexport { AttributeExtractor } from './attribute-extractor.js';\nexport type { ExtractedAttribute } from './attribute-extractor.js';\n\nexport { parseBlockElement } from './markup-parser.js';\n\nexport { ExcludeFilter } from './exclude-filter.js';\nexport type { ExcludePatterns } from './exclude-filter.js';\n\nexport { DOMObserver } from './dom-observer.js';\nexport type { DOMObserverCallbacks } from './dom-observer.js';\n\n\nexport { md5, generateAutoKey } from './md5.js';\n\n// Storage exports\nexport { LocalStorageRepository } from './storage/localstorage-repository.js';\nexport type { LocalStorageRepositoryConfig } from './storage/localstorage-repository.js';\n\nexport { CacheStorageRepository } from './storage/cache-storage-repository.js';\nexport type { CacheStorageRepositoryConfig } from './storage/cache-storage-repository.js';\n\n// Auto-init (runs on script load)\nexport { autoInit, parseConfig } from './auto-init.js';\nexport type { AutoInitConfig, LionRapidInstance } from './auto-init.js';\n", "export enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n NONE = 4,\n}\n\nexport interface LoggerConfig {\n level?: LogLevel;\n enabled?: boolean;\n prefix?: string;\n showLineNumbers?: boolean;\n useColors?: boolean;\n}\n\nexport interface PackageLoggerConfig extends LoggerConfig {\n packageName?: string;\n packageEmoji?: string;\n}\n", "import type { LoggerConfig } from '../config/logger.config.js';\nimport { LogLevel } from '../config/logger.config.js';\n\n// Browser-safe env access \u2014 `process` is a Node global and is undeclared\n// in browser contexts, so a bare `process.env.NODE_ENV` throws\n// `ReferenceError: process is not defined` when this module is imported\n// directly into a browser (e.g., a Vite/Webpack project that doesn't\n// pre-bundle deps from node_modules, or `<script type=module>` consumers).\n// Bundlers like esbuild/Vite still statically substitute `process.env.X`\n// inside the conditional at build time; in unbundled environments we\n// fall back to an empty object so reads are `undefined`, never throw.\nconst _ENV: Record<string, string | undefined> =\n typeof process !== 'undefined' && process.env ? process.env : {};\n\n// Build-time constants for dead code elimination\nconst IS_PRODUCTION = _ENV.NODE_ENV === 'production';\nconst IS_DEVELOPMENT = _ENV.NODE_ENV === 'development';\nconst IS_CI = _ENV.CI === 'true';\nconst LIONRAPID_DEV = _ENV.LIONRAPID_DEV === 'true';\nconst PERFORMANCE_TRACKING = _ENV.LIONRAPID_PERFORMANCE_TRACKING === 'true';\n\n/**\n * Read a runtime log-level override from localStorage in browser contexts.\n * Lets a developer flip on verbose logging without a rebuild via\n * localStorage.LIONRAPID_LOG_LEVEL = 'DEBUG'\n * Returns null on SSR or restrictive sandboxes.\n */\nfunction readBrowserLogLevel(): string | null {\n try {\n if (typeof localStorage !== 'undefined') {\n const v = localStorage.getItem('LIONRAPID_LOG_LEVEL');\n if (v && typeof v === 'string') return v;\n }\n } catch {\n // localStorage unavailable (privacy mode, file://, etc.) \u2014 ignore\n }\n return null;\n}\n\n// Environment-specific configuration.\n// Default is WARN \u2014 quiet by default. Customers consuming the published\n// ESM bundles via npm don't get noisy debug/info chatter on every page load.\n// Override via:\n// - build-time: process.env.LOG_LEVEL=DEBUG\n// - runtime (browser): localStorage.LIONRAPID_LOG_LEVEL = 'DEBUG'\n// - runtime (programmatic): logger.configure({ level: LogLevel.DEBUG })\nconst LOG_LEVEL_ENV = readBrowserLogLevel() || _ENV.LOG_LEVEL || 'WARN';\n\n/**\n * ANSI color codes for terminal output\n */\nexport const Colors = {\n // Reset\n RESET: '\\x1b[0m',\n // Foreground colors\n BLACK: '\\x1b[30m',\n RED: '\\x1b[31m',\n GREEN: '\\x1b[32m',\n YELLOW: '\\x1b[33m',\n BLUE: '\\x1b[34m',\n MAGENTA: '\\x1b[35m',\n CYAN: '\\x1b[36m',\n WHITE: '\\x1b[37m',\n ORANGE: '\\x1b[38;5;208m',\n // Bright foreground colors\n BRIGHT_BLACK: '\\x1b[90m',\n BRIGHT_RED: '\\x1b[91m',\n BRIGHT_GREEN: '\\x1b[92m',\n BRIGHT_YELLOW: '\\x1b[93m',\n BRIGHT_BLUE: '\\x1b[94m',\n BRIGHT_MAGENTA: '\\x1b[95m',\n BRIGHT_CYAN: '\\x1b[96m',\n BRIGHT_WHITE: '\\x1b[97m',\n // Styles\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m',\n UNDERLINE: '\\x1b[4m',\n} as const;\n\nexport interface CallSite {\n fileName: string;\n lineNumber: number;\n functionName?: string;\n}\n\nexport interface PackageLoggerConfig extends LoggerConfig {\n packageName?: string;\n packageEmoji?: string;\n}\n\n// Development logger class - completely eliminated in production\nclass DevelopmentLogger {\n private config: Required<LoggerConfig>;\n\n constructor(config: PackageLoggerConfig = {}) {\n this.config = {\n level: this.getLogLevelFromEnv(),\n enabled: this.shouldEnableLogging(),\n prefix: `${config.packageEmoji || '\uD83D\uDCE6'} ${config.packageName || 'LionRapid'}`,\n showLineNumbers: LIONRAPID_DEV && !IS_CI,\n useColors: this.shouldUseColors(),\n ...config,\n };\n }\n\n configure(config: Partial<LoggerConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n debug(message: string, data?: unknown): void {\n if (!this.config.enabled || this.config.level > LogLevel.DEBUG) return;\n this.log(LogLevel.DEBUG, message, data);\n }\n\n info(message: string, data?: unknown): void {\n if (this.config.level > LogLevel.INFO) return;\n this.log(LogLevel.INFO, message, data);\n }\n\n warn(message: string, data?: unknown): void {\n this.log(LogLevel.WARN, message, data);\n }\n\n error(message: string, data?: unknown): void {\n this.log(LogLevel.ERROR, message, data);\n }\n\n time(label: string): () => void {\n if (!PERFORMANCE_TRACKING || IS_PRODUCTION) return () => {};\n\n const start = IS_DEVELOPMENT ? performance.now() : 0;\n return () => {\n if (IS_DEVELOPMENT) {\n const duration = performance.now() - start;\n this.debug(`\u23F1\uFE0F ${label}: ${duration.toFixed(2)}ms`, { duration });\n }\n };\n }\n\n private log(level: LogLevel, message: string, data?: unknown): void {\n if (!this.config.enabled || level < this.config.level) return;\n\n const levelName = LogLevel[level];\n const levelEmoji = this.getLevelEmoji(level);\n const callSite = this.config.showLineNumbers ? this.getCallSite() : null;\n\n const logMessage = this.buildColoredMessage(\n level,\n levelEmoji,\n levelName,\n message,\n callSite,\n data\n );\n\n switch (level) {\n case LogLevel.ERROR:\n console.error(logMessage);\n break;\n case LogLevel.WARN:\n console.warn(logMessage);\n break;\n case LogLevel.INFO:\n console.info(logMessage);\n break;\n default:\n console.log(logMessage);\n }\n }\n\n private buildColoredMessage(\n level: LogLevel,\n emoji: string,\n levelName: string,\n message: string,\n callSite: CallSite | null,\n data?: unknown\n ): string {\n if (!this.config.useColors) {\n const locationInfo = callSite\n ? ` (${callSite.fileName}:${callSite.lineNumber})`\n : '';\n let logMessage = `${this.config.prefix} ${emoji} ${levelName} ${message}${locationInfo}`;\n if (data !== undefined) {\n logMessage += ` ${JSON.stringify(data)}`;\n }\n return logMessage;\n }\n\n const levelColor = this.getLevelColor(level);\n const reset = Colors.RESET;\n\n const coloredPrefix = `${Colors.BOLD}${Colors.ORANGE}${this.config.prefix}${reset}`;\n const coloredEmoji = emoji;\n const coloredLevel = `${levelColor}${Colors.BOLD}${levelName}${reset}`;\n const coloredMessage = `${levelColor}${message}${reset}`;\n\n const locationInfo = callSite\n ? `${Colors.DIM}${Colors.BRIGHT_BLACK} (${callSite.fileName}:${callSite.lineNumber})${reset}`\n : '';\n\n const dataInfo =\n data !== undefined\n ? `${Colors.DIM}${Colors.CYAN} ${JSON.stringify(data)}${reset}`\n : '';\n\n return `${coloredPrefix} ${coloredEmoji} ${coloredLevel} ${coloredMessage}${locationInfo}${dataInfo}`;\n }\n\n private getLevelColor(level: LogLevel): string {\n switch (level) {\n case LogLevel.DEBUG:\n return Colors.BRIGHT_GREEN;\n case LogLevel.INFO:\n return Colors.BRIGHT_CYAN;\n case LogLevel.WARN:\n return Colors.BRIGHT_YELLOW;\n case LogLevel.ERROR:\n return Colors.BRIGHT_RED;\n default:\n return Colors.BRIGHT_BLACK;\n }\n }\n\n private getLevelEmoji(level: LogLevel): string {\n switch (level) {\n case LogLevel.DEBUG:\n return '\uD83D\uDD0D';\n case LogLevel.INFO:\n return '\u2139\uFE0F';\n case LogLevel.WARN:\n return '\u26A0\uFE0F';\n case LogLevel.ERROR:\n return '\u274C';\n default:\n return '\uD83D\uDCDD';\n }\n }\n\n private getCallSite(): CallSite | null {\n try {\n const stack = new Error().stack;\n if (!stack) return null;\n\n const lines = stack.split('\\n');\n for (let i = 3; i < lines.length; i++) {\n const line = lines[i];\n if (line && !line.includes('logger.ts') && !line.includes('Logger')) {\n return this.parseStackLine(line);\n }\n }\n } catch {\n // Ignore errors\n }\n return null;\n }\n\n private parseStackLine(line: string): CallSite | null {\n let match = line.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n return {\n functionName: match[1],\n fileName: this.extractFileName(match[2]),\n lineNumber: parseInt(match[3], 10),\n };\n }\n\n match = line.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (match) {\n return {\n fileName: this.extractFileName(match[1]),\n lineNumber: parseInt(match[2], 10),\n };\n }\n\n return null;\n }\n\n private extractFileName(filePath: string): string {\n const parts = filePath.split('/');\n return parts[parts.length - 1] || filePath;\n }\n\n colorize(text: string, color: keyof typeof Colors): string {\n if (!this.config.useColors) return text;\n return `${Colors[color]}${text}${Colors.RESET}`;\n }\n\n getColors(): typeof Colors {\n return Colors;\n }\n\n createPackageLogger(\n packageName: string,\n packageEmoji?: string\n ): DevelopmentLogger {\n return new DevelopmentLogger({\n ...this.config,\n packageName,\n packageEmoji: packageEmoji || '\uD83D\uDCE6',\n });\n }\n\n private getLogLevelFromEnv(): LogLevel {\n switch (LOG_LEVEL_ENV.toUpperCase()) {\n case 'DEBUG':\n return LogLevel.DEBUG;\n case 'INFO':\n return LogLevel.INFO;\n case 'WARN':\n return LogLevel.WARN;\n case 'ERROR':\n return LogLevel.ERROR;\n case 'NONE':\n return LogLevel.NONE;\n default:\n // Unknown level \u2192 quiet fallback (WARN).\n return LogLevel.WARN;\n }\n }\n\n private shouldEnableLogging(): boolean {\n if (LOG_LEVEL_ENV === 'NONE') return false;\n return true;\n }\n\n private shouldUseColors(): boolean {\n if (IS_CI) return false;\n // Check if we're in a browser environment\n if (typeof window !== 'undefined') {\n return true; // Browsers support console colors\n }\n // Node.js environment\n if (\n typeof process !== 'undefined' &&\n process.stdout &&\n !process.stdout.isTTY\n ) {\n return false;\n }\n return IS_DEVELOPMENT;\n }\n}\n\n// Production no-op functions - these create completely eliminatable calls\nconst noop = () => {};\nconst noopWithReturn = () => () => {};\n\n// Export logger with build-time method elimination\nexport const logger = IS_PRODUCTION\n ? {\n configure: noop,\n debug: noop, // \u2190 This eliminates the call completely\n info: noop, // \u2190 This eliminates the call completely\n warn: (message: string, data?: unknown) => {\n console.warn(`\uD83E\uDD81 LionRapid Core \u26A0\uFE0F ${message}`, data || '');\n },\n error: (message: string, data?: unknown) => {\n console.error(`\uD83E\uDD81 LionRapid Core \u274C ${message}`, data || '');\n },\n time: noopWithReturn,\n colorize: (text: string) => text,\n getColors: () => Colors,\n createPackageLogger: (packageName: string, packageEmoji?: string) => ({\n configure: noop,\n debug: noop, // \u2190 Package logger debug also eliminated\n info: noop, // \u2190 Package logger info also eliminated\n warn: (message: string, data?: unknown) => {\n const prefix = `${packageEmoji || '\uD83D\uDCE6'} ${packageName}`;\n console.warn(`${prefix} \u26A0\uFE0F ${message}`, data || '');\n },\n error: (message: string, data?: unknown) => {\n const prefix = `${packageEmoji || '\uD83D\uDCE6'} ${packageName}`;\n console.error(`${prefix} \u274C ${message}`, data || '');\n },\n time: noopWithReturn,\n colorize: (text: string) => text,\n getColors: () => Colors,\n createPackageLogger: noop,\n }),\n }\n : new DevelopmentLogger({\n packageName: 'LionRapid Core',\n packageEmoji: '\uD83E\uDD81',\n });\n\n// Export Logger class for type compatibility\nexport const Logger = IS_PRODUCTION\n ? function Logger() {\n return logger;\n }\n : DevelopmentLogger;\n\n// Factory function with build-time elimination\nexport const createPackageLogger = (config: PackageLoggerConfig) => {\n if (IS_PRODUCTION) {\n const prefix = `${config.packageEmoji || '\uD83D\uDCE6'} ${config.packageName || 'LionRapid'}`;\n return {\n configure: noop,\n debug: noop, // \u2190 All debug calls eliminated\n info: noop, // \u2190 All info calls eliminated\n warn: (message: string, data?: unknown) => {\n console.warn(`${prefix} \u26A0\uFE0F ${message}`, data || '');\n },\n error: (message: string, data?: unknown) => {\n console.error(`${prefix} \u274C ${message}`, data || '');\n },\n time: noopWithReturn,\n colorize: (text: string) => text,\n getColors: () => Colors,\n createPackageLogger: noop,\n };\n }\n return new DevelopmentLogger(config);\n};\n\n// Performance measurement helper - eliminated in production\nexport const measure = (name: string) => {\n if (IS_PRODUCTION) {\n return {\n start: noop,\n end: noop,\n elapsed: () => 0,\n };\n }\n\n let startTime: number;\n return {\n start: () => {\n if (IS_DEVELOPMENT) {\n startTime = performance.now();\n logger.debug(`\u23F1\uFE0F ${name} - started`);\n }\n },\n end: () => {\n if (IS_DEVELOPMENT) {\n const duration = performance.now() - startTime;\n logger.debug(`\u23F1\uFE0F ${name} - completed in ${duration.toFixed(2)}ms`);\n return duration;\n }\n return 0;\n },\n elapsed: () => (IS_DEVELOPMENT ? performance.now() - startTime : 0),\n };\n};\n", "/**\n * Shared BCP-47 locale utilities \u2014 pure, Node-safe (no DOM).\n *\n * Aligns the browser runtime with the rest of the stack (see the locale\n * standard):\n * - tm-server accepts BCP-47, canonicalizes to ISO 639-2, and TRUNCATES the\n * region on the content API (`pt-BR \u2192 por`); it does NO cross-locale\n * fallback.\n * - `@lionrapid/edge` already preserves full tags with the grammar mirrored\n * below and negotiates Accept-Language by q-weight.\n *\n * Core previously chopped every tag to its 2-letter primary subtag, so a\n * configured `data-languages=\"pt-BR,\u2026\"` never matched a detected `pt-BR`\n * (it became `pt`) and fell back to the default. These helpers preserve the\n * full tag for matching / URLs / display while still negotiating down to the\n * primary subtag when that is the best available match \u2014 the same rule edge\n * uses, so the two packages agree.\n *\n * @module utils/locale\n */\n\n/**\n * Same locale grammar as `@lionrapid/edge`'s `LOCALE_BODY`, for cross-package\n * parity: 2\u20133 letter language + zero or more `-XXXX` subtags (script/region/\n * variant), each 2\u20134 alphanumerics. Anchored, case-insensitive.\n */\nexport const LOCALE_TAG_REGEX = /^[a-z]{2,3}(?:-[a-z0-9]{2,4})*$/i;\n\n/**\n * RTL languages \u2014 mirrors tm-server's `RTL_ISO639_2 = {ara,fas,heb,urd,yid}`\n * by their ISO 639-1 primary subtags, so client `dir` matches `is_rtl`.\n */\nconst RTL_LANGUAGES = new Set(['ar', 'fa', 'he', 'ur', 'yi']);\n\n/** The primary language subtag, lowercased: `pt-BR \u2192 pt`, `ZH-Hant \u2192 zh`. */\nexport function primarySubtag(tag: string): string {\n return tag.split('-')[0]!.toLowerCase();\n}\n\n/**\n * Canonicalize BCP-47 casing: language lowercase, script Title-case (4 chars),\n * region UPPERCASE (2 chars). `pt-br \u2192 pt-BR`, `ZH-hant \u2192 zh-Hant`. Casing\n * only \u2014 subtags are not validated here (that's `matchLocale`/the grammar).\n */\nexport function normalizeLocale(tag: string): string {\n const trimmed = tag.trim();\n if (!trimmed) return trimmed;\n const [lang, ...rest] = trimmed.split('-');\n const out = [lang.toLowerCase()];\n for (const sub of rest) {\n if (sub.length === 4) {\n out.push(sub[0].toUpperCase() + sub.slice(1).toLowerCase()); // script\n } else if (sub.length === 2) {\n out.push(sub.toUpperCase()); // region (alpha-2)\n } else {\n out.push(sub.toLowerCase()); // variant / numeric region / other\n }\n }\n return out.join('-');\n}\n\n/**\n * Negotiate a locale: for each requested tag (in preference order), return the\n * best `available` match \u2014 exact full tag (case-insensitive) first, then an\n * available entry equal to the requested tag's bare primary subtag. Returns\n * `fallback` when nothing matches. Mirrors edge's `detectFromAcceptLanguage`\n * matching so both packages resolve identically.\n *\n * Note (matches edge + the server): a bare requested `pt` does NOT match an\n * available `pt-BR` \u2014 region-specific availability is not silently widened.\n */\nexport function matchLocale(\n requested: string[],\n available: string[],\n fallback: string,\n): string {\n if (available.length === 0) return fallback;\n const avail = available.map((raw) => ({\n raw,\n lower: normalizeLocale(raw).toLowerCase(),\n }));\n for (const req of requested) {\n if (!req) continue;\n const reqLower = normalizeLocale(req).toLowerCase();\n const exact = avail.find((a) => a.lower === reqLower);\n if (exact) return exact.raw;\n const primary = primarySubtag(req);\n const byPrimary = avail.find((a) => a.lower === primary);\n if (byPrimary) return byPrimary.raw;\n }\n return fallback;\n}\n\n/**\n * Parse an `Accept-Language` header into tags ordered by q-weight (desc).\n * `fr;q=0.8,en;q=0.9 \u2192 ['en','fr']`. Missing q defaults to 1.0; a malformed q\n * sinks to the tail; `*` and empty tags are dropped.\n */\nexport function parseAcceptLanguage(header: string): string[] {\n return header\n .split(',')\n .map((part) => {\n const [tag, ...params] = part.trim().split(';');\n const qParam = params.find((p) => p.trim().startsWith('q='));\n const q = qParam ? parseFloat(qParam.trim().slice(2)) : 1;\n return { tag: tag.trim(), q: Number.isNaN(q) ? 0 : q };\n })\n .filter((x) => x.tag.length > 0 && x.tag !== '*')\n .sort((a, b) => b.q - a.q)\n .map((x) => x.tag);\n}\n\n/**\n * Text direction for a locale \u2014 `'rtl'` for Arabic/Persian/Hebrew/Urdu/\n * Yiddish, else `'ltr'`. Mirrors tm-server `is_rtl`.\n */\nexport function localeDir(tag: string): 'ltr' | 'rtl' {\n return RTL_LANGUAGES.has(primarySubtag(tag)) ? 'rtl' : 'ltr';\n}\n", "/**\n * Enhanced event emitter with language change helpers\n * filepath: /home/janrau/tm-integration/packages/core/src/base/event-emitter.ts\n */\n\nimport type {\n LionRapidEventEnvelope,\n LionRapidEventPayloads,\n LionRapidContext,\n} from '../types/lionRapid.types.js';\nimport type { TranslationRequest } from '../types/translation.types.js';\nimport { logger } from '../utils/logger.js';\nimport { localeDir } from '../utils/locale.js';\n\n// \u2705 Type-safe listener function type\ntype EventListener<T extends Record<string, unknown>, K extends keyof T> = (\n envelope: LionRapidEventEnvelope<T, K>\n) => void;\n\n// \u2705 Type-safe listener storage\n// type EventListenerMap = {\n// [K in keyof LionRapidEventPayloads]: Set<\n// EventListener<LionRapidEventPayloads, K>\n// >;\n// };\n\nexport class EventEmitter {\n // \u2705 Properly typed event listeners without `any`\n private eventListeners = new Map<\n keyof LionRapidEventPayloads,\n Set<EventListener<LionRapidEventPayloads, keyof LionRapidEventPayloads>>\n >();\n\n // Browser-safe: `process` is undeclared in browsers; guard before reading.\n // Bundlers still substitute `process.env.NODE_ENV` at build time.\n private debugMode: boolean =\n typeof process !== 'undefined' &&\n process.env?.NODE_ENV === 'development';\n\n /**\n * Subscribe to events (PUBLIC API) - Fully type-safe\n */\n on<K extends keyof LionRapidEventPayloads>(\n event: K,\n listener: EventListener<LionRapidEventPayloads, K>\n ): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n\n // \u2705 Type assertion is safe here because we control the map structure\n const listeners = this.eventListeners.get(event) as Set<\n EventListener<LionRapidEventPayloads, K>\n >;\n listeners.add(listener);\n }\n\n /**\n * Unsubscribe from events (PUBLIC API) - Fully type-safe\n */\n off<K extends keyof LionRapidEventPayloads>(\n event: K,\n listener: EventListener<LionRapidEventPayloads, K>\n ): void {\n const listeners = this.eventListeners.get(event) as\n | Set<EventListener<LionRapidEventPayloads, K>>\n | undefined;\n if (listeners) {\n listeners.delete(listener);\n }\n }\n\n /**\n * \u2705 Type-safe emit with proper generic constraint\n */\n emit<K extends keyof LionRapidEventPayloads>(\n event: K,\n envelope: LionRapidEventEnvelope<LionRapidEventPayloads, K>\n ): void {\n const listeners = this.eventListeners.get(event) as\n | Set<EventListener<LionRapidEventPayloads, K>>\n | undefined;\n if (listeners) {\n listeners.forEach(listener => {\n try {\n listener(envelope);\n } catch (error) {\n console.error(`Error in event listener for ${String(event)}:`, error);\n }\n });\n }\n }\n\n hasListeners<K extends keyof LionRapidEventPayloads>(event: K): boolean {\n return (\n this.eventListeners.has(event) && this.eventListeners.get(event)!.size > 0\n );\n }\n\n clearEvents(): void {\n this.eventListeners.clear();\n }\n\n /**\n * \u2705 Create base context once per request\n */\n private createContext(\n requestId: string,\n trace: string[],\n extra?: Partial<LionRapidContext>\n ): LionRapidContext {\n return {\n requestId,\n timestamp: performance.now(),\n trace,\n ...extra,\n };\n }\n\n /**\n * \u2705 Type-safe event emission helper\n */\n private emitEvent<K extends keyof LionRapidEventPayloads>(\n event: K,\n payload: LionRapidEventPayloads[K],\n requestId: string,\n trace: string[]\n ): void {\n this.emit(event, {\n context: this.createContext(requestId, trace),\n payload,\n });\n }\n\n /**\n * \u2705 Translation event builder with proper typing\n */\n translation(request: TranslationRequest, handler?: string) {\n const baseTrace = ['translation'];\n const handlerTrace = handler ? [...baseTrace, handler] : baseTrace;\n\n return {\n request: () => {\n this.emit('translation:request', {\n context: this.createContext(request.id, [...baseTrace, 'request']),\n payload: { key: request.cleanKey },\n });\n },\n\n success: (value: string) => {\n this.emit('translation:success', {\n context: this.createContext(request.id, [...handlerTrace, 'success']),\n payload: { key: request.cleanKey, value },\n });\n },\n\n fallback: (value: string) => {\n this.emit('translation:fallback', {\n context: this.createContext(request.id, [...baseTrace, 'fallback']),\n payload: { key: request.cleanKey, value },\n });\n },\n\n missing: (fallbackValue: string, locale: string, namespace: string) => {\n this.emit('translation:missing', {\n context: this.createContext(request.id, [...baseTrace, 'missing']),\n payload: {\n key: request.cleanKey,\n fallbackValue,\n locale,\n namespace,\n },\n });\n },\n\n notFound: (fallbackValue: string, locale: string, namespace: string) => {\n this.emit('translation:not-found', {\n context: this.createContext(request.id, [...baseTrace, 'not-found']),\n payload: {\n key: request.cleanKey,\n fallbackValue,\n locale,\n namespace,\n status: 404 as const,\n },\n });\n },\n\n locked: (fallbackValue: string, locale: string, namespace: string) => {\n this.emit('translation:locked', {\n context: this.createContext(request.id, [...baseTrace, 'locked']),\n payload: {\n key: request.cleanKey,\n fallbackValue,\n locale,\n namespace,\n status: 423 as const,\n },\n });\n },\n };\n }\n\n /**\n * \u2705 Repository event builder with better typing\n */\n repo(request: TranslationRequest | string, source: string) {\n const baseTrace = ['repo', source];\n\n return {\n getStart: () => {\n if (typeof request === 'string') return;\n this.emit('repo:get:start', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'get',\n 'start',\n ]),\n payload: { key: request.cleanKey, source },\n });\n },\n\n getSuccess: (value: string) => {\n if (typeof request === 'string') return;\n this.emit('repo:get:success', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'get',\n 'success',\n ]),\n payload: { key: request.cleanKey, value, source },\n });\n },\n\n getMiss: () => {\n if (typeof request === 'string') return;\n this.emit('repo:get:miss', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'get',\n 'miss',\n ]),\n payload: { key: request.cleanKey, source },\n });\n },\n\n setStart: (value: string) => {\n if (typeof request === 'string') return;\n this.emit('repo:set:start', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'set',\n 'start',\n ]),\n payload: { key: request.cleanKey, value, source },\n });\n },\n\n setSuccess: (value: string) => {\n const id = typeof request === 'string' ? 'system' : request.id;\n const key = typeof request === 'string' ? request : request.cleanKey;\n this.emit('repo:set:success', {\n context: this.createContext(id, [...baseTrace, 'set', 'success']),\n payload: { key: key, value, source },\n });\n },\n\n error: (error: Error) => {\n if (typeof request === 'string') return;\n this.emit('repo:error', {\n context: this.createContext(request.id, [...baseTrace, 'error']),\n payload: { key: request.cleanKey, source, error },\n });\n },\n };\n }\n\n /**\n * \u2705 Network event builder\n */\n network(request: TranslationRequest | string, method?: string) {\n const key = typeof request === 'string' ? request : request.cleanKey;\n const requestId = typeof request === 'string' ? 'network' : request.id;\n const baseTrace = ['network', method || 'request'];\n\n return {\n start: () => {\n this.emit('network:request:start', {\n context: this.createContext(requestId, [...baseTrace, 'start']),\n payload: { key },\n });\n },\n\n success: (value: string) => {\n this.emit('network:request:success', {\n context: this.createContext(requestId, [...baseTrace, 'success']),\n payload: { key, value, method: method || 'GET' },\n });\n },\n\n error: (error: unknown, status?: number) => {\n this.emit('network:request:error', {\n context: this.createContext(requestId, [...baseTrace, 'error']),\n payload: {\n key,\n method: method || 'GET',\n error,\n ...(status && { status }),\n },\n });\n },\n\n retry: (attempt: number, delayMs: number, reason?: string) => {\n this.emit('network:retry', {\n context: this.createContext(requestId, [...baseTrace, 'retry']),\n payload: { key, attempt, delayMs, ...(reason && { reason }) },\n });\n },\n };\n }\n\n /**\n * \u2705 Builder event builder\n */\n builder() {\n const baseTrace = ['builder'];\n const systemId = `build-${Date.now()}`;\n\n return {\n use: (type: 'plugin' | 'sync' | 'async' | 'network') => {\n this.emit('builder:use', {\n context: this.createContext(systemId, [...baseTrace, 'use']),\n payload: { type },\n });\n },\n\n buildStart: (locale: string, namespace: string) => {\n this.emit('builder:build:start', {\n context: this.createContext(systemId, [\n ...baseTrace,\n 'build',\n 'start',\n ]),\n payload: { locale, namespace },\n });\n },\n\n buildDone: (repositories: string[], plugins: string[]) => {\n this.emit('builder:build:done', {\n context: this.createContext(systemId, [\n ...baseTrace,\n 'build',\n 'done',\n ]),\n payload: { repositories, plugins },\n });\n },\n };\n }\n\n /**\n * \u2705 Language change event builder\n */\n language(oldLocale: string, newLocale: string) {\n const requestId = `lang-change-${Date.now()}`;\n const baseTrace = ['language', 'change'];\n\n return {\n start: () => {\n this.emit('language:change:start', {\n context: this.createContext(requestId, [...baseTrace, 'start']),\n payload: { oldLocale, newLocale },\n });\n },\n\n complete: () => {\n this.emit('language:change:success', {\n context: this.createContext(requestId, [...baseTrace, 'complete']),\n payload: { oldLocale, newLocale, dir: localeDir(newLocale) },\n });\n },\n\n error: (error: Error) => {\n this.emit('language:change:error', {\n context: this.createContext(requestId, [...baseTrace, 'error']),\n payload: { oldLocale, newLocale, error },\n });\n },\n };\n }\n\n /**\n * \u2705 Cache operations (debug only)\n */\n cache(operation: 'clear', reason: string, stats?: { clearedCount: number }) {\n // Only emit in debug mode\n if (!this.debugMode) return { start: () => {}, complete: () => {} };\n\n return {\n start: () => {\n logger.debug(`\uD83E\uDDF9 Cache ${operation} starting: ${reason}`);\n },\n\n complete: () => {\n logger.debug(\n `\u2705 Cache ${operation} complete: ${stats?.clearedCount || 0} entries`\n );\n },\n };\n }\n}\n", "/**\n * Array-based handler chain implementation\n * Much simpler than linked list approach\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport type {\n IAsyncHandler,\n ISyncHandler,\n} from '../interfaces/handler.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n TranslationContext,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger } from '../utils/logger.js';\n\nexport class HandlerChain {\n private asyncHandlers: IAsyncHandler[] = [];\n private syncHandlers: ISyncHandler[] = [];\n private bus: EventEmitter;\n\n constructor(eventEmitter: EventEmitter) {\n this.bus = eventEmitter;\n }\n\n addSyncHandler(handler: ISyncHandler): void {\n if (!handler.enabled) return;\n this.syncHandlers.push(handler);\n this.sortHandlersIfNeeded(this.syncHandlers);\n logger.debug(`Sync handler added: ${handler.name}`);\n }\n\n handleSync(request: TranslationRequest): TranslationResult | null {\n for (const handler of this.syncHandlers) {\n try {\n const result = handler.lookup(request);\n if (result !== null && result.value) {\n logger.debug(`Sync hit: ${handler.name} (${result.duration}ms)`);\n return result;\n }\n } catch (error) {\n logger.warn(`Sync lookup failed in ${handler.name}:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n continue;\n }\n }\n return null;\n }\n\n private saveToMemoryHandlers(\n request: TranslationRequest,\n result: TranslationResult,\n _sourceHandler: IAsyncHandler\n ): void {\n const memoryHandlers = this.syncHandlers;\n if (memoryHandlers.length === 0) return;\n logger.debug(`Saving to ${memoryHandlers.length} memory handlers`);\n\n // Result already contains value and styles from source handler\n memoryHandlers.forEach(handler => {\n try {\n handler.save(request, result);\n logger.debug(`Saved to memory: ${handler.name}`);\n } catch (error) {\n logger.warn(`Failed to save to memory ${handler.name}:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n }\n });\n }\n\n private saveNamespaceToMemoryHandlers(\n translations: TranslationData,\n context: TranslationContext\n ): void {\n const memoryHandlers = this.syncHandlers.filter(\n h => h.type === 'memory' && h.saveNamespace\n );\n\n if (memoryHandlers.length === 0) return;\n\n logger.debug(\n `Saving namespace to ${memoryHandlers.length} memory handlers`\n );\n\n // \u2705 Save to memory handlers (sync)\n memoryHandlers.forEach(handler => {\n try {\n handler.saveNamespace!(translations, context);\n logger.debug(`Namespace saved to memory: ${handler.name}`, {\n locale: context.locale,\n namespace: context.namespace,\n });\n } catch (error) {\n logger.warn(\n `Failed to save namespace to memory ${handler.name}:`,\n error\n );\n const repoBus = this.bus.repo(\n `${context.locale}:${context.namespace}`,\n handler.name\n );\n repoBus.error(error as Error);\n }\n });\n }\n\n addAsyncHandler(handler: IAsyncHandler): void {\n if (!handler.enabled) return;\n this.asyncHandlers.push(handler);\n this.sortHandlersIfNeeded(this.asyncHandlers);\n\n logger.debug(`Async handler added: ${handler.name}`);\n }\n\n async handleAsync(\n request: TranslationRequest\n ): Promise<TranslationResult | null> {\n for (const handler of this.asyncHandlers) {\n try {\n logger.debug(`Trying handler: ${handler.name}`);\n const result = await handler.lookup(request);\n\n // Check if we got a successful result (not fallback)\n if (result.value && result.status === 200) {\n // Found translation - save to all storage handlers that come before this one\n logger.debug(`Async hit: ${handler.name} (${result.duration}ms)`);\n\n // If a full namespace was loaded during lookup, save it first\n if (result.namespaceLoaded) {\n logger.debug(\n `Saving loaded namespace: ${result.namespaceLoaded.locale}:${result.namespaceLoaded.namespace}`\n );\n await this.saveNamespaceToHandlers(result.namespaceLoaded.data, {\n locale: result.namespaceLoaded.locale,\n namespace: result.namespaceLoaded.namespace,\n });\n return result;\n }\n\n // Save to storage and memory handlers (styles included in result)\n await this.saveToStorageHandlers(request, result, handler);\n this.saveToMemoryHandlers(request, result, handler);\n\n return result;\n }\n\n // If we got a fallback result (404, 423, error), continue to next handler\n logger.debug(\n `Handler ${handler.name} returned fallback (status: ${result.status})`\n );\n } catch (error) {\n logger.warn(`Handler ${handler.name} failed:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n continue;\n }\n }\n logger.debug(`No async handlers found translation for ${request.cleanKey}`);\n return null; // Not found in any handler\n }\n\n /**\n * Save translation to all storage handlers that come before the source handler\n */\n private async saveToStorageHandlers(\n request: TranslationRequest,\n result: TranslationResult,\n sourceHandler: IAsyncHandler\n ): Promise<void> {\n const sourceIndex = this.asyncHandlers.indexOf(sourceHandler);\n\n // Get all storage handlers with higher priority (lower index) than source\n const storageHandlers = this.asyncHandlers\n .slice(0, sourceIndex)\n .filter(h => h.type === 'storage');\n\n if (storageHandlers.length === 0) return;\n\n logger.debug(`Saving to ${storageHandlers.length} storage handlers`);\n\n // Result already contains value and styles from source handler\n const savePromises = storageHandlers.map(async handler => {\n try {\n await handler.save(request, result);\n logger.debug(`Saved to storage: ${handler.name}`);\n } catch (error) {\n logger.warn(`Failed to save to storage ${handler.name}:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n }\n });\n\n await Promise.allSettled(savePromises);\n }\n\n private async saveNamespaceToStorageHandlers(\n translations: TranslationData,\n context: TranslationContext\n ): Promise<void> {\n const storageHandlers = this.asyncHandlers.filter(\n h => h.type === 'storage' && h.saveNamespace\n );\n\n if (storageHandlers.length === 0) return;\n\n logger.debug(\n `Saving namespace to ${storageHandlers.length} storage handlers`\n );\n\n // \u2705 Save to storage handlers (async/parallel)\n const savePromises = storageHandlers.map(async handler => {\n try {\n await handler.saveNamespace!(translations, context);\n logger.debug(`Namespace saved to storage: ${handler.name}`, {\n locale: context.locale,\n namespace: context.namespace,\n });\n } catch (error) {\n logger.warn(\n `Failed to save namespace to storage ${handler.name}:`,\n error\n );\n const repoBus = this.bus.repo(\n `${context.locale}:${context.namespace}`,\n handler.name\n );\n repoBus.error(error as Error);\n }\n });\n\n await Promise.allSettled(savePromises);\n }\n\n async saveNamespaceToHandlers(\n translations: TranslationData,\n context: TranslationContext\n ): Promise<void> {\n this.saveNamespaceToMemoryHandlers(translations, context);\n await this.saveNamespaceToStorageHandlers(translations, context);\n }\n\n getSyncHandlers(): ISyncHandler[] {\n return [...this.syncHandlers];\n }\n\n getAsyncHandlers(): IAsyncHandler[] {\n return [...this.asyncHandlers];\n }\n\n /**\n * Get chain info for debugging\n */\n getChainInfo(): {\n length: number;\n handlers: Array<{\n name: string;\n priority: number;\n type: 'memory' | 'storage' | 'network' | 'fallback';\n enabled: boolean | undefined;\n }>;\n } {\n return {\n length: this.syncHandlers.length + this.asyncHandlers.length,\n handlers: [\n ...this.syncHandlers.map(h => ({\n name: h.name,\n priority: h.priority,\n type: h.type,\n enabled: h.enabled,\n })),\n ...this.asyncHandlers.map(h => ({\n name: h.name,\n priority: h.priority,\n type: h.type,\n enabled: h.enabled,\n })),\n ],\n };\n }\n\n /**\n * Check if any handler has cached data\n */\n isCached(request: TranslationRequest): boolean {\n return (\n this.syncHandlers.some(h => h.isCached?.(request) === true) ||\n this.asyncHandlers.some(h => h.isCached?.(request) === true)\n );\n }\n\n /**\n * Get combined cache entries\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getEntries(): Record<string, any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const entries: Record<string, any> = {};\n\n // \u2705 Fix: Use proper arrays instead of this.handlers\n const allHandlers = [...this.syncHandlers, ...this.asyncHandlers];\n for (const handler of allHandlers) {\n if (handler.getEntries) {\n entries[handler.name] = handler.getEntries();\n }\n }\n return entries;\n }\n\n /**\n * Destroy all handlers\n */\n async destroy(): Promise<void> {\n // \u2705 Fix: Use proper arrays instead of this.handlers\n const allHandlers = [...this.syncHandlers, ...this.asyncHandlers];\n\n const destroyPromises = allHandlers.map(async handler => {\n try {\n await handler.destroy?.();\n logger.debug(`Handler destroyed: ${handler.name}`);\n } catch (error) {\n logger.warn(`Failed to destroy handler: ${handler.name}`, error);\n }\n });\n\n await Promise.allSettled(destroyPromises);\n\n // Clear handler arrays\n this.syncHandlers = [];\n this.asyncHandlers = [];\n }\n\n private sortHandlersIfNeeded(\n handlers: ISyncHandler[] | IAsyncHandler[]\n ): void {\n const hasExplicitPriorities = handlers.some(h => h.priority > 0);\n\n if (hasExplicitPriorities) {\n handlers.sort((a, b) => {\n const priorityA = a.priority || Number.MAX_SAFE_INTEGER;\n const priorityB = b.priority || Number.MAX_SAFE_INTEGER;\n return priorityA - priorityB;\n });\n }\n }\n\n async loadNamespace(\n locale: string,\n namespace: string\n ): Promise<TranslationData | null> {\n for (const handler of this.asyncHandlers) {\n if (handler.type !== 'network') continue;\n try {\n logger.debug(\n `Trying to load namespace: ${locale}:${namespace} from ${handler.name}`\n );\n const result = await handler.loadNamespace?.(locale, namespace);\n if (result && result.data && result.status === 200) {\n logger.debug(\n `Loaded namespace: ${locale}:${namespace} from ${handler.name}`\n );\n await this.saveNamespaceToStorageHandlers(result.data, {\n namespace,\n locale,\n });\n this.saveNamespaceToMemoryHandlers(result.data, {\n namespace,\n locale,\n });\n return result.data;\n }\n } catch (error) {\n logger.warn(\n `Failed to load namespace: ${locale}:${namespace} from ${handler.name}`,\n error\n );\n const repoBus = this.bus.repo(`${locale}:${namespace}`, handler.name);\n repoBus.error(error as Error);\n continue;\n }\n }\n logger.debug(`No handlers found namespace: ${locale}:${namespace}`);\n return null;\n }\n\n clearCache(): void {\n const allHandlers = [...this.syncHandlers, ...this.asyncHandlers];\n\n for (const handler of allHandlers) {\n try {\n handler.destroy?.();\n logger.debug(`Cache cleared for handler: ${handler.name}`);\n } catch (error) {\n logger.warn(\n `Failed to clear cache for handler: ${handler.name}`,\n error\n );\n }\n }\n\n logger.debug('Cache cleared for all handlers');\n }\n\n /**\n * Clear cache entries for a specific namespace\n */\n clearNamespace(locale: string, namespace: string): void {\n // Clear from sync handlers (memory)\n for (const handler of this.syncHandlers) {\n try {\n handler.clearNamespace?.(locale, namespace);\n } catch (error) {\n logger.warn(\n `Failed to clear namespace for handler: ${handler.name}`,\n error\n );\n }\n }\n\n logger.debug(`Cleared namespace: ${locale}:${namespace}`);\n }\n\n /**\n * Set a value directly in the cache (for optimistic updates)\n * Bypasses the normal handler flow to directly set values in memory handlers\n * Stores as ContentUnit (text + styles) for consistency\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @param value - Translation value\n * @param styles - Optional styles for indexed tags\n */\n setCache(key: string, value: string, styles?: Record<string, string[]>): void {\n // Save to memory handlers using the dedicated setCache method\n // Handler stores as ContentUnit JSON internally\n for (const handler of this.syncHandlers) {\n if (handler.type === 'memory' && handler.setCache) {\n try {\n handler.setCache(key, value, styles);\n } catch (error) {\n logger.warn(`Failed to set cache in handler: ${handler.name}`, error);\n }\n }\n }\n\n logger.debug(`Cache set: ${key}`);\n }\n\n /**\n * Get namespace data from cache for ContentUnit style lookup\n *\n * Used by t() to retrieve styles for indexed tags at render time.\n *\n * @param namespaceCacheKey - Cache key in format @locale:namespace\n * @returns Parsed namespace data or null if not found\n */\n getNamespaceData(namespaceCacheKey: string): TranslationData | null {\n // Try to get from memory handlers first (sync)\n for (const handler of this.syncHandlers) {\n if (handler.type === 'memory') {\n try {\n const entries = handler.getEntries?.();\n if (entries && entries[namespaceCacheKey]) {\n const data = entries[namespaceCacheKey];\n // Parse if it's a string (JSON)\n if (typeof data === 'string') {\n return JSON.parse(data);\n }\n return data;\n }\n } catch (error) {\n logger.debug(`Error getting namespace data from ${handler.name}:`, error);\n }\n }\n }\n return null;\n }\n}\n", "import type { ParsedNamespaceKey } from '../types/translation.types.js';\n/**\n * Namespace parsing utilities for translation keys\n * Supports patterns like: 'common:welcome', 'user.profile.name', 'errors:validation.required'\n */\n\n\n/**\n * Parse namespace from translation key\n * Supports: 'namespace:key' pattern\n * Future: Could support other patterns like 'namespace.key' or 'namespace/key'\n * \n * @param key - Translation key (e.g., 'common:welcome' or 'welcome')\n * @returns Parsed namespace information\n */\nexport function parseNamespaceKey(key: string): ParsedNamespaceKey {\n // Simple namespace pattern: 'namespace:key'\n const colonIndex = key.indexOf(':');\n \n if (colonIndex > 0 && colonIndex < key.length - 1) {\n // Has explicit namespace\n const namespace = key.substring(0, colonIndex);\n const cleanKey = key.substring(colonIndex + 1);\n \n return {\n originalKey: key,\n namespace,\n cleanKey,\n hasExplicitNamespace: true\n };\n }\n \n // No namespace found\n return {\n originalKey: key,\n cleanKey: key,\n hasExplicitNamespace: false\n };\n}\n\n/**\n * Create a full namespaced key\n * \n * @param key - Clean translation key\n * @param namespace - Namespace to prepend\n * @returns Namespaced key (e.g., 'common:welcome')\n */\nexport function createNamespacedKey(key: string, namespace?: string): string {\n if (!namespace) return key;\n return `${namespace}:${key}`;\n}\n\n/**\n * Validate namespace format\n * \n * @param namespace - Namespace to validate\n * @returns Whether namespace is valid\n */\nexport function isValidNamespace(namespace: string): boolean {\n // Simple validation: alphanumeric, underscore, hyphen\n return /^[a-zA-Z0-9_-]+$/.test(namespace);\n}", "/**\n * Translation context creation utilities\n */\n\nimport type { TranslationContext, ParsedNamespaceKey } from '../types/translation.types.js';\n\n/**\n * Create translation context with namespace resolution\n * \n * @param parsedKey - Parsed namespace key information\n * @param currentLocale - Current locale\n * @param defaultNamespace - Default namespace if none specified\n * @returns Complete translation context\n */\nexport function createTranslationContext(\n parsedKey: ParsedNamespaceKey,\n currentLocale: string,\n defaultNamespace?: string\n): TranslationContext {\n // Use explicit namespace if provided, otherwise use default\n const effectiveNamespace = parsedKey.hasExplicitNamespace\n ? parsedKey.namespace\n : defaultNamespace;\n\n return {\n locale: currentLocale,\n namespace: effectiveNamespace\n };\n}\n\n/**\n * Check if two contexts are equivalent (for caching)\n * \n * @param context1 - First context\n * @param context2 - Second context \n * @returns Whether contexts are equivalent\n */\nexport function areContextsEquivalent(\n context1: TranslationContext, \n context2: TranslationContext\n): boolean {\n return (\n context1.locale === context2.locale &&\n context1.namespace === context2.namespace\n );\n}", "/**\n * Translation value processing utilities\n * Handles simple strings, nested objects, pluralization, and context\n */\n\n// import type { TranslationParams } from '../types/translation.types.js';\n// import { interpolateParams } from './translation-utils.js';\nimport { logger } from './logger.js';\n\n\n/**\n * \u2705 Resolve nested key path in translation object\n */\n/**\n * \u2705 Resolve nested key from namespace object\n * Examples:\n * - resolveNestedKey({user: {profile: {name: \"John\"}}}, \"user.profile.name\") \u2192 \"John\"\n * - resolveNestedKey({items: [{name: \"Apple\"}]}, \"items[0].name\") \u2192 \"Apple\"\n * - resolveNestedKey({welcome: \"Hello\"}, \"welcome\") \u2192 \"Hello\"\n */\nexport function resolveNestedKey(\n namespace: Record<string, unknown>,\n keyPath: string\n): unknown {\n if (!namespace || !keyPath) {\n return undefined;\n }\n\n // Handle simple key (no nesting)\n if (!keyPath.includes('.') && !keyPath.includes('[')) {\n return namespace[keyPath];\n }\n\n // Handle nested key navigation\n try {\n const keys = parseKeyPath(keyPath);\n let current: unknown = namespace;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n logger.debug(\n `\uD83D\uDD0D Nested key resolution stopped at null/undefined for: ${keyPath}`\n );\n return undefined;\n }\n\n if (typeof key === 'number') {\n // Array index access\n if (!Array.isArray(current)) {\n logger.debug(\n `\uD83D\uDD0D Expected array for index ${key} in path: ${keyPath}`\n );\n return undefined;\n }\n current = current[key];\n } else {\n // Object property access\n if (typeof current !== 'object') {\n logger.debug(\n `\uD83D\uDD0D Expected object for key '${key}' in path: ${keyPath}`\n );\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n }\n\n logger.debug(\n `\uD83D\uDD0D Nested key resolved: ${keyPath} \u2192 ${typeof current === 'object' ? '[Object]' : current}`\n );\n return current;\n } catch (error) {\n logger.debug(`\uD83D\uDD0D Nested key resolution error for '${keyPath}':`, error);\n return undefined;\n }\n}\n\n/**\n * \u2705 Parse key path into array of keys/indices\n * Examples:\n * - \"user.profile.name\" \u2192 [\"user\", \"profile\", \"name\"]\n * - \"items[0].name\" \u2192 [\"items\", 0, \"name\"]\n * - \"settings.ui.theme\" \u2192 [\"settings\", \"ui\", \"theme\"]\n */\nexport function parseKeyPath(keyPath: string): (string | number)[] {\n const keys: (string | number)[] = [];\n let currentKey = '';\n let inBrackets = false;\n\n for (let i = 0; i < keyPath.length; i++) {\n const char = keyPath[i];\n\n if (char === '.' && !inBrackets) {\n // End of current key\n if (currentKey) {\n keys.push(currentKey);\n currentKey = '';\n }\n } else if (char === '[') {\n // Start of array index\n if (currentKey) {\n keys.push(currentKey);\n currentKey = '';\n }\n inBrackets = true;\n } else if (char === ']' && inBrackets) {\n // End of array index\n if (currentKey) {\n const index = parseInt(currentKey, 10);\n if (!isNaN(index)) {\n keys.push(index);\n } else {\n // Non-numeric index, treat as string\n keys.push(currentKey);\n }\n currentKey = '';\n }\n inBrackets = false;\n } else {\n // Regular character\n currentKey += char;\n }\n }\n\n // Add remaining key\n if (currentKey) {\n keys.push(currentKey);\n }\n\n return keys;\n}\n\n\n/**\n * \u2705 Create individual cache key: locale:namespace:key\n */\nexport function createIndividualCacheKey(\n locale: string,\n namespace: string | undefined,\n key: string\n): string {\n const parts = [locale];\n if (namespace) {\n parts.push(namespace);\n }\n parts.push(key);\n return parts.join(':');\n}\n\n/**\n * \u2705 Create namespace cache key: @locale:namespace\n */\nexport function createNamespaceCacheKey(\n locale: string,\n namespace: string\n): string {\n return `@${locale}:${namespace}`;\n}\n\n/**\n * \u2705 Check if key is namespace cache entry\n */\nexport function isNamespaceCacheKey(key: string): boolean {\n return key.startsWith('@');\n}\n\n/**\n * \u2705 Parse namespace cache key\n */\nexport function parseNamespaceCacheKey(\n key: string\n): { locale: string; namespace: string } | null {\n if (!key.startsWith('@')) return null;\n\n const parts = key.substring(1).split(':');\n if (parts.length !== 2) return null;\n\n const [locale, namespace] = parts;\n return { locale, namespace };\n}\n\n/**\n * \u2705 Parse individual cache key\n */\nexport function parseIndividualCacheKey(\n key: string\n): { locale: string; namespace?: string; translationKey: string } | null {\n if (key.startsWith('@')) return null;\n\n const parts = key.split(':');\n if (parts.length < 2) return null;\n\n if (parts.length === 2) {\n const [locale, translationKey] = parts;\n return { locale, translationKey };\n }\n\n if (parts.length === 3) {\n const [locale, namespace, translationKey] = parts;\n return { locale, namespace, translationKey };\n }\n\n return null;\n}\n\n/**\n * \u2705 Flatten nested translations for caching individual keys\n * Handles both ICU MessageFormat strings and structured objects\n * Stores full ContentUnit as JSON - includes both text and styles\n */\nexport function flattenTranslations(\n translations: Record<string, unknown>,\n prefix = '',\n locale: string,\n namespace: string\n): Record<string, string> {\n const flattened: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(translations)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const cacheKey = createIndividualCacheKey(locale, namespace, fullKey);\n\n if (typeof value === 'object' && value !== null && 'text' in value && 'styles' in value) {\n // Server returns ContentUnit format: { text, styles }\n // Store as JSON to preserve both text and styles\n flattened[cacheKey] = JSON.stringify(value);\n } else if (typeof value === 'object' && value !== null) {\n // Nested object - flatten recursively\n Object.assign(\n flattened,\n flattenTranslations(value as Record<string, unknown>, fullKey, locale, namespace)\n );\n } else {\n // Fallback for plain strings - wrap in ContentUnit format\n flattened[cacheKey] = JSON.stringify({ text: String(value), styles: {} });\n }\n }\n\n return flattened;\n}\n", "/**\n * Enhanced translation process flow utilities\n * Organizes the step-by-step translation resolution process with i18n features\n */\n\nimport type { TranslationRequest } from '../types/translation.types.js';\nimport { createTranslationContext } from './context-utils.js';\nimport { parseNamespaceKey } from './namespace-utils.js';\nimport {\n createIndividualCacheKey,\n createNamespaceCacheKey,\n} from './translation-value-utils.js';\n\n/**\n * \u2705 Enhanced: Parse and prepare translation request with cache keys\n * This is the entry point that organizes all the parsing logic\n */\nexport function prepareTranslationRequest(\n key: string,\n currentLocale: string,\n defaultValueOrParams?: string | Record<string, unknown>,\n paramsOrDefaultValue?: Record<string, unknown> | string,\n defaultNamespace?: string\n): TranslationRequest {\n const startTime = performance.now();\n\n // Parse flexible parameters\n const { defaultValue, params } = parseTranslationParams(\n defaultValueOrParams,\n paramsOrDefaultValue\n );\n\n // Parse namespace from key\n const parsedKey = parseNamespaceKey(key);\n\n // Create translation context\n const context = createTranslationContext(\n parsedKey,\n currentLocale,\n defaultNamespace\n );\n\n // \u2705 Generate cache keys using unified pattern\n const individualCacheKey = createIndividualCacheKey(\n context.locale,\n context.namespace,\n parsedKey.cleanKey\n );\n\n const namespaceCacheKey = context.namespace\n ? createNamespaceCacheKey(context.locale, context.namespace)\n : undefined;\n\n // Generate unique ID for the request (could be a hash or UUID)\n const id = `${individualCacheKey}-${startTime}`;\n\n return {\n id, // Unique request ID\n originalKey: key,\n originalParams: defaultValueOrParams,\n originalDefaultValue: paramsOrDefaultValue,\n cleanKey: parsedKey.cleanKey,\n hasExplicitNamespace: parsedKey.hasExplicitNamespace,\n parsedParams: params,\n parsedDefaultValue: defaultValue,\n locale: currentLocale,\n namespace: context.namespace, // \u2705 Use effective namespace (explicit or default)\n individualCacheKey, // \u2705 Ready-to-use cache key\n namespaceCacheKey, // \u2705 Ready-to-use namespace key\n startTime,\n };\n}\n\n/**\n * Parse flexible translation parameters\n */\nexport function parseTranslationParams(\n secondParam?: string | Record<string, unknown>,\n thirdParam?: Record<string, unknown> | string\n): { defaultValue?: string; params?: Record<string, unknown> } {\n let defaultValue: string | undefined;\n let params: Record<string, unknown> | undefined;\n\n // Runtime validation: Warn if both params are objects (likely misuse).\n // process is Node-only; browsers throw ReferenceError without the typeof\n // guard. Treat \"no process\" as \"not production\" so the dev warning still\n // fires in browser dev environments.\n const _isNotProd =\n typeof process === 'undefined' ||\n process.env?.NODE_ENV !== 'production';\n if (\n typeof secondParam === 'object' &&\n typeof thirdParam === 'object' &&\n _isNotProd\n ) {\n console.warn(\n '[LionRapid] Warning: Both secondParam and thirdParam are objects. ' +\n 'Expected pattern: t(key, params, defaultValue) or t(key, defaultValue, params). ' +\n 'Second object will be ignored as it cannot be a defaultValue.'\n );\n }\n\n if (typeof secondParam === 'string') {\n // t(key, defaultValue) or t(key, defaultValue, params)\n defaultValue = secondParam;\n if (typeof thirdParam === 'object') {\n params = thirdParam;\n }\n } else if (typeof secondParam === 'object') {\n // t(key, params) or t(key, params, defaultValue)\n params = secondParam;\n if (typeof thirdParam === 'string') {\n defaultValue = thirdParam;\n }\n }\n\n return { defaultValue, params };\n}\n", "/**\n * Simplified memory cache handler\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport { ISyncHandler } from '../interfaces/handler.interface.js';\nimport {\n IStatsProvider,\n ISyncRepository,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n TranslationContext,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger } from '../utils/index.js';\nimport {\n createNamespaceCacheKey,\n flattenTranslations,\n resolveNestedKey,\n} from '../utils/translation-value-utils.js';\n\n/**\n * Parsed cache entry containing both text and styles\n */\ninterface CachedContentUnit {\n text: string;\n styles: Record<string, string[]>;\n}\n\n/**\n * Simple memory cache handler\n */\nexport class SyncHandler implements ISyncHandler {\n readonly name: string;\n readonly version = '1.0.0';\n readonly priority: number;\n readonly type = 'memory' as const;\n readonly enabled: boolean;\n private ttlMap = new Map<string, number>();\n private ttl: number;\n private repository: ISyncRepository & IStatsProvider;\n private bus: EventEmitter;\n\n constructor(\n eventEmitter: EventEmitter,\n repository: ISyncRepository & IStatsProvider\n ) {\n this.bus = eventEmitter;\n this.repository = repository;\n this.name = repository.name;\n const config = repository.getConfig();\n this.enabled = config.enabled ?? true;\n this.priority = config.priority ?? 0;\n this.ttl = config.options?.ttl ?? 30 * 60 * 1000; // Default 30 minutes\n }\n\n getSourceType(): 'memory' | 'storage' | 'network' | 'fallback' {\n return 'memory';\n }\n\n /**\n * Simple lookup implementation\n * Returns ContentUnit with both text and styles\n */\n lookup(request: TranslationRequest): TranslationResult {\n const startTime = Date.now();\n logger.debug(`Sync lookup: ${request.cleanKey}`);\n const repoBus = this.bus.repo(request, this.name);\n repoBus.getStart();\n\n const directResult = this.tryDirectLookup(request);\n if (directResult !== null) {\n logger.debug(`Cache hit: ${request.cleanKey}`);\n repoBus.getSuccess(directResult.text);\n return this.createResult(directResult, 'memory', 200, startTime, true);\n }\n\n // Try namespace lookup for nested keys\n if (request.cleanKey.includes('.') && request.namespace) {\n const namespaceResult = this.tryNamespaceLookup(request);\n if (namespaceResult !== null) {\n logger.debug(`Namespace hit: ${request.cleanKey}`);\n repoBus.getSuccess(namespaceResult.text);\n return this.createResult(\n namespaceResult,\n 'memory',\n 200,\n startTime,\n true\n );\n }\n }\n\n logger.debug(`Cache miss: ${request.cleanKey}`);\n repoBus.getMiss();\n\n // Return fallback result (no styles for fallback)\n return this.createResult(\n { text: request.parsedDefaultValue || request.cleanKey, styles: {} },\n 'fallback',\n 404,\n startTime\n );\n }\n\n /**\n * Simple save implementation\n * Stores ContentUnit (text + styles) as JSON\n */\n save(request: TranslationRequest, result: TranslationResult): void {\n if (!result.value) return;\n const repoBus = this.bus.repo(request, this.name);\n\n // Store as ContentUnit JSON (text + styles together)\n const contentUnit: CachedContentUnit = {\n text: result.value,\n styles: result.styles || {},\n };\n this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Saved to cache: ${request.cleanKey}`);\n repoBus.setSuccess(result.value);\n }\n\n /**\n * Namespace saving implementation\n */\n saveNamespace(\n translations: TranslationData,\n context: TranslationContext\n ): void {\n if (!context.namespace) return;\n const repoBus = this.bus.repo(\n context.locale + ':' + context.namespace,\n this.name\n );\n\n // Store full namespace: @locale:namespace\n const namespaceCacheKey = createNamespaceCacheKey(\n context.locale,\n context.namespace\n );\n this.setWithTTL(namespaceCacheKey, JSON.stringify(translations));\n\n // Store flattened individual keys: locale:namespace:key\n const flattened = flattenTranslations(\n translations,\n '',\n context.locale,\n context.namespace!\n );\n\n for (const [flatKey, flatValue] of Object.entries(flattened)) {\n this.setWithTTL(flatKey, flatValue);\n }\n repoBus.setSuccess(JSON.stringify(translations));\n }\n\n /**\n * \u2705 Strategy 1: Direct cache lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private tryDirectLookup(request: TranslationRequest): CachedContentUnit | null {\n // Check TTL and expire if needed\n if (this.checkAndExpireTTL(request.individualCacheKey)) {\n return null;\n }\n\n const cachedValue = this.repository.get(request.individualCacheKey);\n if (!cachedValue) return null;\n\n this.refreshTTL(request.individualCacheKey); // Refresh TTL on access\n\n // Parse cached ContentUnit JSON\n try {\n const parsed = JSON.parse(cachedValue);\n if (typeof parsed === 'object' && 'text' in parsed) {\n return {\n text: String(parsed.text),\n styles: parsed.styles || {},\n };\n }\n // Legacy format: plain string (shouldn't happen with new data)\n return { text: cachedValue, styles: {} };\n } catch {\n // If parse fails, treat as legacy plain string\n return { text: cachedValue, styles: {} };\n }\n }\n\n /**\n * \u2705 Strategy 2: Namespace lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private tryNamespaceLookup(request: TranslationRequest): CachedContentUnit | null {\n if (!request.namespace) return null;\n\n const namespaceCacheKey = createNamespaceCacheKey(\n request.locale,\n request.namespace\n );\n\n // Check TTL for namespace\n if (this.checkAndExpireTTL(namespaceCacheKey)) {\n return null;\n }\n\n const namespaceData = this.repository.get(namespaceCacheKey);\n if (!namespaceData) return null;\n this.refreshTTL(namespaceCacheKey); // Refresh TTL on access\n\n try {\n const translations = JSON.parse(namespaceData);\n const value = resolveNestedKey(translations, request.cleanKey);\n\n if (value !== null && value !== undefined) {\n // Extract ContentUnit from namespace data\n let contentUnit: CachedContentUnit;\n\n if (typeof value === 'object' && value !== null && 'text' in value) {\n // Server ContentUnit format: { text, styles }\n contentUnit = {\n text: String((value as { text: unknown }).text),\n styles: (value as { styles?: Record<string, string[]> }).styles || {},\n };\n } else {\n // Plain string fallback\n contentUnit = { text: String(value), styles: {} };\n }\n\n // Cache the individual key for faster future access (as JSON)\n this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Cached from namespace: ${request.cleanKey}`);\n return contentUnit;\n }\n } catch (error) {\n // Invalid JSON in namespace cache\n logger.debug(\n `Invalid JSON in namespace cache: ${namespaceCacheKey}`,\n error\n );\n this.repository.remove(namespaceCacheKey);\n this.ttlMap.delete(namespaceCacheKey);\n }\n\n return null;\n }\n\n /**\n * Helper to create consistent TranslationResult objects\n * Now includes styles from ContentUnit\n */\n private createResult(\n contentUnit: CachedContentUnit,\n source: 'memory' | 'storage' | 'network' | 'fallback',\n status: number,\n startTime: number,\n cached?: boolean\n ): TranslationResult {\n return {\n value: contentUnit.text,\n styles: contentUnit.styles,\n source,\n status,\n duration: Date.now() - startTime,\n ...(cached !== undefined && { cached }),\n };\n }\n\n /**\n * Check TTL and expire if needed\n * Returns true if expired, false if still valid\n */\n private checkAndExpireTTL(cacheKey: string): boolean {\n const timestamp = this.ttlMap.get(cacheKey);\n if (timestamp && Date.now() - timestamp > this.ttl) {\n this.repository.remove(cacheKey);\n this.ttlMap.delete(cacheKey);\n logger.debug(`TTL expired: ${cacheKey}`);\n return true;\n }\n return false;\n }\n\n /**\n * Set value in repository and update TTL\n */\n private setWithTTL(cacheKey: string, value: string): void {\n this.repository.set(cacheKey, value);\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Refresh TTL on access\n */\n private refreshTTL(cacheKey: string): void {\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Get TTL information for debugging\n */\n getTTLInfo(): Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > {\n const ttlInfo: Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > = {};\n const now = Date.now();\n\n for (const [key, timestamp] of this.ttlMap.entries()) {\n const age = now - timestamp;\n const remaining = Math.max(0, this.ttl - age);\n ttlInfo[key] = { timestamp, age, remaining };\n }\n\n return ttlInfo;\n }\n\n getEntries() {\n if (this.repository.getEntries !== undefined) {\n return this.repository.getEntries();\n }\n }\n\n /**\n * Clear all entries for a specific namespace\n * Removes namespace cache entry, individual keys, and TTL entries\n */\n clearNamespace(locale: string, namespace: string): void {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n const keyPrefix = `${locale}:${namespace}:`;\n\n // Remove namespace cache entry\n this.repository.remove(namespaceCacheKey);\n this.ttlMap.delete(namespaceCacheKey);\n\n // Remove individual translation keys and their TTL entries\n const entries = this.repository.getEntries?.();\n if (entries) {\n for (const key of Object.keys(entries)) {\n if (key.startsWith(keyPrefix)) {\n this.repository.remove(key);\n this.ttlMap.delete(key);\n }\n }\n }\n\n logger.debug(`Cleared namespace: ${locale}:${namespace}`);\n }\n\n destroy(): void {\n this.repository.clear();\n this.ttlMap.clear();\n }\n\n /**\n * Direct cache set (for optimistic updates)\n * Bypasses event emission for direct cache manipulation\n * Stores as ContentUnit JSON (text + styles)\n */\n setCache(key: string, value: string, styles?: Record<string, string[]>): void {\n const contentUnit: CachedContentUnit = {\n text: value,\n styles: styles || {},\n };\n this.setWithTTL(key, JSON.stringify(contentUnit));\n logger.debug(`Direct cache set: ${key}`);\n }\n}\n", "/**\n * Simplified memory cache handler\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport { StorageRepositoryConfig } from '../config';\nimport { IAsyncHandler } from '../interfaces/handler.interface.js';\nimport {\n IAsyncRepository,\n IStatsProvider,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n TranslationContext,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger } from '../utils/index.js';\nimport {\n createNamespaceCacheKey,\n flattenTranslations,\n resolveNestedKey,\n} from '../utils/translation-value-utils.js';\n\n/**\n * Parsed cache entry containing both text and styles\n */\ninterface CachedContentUnit {\n text: string;\n styles: Record<string, string[]>;\n}\n\n/**\n * Async storage cache handler (IndexedDB, localStorage, etc.)\n */\nexport class AsyncHandler implements IAsyncHandler {\n readonly name: string;\n readonly version = '1.0.0';\n readonly priority: number;\n readonly type = 'storage' as const;\n readonly enabled: boolean;\n private ttlMap = new Map<string, number>();\n private ttl: number;\n private repository: IAsyncRepository & IStatsProvider;\n private bus: EventEmitter;\n\n constructor(\n eventEmitter: EventEmitter,\n repository: IAsyncRepository & IStatsProvider\n ) {\n this.bus = eventEmitter;\n this.repository = repository;\n this.name = repository.name;\n const config = repository.getConfig() as StorageRepositoryConfig;\n this.enabled = config.enabled ?? true;\n this.priority = config.priority ?? 0;\n this.ttl = config.options?.ttl ?? 30 * 60 * 1000; // Default 30 minutes\n }\n\n getSourceType(): 'memory' | 'storage' | 'network' | 'fallback' {\n return 'memory';\n }\n\n /**\n * Simple lookup implementation\n * Returns ContentUnit with both text and styles\n */\n async lookup(request: TranslationRequest): Promise<TranslationResult> {\n const startTime = Date.now();\n logger.debug(`Async lookup: ${request.cleanKey}`);\n const repoBus = this.bus.repo(request, this.name);\n\n const directResult = await this.tryDirectLookup(request);\n if (directResult !== null) {\n logger.debug(`Cache hit: ${request.cleanKey}`);\n repoBus.getSuccess(directResult.text);\n return this.createResult(directResult, 'storage', 200, startTime, true);\n }\n\n // Try namespace lookup for nested keys\n if (request.cleanKey.includes('.') && request.namespace) {\n const namespaceResult = await this.tryNamespaceLookup(request);\n if (namespaceResult !== null) {\n logger.debug(`Namespace hit: ${request.cleanKey}`);\n repoBus.getSuccess(namespaceResult.text);\n return this.createResult(\n namespaceResult,\n 'storage',\n 200,\n startTime,\n true\n );\n }\n }\n\n logger.debug(`Cache miss: ${request.cleanKey}`);\n repoBus.getMiss();\n\n // Return fallback result (no styles for fallback)\n return this.createResult(\n { text: request.parsedDefaultValue || request.cleanKey, styles: {} },\n 'fallback',\n 404,\n startTime\n );\n }\n\n /**\n * Simple save implementation\n * Stores ContentUnit (text + styles) as JSON\n */\n async save(\n request: TranslationRequest,\n result: TranslationResult\n ): Promise<void> {\n if (!result.value) return;\n const repoBus = this.bus.repo(request, this.name);\n\n // Store as ContentUnit JSON (text + styles together)\n const contentUnit: CachedContentUnit = {\n text: result.value,\n styles: result.styles || {},\n };\n await this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Saved to cache: ${request.cleanKey}`);\n repoBus.setSuccess(result.value);\n }\n\n /**\n * Namespace saving implementation\n */\n async saveNamespace(\n translations: TranslationData,\n context: TranslationContext\n ): Promise<void> {\n if (!context.namespace) return;\n const repoBus = this.bus.repo(\n context.locale + ':' + context.namespace,\n this.name\n );\n const keyCount = Object.keys(translations).length;\n logger.debug(\n `Saving namespace: ${context.locale}:${context.namespace} (${keyCount} keys)`\n );\n\n // Store full namespace: @locale:namespace\n const namespaceCacheKey = createNamespaceCacheKey(\n context.locale,\n context.namespace\n );\n await this.setWithTTL(namespaceCacheKey, JSON.stringify(translations));\n\n // Store flattened individual keys: locale:namespace:key\n const flattened = flattenTranslations(\n translations,\n '',\n context.locale,\n context.namespace!\n );\n\n let savedCount = 0;\n for (const [flatKey, flatValue] of Object.entries(flattened)) {\n await this.setWithTTL(flatKey, flatValue);\n savedCount++;\n }\n\n logger.debug(`Saved: ${savedCount} keys + namespace blob`);\n repoBus.setSuccess(JSON.stringify(translations));\n }\n\n /**\n * \u2705 Strategy 1: Direct cache lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private async tryDirectLookup(\n request: TranslationRequest\n ): Promise<CachedContentUnit | null> {\n // Check TTL and expire if needed\n if (await this.checkAndExpireTTL(request.individualCacheKey)) {\n return null;\n }\n\n const cachedValue = await this.repository.get(request.individualCacheKey);\n if (!cachedValue) return null;\n\n this.refreshTTL(request.individualCacheKey); // Refresh TTL on access\n\n // Parse cached ContentUnit JSON\n try {\n const parsed = JSON.parse(cachedValue);\n if (typeof parsed === 'object' && 'text' in parsed) {\n return {\n text: String(parsed.text),\n styles: parsed.styles || {},\n };\n }\n // Legacy format: plain string\n return { text: cachedValue, styles: {} };\n } catch {\n // If parse fails, treat as legacy plain string\n return { text: cachedValue, styles: {} };\n }\n }\n\n /**\n * \u2705 Strategy 2: Namespace lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private async tryNamespaceLookup(\n request: TranslationRequest\n ): Promise<CachedContentUnit | null> {\n if (!request.namespace) return null;\n\n const namespaceCacheKey = createNamespaceCacheKey(\n request.locale,\n request.namespace\n );\n\n // Check TTL for namespace\n if (await this.checkAndExpireTTL(namespaceCacheKey)) {\n return null;\n }\n\n const namespaceData = await this.repository.get(namespaceCacheKey);\n if (!namespaceData) return null;\n this.refreshTTL(namespaceCacheKey); // Refresh TTL on access\n\n try {\n const translations = JSON.parse(namespaceData);\n const value = resolveNestedKey(translations, request.cleanKey);\n\n if (value !== null && value !== undefined) {\n // Extract ContentUnit from namespace data\n let contentUnit: CachedContentUnit;\n\n if (typeof value === 'object' && value !== null && 'text' in value) {\n // Server ContentUnit format: { text, styles }\n contentUnit = {\n text: String((value as { text: unknown }).text),\n styles: (value as { styles?: Record<string, string[]> }).styles || {},\n };\n } else {\n // Plain string fallback\n contentUnit = { text: String(value), styles: {} };\n }\n\n // Cache the individual key for faster future access (as JSON)\n await this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Cached from namespace: ${request.cleanKey}`);\n return contentUnit;\n }\n } catch (error) {\n // Invalid JSON in namespace cache\n logger.debug(\n `Invalid JSON in namespace cache: ${namespaceCacheKey}`,\n error\n );\n await this.repository.remove(namespaceCacheKey);\n this.ttlMap.delete(namespaceCacheKey);\n }\n\n return null;\n }\n\n /**\n * Helper to create consistent TranslationResult objects\n * Now includes styles from ContentUnit\n */\n private createResult(\n contentUnit: CachedContentUnit,\n source: 'memory' | 'storage' | 'network' | 'fallback',\n status: number,\n startTime: number,\n cached?: boolean\n ): TranslationResult {\n return {\n value: contentUnit.text,\n styles: contentUnit.styles,\n source,\n status,\n duration: Date.now() - startTime,\n ...(cached !== undefined && { cached }),\n };\n }\n\n /**\n * Check TTL and expire if needed (async version)\n * Returns true if expired, false if still valid\n */\n private async checkAndExpireTTL(cacheKey: string): Promise<boolean> {\n const timestamp = this.ttlMap.get(cacheKey);\n if (timestamp && Date.now() - timestamp > this.ttl) {\n await this.repository.remove(cacheKey);\n this.ttlMap.delete(cacheKey);\n logger.debug(`TTL expired: ${cacheKey}`);\n return true;\n }\n return false;\n }\n\n /**\n * Set value in repository and update TTL (async version)\n */\n private async setWithTTL(cacheKey: string, value: string): Promise<void> {\n await this.repository.set(cacheKey, value);\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Refresh TTL on access\n */\n private refreshTTL(cacheKey: string): void {\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Get TTL information for debugging\n */\n getTTLInfo(): Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > {\n const ttlInfo: Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > = {};\n const now = Date.now();\n\n for (const [key, timestamp] of this.ttlMap.entries()) {\n const age = now - timestamp;\n const remaining = Math.max(0, this.ttl - age);\n ttlInfo[key] = { timestamp, age, remaining };\n }\n\n return ttlInfo;\n }\n\n async destroy(): Promise<void> {\n await this.repository.clear();\n this.ttlMap.clear();\n }\n\n getEntries(): Record<string, string> | undefined {\n if (this.repository.getEntries !== undefined) {\n return this.repository.getEntries();\n }\n }\n}\n", "/**\n * Custom error classes for translation operations\n * Used for type-safe exception handling in repositories and handlers\n */\n\n/**\n * Base error class for all translation-related errors\n */\nexport class TranslationError extends Error {\n constructor(\n public readonly key: string,\n public readonly status: number,\n message: string\n ) {\n super(message);\n this.name = this.constructor.name;\n // Maintains proper stack trace for where our error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Translation not found in backend (HTTP 404)\n * Should be synced to backend for translators to fill in\n */\nexport class TranslationNotFoundError extends TranslationError {\n constructor(key: string) {\n super(key, 404, `Translation not found: ${key}`);\n }\n}\n\n/**\n * Translation exists but is locked/not ready (HTTP 423)\n * Should NOT be synced to backend - will retry on next app start\n */\nexport class TranslationLockedError extends TranslationError {\n constructor(\n key: string,\n public readonly retryAfter?: number\n ) {\n super(key, 423, `Translation locked: ${key}`);\n }\n}\n\n/**\n * Server error (HTTP 5xx)\n * Should trigger retry logic with exponential backoff\n */\nexport class ServerError extends TranslationError {\n constructor(key: string, status: number) {\n super(key, status, `Server error ${status}: ${key}`);\n }\n}\n\n/**\n * Network error (timeout, DNS failure, CORS, etc.)\n * Not an HTTP error - network layer failed\n */\nexport class NetworkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'NetworkError';\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Type guard to check if error is a TranslationError\n */\nexport function isTranslationError(error: unknown): error is TranslationError {\n return error instanceof TranslationError;\n}\n\n/**\n * Type guard to check if error is retryable (5xx or network)\n */\nexport function isRetryableError(error: unknown): boolean {\n return error instanceof ServerError || error instanceof NetworkError;\n}\n\n/**\n * Type guard to check if error is client error (4xx - not retryable)\n */\nexport function isClientError(error: unknown): boolean {\n return (\n error instanceof TranslationNotFoundError ||\n error instanceof TranslationLockedError\n );\n}\n", "/**\n * Simplified API handler - no automatic namespace loading\n * Namespace loading is now explicit via builder configuration\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport { NetworkRepositoryConfig, PreloadNamespaces } from '../config';\nimport type { ContentUnit } from '../content/types.js';\nimport {\n isRetryableError,\n TranslationLockedError,\n TranslationNotFoundError,\n} from '../errors/translation-errors.js';\nimport { IAsyncHandler } from '../interfaces/handler.interface.js';\nimport { IAsyncRepository } from '../interfaces/repository.interface.js';\nimport { NetworkRepository } from '../repositories/network-repository.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n NamespaceResult,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger, resolveNestedKey } from '../utils/index.js';\n\n/**\n * Simple API handler - only loads individual keys\n * Namespace loading is handled explicitly by builder\n */\nexport class NetworkHandler implements IAsyncHandler {\n repository: IAsyncRepository;\n readonly name: string;\n readonly priority: number;\n readonly version = '1.0.0';\n readonly type = 'network' as const;\n readonly enabled: boolean;\n private bus: EventEmitter;\n\n private retryCount: number;\n private retryDelay: number;\n\n constructor(eventEmitter: EventEmitter, repository: IAsyncRepository) {\n this.bus = eventEmitter;\n this.repository = repository;\n this.name = repository.name;\n const config = repository.getConfig() as NetworkRepositoryConfig;\n this.enabled = config.enabled ?? false;\n this.priority = config.priority ?? 0;\n this.retryCount = config.options?.retries ?? 3;\n this.retryDelay = config.options?.retryDelay ?? 1000;\n }\n\n initialize(): Promise<void> {\n return Promise.resolve();\n }\n\n getSourceType(): 'memory' | 'storage' | 'network' | 'fallback' {\n return 'network';\n }\n\n /**\n * \u2705 Lookup translation with full error handling\n * Strategy: Key first, namespace as fallback\n * Returns TranslationResult with status, source, duration, styles, and optional error\n */\n async lookup(request: TranslationRequest): Promise<TranslationResult> {\n const startTime = Date.now();\n const fallbackValue = request.parsedDefaultValue || request.cleanKey;\n\n if (!this.enabled) {\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 0,\n startTime\n );\n }\n\n const networkBus = this.bus.network(request, this.name);\n networkBus.start();\n logger.debug(`Network lookup: ${request.cleanKey}`);\n\n // Strategy 1: Try individual key lookup first (returns ContentUnit with styles)\n try {\n const contentUnit = await this.lookupContentUnitWithRetry(\n request.individualCacheKey\n );\n\n logger.debug(`Network hit: ${request.cleanKey}`);\n networkBus.success(contentUnit.text);\n\n // Return text + styles for caching\n return this.createTranslationResult(\n contentUnit.text,\n 'network',\n 200,\n startTime,\n undefined,\n false,\n undefined,\n contentUnit.styles\n );\n } catch (error) {\n // Handle 404 - key not found, try namespace fallback\n if (error instanceof TranslationNotFoundError && request.namespace) {\n logger.debug(\n `Individual key not found, trying namespace: ${request.cleanKey}`\n );\n return this.lookupFromNamespace(request, fallbackValue, startTime, networkBus);\n }\n\n // Handle 423 - locked translation\n if (error instanceof TranslationLockedError) {\n logger.debug(`Translation locked (423): ${request.cleanKey}`);\n return this.handleTranslationLocked(\n request,\n fallbackValue,\n error,\n startTime,\n networkBus\n );\n }\n\n // Handle other errors (server errors, network errors)\n logger.debug(`Network error: ${request.cleanKey}`, error);\n networkBus.error(error as Error);\n\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 0,\n startTime,\n error as Error\n );\n }\n }\n\n /**\n * Strategy 2: Namespace fallback when individual key not found\n */\n private async lookupFromNamespace(\n request: TranslationRequest,\n fallbackValue: string,\n startTime: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n networkBus: any\n ): Promise<TranslationResult> {\n try {\n const namespaceResult = await this.loadNamespace(\n request.locale,\n request.namespace!\n );\n\n if (namespaceResult && namespaceResult.data) {\n const nestedValue = resolveNestedKey(\n namespaceResult.data,\n request.cleanKey\n );\n\n if (nestedValue !== undefined && nestedValue !== null) {\n // Handle both ContentUnit format and plain strings\n let resolvedValue: string;\n let styles: Record<string, string[]> = {};\n\n if (typeof nestedValue === 'object' && nestedValue !== null && 'text' in nestedValue) {\n // ContentUnit format: { text, styles }\n const contentUnit = nestedValue as { text: unknown; styles?: Record<string, string[]> };\n resolvedValue = String(contentUnit.text);\n styles = contentUnit.styles || {};\n } else {\n // Plain string\n resolvedValue = String(nestedValue);\n }\n\n logger.debug(`Network namespace hit: ${request.cleanKey}, hasStyles=${Object.keys(styles).length > 0}`);\n networkBus.success(resolvedValue);\n\n return this.createTranslationResult(\n resolvedValue,\n 'network',\n 200,\n startTime,\n undefined,\n false,\n {\n locale: request.locale,\n namespace: request.namespace!,\n data: namespaceResult.data,\n },\n styles\n );\n }\n }\n\n // Key not found in namespace either\n const error = new TranslationNotFoundError(request.cleanKey);\n return this.handleTranslationNotFound(\n request,\n fallbackValue,\n error,\n startTime\n );\n } catch (nsError) {\n // Namespace load failed\n logger.debug(`Namespace load failed: ${request.cleanKey}`, nsError);\n\n if (nsError instanceof TranslationNotFoundError) {\n return this.handleTranslationNotFound(\n request,\n fallbackValue,\n nsError,\n startTime\n );\n }\n\n if (nsError instanceof TranslationLockedError) {\n return this.handleTranslationLocked(\n request,\n fallbackValue,\n nsError,\n startTime,\n networkBus\n );\n }\n\n networkBus.error(nsError as Error);\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 0,\n startTime,\n nsError as Error\n );\n }\n }\n\n /**\n * \u2705 Load entire namespace (used for preloading)\n * Returns NamespaceResult with status and error information\n */\n async loadNamespace(\n locale: string,\n namespace: string\n ): Promise<NamespaceResult | null> {\n const startTime = Date.now();\n\n if (!this.enabled) {\n return this.createNamespaceResult(null, 'fallback', 0, startTime);\n }\n\n try {\n const data = await this.loadNamespaceWithRetry(locale, namespace);\n\n // 304 Not Modified \u2014 cached translations are still fresh\n if (data === null) {\n logger.debug(`Network namespace not modified: ${locale}:${namespace}`);\n return this.createNamespaceResult(null, 'network', 304, startTime);\n }\n\n logger.debug(`Network namespace loaded: ${locale}:${namespace}`);\n return this.createNamespaceResult(data, 'network', 200, startTime);\n } catch (error) {\n if (error instanceof TranslationLockedError) {\n logger.debug(`Namespace locked (423): ${locale}:${namespace}`);\n\n return this.createNamespaceResult(\n null,\n 'fallback',\n 423,\n startTime,\n error\n );\n }\n\n if (error instanceof TranslationNotFoundError) {\n logger.debug(`Network namespace not found: ${locale}:${namespace}`);\n\n return this.createNamespaceResult(\n null,\n 'fallback',\n 404,\n startTime,\n error\n );\n }\n\n logger.debug(`Network namespace error: ${locale}:${namespace}`, error);\n\n return this.createNamespaceResult(\n null,\n 'fallback',\n 0,\n startTime,\n error as Error\n );\n }\n }\n\n /**\n * \u2705 Namespace lookup with retry logic\n * Throws custom errors (TranslationNotFoundError, TranslationLockedError, etc.)\n */\n private async loadNamespaceWithRetry(\n locale: string,\n namespace: string\n ): Promise<TranslationData | null> {\n return this.withRetry(\n () => this.repository.getNamespace(locale, namespace),\n `${locale}:${namespace}`,\n 'namespace request'\n );\n }\n\n /**\n * Simple save implementation (API usually doesn't save)\n */\n async save(\n request: TranslationRequest,\n result: TranslationResult\n ): Promise<void> {\n // APIs usually don't save translations, but we could implement PUT if needed\n void request;\n void result;\n }\n\n /**\n * \u2705 Lookup with retry logic for individual keys\n * Throws custom errors (TranslationNotFoundError, TranslationLockedError, etc.)\n */\n private async lookupWithRetry(cacheKey: string): Promise<string> {\n return this.withRetry(\n () => this.repository.get(cacheKey),\n cacheKey,\n 'network request'\n );\n }\n\n /**\n * \u2705 Lookup ContentUnit with retry logic for individual keys\n * Returns full ContentUnit with text and styles\n * Throws custom errors (TranslationNotFoundError, TranslationLockedError, etc.)\n */\n private async lookupContentUnitWithRetry(cacheKey: string): Promise<ContentUnit> {\n // Check if repository supports getContentUnit (NetworkRepository does)\n const repo = this.repository as NetworkRepository;\n if (typeof repo.getContentUnit !== 'function') {\n // Fallback: use get() and wrap in ContentUnit\n const text = await this.lookupWithRetry(cacheKey);\n return { text, styles: {} };\n }\n\n return this.withRetry(\n () => repo.getContentUnit(cacheKey),\n cacheKey,\n 'network content unit request'\n );\n }\n\n /**\n * Delay utility for retries\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private calculateBackoff(attempt: number): number {\n const baseDelay = this.retryDelay;\n const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);\n const maxDelay = 10000; // 10 seconds max\n\n // Add jitter to prevent thundering herd\n const jitter = Math.random() * 0.1 * exponentialDelay;\n\n return Math.min(exponentialDelay + jitter, maxDelay);\n }\n\n /**\n * Generic retry wrapper for repository operations\n * Handles retryable errors with exponential backoff\n */\n private async withRetry<T>(\n operation: () => Promise<T>,\n contextKey: string,\n contextDescription: string,\n attempt = 1\n ): Promise<T> {\n const networkBus = this.bus.network(contextKey, 'withRetry');\n\n try {\n return await operation();\n } catch (error) {\n // Retry only on retryable errors (5xx, network errors)\n if (attempt <= this.retryCount && isRetryableError(error)) {\n const delay = this.calculateBackoff(attempt);\n networkBus.retry(attempt, delay, (error as Error).message);\n await this.delay(delay);\n\n logger.debug(\n `Retrying ${contextDescription} (${attempt}/${this.retryCount}) after ${delay}ms`\n );\n return this.withRetry(\n operation,\n contextKey,\n contextDescription,\n attempt + 1\n );\n }\n\n // Don't retry client errors (404, 423)\n throw error;\n }\n }\n\n /**\n * Handle translation not found (after namespace fallback also failed)\n */\n private handleTranslationNotFound(\n request: TranslationRequest,\n fallbackValue: string,\n error: TranslationNotFoundError,\n startTime: number\n ): TranslationResult {\n logger.debug(`Network namespace miss: ${request.cleanKey}`);\n const translateBus = this.bus.translation(request);\n translateBus.notFound(\n fallbackValue,\n request.locale,\n request.namespace || 'default'\n );\n\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 404,\n startTime,\n error\n );\n }\n\n /**\n * Handle TranslationLockedError for translation lookups\n */\n private handleTranslationLocked(\n request: TranslationRequest,\n fallbackValue: string,\n error: TranslationLockedError,\n startTime: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n networkBus: any\n ): TranslationResult {\n const translateBus = this.bus.translation(request);\n translateBus.locked(\n fallbackValue,\n request.locale,\n request.namespace || 'default'\n );\n networkBus.error(error, 423);\n\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 423,\n startTime,\n error\n );\n }\n\n /**\n * Helper to create consistent TranslationResult objects\n */\n private createTranslationResult(\n value: string,\n source: 'network' | 'fallback' | 'storage' | 'memory',\n status: number,\n startTime: number,\n error?: Error,\n cached?: boolean,\n namespaceLoaded?: {\n locale: string;\n namespace: string;\n data: TranslationData;\n },\n styles?: Record<string, string[]>\n ): TranslationResult {\n return {\n value,\n source,\n status,\n duration: Date.now() - startTime,\n ...(error && { error }),\n ...(cached !== undefined && { cached }),\n ...(namespaceLoaded && { namespaceLoaded }),\n ...(styles && Object.keys(styles).length > 0 && { styles }),\n };\n }\n\n /**\n * Helper to create consistent NamespaceResult objects\n */\n private createNamespaceResult(\n data: TranslationData | null,\n source: 'network' | 'fallback' | 'storage' | 'memory',\n status: number,\n startTime: number,\n error?: Error\n ): NamespaceResult {\n return {\n data,\n source,\n status,\n duration: Date.now() - startTime,\n ...(error && { error }),\n };\n }\n\n getPreload(): Array<PreloadNamespaces> {\n const config = this.repository.getConfig() as NetworkRepositoryConfig;\n return config.options?.preloadNamespaces || [];\n }\n}\n", "/**\n * Canonical opening-tag format for ContentUnit `raw:` styles.\n *\n * All four parsers (edge, core HTML walker, core DOM walker, PHP) must\n * produce byte-identical output for the same source element. Rules:\n * - tag name lowercased\n * - attribute names lowercased\n * - attribute values always wrapped in double-quotes\n * - attribute insertion order preserved from source\n * - boolean attrs emitted as `attr=\"\"`\n * - void elements use the same form (no self-closing slash, no close tag emitted)\n *\n * Attribute values are stored byte-for-byte as captured from the source\n * (the source's own entity encoding is preserved \u2014 already valid HTML).\n * The serializer only re-escapes `\"` \u2192 `&quot;` so the chosen double-quote\n * delimiter stays well-formed when the source used single quotes.\n */\n\nexport const VOID_TAGS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\nfunction escapeAttrValue(value: string): string {\n return value.replace(/\"/g, '&quot;');\n}\n\n/**\n * Build the canonical opening tag string. Used by parsers to produce\n * the `raw:<...>` style content.\n */\nexport function serializeOpeningTag(\n tagName: string,\n attrs: Record<string, string>,\n): string {\n const tag = tagName.toLowerCase();\n let result = `<${tag}`;\n for (const [name, value] of Object.entries(attrs)) {\n result += ` ${name.toLowerCase()}=\"${escapeAttrValue(value)}\"`;\n }\n result += '>';\n return result;\n}\n\n/**\n * Extract the tag name from a canonical opening tag string.\n * `<span class=\"x\">` \u2192 `span`. Returns lowercase.\n */\nexport function extractTagName(rawOpenTag: string): string {\n const end = rawOpenTag.search(/[\\s>]/);\n return rawOpenTag.slice(1, end === -1 ? rawOpenTag.length : end).toLowerCase();\n}\n\n/**\n * Return the raw opening tag (the portion after `raw:`) from a style array,\n * or null if no `raw:` style is present.\n */\nexport function readRawStyle(styles: string[]): string | null {\n for (const s of styles) {\n if (s.startsWith('raw:')) return s.slice(4);\n }\n return null;\n}\n", "/**\n * Markup parser \u2014 converts HTML strings to ContentUnit (raw-only).\n *\n * Every inline element becomes an indexed tag whose style is the verbatim\n * opening tag in canonical form (see canonical-tag.ts). No element-to-\n * semantic-style mapping \u2014 wrappers round-trip exactly.\n *\n * @module content/parser/MarkupParser\n */\n\nimport type { IParser } from './IParser.js';\nimport type { ContentUnit } from '../types.js';\nimport { serializeOpeningTag, VOID_TAGS } from '../canonical-tag.js';\n\ninterface TagMatch {\n tag: string;\n attrs: Record<string, string>;\n isClosing: boolean;\n isSelfClosing: boolean;\n startIndex: number;\n endIndex: number;\n}\n\n/**\n * Parser that converts HTML markup strings to ContentUnit (raw-only).\n *\n * @example\n * ```typescript\n * const parser = new MarkupParser();\n * parser.parse('Read our <b>Terms</b>.');\n * // \u2192 { text: 'Read our <1>Terms</1>.', styles: { '1': ['raw:<b>'] } }\n * ```\n */\n/**\n * Decode named + numeric HTML entities to their literal Unicode characters.\n *\n * Why: the parser may be fed strings from several sources that historically\n * encoded entities differently \u2014 developer-authored JSX strings (`<Trans\n * defaultValue=\"It&apos;s working\">`), cached translation values that came\n * through `tHtml`, or server-rendered HTML processed by edge/WP. The other\n * three parsers in the stack (browser DOM, edge regex, PHP regex) all see\n * decoded characters by the time they hash. Decoding here so this parser\n * does too keeps `auto_` keys consistent across every entry point. Decode\n * is a no-op for entity-free input, which is the overwhelmingly common\n * case in JSX where developers type literal characters.\n *\n * Covers the named entities WordPress's wptexturize commonly emits plus\n * all numeric forms (`&#NNN;` / `&#xHHH;`). Anything else is left alone.\n */\nfunction decodeEntities(text: string): string {\n const named: Record<string, string> = {\n amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\", nbsp: ' ',\n rsquo: '\u2019', lsquo: '\u2018', rdquo: '\u201D', ldquo: '\u201C',\n hellip: '\u2026', mdash: '\u2014', ndash: '\u2013', copy: '\u00A9',\n reg: '\u00AE', trade: '\u2122',\n };\n return text.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z][a-z0-9]*);/gi, (m, body) => {\n if (body[0] === '#') {\n const cp = body[1] === 'x' || body[1] === 'X'\n ? parseInt(body.slice(2), 16)\n : parseInt(body.slice(1), 10);\n if (Number.isFinite(cp) && cp > 0) {\n try { return String.fromCodePoint(cp); } catch { return m; }\n }\n return m;\n }\n return named[body.toLowerCase()] ?? m;\n });\n}\n\nexport class MarkupParser implements IParser<string> {\n parse(input: string): ContentUnit {\n // Already indexed tags from server \u2014 still decode entities so the text\n // hashes identically regardless of which path produced it.\n if (/<\\/?[0-9]+>/.test(input)) {\n return { text: decodeEntities(input), styles: {} };\n }\n\n const styles: Record<string, string[]> = {};\n let tagIndex = 0;\n const tagStack: Array<{ tag: string; index: number }> = [];\n let result = '';\n let pos = 0;\n\n while (pos < input.length) {\n const tag = this.matchTag(input, pos);\n if (!tag) {\n result += input.slice(pos);\n break;\n }\n\n result += input.slice(pos, tag.startIndex);\n\n if (tag.isClosing) {\n let matchIdx: number | null = null;\n for (let i = tagStack.length - 1; i >= 0; i--) {\n if (tagStack[i].tag === tag.tag.toLowerCase()) {\n matchIdx = tagStack[i].index;\n tagStack.splice(i, 1);\n break;\n }\n }\n if (matchIdx !== null) {\n result += `</${matchIdx}>`;\n }\n // Stray close \u2014 drop.\n } else {\n const tagName = tag.tag.toLowerCase();\n const isVoid = VOID_TAGS.has(tagName);\n const isSelfClosing = tag.isSelfClosing || isVoid;\n\n tagIndex++;\n styles[String(tagIndex)] = [`raw:${serializeOpeningTag(tagName, tag.attrs)}`];\n\n if (isSelfClosing) {\n result += `<${tagIndex}/>`;\n } else {\n result += `<${tagIndex}>`;\n tagStack.push({ tag: tagName, index: tagIndex });\n }\n }\n\n pos = tag.endIndex;\n }\n\n while (tagStack.length > 0) {\n const unclosed = tagStack.pop()!;\n result += `</${unclosed.index}>`;\n }\n\n return { text: decodeEntities(result), styles };\n }\n\n private matchTag(input: string, startPos: number): TagMatch | null {\n const tagStart = input.indexOf('<', startPos);\n if (tagStart === -1) return null;\n\n const tagPattern =\n /^<(\\/?)([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z][a-zA-Z0-9-]*(?:=(?:\"[^\"]*\"|'[^']*'|[^\\s>]*))?)*)\\s*(\\/?)>/;\n const remaining = input.slice(tagStart);\n const match = remaining.match(tagPattern);\n\n if (!match) {\n if (tagStart + 1 < input.length) {\n return this.matchTag(input, tagStart + 1);\n }\n return null;\n }\n\n const [fullMatch, closingSlash, tagName, attrsString, selfClosingSlash] = match;\n return {\n tag: tagName,\n attrs: this.parseAttributes(attrsString),\n isClosing: closingSlash === '/',\n isSelfClosing: selfClosingSlash === '/',\n startIndex: tagStart,\n endIndex: tagStart + fullMatch.length,\n };\n }\n\n private parseAttributes(attrsString: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n if (!attrsString.trim()) return attrs;\n\n const attrPattern = /([a-zA-Z][a-zA-Z0-9-]*)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]*)))?/g;\n let match;\n while ((match = attrPattern.exec(attrsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, unquoted] = match;\n attrs[name.toLowerCase()] = doubleQuoted ?? singleQuoted ?? unquoted ?? '';\n }\n return attrs;\n }\n}\n", "/**\n * Shared allowlist HTML sanitizer \u2014 pure string functions, Node-safe (no DOM).\n *\n * One implementation for every sink that turns translation data into HTML:\n * core's HTMLSerializer/auto-translator, the editor text sinks, the snapshot\n * viewer, react `<Trans>`, and WordPress TS. The WordPress PHP port must\n * mirror `SAFE_TAGS`/`SAFE_ATTRS` exactly (see improvement-plan \u00A74 item 2).\n *\n * Threat model: translation values (and their `raw:` styles) come from the\n * server/KV and may be attacker-controlled \u2014 they are NOT guaranteed to be in\n * canonical form. Everything here is allowlist-based: unknown tags are\n * rejected, unknown attributes dropped, URL schemes checked after entity\n * decoding.\n *\n * @module content/sanitizer/HTMLSanitizer\n */\n\nimport { extractTagName, readRawStyle, serializeOpeningTag } from '../canonical-tag.js';\nimport type { ContentUnit } from '../types.js';\n\n/**\n * Inline formatting elements allowed inside translated content. Block\n * structure lives outside ContentUnit (block-level pipeline), so anything\n * that isn't inline text formatting is rejected outright.\n */\nexport const SAFE_TAGS = new Set([\n 'a', 'abbr', 'b', 'bdi', 'bdo', 'br', 'cite', 'code', 'del', 'dfn',\n 'em', 'i', 'img', 'ins', 'kbd', 'mark', 'q', 's', 'samp', 'small',\n 'span', 'strong', 'sub', 'sup', 'time', 'u', 'var', 'wbr',\n]);\n\n/**\n * Flat attribute allowlist (plus `data-*`/`aria-*` prefixes, handled in\n * `sanitizeOpeningTag`). Kept flat \u2014 not per-tag \u2014 so the PHP mirror stays\n * trivial; an allowed attribute on the wrong tag is inert.\n */\nexport const SAFE_ATTRS = new Set([\n 'alt', 'cite', 'class', 'datetime', 'dir', 'height', 'href', 'id',\n 'lang', 'loading', 'rel', 'role', 'src', 'target', 'title', 'width',\n]);\n\n/** Attributes whose values are URLs and must pass `sanitizeUrl`. */\nconst URL_ATTRS = new Set(['href', 'src', 'cite']);\n\n/**\n * CSS properties allowed through an inline `style` attribute.\n *\n * RISK NOTE \u2014 why `style` never passes through verbatim: with zero\n * JavaScript, an attacker who controls a style value can render a\n * full-viewport overlay (`position:fixed;inset:0` \u2192 pixel-perfect fake\n * login UI on the customer's real domain), fire tracking/exfiltration\n * beacons via `url(...)`, or hide and deface content. Translation data is\n * attacker-writable in our threat model, so `sanitizeStyle` re-parses the\n * declarations and keeps only the properties below: cosmetic text/font\n * properties whose value grammar cannot fetch a URL and cannot reposition\n * or restack the element (no `position`/`inset`/`display`/`z-index`/\n * `opacity`/`transform`, no `background` shorthand). A smuggled `url(...)`\n * inside an allowed property is doubly inert: the value is rejected here,\n * and these properties ignore URL values anyway.\n *\n * CONTINUOUS DEVELOPMENT: this allowlist is intentionally minimal and is\n * expected to grow deliberately as real sites surface legitimate inline\n * styling the strict set drops (tracked as a WATCH item in\n * IMPLEMENTATION.md). When extending it: (1) never add a property that\n * accepts `url()`/`image()`/`element()` values or that affects layout,\n * positioning, or stacking; (2) add both hostile and benign cases to\n * html-sanitizer.test.ts; (3) mirror the change in the WordPress PHP port.\n */\nexport const SAFE_STYLE_PROPS = new Set([\n 'color', 'background-color', 'font-family', 'font-size', 'font-style',\n 'font-weight', 'letter-spacing', 'line-height', 'text-decoration',\n 'text-decoration-color', 'text-decoration-line', 'text-decoration-style',\n 'text-transform', 'vertical-align', 'white-space', 'word-spacing',\n]);\n\n/**\n * Value-level rejections inside an otherwise-allowed declaration: URL/code\n * carriers, and backslashes because CSS escape sequences (`\\75\\72\\6c`)\n * can spell `url(` past a textual check.\n */\nconst DANGEROUS_CSS_VALUE =\n /url\\s*\\(|expression\\s*\\(|image-set\\s*\\(|element\\s*\\(|paint\\s*\\(|javascript:|\\\\|[<>{}@]/i;\n\nconst SAFE_SCHEMES = new Set(['http', 'https', 'mailto', 'tel']);\n\n/**\n * The named entities that matter for scheme smuggling (`&colon;`, `&Tab;`)\n * plus the basic set. Names are case-sensitive, as in HTML.\n */\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\", nbsp: '\u00A0',\n colon: ':', semi: ';', sol: '/', bsol: '\\\\',\n Tab: '\\t', NewLine: '\\n',\n};\n\n/**\n * Decode entities exactly once \u2014 mirroring the single decode a browser does\n * when parsing an attribute value out of HTML.\n */\nfunction decodeEntities(value: string): string {\n return value.replace(\n /&(?:#[xX]([0-9a-fA-F]+);?|#(\\d+);?|([a-zA-Z]+);)/g,\n (full, hex: string, dec: string, name: string) => {\n if (hex) return String.fromCodePoint(parseInt(hex, 16));\n if (dec) return String.fromCodePoint(parseInt(dec, 10));\n return NAMED_ENTITIES[name] ?? full;\n },\n );\n}\n\n/** HTML-escape text for safe use in element content or attribute values. */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/**\n * Validate a URL attribute value. Returns the value unchanged when safe,\n * or `null` when it must be dropped.\n *\n * Entity-decodes first, then strips the control/whitespace characters\n * browsers ignore inside a scheme (`jav\\tascript:`), then requires any\n * explicit scheme to be on the allowlist. Scheme-less (relative) URLs pass.\n */\nexport function sanitizeUrl(value: string): string | null {\n const decoded = decodeEntities(value);\n // eslint-disable-next-line no-control-regex -- stripping C0 controls/space/DEL is the point\n const probe = decoded.replace(/[\\u0000-\\u0020\\u007f]/g, '').toLowerCase();\n const scheme = /^([a-z][a-z0-9+.-]*):/.exec(probe);\n if (!scheme) return value;\n return SAFE_SCHEMES.has(scheme[1]) ? value : null;\n}\n\n/**\n * Sanitize an inline `style` attribute value by re-parsing its declarations\n * and keeping only `SAFE_STYLE_PROPS` with clean values (see the risk note\n * on `SAFE_STYLE_PROPS`). Returns the rebuilt declaration list in canonical\n * `prop: value; prop: value` form, or `null` when nothing survives \u2014 the\n * caller then drops the attribute entirely.\n */\nexport function sanitizeStyle(value: string): string | null {\n return filterCssDeclarations(value, true);\n}\n\n/**\n * Relaxed CSS profile for the snapshot viewer: keeps ANY standard property\n * (a snapshot is a full captured page \u2014 `position:fixed` navbars and layout\n * styles are legitimate and must render) but still rejects value-level\n * dangers: `url(...)` beacons, `expression()`, CSS escape smuggling. The\n * residual risk (page-authored overlay styles) is accepted for snapshots:\n * the PM is deliberately viewing arbitrary captured pages, and the editor\n * UI itself lives in a Shadow DOM host stacked above the snapshot root.\n */\nexport function sanitizeCssDeclarations(value: string): string | null {\n return filterCssDeclarations(value, false);\n}\n\nfunction filterCssDeclarations(\n value: string,\n requirePropAllowlist: boolean,\n): string | null {\n const decoded = decodeEntities(value);\n const kept: string[] = [];\n for (const declaration of decoded.split(';')) {\n const colon = declaration.indexOf(':');\n if (colon === -1) continue;\n const prop = declaration.slice(0, colon).trim().toLowerCase();\n const val = declaration.slice(colon + 1).trim();\n if (!/^[a-z-]+$/.test(prop)) continue; // also blocks --custom-prop indirection\n if (requirePropAllowlist && !SAFE_STYLE_PROPS.has(prop)) continue;\n if (val === '' || DANGEROUS_CSS_VALUE.test(val)) continue;\n kept.push(`${prop}: ${val}`);\n }\n return kept.length > 0 ? kept.join('; ') : null;\n}\n\n/**\n * Attribute scanner for a (possibly hostile, non-canonical) opening tag.\n * Handles double-quoted, single-quoted, unquoted, and bare boolean attrs.\n */\nconst ATTR_PATTERN =\n /([^\\s=/>\"']+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]*)))?/g;\n\n/**\n * Sanitize a raw opening tag (`raw:` style payload). Returns the canonical\n * rebuilt tag with only allowlisted attributes, or `null` when the element\n * itself is not allowed \u2014 callers must then drop the tag entirely (emit the\n * indexed marker verbatim / skip the element).\n */\nexport function sanitizeOpeningTag(rawOpen: string): string | null {\n if (!rawOpen.startsWith('<')) return null;\n const tagName = extractTagName(rawOpen);\n if (!/^[a-z][a-z0-9-]*$/.test(tagName) || !SAFE_TAGS.has(tagName)) {\n return null;\n }\n\n // The slice between `<tagname` and the closing `>` (or end of string \u2014\n // hostile input may be truncated).\n const end = rawOpen.endsWith('/>')\n ? rawOpen.length - 2\n : rawOpen.endsWith('>')\n ? rawOpen.length - 1\n : rawOpen.length;\n const attrSource = rawOpen.slice(1 + tagName.length, end);\n\n const attrs: Record<string, string> = {};\n for (const match of attrSource.matchAll(ATTR_PATTERN)) {\n const name = match[1].toLowerCase();\n const value = match[2] ?? match[3] ?? match[4] ?? '';\n if (name in attrs) continue; // first occurrence wins, as in HTML\n if (name === 'style') {\n // Never verbatim \u2014 re-parsed against the CSS property allowlist.\n const cleanStyle = sanitizeStyle(value);\n if (cleanStyle !== null) attrs[name] = cleanStyle;\n continue;\n }\n const allowed =\n SAFE_ATTRS.has(name) ||\n /^data-[a-z0-9-]*$/.test(name) ||\n /^aria-[a-z0-9-]*$/.test(name);\n if (!allowed) continue;\n if (URL_ATTRS.has(name)) {\n if (sanitizeUrl(value) === null) continue;\n }\n attrs[name] = value;\n }\n\n return serializeOpeningTag(tagName, attrs);\n}\n\n/**\n * Sanitize a ContentUnit at an ingest boundary: run every `raw:` style\n * through {@link sanitizeOpeningTag} so no dangerous element/attribute/scheme\n * enters the translation store. Render-time sinks (HTMLSerializer etc.)\n * sanitize again \u2014 this is the store-side half, protecting every other\n * consumer of stored units (server, MT/TM, exports, the WP PHP port).\n *\n * `text` is never modified, so `generateAutoKey(unit.text)` is unaffected \u2014\n * key parity across surfaces holds even for hostile input. A rejected\n * element's `raw:` style is dropped entirely; the indexed tag left in the\n * text is emitted by serializers as an inert marker. Returns the SAME object\n * when nothing changed, so benign units round-trip identically.\n */\nexport function sanitizeContentUnit(unit: ContentUnit): ContentUnit {\n let changed = false;\n const styles: Record<string, string[]> = {};\n\n for (const [index, styleList] of Object.entries(unit.styles)) {\n const raw = readRawStyle(styleList);\n if (raw === null) {\n styles[index] = styleList; // no raw tag \u2192 nothing to sanitize\n continue;\n }\n const safe = sanitizeOpeningTag(raw);\n if (safe === null) {\n // Element rejected \u2014 drop the raw style (keep any non-raw entries).\n changed = true;\n const rest = styleList.filter((s) => !s.startsWith('raw:'));\n if (rest.length > 0) styles[index] = rest;\n } else if (safe === raw) {\n styles[index] = styleList;\n } else {\n changed = true;\n styles[index] = styleList.map((s) => (s.startsWith('raw:') ? `raw:${safe}` : s));\n }\n }\n\n return changed ? { text: unit.text, styles } : unit;\n}\n", "/**\n * HTML serializer \u2014 converts ContentUnit back to HTML strings (raw-only).\n *\n * Every indexed tag carries a `raw:<opening tag>` style. The serializer\n * routes the stored opening tag through the shared allowlist sanitizer and\n * derives the close tag from the embedded tag name. Void elements get no\n * close tag. Text segments are HTML-escaped (ContentUnit.text holds decoded\n * Unicode \u2014 see MarkupParser.decodeEntities), so serializer output is inert\n * even when the translation value is attacker-controlled. `ContentUnit.text`\n * itself is never modified \u2014 auto_key hashing is unaffected.\n *\n * @module content/serializer/HTMLSerializer\n */\n\nimport type { ISerializer } from './ISerializer.js';\nimport type { ContentUnit } from '../types.js';\nimport { extractTagName, readRawStyle, VOID_TAGS } from '../canonical-tag.js';\nimport { escapeHtml, sanitizeOpeningTag } from '../sanitizer/HTMLSanitizer.js';\n\n/**\n * Serializer that converts ContentUnit format back to HTML strings.\n *\n * @example\n * ```typescript\n * const serializer = new HTMLSerializer();\n * serializer.serialize({\n * text: 'Read our <1>Terms</1>.',\n * styles: { '1': ['raw:<b>'] }\n * });\n * // \u2192 'Read our <b>Terms</b>.'\n * ```\n */\nexport class HTMLSerializer implements ISerializer<string> {\n serialize(unit: ContentUnit): string {\n const { text, styles } = unit;\n const tagPattern = /<(\\/?)?(\\d+)(\\/)?>/g;\n\n let result = '';\n let lastIndex = 0;\n let match;\n\n while ((match = tagPattern.exec(text)) !== null) {\n result += escapeHtml(text.slice(lastIndex, match.index));\n\n const [fullMatch, closingSlash, indexStr] = match;\n const styleList = styles[indexStr] ?? [];\n const rawOpen = readRawStyle(styleList);\n const safeOpen = rawOpen === null ? null : sanitizeOpeningTag(rawOpen);\n\n if (rawOpen && safeOpen !== null) {\n const tagName = extractTagName(rawOpen);\n const isVoid = VOID_TAGS.has(tagName);\n\n if (closingSlash) {\n if (!isVoid) result += `</${tagName}>`;\n } else {\n // Both <N> and <N/> emit the opening tag. For void tags that's the\n // complete element.\n result += safeOpen;\n }\n } else {\n // No raw style, or the sanitizer rejected the element \u2014 preserve the\n // indexed marker (parses as inert text) so the problem is visible\n // rather than silently dropping content, and never emit a close tag\n // for a rejected element.\n result += fullMatch;\n }\n\n lastIndex = match.index + fullMatch.length;\n }\n\n result += escapeHtml(text.slice(lastIndex));\n return result;\n }\n}\n", "/**\n * CacheManager - TanStack Query-inspired cache management\n *\n * Provides unified cache invalidation and optimistic update patterns.\n */\n\nimport type { EventEmitter } from '../base/event-emitter.js';\nimport type { HandlerChain } from '../handlers/handler-chain.js';\n\n/**\n * Options for cache invalidation (like TanStack's invalidateQueries)\n */\nexport interface InvalidateOptions {\n /** Invalidate by namespace */\n namespace?: string;\n /** Invalidate by locale */\n locale?: string;\n /** Invalidate specific key */\n key?: string;\n /** Custom predicate filter */\n predicate?: (key: string) => boolean;\n /** Whether to refetch after invalidation (default: true) */\n refetch?: boolean;\n}\n\n/**\n * Cached translation entry\n */\nexport interface CacheEntry {\n value: string;\n styles?: Record<string, string[]>;\n}\n\n/**\n * Cache event payloads\n */\nexport interface CacheEventPayloads {\n 'cache:invalidate': {\n filter: InvalidateOptions;\n keysCleared: number;\n refetch: boolean;\n };\n 'cache:set': {\n key: string;\n value: string;\n styles?: Record<string, string[]>;\n optimistic: boolean;\n };\n 'cache:rollback': {\n key: string;\n reason: string;\n };\n}\n\n/**\n * CacheManager - Unified cache API inspired by TanStack Query\n *\n * @example\n * ```typescript\n * // Invalidate by namespace\n * await i18n.cache.invalidate({ namespace: 'app' });\n *\n * // Optimistic update\n * const previous = i18n.cache.get('en:app:welcome');\n * i18n.cache.set('en:app:welcome', 'New value');\n * // ... if error, rollback:\n * i18n.cache.set('en:app:welcome', previous.value);\n * ```\n */\nexport class CacheManager {\n private handlerChain: HandlerChain;\n private bus: EventEmitter;\n private currentLocale: () => string;\n private loadNamespaces: (locale: string, namespaces: string[]) => Promise<void>;\n\n constructor(\n handlerChain: HandlerChain,\n bus: EventEmitter,\n getCurrentLocale: () => string,\n loadNamespaces: (locale: string, namespaces: string[]) => Promise<void>\n ) {\n this.handlerChain = handlerChain;\n this.bus = bus;\n this.currentLocale = getCurrentLocale;\n this.loadNamespaces = loadNamespaces;\n }\n\n /**\n * Get a cached translation entry\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @returns Cache entry with value and styles, or null if not found\n */\n get(key: string): CacheEntry | null {\n const entries = this.handlerChain.getEntries();\n\n // Search through all handler entries\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n if (key in handlerEntries) {\n const rawValue = handlerEntries[key];\n\n // Parse ContentUnit JSON (stored as { text, styles })\n try {\n if (typeof rawValue === 'string') {\n const parsed = JSON.parse(rawValue);\n if (typeof parsed === 'object' && 'text' in parsed) {\n return {\n value: String(parsed.text),\n styles: parsed.styles || undefined,\n };\n }\n // Legacy plain string\n return { value: rawValue, styles: undefined };\n }\n // Already an object\n return {\n value: JSON.stringify(rawValue),\n styles: undefined,\n };\n } catch {\n // If parse fails, treat as plain string\n return {\n value: typeof rawValue === 'string' ? rawValue : JSON.stringify(rawValue),\n styles: undefined,\n };\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Set a cache entry (for optimistic updates)\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @param value - Translation value\n * @param styles - Optional styles for indexed tags\n */\n set(key: string, value: string, styles?: Record<string, string[]>): void {\n // Parse the key to get locale, namespace, and translation key\n const [locale, namespace, ...keyParts] = key.split(':');\n const translationKey = keyParts.join(':');\n\n if (!locale || !namespace || !translationKey) {\n throw new Error(\n `Invalid cache key format: \"${key}\". Expected format: \"locale:namespace:key\"`\n );\n }\n\n // Use the handler chain's setCache method for optimistic updates\n this.handlerChain.setCache(key, value, styles);\n\n // Emit cache:set event\n this.bus.emit('cache:set', {\n payload: {\n key,\n value,\n styles,\n optimistic: true,\n },\n });\n }\n\n /**\n * Check if a key exists in cache\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @returns true if key is cached\n */\n has(key: string): boolean {\n return this.get(key) !== null;\n }\n\n /**\n * Invalidate cache entries and optionally refetch\n *\n * Like TanStack Query's invalidateQueries, this clears matching cache entries\n * and triggers background refetch by default.\n *\n * @param options - Filter options for invalidation\n *\n * @example\n * ```typescript\n * // Invalidate all\n * await cache.invalidate();\n *\n * // Invalidate by namespace\n * await cache.invalidate({ namespace: 'app' });\n *\n * // Invalidate by locale\n * await cache.invalidate({ locale: 'es' });\n *\n * // Invalidate specific key\n * await cache.invalidate({ key: 'en:app:welcome' });\n *\n * // Invalidate with predicate\n * await cache.invalidate({ predicate: (k) => k.includes('common:') });\n *\n * // Invalidate without refetch\n * await cache.invalidate({ namespace: 'app', refetch: false });\n * ```\n */\n async invalidate(options: InvalidateOptions = {}): Promise<void> {\n const { namespace, locale, key, predicate, refetch = true } = options;\n const currentLocale = this.currentLocale();\n\n let keysCleared = 0;\n\n // Determine what to clear\n if (key) {\n // Clear specific key\n const [keyLocale, keyNamespace] = key.split(':');\n if (keyLocale && keyNamespace) {\n this.handlerChain.clearNamespace(keyLocale, keyNamespace);\n keysCleared = 1;\n }\n } else if (namespace && locale) {\n // Clear specific locale + namespace\n this.handlerChain.clearNamespace(locale, namespace);\n keysCleared = this.countClearedKeys(locale, namespace);\n } else if (namespace) {\n // Clear namespace for current locale\n this.handlerChain.clearNamespace(currentLocale, namespace);\n keysCleared = this.countClearedKeys(currentLocale, namespace);\n } else if (locale) {\n // Clear all namespaces for a specific locale\n const entries = this.handlerChain.getEntries();\n const namespacesToClear = new Set<string>();\n\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n for (const entryKey of Object.keys(handlerEntries)) {\n if (entryKey.startsWith(`${locale}:`) || entryKey.startsWith(`@${locale}:`)) {\n const parts = entryKey.replace('@', '').split(':');\n if (parts[1]) {\n namespacesToClear.add(parts[1]);\n }\n }\n }\n }\n }\n\n for (const ns of namespacesToClear) {\n this.handlerChain.clearNamespace(locale, ns);\n keysCleared++;\n }\n } else if (predicate) {\n // Clear with custom predicate\n const entries = this.handlerChain.getEntries();\n const toClear = new Map<string, Set<string>>(); // locale -> namespaces\n\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n for (const entryKey of Object.keys(handlerEntries)) {\n if (predicate(entryKey)) {\n const parts = entryKey.replace('@', '').split(':');\n const entryLocale = parts[0];\n const entryNs = parts[1];\n if (entryLocale && entryNs) {\n if (!toClear.has(entryLocale)) {\n toClear.set(entryLocale, new Set());\n }\n toClear.get(entryLocale)!.add(entryNs);\n keysCleared++;\n }\n }\n }\n }\n }\n\n for (const [loc, namespaces] of toClear) {\n for (const ns of namespaces) {\n this.handlerChain.clearNamespace(loc, ns);\n }\n }\n } else {\n // Clear all\n this.handlerChain.clearCache();\n keysCleared = -1; // Indicates all cleared\n }\n\n // Emit invalidate event\n this.bus.emit('cache:invalidate', {\n payload: {\n filter: options,\n keysCleared,\n refetch,\n },\n });\n\n // Refetch if requested\n if (refetch) {\n await this.refetchAfterInvalidate(options);\n }\n }\n\n /**\n * Count keys that would be cleared (for event reporting)\n */\n private countClearedKeys(locale: string, namespace: string): number {\n const entries = this.handlerChain.getEntries();\n let count = 0;\n const prefix = `${locale}:${namespace}:`;\n const namespaceKey = `@${locale}:${namespace}`;\n\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n for (const key of Object.keys(handlerEntries)) {\n if (key.startsWith(prefix) || key === namespaceKey) {\n count++;\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Refetch data after invalidation\n */\n private async refetchAfterInvalidate(options: InvalidateOptions): Promise<void> {\n const { namespace, locale, key } = options;\n const currentLocale = this.currentLocale();\n\n if (key) {\n // Refetch specific namespace from key\n const [keyLocale, keyNamespace] = key.split(':');\n if (keyLocale && keyNamespace) {\n await this.loadNamespaces(keyLocale, [keyNamespace]);\n }\n } else if (namespace) {\n // Refetch namespace for specific or current locale\n await this.loadNamespaces(locale || currentLocale, [namespace]);\n } else if (locale) {\n // For locale-wide invalidation, we can't easily know which namespaces to reload\n // The app will lazy-load them as needed\n }\n // For full cache clear, lazy loading will handle refetch\n }\n}\n", "/**\n * Enhanced LionRapid Core with event-based language change and smart caching\n * filepath: /home/janrau/tm-integration/packages/core/src/lionRapid.ts\n */\nimport { EventEmitter } from './base/event-emitter.js';\nimport { HandlerChain } from './handlers/handler-chain.js';\nimport type {\n FormatterFunction,\n IEmbeddedPlugin,\n IPlugin,\n ValueProcessor,\n} from './interfaces/plugin.interface.js';\nimport type { TranslationKeys } from './types/generated.types.js';\nimport type { TranslationRequest } from './types/translation.types.js';\nimport { logger, resolveNestedKey } from './utils/index.js';\nimport { prepareTranslationRequest } from './utils/translation-flow.js';\nimport { createNamespaceCacheKey } from './utils/translation-value-utils.js';\n\n// Content module imports for ContentUnit processing\nimport type { ContentUnit } from './content/types.js';\nimport { MarkupParser } from './content/parser/MarkupParser.js';\nimport { HTMLSerializer } from './content/serializer/HTMLSerializer.js';\n\n// Cache module\nimport { CacheManager } from './cache/CacheManager.js';\n\n/**\n * Regex to detect indexed tags in a string (from server ContentUnit)\n * Matches patterns like <1>, </1>, <2>, </2>, etc.\n */\nconst INDEXED_TAG_REGEX = /<\\/?[0-9]+\\/?>/;\n\n/**\n * Regex to detect HTML tags in a string\n * Matches patterns like <b>, <a href=\"...\">, <em>, etc.\n */\nconst HTML_TAG_REGEX = /<[a-z][a-z0-9]*(?:\\s+[^>]*)?\\/?>/i;\n\nexport class LionRapidCore {\n private handlerChain: HandlerChain;\n private currentLocale: string;\n private defaultNamespace?: string;\n private pendingTranslations = new Map<string, Promise<void>>();\n bus: EventEmitter;\n\n private plugins = new Map<string, IPlugin>();\n\n // \uD83D\uDD25 EMBEDDED: Core integration maps\n private formatters = new Map<string, FormatterFunction>();\n private processors = new Map<string, ValueProcessor>();\n private warnedNoInterpolate = false;\n\n // \uD83D\uDCE1 EVENT-DRIVEN: Just track for cleanup\n private eventPlugins = new Set<IPlugin>();\n\n // \uD83D\uDCE6 CONTENT: Parser and serializer for ContentUnit processing\n private readonly markupParser = new MarkupParser();\n private readonly htmlSerializer = new HTMLSerializer();\n\n // \uD83D\uDD04 CACHE: TanStack Query-inspired cache management\n public readonly cache: CacheManager;\n\n constructor(\n eventEmitter: EventEmitter,\n handlerChain: HandlerChain,\n defaultLocale = 'en',\n defaultNamespace?: string\n ) {\n this.bus = eventEmitter;\n this.handlerChain = handlerChain;\n this.currentLocale = defaultLocale;\n this.defaultNamespace = defaultNamespace;\n\n // Initialize cache manager with dependencies\n this.cache = new CacheManager(\n this.handlerChain,\n this.bus,\n () => this.currentLocale,\n (locale, namespaces) => this.loadNamespaces(locale, namespaces)\n );\n }\n\n /**\n * \u2705 Register plugin (called by builder)\n */\n registerPlugin(plugin: IPlugin): void {\n this.plugins.set(plugin.name, plugin);\n\n // \uD83D\uDD25 EMBEDDED PLUGINS: Extract functionality for core integration\n if (this.isEmbeddedPlugin(plugin)) {\n this.integrateEmbeddedPlugin(plugin as IEmbeddedPlugin);\n }\n\n // \uD83D\uDCE1 EVENT-DRIVEN PLUGINS: Just track for cleanup\n if (this.isEventPlugin(plugin)) {\n this.eventPlugins.add(plugin);\n }\n }\n\n /**\n * \uD83D\uDD25 EMBEDDED: Integrate plugin functionality into core\n */\n private integrateEmbeddedPlugin(plugin: IEmbeddedPlugin): void {\n // Extract formatters\n if (plugin.getFormatters) {\n const pluginFormatters = plugin.getFormatters();\n Object.entries(pluginFormatters).forEach(([name, formatter]) => {\n this.formatters.set(name, formatter);\n logger.debug(`Embedded formatter: ${name} from ${plugin.name}`);\n });\n }\n\n // Extract processors\n if (plugin.getProcessors) {\n const pluginProcessors = plugin.getProcessors();\n Object.entries(pluginProcessors).forEach(([name, processor]) => {\n this.processors.set(name, processor);\n logger.debug(`Embedded processor: ${name} from ${plugin.name}`);\n });\n }\n }\n\n /**\n * \uD83D\uDCE6 TRANSLATION API - Returns PLAIN TEXT\n *\n * Strips indexed tags and returns safe plain text output.\n * For HTML output with styles, use tHtml() instead.\n *\n * @param key - Translation key\n * @param params - Optional interpolation parameters\n * @param defaultValue - Optional default value\n * @returns Plain text string (safe, no XSS risk)\n *\n * @example\n * ```typescript\n * t('welcome') // \u2192 \"Hello World\"\n * t('greeting', { name: 'John' }) // \u2192 \"Hello John\"\n * t('missing', 'Default text') // \u2192 \"Default text\" (if key missing)\n * ```\n */\n t<K extends string>(\n key: K,\n ...args: K extends keyof TranslationKeys\n ? TranslationKeys[K] extends Record<string, never>\n ? [defaultValue?: string]\n : [params: TranslationKeys[K], defaultValue?: string]\n : [params?: Record<string, unknown>, defaultValue?: string]\n ): string {\n const [firstArg, secondArg] = args;\n\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n firstArg as string | Record<string, unknown> | undefined,\n secondArg as Record<string, unknown> | string | undefined,\n this.defaultNamespace\n );\n\n // Emit request event\n logger.debug(`Translation requested: ${request.cleanKey}`);\n const translateBus = this.bus.translation(request);\n translateBus.request();\n\n // Try memory cache (sync)\n const syncResult = this.handlerChain.handleSync(request);\n if (syncResult && syncResult.status === 200) {\n const result = this.processValue(syncResult.value, request);\n logger.debug(\n `Translation found: ${request.cleanKey} from ${syncResult.source} (${syncResult.duration}ms)`\n );\n translateBus.success(result);\n return result;\n }\n\n // Cache miss - trigger background load\n this.triggerBackgroundLoad(request);\n\n // Return fallback immediately\n const fallbackValue = request.parsedDefaultValue || request.cleanKey;\n const fallbackResult = this.processValue(fallbackValue, request);\n logger.debug(`Translation fallback: ${request.cleanKey}`);\n translateBus.fallback(fallbackResult);\n return fallbackResult;\n }\n\n /**\n * \uD83D\uDCE6 HTML TRANSLATION API\n * Returns translation as HTML string with styles applied.\n *\n * Use for innerHTML, dangerouslySetInnerHTML, or server-side rendering.\n * For React components, prefer using <Trans> instead.\n *\n * @param key - Translation key\n * @param params - Optional interpolation parameters\n * @param defaultValue - Optional default value (can contain HTML)\n * @returns HTML string with styles applied\n *\n * @example\n * ```typescript\n * // Vanilla JS\n * element.innerHTML = i18n.tHtml('welcome');\n * // \u2192 \"Hello <b>World</b>\"\n *\n * // React (use sparingly)\n * <span dangerouslySetInnerHTML={{ __html: tHtml('welcome') }} />\n * ```\n */\n tHtml<K extends string>(\n key: K,\n ...args: K extends keyof TranslationKeys\n ? TranslationKeys[K] extends Record<string, never>\n ? [defaultValue?: string]\n : [params: TranslationKeys[K], defaultValue?: string]\n : [params?: Record<string, unknown>, defaultValue?: string]\n ): string {\n // Pass arguments directly to prepareTranslationRequest\n // which handles the flexible parameter parsing\n const [firstArg, secondArg] = args;\n\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n firstArg as string | Record<string, unknown> | undefined,\n secondArg as Record<string, unknown> | string | undefined,\n this.defaultNamespace\n );\n\n // Emit request event\n logger.debug(`HTML translation requested: ${request.cleanKey}`);\n const translateBus = this.bus.translation(request);\n translateBus.request();\n\n // Try memory cache (sync) - result now includes styles\n const syncResult = this.handlerChain.handleSync(request);\n if (syncResult && syncResult.status === 200) {\n const result = this.processValueAsHtml(syncResult.value, request, syncResult.styles);\n logger.debug(\n `HTML translation found: ${request.cleanKey} from ${syncResult.source}`\n );\n translateBus.success(result);\n return result;\n }\n\n // Cache miss - trigger background load\n this.triggerBackgroundLoad(request);\n\n // Return fallback immediately (processed as HTML, no styles)\n const fallbackValue = request.parsedDefaultValue || request.cleanKey;\n const fallbackResult = this.processValueAsHtml(fallbackValue, request);\n logger.debug(`HTML translation fallback: ${request.cleanKey}`);\n translateBus.fallback(fallbackResult);\n return fallbackResult;\n }\n\n /**\n * \uD83D\uDCE6 Process value as HTML (for tHtml)\n *\n * Converts indexed tags to HTML using styles from result or namespace cache.\n *\n * @internal\n */\n private processValueAsHtml(\n value: string,\n request: TranslationRequest,\n resultStyles?: Record<string, string[]>\n ): string {\n // Process ICU first\n const processedText = this.processTranslationValue(value, request);\n\n // Check for indexed tags (from server ContentUnit)\n if (this.containsIndexedTags(processedText)) {\n // Use styles from result, or fall back to namespace lookup\n const styles = resultStyles || this.getStylesFromNamespace(request);\n const unit: ContentUnit = {\n text: processedText,\n styles,\n };\n return this.htmlSerializer.serialize(unit);\n }\n\n // Check for HTML in defaultValue\n if (this.containsHtml(processedText)) {\n const unit = this.markupParser.parse(processedText);\n return this.htmlSerializer.serialize(unit);\n }\n\n // Plain text - return as-is\n return processedText;\n }\n\n /**\n * \uD83D\uDCE6 Process a value through ContentUnit or ICU pipeline\n *\n * Processing priority:\n * 1. Indexed tags (<1>...</1>) from server ContentUnit \u2192 convert to HTML at render time\n * 2. HTML tags (from defaultValue or legacy) \u2192 MarkupParser \u2192 ContentUnit \u2192 HTML\n * 3. Plain text \u2192 standard ICU processing\n *\n * @internal\n */\n private processValue(value: string, request: TranslationRequest): string {\n // Priority 1: Check for indexed tags (from server ContentUnit)\n // These need to be converted to HTML using the stored styles\n if (this.containsIndexedTags(value)) {\n return this.processIndexedValue(value, request);\n }\n\n // Priority 2: Auto-detect HTML and process through ContentUnit if found\n if (this.containsHtml(value)) {\n return this.processHtmlValue(value, request);\n }\n\n // Priority 3: Standard ICU processing for plain text\n return this.processTranslationValue(value, request);\n }\n\n /**\n * \uD83D\uDCE6 Check if a string contains indexed tags\n *\n * Used for auto-detection of server ContentUnit format.\n *\n * @param value - String to check\n * @returns true if indexed tags are detected\n */\n private containsIndexedTags(value: string): boolean {\n return INDEXED_TAG_REGEX.test(value);\n }\n\n /**\n * \uD83D\uDCE6 Process indexed value - returns PLAIN TEXT\n *\n * Strips indexed tags (<1>text</1>) \u2192 \"text\"\n * For HTML output, use tHtml() instead.\n *\n * @internal\n */\n private processIndexedValue(\n value: string,\n request: TranslationRequest\n ): string {\n // 1. Process ICU first (with indexed tags intact)\n const processedText = this.processTranslationValue(value, request);\n\n // 2. Strip indexed tags - t() returns plain text\n return processedText.replace(/<\\/?[0-9]+\\/?>/g, '');\n }\n\n /**\n * \uD83D\uDCE6 Get styles for a translation key from namespace cache (fallback)\n *\n * Used when styles are not available in the result (e.g., for fallback values).\n * Looks up the full ContentUnit from the namespace cache to get styles.\n *\n * @internal\n */\n private getStylesFromNamespace(\n request: TranslationRequest\n ): Record<string, string[]> {\n if (!request.namespace) {\n return {};\n }\n\n try {\n // Get namespace cache key: @locale:namespace\n const namespaceCacheKey = createNamespaceCacheKey(\n request.locale,\n request.namespace\n );\n\n // Get namespace data from handler chain\n const namespaceData = this.handlerChain.getNamespaceData(namespaceCacheKey);\n if (!namespaceData) {\n return {};\n }\n\n // Resolve the content unit for this key (server always returns ContentUnit format)\n const resolved = resolveNestedKey(namespaceData, request.cleanKey);\n\n if (resolved && typeof resolved === 'object' && 'styles' in resolved) {\n const contentUnit = resolved as ContentUnit;\n return contentUnit.styles;\n }\n\n return {};\n } catch (error) {\n logger.debug(`Error getting styles for key ${request.cleanKey}:`, error);\n return {};\n }\n }\n\n /**\n * \uD83D\uDCE6 Process HTML value - returns PLAIN TEXT\n *\n * Parses HTML to ContentUnit, processes ICU, strips indexed tags.\n * For HTML output, use tHtml() instead.\n *\n * @internal\n */\n private processHtmlValue(value: string, request: TranslationRequest): string {\n try {\n // 1. Parse HTML to ContentUnit (converts HTML tags to indexed format)\n const unit = this.markupParser.parse(value);\n\n // 2. Process ICU expressions in the text\n const processedText = this.processTranslationValue(unit.text, request);\n\n // 3. Strip indexed tags - t() returns plain text\n return processedText.replace(/<\\/?[0-9]+\\/?>/g, '');\n } catch (error) {\n logger.warn(`ContentUnit processing failed for \"${value}\":`, error);\n // Fallback to standard processing\n return this.processTranslationValue(value, request);\n }\n }\n\n /**\n * \u2705 Process translation value through embedded plugins\n *\n * Public overload for Trans component usage (simple API)\n */\n public processTranslationValue(\n value: string,\n params?: Record<string, unknown>,\n locale?: string,\n key?: string\n ): string;\n\n /**\n * Internal overload (with full TranslationRequest for t() method)\n */\n public processTranslationValue(\n value: string,\n request: TranslationRequest\n ): string;\n\n /**\n * Implementation (handles both overloads)\n */\n public processTranslationValue(\n value: string,\n paramsOrRequest?: Record<string, unknown> | TranslationRequest,\n locale?: string,\n key?: string\n ): string {\n // Determine which overload was called\n let params: Record<string, unknown> | undefined;\n let resolvedLocale: string;\n let resolvedKey: string | undefined;\n\n if (paramsOrRequest && 'cleanKey' in paramsOrRequest) {\n // Internal overload: TranslationRequest\n const request = paramsOrRequest as TranslationRequest;\n params = request.parsedParams;\n resolvedLocale = request.locale;\n resolvedKey = request.cleanKey;\n } else {\n // Public overload: simple parameters\n params = paramsOrRequest as Record<string, unknown> | undefined;\n resolvedLocale = locale || this.currentLocale;\n resolvedKey = key;\n }\n\n let processedValue = value;\n\n try {\n // \u2705 Step 1: Handle structured translation data (plurals, context variations)\n processedValue = this.applyStructuralFormatters(\n processedValue,\n params,\n resolvedKey\n );\n\n // \u2705 Step 2: Apply interpolation through embedded formatter plugin\n // ICU messages need processing even without params (for 'other' defaults)\n if (this.formatters.has('interpolate')) {\n const interpolateFormatter = this.formatters.get('interpolate')!;\n processedValue = interpolateFormatter(\n processedValue,\n params,\n resolvedLocale,\n resolvedKey\n );\n } else if (\n !this.warnedNoInterpolate &&\n params &&\n Object.keys(params).length > 0 &&\n processedValue.includes('{')\n ) {\n // Params against a {placeholder} string with nothing to interpolate:\n // without this, the miswiring is invisible and the SDK looks broken.\n this.warnedNoInterpolate = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[LionRapid] Translation params were passed but no interpolate ' +\n 'formatter is registered \u2014 {placeholders} render literally. ' +\n 'Install @lionrapid/formatters and add .use(coreFormattersPlugin) ' +\n 'to the builder.'\n );\n }\n\n // \u2705 Step 3: Apply value processors (escaping, sanitization, etc.)\n if (this.processors.size > 0) {\n for (const [name, processor] of this.processors.entries()) {\n try {\n processedValue = processor(processedValue, params, resolvedKey);\n } catch (error) {\n logger.warn(`Processor ${name} failed:`, error);\n }\n }\n }\n\n return processedValue;\n } catch (error) {\n logger.warn(`Translation processing failed for \"${value}\":`, error);\n return value;\n }\n }\n\n /**\n * \uD83D\uDCE6 CONTENT UNIT API\n * Returns translation as ContentUnit for JSX rendering (Trans component)\n *\n * This is the preferred method for components that need to render\n * styled content with JSX interpolation.\n *\n * @param key - Translation key\n * @param params - Optional interpolation parameters\n * @param defaultValue - Optional default value (can contain HTML)\n * @returns ContentUnit with indexed tags and styles\n *\n * @example\n * ```typescript\n * const unit = i18n.getContentUnit('terms', {}, 'Read our <b>Terms</b>.');\n * // \u2192 { text: \"Read our <1>Terms</1>.\", styles: {\"1\": [\"raw:<b>\"]} }\n * ```\n */\n getContentUnit(\n key: string,\n params?: Record<string, unknown>,\n defaultValue?: string\n ): ContentUnit {\n // Get translation value (ICU processing done separately per segment)\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n params,\n defaultValue,\n this.defaultNamespace\n );\n\n // Try memory cache\n const syncResult = this.handlerChain.handleSync(request);\n const rawValue =\n syncResult && syncResult.status === 200\n ? syncResult.value\n : request.parsedDefaultValue || request.cleanKey;\n\n // If no translation found, trigger background load\n if (!syncResult || syncResult.status !== 200) {\n this.triggerBackgroundLoad(request);\n }\n\n // Parse HTML to ContentUnit\n return this.markupParser.parse(rawValue);\n }\n\n /**\n * \uD83D\uDCE6 Process ContentUnit text through ICU formatters\n *\n * Used by JSX serializers to process individual text segments.\n *\n * @param text - Text segment (may contain ICU expressions like {name})\n * @param params - Interpolation parameters\n * @returns Processed text with ICU expressions resolved\n */\n processContentText(text: string, params?: Record<string, unknown>): string {\n return this.processTranslationValue(text, params, this.currentLocale);\n }\n\n /**\n * \uD83D\uDCE6 Check if a string contains HTML tags\n *\n * Used for auto-detection of HTML in default values.\n *\n * @param value - String to check\n * @returns true if HTML tags are detected\n */\n containsHtml(value: string): boolean {\n return HTML_TAG_REGEX.test(value);\n }\n\n /**\n * \u2705 Handle structured formatters (plural, context) - embedded in core\n */\n private applyStructuralFormatters(\n value: string,\n params?: Record<string, unknown>,\n translationKey?: string\n ): string {\n const translationData: string = value;\n\n // Type guard for params having a count property\n const hasCount = (\n p: Record<string, unknown> | undefined\n ): p is { count: number } => typeof p?.count === 'number';\n\n // Type guard for params having a context property\n const hasContext = (\n p: Record<string, unknown> | undefined\n ): p is { context: string } => typeof p?.context === 'string';\n\n // Apply plural formatter if available and applicable\n if (this.formatters.has('plural') && hasCount(params)) {\n const pluralFormatter = this.formatters.get('plural')!;\n try {\n const pluralResult = pluralFormatter(\n translationData,\n params,\n this.currentLocale,\n translationKey\n );\n if (pluralResult !== String(translationData)) {\n return pluralResult;\n }\n } catch (error) {\n logger.warn('Plural formatting failed:', error);\n }\n }\n\n // Apply context formatter if available and applicable\n if (this.formatters.has('context') && hasContext(params)) {\n const contextFormatter = this.formatters.get('context')!;\n try {\n const contextResult = contextFormatter(\n translationData,\n params,\n this.currentLocale,\n translationKey\n );\n if (contextResult !== String(translationData)) {\n return contextResult;\n }\n } catch (error) {\n logger.warn('Context formatting failed:', error);\n }\n }\n\n return String(translationData);\n }\n\n /**\n * Trigger background load via handler chain\n */\n private triggerBackgroundLoad(request: TranslationRequest): void {\n logger.debug(`Background load: ${request.cleanKey}`);\n const cacheKey = request.individualCacheKey;\n\n if (!this.pendingTranslations.has(cacheKey)) {\n const promise = this.handlerChain\n .handleAsync(request)\n .then(result => {\n if (result && result.value) {\n logger.debug(`Cached: ${request.cleanKey} = \"${result.value}\"`);\n } else {\n logger.debug(`Not found: ${request.cleanKey}`);\n }\n })\n .catch(error => {\n logger.warn(`Background load failed: ${request.cleanKey}`, error);\n });\n\n this.pendingTranslations.set(cacheKey, promise);\n promise.finally(() => this.pendingTranslations.delete(cacheKey));\n }\n }\n\n /**\n * Get the current locale\n */\n getCurrentLocale(): string {\n return this.currentLocale;\n }\n\n /**\n * Set default namespace (useful for scoped translations)\n */\n setDefaultNamespace(namespace?: string): void {\n this.defaultNamespace = namespace;\n }\n\n /**\n * Get current default namespace\n */\n getDefaultNamespace(): string | undefined {\n return this.defaultNamespace;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getEntries(): Record<string, any> {\n return this.handlerChain.getEntries();\n }\n\n isCached(key: string): boolean {\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n undefined,\n undefined,\n this.defaultNamespace\n );\n\n return this.handlerChain.isCached(request);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getHandlerChainInfo(): any {\n return this.handlerChain.getChainInfo();\n }\n\n /**\n * \u2705 Smart language change with selective cache clearing\n */\n async changeLanguage(\n newLocale: string,\n options?: {\n clear?: boolean;\n preloadNamespaces?: string[];\n }\n ): Promise<void> {\n const oldLocale = this.currentLocale;\n\n if (oldLocale === newLocale) {\n logger.debug(`Language already set to ${newLocale}`);\n return;\n }\n\n const clear = options?.clear || false;\n const languageBus = this.bus.language(oldLocale, newLocale);\n\n try {\n logger.info(`Language change: ${oldLocale} \u2192 ${newLocale}`);\n logger.debug('Language change options', {\n clear,\n preloadNamespaces: options?.preloadNamespaces,\n });\n\n languageBus.start();\n\n this.currentLocale = newLocale;\n\n if (clear) {\n await this.clearCache();\n this.clearOldLocalePendingTranslations(oldLocale);\n }\n\n if (options?.preloadNamespaces?.length) {\n await this.loadNamespaces(newLocale, options.preloadNamespaces);\n }\n\n languageBus.complete();\n\n logger.info(`Language changed: ${newLocale}`);\n } catch (error) {\n logger.error('Language change failed:', error);\n languageBus.error(error as Error);\n throw error;\n }\n }\n\n private async clearCache(): Promise<void> {\n this.handlerChain.clearCache();\n logger.debug(`Cache cleared for locale: ${this.currentLocale}`);\n }\n\n private clearOldLocalePendingTranslations(oldLocale: string): void {\n let clearedCount = 0;\n\n for (const key of this.pendingTranslations.keys()) {\n if (key.includes(`${oldLocale}:`)) {\n this.pendingTranslations.delete(key);\n clearedCount++;\n }\n }\n\n if (clearedCount > 0) {\n logger.debug(\n `Cleared ${clearedCount} pending translations for ${oldLocale}`\n );\n }\n }\n\n private async loadNamespaces(\n locale: string,\n namespaces: string[]\n ): Promise<void> {\n logger.debug(`Preloading ${namespaces.length} namespaces for ${locale}`);\n\n const preloadPromises = namespaces.map(async namespace => {\n try {\n await this.handlerChain.loadNamespace?.(locale, namespace);\n logger.debug(`Preloaded: ${locale}:${namespace}`);\n } catch (error) {\n logger.warn(`Failed to preload ${locale}:${namespace}:`, error);\n }\n });\n\n await Promise.allSettled(preloadPromises);\n }\n\n /**\n * Reload a namespace by clearing cache and fetching fresh data from server\n * Useful after syncing new translations to ensure fresh data\n *\n * @param namespace - The namespace to reload\n * @param locale - Optional locale (defaults to current locale)\n * @deprecated Use cache.invalidate({ namespace, refetch: true }) instead\n */\n async reloadNamespace(namespace: string, locale?: string): Promise<void> {\n const targetLocale = locale || this.currentLocale;\n logger.debug(`Reloading namespace: ${targetLocale}:${namespace}`);\n\n // Delegate to cache manager\n await this.cache.invalidate({\n namespace,\n locale: targetLocale,\n refetch: true,\n });\n\n logger.info(`Namespace reloaded: ${targetLocale}:${namespace}`);\n }\n\n // Helper methods\n private isEmbeddedPlugin(plugin: IPlugin): boolean {\n return plugin.capabilities.some(cap =>\n ['formatters', 'processors', 'pluralization', 'context'].includes(cap)\n );\n }\n\n private isEventPlugin(plugin: IPlugin): boolean {\n return plugin.capabilities.some(cap =>\n [\n 'analytics',\n 'logging',\n 'react',\n 'validation',\n 'dev-tools',\n 'monitoring',\n ].includes(cap)\n );\n }\n}\n", "import { MemoryRepositoryConfig } from '../config/repository.config.js';\nimport type {\n IStatsProvider,\n ISyncRepository,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport { createNamespaceCacheKey } from '../utils/index.js';\n\nexport class MemoryRepository\n implements ISyncRepository<MemoryRepositoryConfig>, IStatsProvider\n{\n readonly name = 'MemoryRepository';\n readonly type = 'memory';\n readonly config: MemoryRepositoryConfig = {};\n private cache = new Map<string, string>();\n private accessOrder = new Map<string, number>();\n private maxSize: number = 1000;\n\n constructor(config: MemoryRepositoryConfig) {\n this.config = config;\n this.maxSize = this.config.options?.maxSize || 1000;\n }\n\n get(key: string): string | null {\n const value = this.cache.get(key);\n if (value !== undefined) {\n // Update access time for LRU\n this.accessOrder.set(key, Date.now());\n return value;\n }\n return null;\n }\n\n set(key: string, value: string): void {\n if (this.cache.size >= this.maxSize && !this.cache.has(key)) {\n this.evictOldest();\n }\n\n this.cache.set(key, value);\n this.accessOrder.set(key, Date.now());\n }\n\n remove(key: string): void {\n this.cache.delete(key);\n this.accessOrder.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n this.accessOrder.clear();\n }\n\n /**\n * Clear all entries for a specific namespace\n * Removes both the namespace cache entry and all individual translation keys\n */\n clearNamespace(locale: string, namespace: string): void {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n const keyPrefix = `${locale}:${namespace}:`;\n\n // Remove namespace cache entry\n this.cache.delete(namespaceCacheKey);\n this.accessOrder.delete(namespaceCacheKey);\n\n // Remove individual translation keys\n for (const key of this.cache.keys()) {\n if (key.startsWith(keyPrefix)) {\n this.cache.delete(key);\n this.accessOrder.delete(key);\n }\n }\n }\n\n getNamespace(locale: string, namespace: string): TranslationData | null {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n const namespaceData = this.cache.get(namespaceCacheKey);\n if (!namespaceData) return null;\n\n try {\n return JSON.parse(namespaceData);\n } catch (error) {\n this.cache.delete(namespaceCacheKey);\n return null;\n }\n }\n\n setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): void {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n this.cache.set(namespaceCacheKey, JSON.stringify(translations));\n }\n\n private evictOldest(): void {\n let oldestKey = '';\n let oldestTime = Date.now();\n\n for (const [key, time] of this.accessOrder.entries()) {\n if (time < oldestTime) {\n oldestTime = time;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.cache.delete(oldestKey);\n this.accessOrder.delete(oldestKey);\n }\n }\n /**\n * Get all cache entries for debugging\n */\n getEntries(): Record<string, string> {\n const entries: Record<string, string> = {};\n for (const [key, value] of this.cache.entries()) {\n entries[key] = value;\n }\n return entries;\n }\n\n getConfig(): MemoryRepositoryConfig {\n return this.config;\n }\n}\n", "import { MemoryRepositoryConfig } from '../config/repository.config.js';\nimport type {\n IStatsProvider,\n ISyncRepository,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport { flattenTranslations } from '../utils/index.js';\nimport { MemoryRepository } from './memory-repository.js';\n\n/**\n * A bundle of translations to seed offline-first: locale \u2192 namespace \u2192 data,\n * where `data` is the raw `{ key: ContentUnit }` map the backend returns (and\n * the CLI `snapshot` command writes). Styles MUST be preserved (no flattening\n * to display strings), so inline markup renders offline.\n */\nexport type StaticBundle = Record<string, Record<string, TranslationData>>;\n\n/**\n * Read-only, pre-seeded sync repository for OFFLINE RESILIENCE. Bundle a\n * snapshot (or import the CLI's snapshot files) and feed it in; `t()` then\n * resolves synchronously from the bundle even with the server down and nothing\n * cached \u2014 the gap browser localStorage/Cache can't fill on a first load.\n *\n * It seeds an internal MemoryRepository exactly the way `SyncHandler.saveNamespace`\n * does (the namespace blob `@locale:namespace` + flattened `locale:namespace:key`\n * entries, each a JSON ContentUnit), so the standard SyncHandler resolves it with\n * zero special-casing. Writes are no-ops: when the network succeeds, the LIVE\n * MemoryRepository (priority 0) holds the fresh value and shadows this layer\n * (which sits at priority 0.5), so the bundle is never overwritten or corrupted.\n * TTL/size are effectively infinite so the bundle never expires or evicts.\n */\nexport class StaticRepository\n implements ISyncRepository<MemoryRepositoryConfig>, IStatsProvider\n{\n readonly name = 'StaticRepository';\n readonly type = 'memory' as const;\n readonly config: MemoryRepositoryConfig;\n private readonly mem: MemoryRepository;\n\n constructor(bundle: StaticBundle, config: MemoryRepositoryConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n priority: config.priority ?? 0.5, // after the live memory (0), before storage\n options: {\n ttl: Number.MAX_SAFE_INTEGER,\n maxSize: Number.MAX_SAFE_INTEGER,\n ...config.options,\n },\n };\n this.mem = new MemoryRepository({ options: { maxSize: Number.MAX_SAFE_INTEGER } });\n\n for (const [locale, namespaces] of Object.entries(bundle)) {\n for (const [namespace, translations] of Object.entries(namespaces)) {\n this.mem.setNamespace(locale, namespace, translations);\n const flat = flattenTranslations(\n translations as Record<string, unknown>,\n '',\n locale,\n namespace\n );\n for (const [key, value] of Object.entries(flat)) this.mem.set(key, value);\n }\n }\n }\n\n get(key: string): string | null {\n return this.mem.get(key);\n }\n\n getNamespace(locale: string, namespace: string): TranslationData | null {\n return this.mem.getNamespace(locale, namespace);\n }\n\n getEntries(): Record<string, string> {\n return this.mem.getEntries();\n }\n\n getConfig(): MemoryRepositoryConfig {\n return this.config;\n }\n\n // Read-only: the live memory layer owns fresh network data; this stays pristine.\n set(): void {}\n remove(): void {}\n clear(): void {}\n setNamespace(): void {}\n}\n", "/**\n * Queue for batching and syncing missing translations to the backend\n * Uses debouncing (500ms default) and batching (50 items default)\n */\n\nimport type { EventEmitter } from '../base/event-emitter.js';\nimport type { IAsyncRepository } from '../interfaces/repository.interface.js';\nimport { logger } from '../utils/logger.js';\n\nexport interface MissingTranslationItem {\n key: string;\n fallbackValue: string;\n styles?: Record<string, string[]>;\n locale: string;\n namespace: string;\n}\n\nexport interface MissingTranslationQueueConfig {\n enabled: boolean;\n debounceMs: number;\n batchSize: number;\n}\n\nconst COOLDOWN_MS = 60_000; // 60s cooldown before re-syncing same key\n\nexport class MissingTranslationQueue {\n private queue: Map<string, MissingTranslationItem> = new Map();\n private debounceTimer: NodeJS.Timeout | null = null;\n private repository: IAsyncRepository;\n private config: MissingTranslationQueueConfig;\n private eventEmitter: EventEmitter | null;\n private recentlySynced: Map<string, number> = new Map();\n\n constructor(\n repository: IAsyncRepository,\n config: MissingTranslationQueueConfig,\n eventEmitter?: EventEmitter\n ) {\n this.repository = repository;\n this.config = config;\n this.eventEmitter = eventEmitter ?? null;\n\n if (!config.enabled) {\n logger.debug('MissingTranslationQueue is disabled');\n } else {\n logger.debug(\n `MissingTranslationQueue: debounce=${config.debounceMs}ms, batchSize=${config.batchSize}`\n );\n }\n }\n\n /**\n * Add a missing translation to the queue\n * Triggers debounce timer or immediate flush if batch size reached\n */\n add(item: MissingTranslationItem): void {\n if (!this.config.enabled) return;\n\n // Use individual cache key format: locale:namespace:key\n const cacheKey = `${item.locale}:${item.namespace}:${item.key}`;\n\n // Skip keys synced within cooldown period (prevents re-sync loops)\n const syncedAt = this.recentlySynced.get(cacheKey);\n if (syncedAt && Date.now() - syncedAt < COOLDOWN_MS) {\n logger.debug(`Skipping recently synced key: ${cacheKey}`);\n return;\n }\n\n // Add to queue (overwrites if already exists)\n this.queue.set(cacheKey, item);\n\n logger.debug(\n `Missing translation queued: ${cacheKey} (queue size: ${this.queue.size})`\n );\n\n // Clear existing timer\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n // Check if batch size limit reached\n if (this.queue.size >= this.config.batchSize) {\n logger.debug(`Batch size reached (${this.config.batchSize}), flushing`);\n this.flush();\n return;\n }\n\n // Start new debounce timer\n this.debounceTimer = setTimeout(() => {\n this.flush();\n }, this.config.debounceMs);\n }\n\n /**\n * Flush the queue - send all queued items to the backend\n * Fire-and-forget pattern (async but not awaited)\n */\n flush(): void {\n if (this.queue.size === 0) return;\n\n // Clean up expired cooldown entries\n const now = Date.now();\n for (const [key, ts] of this.recentlySynced) {\n if (now - ts >= COOLDOWN_MS) this.recentlySynced.delete(key);\n }\n\n // Convert queue to array, preserving styles\n const batch = Array.from(this.queue.entries()).map(([cacheKey, item]) => ({\n key: cacheKey,\n value: item.fallbackValue,\n styles: item.styles,\n }));\n\n const batchSize = batch.length;\n\n // Clear queue\n this.queue.clear();\n\n // Clear timer\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n logger.debug(`Flushing ${batchSize} missing translations`);\n\n // Fire-and-forget sync (no await)\n this.syncBatch(batch).catch(error => {\n logger.warn(`Failed to sync ${batchSize} missing translations:`, error);\n });\n }\n\n /**\n * Send batch to backend via repository\n * Uses repository's retry logic from makeRequest()\n */\n private async syncBatch(\n batch: Array<{ key: string; value: string; styles?: Record<string, string[]> }>\n ): Promise<void> {\n try {\n // Use setBatchContentUnits when any item has styles\n const hasStyles = batch.some(item => item.styles && Object.keys(item.styles).length > 0);\n\n if (hasStyles && 'setBatchContentUnits' in this.repository) {\n const contentUnitBatch = batch.map(item => ({\n key: item.key,\n value: { text: item.value, styles: item.styles ?? {} },\n }));\n await (\n this.repository as IAsyncRepository & {\n setBatchContentUnits: (\n items: Array<{ key: string; value: { text: string; styles: Record<string, string[]> } }>\n ) => Promise<void>;\n }\n ).setBatchContentUnits(contentUnitBatch);\n logger.debug(`Synced ${batch.length} missing translations (ContentUnit)`);\n } else if ('setBatch' in this.repository) {\n // Plain string batch (no styles)\n const plainBatch = batch.map(item => ({ key: item.key, value: item.value }));\n await (\n this.repository as IAsyncRepository & {\n setBatch: (\n items: Array<{ key: string; value: string }>\n ) => Promise<void>;\n }\n ).setBatch(plainBatch);\n logger.debug(`Synced ${batch.length} missing translations`);\n } else {\n // Fallback: sync individually (parallel)\n logger.warn(\n 'Repository does not support setBatch, syncing individually'\n );\n await this.syncIndividually(batch);\n }\n // Record synced keys for cooldown\n const now = Date.now();\n const syncedKeys: string[] = [];\n for (const item of batch) {\n this.recentlySynced.set(item.key, now);\n syncedKeys.push(item.key);\n }\n\n // Emit sync:batch:complete event\n if (this.eventEmitter) {\n this.eventEmitter.emit('sync:batch:complete', {\n payload: { count: batch.length, keys: syncedKeys },\n });\n }\n } catch (error) {\n logger.error('Batch sync failed:', error);\n throw error;\n }\n }\n\n /**\n * Fallback: sync items individually in parallel\n */\n private async syncIndividually(\n batch: Array<{ key: string; value: string }>\n ): Promise<void> {\n const syncPromises = batch.map(async item => {\n try {\n await this.repository.set(item.key, item.value);\n logger.debug(`Synced: ${item.key}`);\n } catch (error) {\n logger.warn(`Failed to sync ${item.key}:`, error);\n }\n });\n\n await Promise.allSettled(syncPromises);\n }\n\n /**\n * Get current queue size (for debugging)\n */\n getQueueSize(): number {\n return this.queue.size;\n }\n\n /**\n * Get queue stats (for debugging)\n */\n getStats(): {\n queueSize: number;\n enabled: boolean;\n debounceMs: number;\n batchSize: number;\n } {\n return {\n queueSize: this.queue.size,\n enabled: this.config.enabled,\n debounceMs: this.config.debounceMs,\n batchSize: this.config.batchSize,\n };\n }\n\n /**\n * Cleanup - clear timer and queue\n */\n destroy(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n // Discard to avoid blocking during shutdown\n this.queue.clear();\n this.recentlySynced.clear();\n\n logger.debug('MissingTranslationQueue destroyed');\n }\n}\n", "/**\n * LionRapid Builder - Enhanced with explicit namespace preloading\n */\n\nimport { EventEmitter } from './base/event-emitter.js';\nimport type { LionRapidCoreConfig } from './config/lionrapid.config.js';\nimport type { NetworkRepositoryConfig } from './config/repository.config.js';\nimport { HandlerChain } from './handlers/handler-chain.js';\nimport { AsyncHandler, NetworkHandler, SyncHandler } from './handlers/index.js';\nimport type {\n IEmbeddedPlugin,\n IPlugin,\n} from './interfaces/plugin.interface.js';\nimport {\n IAsyncRepository,\n ISyncRepository,\n} from './interfaces/repository.interface.js';\nimport { LionRapidCore } from './lionRapid.js';\nimport {\n TranslationLockedError,\n TranslationNotFoundError,\n} from './errors/translation-errors.js';\nimport {\n StaticRepository,\n type StaticBundle,\n} from './repositories/static-repository.js';\nimport { MissingTranslationQueue } from './sync/missing-translation-queue.js';\nimport { logger } from './utils/logger.js';\n\n/**\n * True when a preload failure deserves a loud console diagnostic: network or\n * server trouble the integrator should hear about. 404 (empty project) and\n * 423 (content still being prepared) are routine states, not failures.\n * The internal logger is compiled out of production bundles, so genuine\n * failures must reach console.warn explicitly.\n */\nexport function isLoudPreloadFailure(error: unknown): boolean {\n return !(\n error instanceof TranslationNotFoundError ||\n error instanceof TranslationLockedError\n );\n}\n\nexport class LionRapidBuilder {\n private config: LionRapidCoreConfig;\n private plugins: IPlugin[] = [];\n private syncStorageRepos: ISyncRepository[] = [];\n private asyncStorageRepos: IAsyncRepository[] = [];\n private networkRepos: IAsyncRepository[] = [];\n private syncQueue: MissingTranslationQueue | null = null;\n\n constructor(config: LionRapidCoreConfig) {\n this.config = {\n defaultLocale: config.defaultLocale || 'en',\n namespace: config.namespace || 'app',\n };\n }\n\n static init(config: LionRapidCoreConfig = {}): LionRapidBuilder {\n return new LionRapidBuilder(config);\n }\n\n private useSyncStorage(memory: ISyncRepository): LionRapidBuilder {\n this.syncStorageRepos.push(memory);\n return this;\n }\n\n private useAsyncStorage(storage: IAsyncRepository): LionRapidBuilder {\n this.asyncStorageRepos.push(storage);\n return this;\n }\n\n private useNetwork(network: IAsyncRepository): LionRapidBuilder {\n this.networkRepos.push(network);\n return this;\n }\n\n use(\n instance: IPlugin | IEmbeddedPlugin | ISyncRepository | IAsyncRepository\n ): LionRapidBuilder {\n switch (instance.type) {\n case 'plugin':\n this.plugins.push(instance);\n break;\n case 'memory':\n this.useSyncStorage(instance);\n break;\n case 'storage':\n this.useAsyncStorage(instance);\n break;\n case 'network':\n this.useNetwork(instance);\n break;\n }\n return this;\n }\n\n /**\n * Offline resilience: seed a translation bundle (or the CLI's snapshot files)\n * as a read-only sync layer that resolves synchronously even with the server\n * down and nothing cached. Sits after the live memory layer (priority 0) at\n * `priority` (default 0.5), so fresh network data always shadows it.\n */\n useStaticBundle(bundle: StaticBundle, priority = 0.5): LionRapidBuilder {\n return this.use(new StaticRepository(bundle, { priority }));\n }\n\n async build(): Promise<LionRapidCore> {\n const eventEmitter = new EventEmitter();\n const buildBus = eventEmitter.builder();\n\n logger.info('Builder started');\n logger.debug('Builder config', this.config);\n buildBus.buildStart(this.config.defaultLocale!, this.config.namespace!);\n\n const handlerChain = new HandlerChain(eventEmitter);\n // Always add memory cache handler first\n for (const syncRepo of this.syncStorageRepos) {\n if (!syncRepo.getConfig().enabled) continue;\n const syncHandler = new SyncHandler(eventEmitter, syncRepo);\n buildBus.use('sync');\n handlerChain.addSyncHandler(syncHandler);\n }\n // Always add storage cache handler second\n for (const asyncRepo of this.asyncStorageRepos) {\n if (!asyncRepo.getConfig().enabled) continue;\n const asyncHandler = new AsyncHandler(eventEmitter, asyncRepo);\n buildBus.use('async');\n handlerChain.addAsyncHandler(asyncHandler);\n }\n\n // Always add network cache handler last\n let networkFirst: NetworkHandler | null = null;\n for (const networkRepo of this.networkRepos) {\n if (\n !networkRepo.getConfig().enabled ||\n !networkRepo.getConfig().options?.baseUrl\n )\n continue;\n const networkHandler = new NetworkHandler(eventEmitter, networkRepo);\n if (!networkFirst) {\n networkFirst = networkHandler;\n }\n buildBus.use('network');\n handlerChain.addAsyncHandler(networkHandler);\n\n // \u2705 Initialize missing translation sync queue if enabled\n const config = networkRepo.getConfig() as NetworkRepositoryConfig;\n if (config.options?.syncMissing?.enabled) {\n this.syncQueue = new MissingTranslationQueue(networkRepo, {\n enabled: config.options.syncMissing.enabled,\n debounceMs: config.options.syncMissing.debounceMs || 500,\n batchSize: config.options.syncMissing.batchSize || 50,\n }, eventEmitter);\n\n // Subscribe to translation:not-found events (404 only)\n // Note: translation:locked (423) is NOT synced since translation exists but is not ready\n eventEmitter.on('translation:not-found', envelope => {\n if (this.syncQueue) {\n this.syncQueue.add({\n key: envelope.payload.key,\n fallbackValue: envelope.payload.fallbackValue,\n styles: envelope.payload.styles,\n locale: envelope.payload.locale,\n namespace: envelope.payload.namespace,\n });\n }\n });\n\n logger.info('Missing translation sync enabled');\n logger.debug('Sync queue config', config.options.syncMissing);\n }\n }\n\n logger.debug('Handler chain constructed');\n\n // Create facade\n const facade = new LionRapidCore(\n eventEmitter,\n handlerChain,\n this.config.defaultLocale,\n this.config.namespace\n );\n\n // Initialize plugins and add their handlers\n for (const plugin of this.plugins) {\n buildBus.use('plugin');\n await plugin.initialize({ core: facade, bus: eventEmitter });\n facade.registerPlugin(plugin);\n logger.info(`Plugin initialized: ${plugin.name}`);\n logger.debug(`Plugin version: ${plugin.version}`, plugin.capabilities);\n }\n\n const chainInfo = handlerChain.getChainInfo();\n\n // \u2705 Explicit namespace preloading\n if (networkFirst) {\n await this.executePreloading(networkFirst, handlerChain);\n }\n logger.info('Builder completed');\n buildBus.buildDone(\n chainInfo.handlers.map(r => r.name),\n this.plugins.map(p => p.name)\n );\n\n return facade;\n }\n\n // \u2705 CLEAN: Preloading logic\n private async executePreloading(\n networkHandler: NetworkHandler,\n handlerChain: HandlerChain\n ): Promise<void> {\n const eagerPreloads = networkHandler\n .getPreload()\n .filter(config => config.eager !== false);\n\n if (!eagerPreloads || eagerPreloads.length === 0) {\n return;\n }\n\n logger.info(`Preloading ${eagerPreloads.length} namespaces`);\n logger.debug('Preload targets', {\n namespaces: eagerPreloads.map(c => `${c.locale}:${c.namespace}`),\n });\n\n let warnedLoudly = false;\n const warnLoudlyOnce = (namespaceKey: string, error: unknown) => {\n if (!isLoudPreloadFailure(error) || warnedLoudly) return;\n warnedLoudly = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[LionRapid] Could not load translations for ${namespaceKey} \u2014 the ` +\n 'page stays untranslated until the server is reachable.',\n error\n );\n };\n const promises = eagerPreloads.map(async preloadConfig => {\n const namespaceKey = `${preloadConfig.locale}:${preloadConfig.namespace}`;\n try {\n const result = await networkHandler.loadNamespace(\n preloadConfig.locale,\n preloadConfig.namespace\n );\n\n if (result && result.data && result.status === 200) {\n const context = {\n locale: preloadConfig.locale,\n namespace: preloadConfig.namespace,\n };\n\n await handlerChain.saveNamespaceToHandlers(result.data, context);\n logger.debug(`Preloaded: ${namespaceKey}`);\n return;\n }\n\n // loadNamespace never throws \u2014 failures come back as a fallback\n // result with the error attached (status 0 = network/transport).\n if (result?.error) {\n warnLoudlyOnce(namespaceKey, result.error);\n logger.warn(`Preload failed: ${namespaceKey}`, result.error);\n }\n } catch (error) {\n warnLoudlyOnce(namespaceKey, error);\n logger.warn(`Preload failed: ${namespaceKey}`, error);\n }\n });\n\n await Promise.allSettled(promises);\n logger.info('Preloading completed');\n }\n}\n", "/**\n * API repository - Simple HTTP data access layer\n * No business logic - just GET/POST operations\n *\n * Server always returns ContentUnit format: { text, styles }\n */\n\nimport type { NetworkRepositoryConfig } from '../config/repository.config.js';\nimport type { ContentUnit } from '../content/types.js';\nimport {\n NetworkError,\n ServerError,\n TranslationLockedError,\n TranslationNotFoundError,\n} from '../errors/translation-errors.js';\nimport type { IAsyncRepository } from '../interfaces/repository.interface.js';\nimport type {\n ContentUnitData,\n TranslationData,\n} from '../types/translation-data.types.js';\nimport { logger } from '../utils/logger.js';\n\n/** Server version + the exact payload it describes, stored atomically. */\ninterface NamespaceSnapshot {\n version: string;\n translations: Record<string, unknown>;\n}\n\n/**\n * API repository implementation\n * Pure data access - no caching, no business logic\n */\nexport class NetworkRepository\n implements IAsyncRepository<NetworkRepositoryConfig>\n{\n readonly name = 'NetworkRepository';\n readonly type = 'network';\n readonly config: NetworkRepositoryConfig = {};\n\n /**\n * Namespace snapshot per key \"locale:namespace\": the server version TOGETHER\n * with the payload it describes, persisted as ONE localStorage entry.\n *\n * Canonical 304 contract (same as edge KV bundle + WP transient cache):\n * never claim freshness you can't back. If-None-Match is only sent when the\n * snapshot is in hand; a 304 answers with that snapshot's payload; version\n * and payload can never desync because they live and die together.\n */\n private namespaceSnapshots = new Map<string, NamespaceSnapshot>();\n\n /** localStorage key prefix for persisted snapshots (version + payload) */\n private static readonly SNAPSHOT_PREFIX = 'lionrapid:ns:';\n\n /** Legacy bare-version prefix \u2014 a version WITHOUT its payload is exactly the\n * desync the snapshot store exists to prevent; entries are deleted on sight. */\n private static readonly LEGACY_VERSION_PREFIX = 'lionrapid:v:';\n\n /**\n * Default endpoint templates with placeholder support\n * Placeholders: :key, :locale, :namespace\n */\n private readonly DEFAULT_ENDPOINTS = {\n getTranslation: '/api/integrations/translations/:key',\n getNamespace: '/api/integrations/translations/:locale/:namespace',\n setTranslation: '/api/integrations/sync/:key',\n setNamespace: '/api/integrations/sync/:locale/:namespace',\n setBatch: '/api/integrations/sync/batch',\n removeTranslation: '/api/integrations/sync/:key',\n clearTranslations: '/translations',\n } as const;\n\n constructor(config: NetworkRepositoryConfig = {}) {\n this.config = {\n options: {\n timeout: config.options?.timeout ?? 5000,\n baseUrl: config.options?.baseUrl ?? '',\n headers: config.options?.headers ?? {},\n },\n ...config,\n };\n }\n\n /**\n * Get single translation from API\n * Uses platform-specific integration endpoint\n * @throws {TranslationNotFoundError} When translation doesn't exist (404)\n * @throws {TranslationLockedError} When translation is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async get(key: string): Promise<string> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n const url = this.buildUrl('getTranslation', { key });\n logger.debug(`API GET: ${url}`);\n\n try {\n const response = await this.makeRequest(url, 'GET');\n\n if (!response.ok) {\n this.handleHttpError(response, key);\n }\n\n const data = await response.json();\n logger.debug('API response data:', data);\n\n // Try multiple key formats: meta.key, original key, or first translation\n const translation = data.translations[data.meta?.key]\n || data.translations[key]\n || Object.values(data.translations)[0];\n\n logger.debug(`Fetched translation for key \"${key}\":`, translation);\n if (!translation) {\n throw new TranslationNotFoundError(key);\n }\n\n // Handle both ContentUnit format and plain string\n if (typeof translation === 'object' && 'text' in translation) {\n logger.debug(`ContentUnit text: \"${translation.text}\"`);\n return translation.text;\n }\n\n return String(translation);\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Get single translation as full ContentUnit (with styles)\n * Used by NetworkHandler for individual key lookups that need styles\n * @throws {TranslationNotFoundError} When translation doesn't exist (404)\n * @throws {TranslationLockedError} When translation is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async getContentUnit(key: string): Promise<ContentUnit> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n const url = this.buildUrl('getTranslation', { key });\n logger.debug(`API GET ContentUnit: ${url}`);\n\n try {\n const response = await this.makeRequest(url, 'GET');\n\n if (!response.ok) {\n this.handleHttpError(response, key);\n }\n\n const data = await response.json();\n logger.debug('API response data:', data);\n\n // Try multiple key formats: meta.key, original key, or first translation\n const translation = data.translations[data.meta?.key]\n || data.translations[key]\n || Object.values(data.translations)[0];\n\n if (!translation) {\n throw new TranslationNotFoundError(key);\n }\n\n // Handle both ContentUnit format and plain string\n if (typeof translation === 'object' && 'text' in translation) {\n // Server returned ContentUnit format\n logger.debug(`ContentUnit for \"${key}\": text=\"${translation.text}\", styles=`, translation.styles);\n return {\n text: translation.text,\n styles: translation.styles || {},\n };\n }\n\n // Server returned plain string - wrap in ContentUnit\n logger.debug(`Plain string for \"${key}\": \"${translation}\" (no styles)`);\n return {\n text: String(translation),\n styles: {},\n };\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Get namespace with all translations\n * @throws {TranslationNotFoundError} When namespace doesn't exist (404)\n * @throws {TranslationLockedError} When namespace is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async getNamespace(\n locale: string,\n namespace: string\n ): Promise<TranslationData | null> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n try {\n return (await this.fetchNamespaceRaw(locale, namespace)) as TranslationData;\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Shared namespace fetch with the canonical 304 contract:\n * - If-None-Match is sent ONLY when a snapshot (version + payload) is in hand.\n * - 304 answers with that snapshot's payload \u2014 never with \"nothing\".\n * - A 304 with no snapshot (server/proxy surprise) refetches unconditionally.\n * - A 200 stores version + payload atomically before either is trusted.\n */\n private async fetchNamespaceRaw(\n locale: string,\n namespace: string,\n allowConditional = true\n ): Promise<Record<string, unknown>> {\n const url = this.buildUrl('getNamespace', { locale, namespace });\n logger.debug(`API GET Namespace: ${url}`);\n\n const namespaceKey = `${locale}:${namespace}`;\n\n const snapshot = allowConditional ? this.getSnapshot(namespaceKey) : undefined;\n const extraHeaders: Record<string, string> = {};\n if (snapshot) {\n extraHeaders['If-None-Match'] = `W/\"${snapshot.version}\"`;\n }\n\n const response = await this.makeRequest(url, 'GET', undefined, extraHeaders);\n\n if (response.status === 304) {\n if (snapshot) {\n // Not modified \u2014 serve the exact payload the version vouches for, so\n // callers rehydrate the cache layers instead of assuming they're intact.\n logger.debug(`Namespace ${namespaceKey}: 304 Not Modified (snapshot served)`);\n return snapshot.translations;\n }\n // We never claimed freshness \u2014 refetch without the conditional header.\n logger.debug(`Namespace ${namespaceKey}: unexpected 304 with no snapshot \u2014 refetching`);\n return this.fetchNamespaceRaw(locale, namespace, false);\n }\n\n if (!response.ok) {\n this.handleHttpError(response, namespaceKey);\n }\n\n const data = await response.json();\n logger.debug('API response data:', data);\n\n if (!data.translations) {\n throw new TranslationNotFoundError(namespaceKey);\n }\n\n const version = data.meta?.version != null ? String(data.meta.version) : null;\n if (version) {\n this.setSnapshot(namespaceKey, { version, translations: data.translations });\n }\n\n return data.translations;\n }\n\n /**\n * Save translation to API (if supported)\n */\n async set(key: string, value: string): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('setTranslation', { key });\n const response = await this.makeRequest(url, 'PUT', {\n translation: value,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to save translation: ${response.status}`);\n }\n } catch (error) {\n logger.debug(`API set failed for key \"${key}\":`, error);\n throw error;\n }\n }\n\n async setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('setNamespace', { locale, namespace });\n const response = await this.makeRequest(url, 'PUT', {\n translations,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to save namespace: ${response.status}`);\n }\n } catch (error) {\n logger.debug(\n `API setNamespace failed for ${locale}:${namespace}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Batch sync multiple missing translations\n * Uses new batch endpoint for efficiency\n */\n async setBatch(items: Array<{ key: string; value: string }>): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n\n try {\n const url = this.buildUrl('setBatch');\n logger.debug(`API POST Batch: ${url} (${items.length} items)`);\n\n const response = await this.makeRequest(url, 'POST', {\n translations: items,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to sync batch: ${response.status}`);\n }\n\n logger.debug(`Batch sync successful: ${items.length} items`);\n } catch (error) {\n logger.debug(`API setBatch failed for ${items.length} items:`, error);\n throw error;\n }\n }\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // ContentUnit API Methods\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n /**\n * Get namespace with all translations as ContentUnit data\n *\n * @returns ContentUnitData (Record<string, ContentUnit>)\n * @throws {TranslationNotFoundError} When namespace doesn't exist (404)\n * @throws {TranslationLockedError} When namespace is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async getNamespaceContentUnits(\n locale: string,\n namespace: string\n ): Promise<ContentUnitData | null> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n try {\n // Server always returns ContentUnit format\n return (await this.fetchNamespaceRaw(locale, namespace)) as ContentUnitData;\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Save ContentUnit to API\n *\n * Sends the ContentUnit format to server for storage.\n * Server should store in ContentUnit format for efficient retrieval.\n *\n * @param key - Translation key\n * @param unit - ContentUnit to save\n */\n async setContentUnit(key: string, unit: ContentUnit): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n\n try {\n const url = this.buildUrl('setTranslation', { key });\n const response = await this.makeRequest(url, 'PUT', {\n translation: unit,\n format: 'contentunit', // Signal to server that this is ContentUnit format\n });\n\n if (!response.ok) {\n throw new Error(`Failed to save ContentUnit: ${response.status}`);\n }\n\n logger.debug(`Saved ContentUnit for key \"${key}\"`);\n } catch (error) {\n logger.debug(`API setContentUnit failed for key \"${key}\":`, error);\n throw error;\n }\n }\n\n /**\n * Batch sync multiple ContentUnits\n *\n * Sends ContentUnit format to server for batch storage.\n *\n * @param items - Array of key-ContentUnit pairs\n */\n async setBatchContentUnits(\n items: Array<{ key: string; value: ContentUnit }>\n ): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n\n try {\n const url = this.buildUrl('setBatch');\n logger.debug(\n `API POST Batch ContentUnits: ${url} (${items.length} items)`\n );\n\n const response = await this.makeRequest(url, 'POST', {\n translations: items,\n format: 'contentunit', // Signal to server that this is ContentUnit format\n });\n\n if (!response.ok) {\n throw new Error(`Failed to sync batch ContentUnits: ${response.status}`);\n }\n\n logger.debug(`Batch ContentUnit sync successful: ${items.length} items`);\n } catch (error) {\n logger.debug(\n `API setBatchContentUnits failed for ${items.length} items:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Remove translation from API (if supported)\n */\n async remove(key: string): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('removeTranslation', { key });\n const response = await this.makeRequest(url, 'DELETE');\n\n if (!response.ok) {\n throw new Error(`Failed to remove translation: ${response.status}`);\n }\n } catch (error) {\n logger.debug(`API remove failed for key \"${key}\":`, error);\n throw error;\n }\n }\n\n /**\n * Clear all translations (if supported)\n */\n async clear(): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('clearTranslations');\n const response = await this.makeRequest(url, 'DELETE');\n\n if (!response.ok) {\n throw new Error(`Failed to clear translations: ${response.status}`);\n }\n } catch (error) {\n logger.debug('API clear failed:', error);\n throw error;\n }\n }\n\n getConfig(): NetworkRepositoryConfig {\n return this.config;\n }\n\n /** Read a persisted snapshot (version + payload), falling back to memory.\n * Legacy bare-version entries and corrupt snapshots are deleted on sight \u2014\n * a version without its payload must never drive a conditional request. */\n private getSnapshot(namespaceKey: string): NamespaceSnapshot | undefined {\n const mem = this.namespaceSnapshots.get(namespaceKey);\n if (mem) return mem;\n try {\n localStorage.removeItem(NetworkRepository.LEGACY_VERSION_PREFIX + namespaceKey);\n const raw = localStorage.getItem(NetworkRepository.SNAPSHOT_PREFIX + namespaceKey);\n if (raw) {\n const parsed = JSON.parse(raw) as NamespaceSnapshot;\n if (\n parsed &&\n typeof parsed.version === 'string' &&\n parsed.version.length > 0 &&\n parsed.translations &&\n typeof parsed.translations === 'object'\n ) {\n this.namespaceSnapshots.set(namespaceKey, parsed);\n return parsed;\n }\n localStorage.removeItem(NetworkRepository.SNAPSHOT_PREFIX + namespaceKey);\n }\n } catch {\n /* SSR, localStorage unavailable, or corrupt JSON */\n }\n return undefined;\n }\n\n /** Persist version + payload as ONE entry (memory + localStorage). On quota\n * failure the previous stored snapshot stays \u2014 still a consistent pair. */\n private setSnapshot(namespaceKey: string, snapshot: NamespaceSnapshot): void {\n this.namespaceSnapshots.set(namespaceKey, snapshot);\n try {\n localStorage.setItem(\n NetworkRepository.SNAPSHOT_PREFIX + namespaceKey,\n JSON.stringify(snapshot)\n );\n localStorage.removeItem(NetworkRepository.LEGACY_VERSION_PREFIX + namespaceKey);\n } catch {\n /* quota exceeded or unavailable \u2014 memory copy still serves this session */\n }\n }\n\n /**\n * Handle HTTP error responses by mapping to domain errors\n * @throws {TranslationNotFoundError} When status is 404\n * @throws {TranslationLockedError} When status is 423\n * @throws {ServerError} When status is 5xx\n * @throws {NetworkError} For other client errors\n */\n private handleHttpError(response: Response, key: string): never {\n logger.debug(`API response: ${response.status} ${response.statusText}`);\n\n if (response.status === 404) {\n throw new TranslationNotFoundError(key);\n }\n\n if (response.status === 423) {\n const retryAfter = response.headers.get('Retry-After');\n throw new TranslationLockedError(\n key,\n retryAfter ? parseInt(retryAfter, 10) * 1000 : undefined\n );\n }\n\n if (response.status >= 500 && response.status < 600) {\n throw new ServerError(key, response.status);\n }\n\n // Other client errors (400, 401, 403, etc.)\n throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n /**\n * Handle caught errors by wrapping non-domain errors\n * @throws {TranslationError} Always throws - propagates domain errors or wraps unexpected ones\n */\n private handleCaughtError(error: unknown): never {\n // Custom errors propagate automatically, wrap everything else\n if (\n error instanceof TranslationNotFoundError ||\n error instanceof TranslationLockedError ||\n error instanceof ServerError ||\n error instanceof NetworkError\n ) {\n throw error;\n }\n\n // Wrap unexpected errors (fetch abort, JSON parse, etc.)\n throw new NetworkError('Network request failed', error);\n }\n\n /**\n * Build URL from endpoint template and parameters\n * Supports placeholders: :key, :locale, :namespace\n * @param endpoint - Endpoint key from DEFAULT_ENDPOINTS\n * @param params - Parameters to replace placeholders with\n * @returns Complete URL with baseUrl + endpoint path\n */\n private buildUrl(\n endpoint: keyof typeof this.DEFAULT_ENDPOINTS,\n params: Record<string, string> = {}\n ): string {\n const baseUrl = this.config.options?.baseUrl || '';\n\n // Get endpoint template from config or use default\n let endpointTemplate =\n this.config.options?.endpoints?.[endpoint] ||\n this.DEFAULT_ENDPOINTS[endpoint];\n\n // Ensure endpoint starts with / for consistent URL building\n if (!endpointTemplate.startsWith('/')) {\n endpointTemplate = `/${endpointTemplate}`;\n }\n\n // Replace all placeholders with actual values (encoded)\n // Use global replace to handle multiple occurrences\n let path = endpointTemplate;\n for (const [key, value] of Object.entries(params)) {\n const placeholder = new RegExp(`:${key}`, 'g');\n path = path.replace(placeholder, encodeURIComponent(value));\n }\n\n return `${baseUrl}${path}`;\n }\n\n /**\n * Make HTTP request with timeout and headers\n */\n private async makeRequest(\n url: string,\n method: string,\n body?: unknown,\n extraHeaders?: Record<string, string>\n ): Promise<Response> {\n const controller = new AbortController();\n const timeout = this.config.options?.timeout ?? 10000;\n const timeoutId = setTimeout(\n () => controller.abort(),\n timeout\n );\n\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.config.options?.headers,\n ...extraHeaders,\n };\n\n if (this.config.options?.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.options.apiKey}`;\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n}\n", "/**\n * Exclude Filter\n * Filters out text that should not be translated\n * Mirrors PHP's HtmlTranslator logic\n */\n\nexport interface ExcludePatterns {\n emails: boolean;\n urls: boolean;\n numbers: boolean;\n phones: boolean;\n}\n\nconst DEFAULT_PATTERNS: ExcludePatterns = {\n emails: true,\n urls: true,\n numbers: true,\n phones: true,\n};\n\n// Regex patterns matching PHP's HtmlTranslator\nconst PATTERNS = {\n email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n url: /^(https?:\\/\\/|www\\.)[^\\s]+$/i,\n number: /^[\\d\\s.,+-]+$/,\n phone: /^[+\\d][\\d\\s().-]{6,}$/,\n};\n\nexport class ExcludeFilter {\n private patterns: ExcludePatterns;\n private minTextLength: number;\n\n constructor(patterns: Partial<ExcludePatterns> = {}, minTextLength = 2) {\n this.patterns = { ...DEFAULT_PATTERNS, ...patterns };\n this.minTextLength = minTextLength;\n }\n\n /**\n * Check if text should be excluded from translation\n */\n shouldExclude(text: string): boolean {\n const trimmed = text.trim();\n\n // Too short\n if (trimmed.length < this.minTextLength) {\n return true;\n }\n\n // Check auto-exclude patterns\n if (this.patterns.emails && PATTERNS.email.test(trimmed)) {\n return true;\n }\n\n if (this.patterns.urls && PATTERNS.url.test(trimmed)) {\n return true;\n }\n\n if (this.patterns.numbers && PATTERNS.number.test(trimmed)) {\n return true;\n }\n\n if (this.patterns.phones && PATTERNS.phone.test(trimmed)) {\n return true;\n }\n\n return false;\n }\n}\n", "/**\n * DOM-based Markup Parser (raw-only)\n *\n * Converts a block element's childNodes into ContentUnit by walking the\n * DOM. Every inline element becomes an indexed tag whose style is the\n * verbatim opening tag in canonical form (see content/canonical-tag.ts).\n *\n * Mirrors the regex-based parser in `content/parser/MarkupParser.ts` and\n * the edge proxy parser, producing byte-identical text + styles for the\n * same source so translation keys match across boundaries.\n */\n\nimport type { ContentUnit } from '../content/types.js';\nimport { serializeOpeningTag, VOID_TAGS } from '../content/canonical-tag.js';\n\n/**\n * Parse a block element into ContentUnit using DOM walking.\n */\nexport function parseBlockElement(element: Element): ContentUnit {\n const styles: Record<string, string[]> = {};\n let tagIndex = 0;\n\n function walk(node: Node): string {\n if (node.nodeType === Node.TEXT_NODE) {\n return node.nodeValue ?? '';\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return '';\n }\n\n const el = node as Element;\n const tag = el.tagName.toLowerCase();\n\n // Collect attributes preserving source insertion order.\n const attrs: Record<string, string> = {};\n for (let i = 0; i < el.attributes.length; i++) {\n const attr = el.attributes[i];\n attrs[attr.name.toLowerCase()] = attr.value;\n }\n\n tagIndex++;\n const idx = tagIndex;\n styles[String(idx)] = [`raw:${serializeOpeningTag(tag, attrs)}`];\n\n if (VOID_TAGS.has(tag)) {\n return `<${idx}/>`;\n }\n\n let inner = '';\n for (let i = 0; i < node.childNodes.length; i++) {\n inner += walk(node.childNodes[i]);\n }\n return `<${idx}>${inner}</${idx}>`;\n }\n\n let text = '';\n for (let i = 0; i < element.childNodes.length; i++) {\n text += walk(element.childNodes[i]);\n }\n\n return { text, styles };\n}\n", "/**\n * MD5 Hash Implementation\n * Minimal implementation to match PHP's md5() function\n * Used for generating auto_* keys that match server-side\n */\n\n/* eslint-disable no-bitwise */\n\nfunction safeAdd(x: number, y: number): number {\n const lsw = (x & 0xffff) + (y & 0xffff);\n const msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xffff);\n}\n\nfunction bitRotateLeft(num: number, cnt: number): number {\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\nfunction md5cmn(\n q: number,\n a: number,\n b: number,\n x: number,\n s: number,\n t: number\n): number {\n return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);\n}\n\nfunction md5ff(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn((b & c) | (~b & d), a, b, x, s, t);\n}\n\nfunction md5gg(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\n\nfunction md5hh(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn(b ^ c ^ d, a, b, x, s, t);\n}\n\nfunction md5ii(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn(c ^ (b | ~d), a, b, x, s, t);\n}\n\nfunction binlMD5(x: number[], len: number): number[] {\n x[len >> 5] |= 0x80 << len % 32;\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n let a = 1732584193;\n let b = -271733879;\n let c = -1732584194;\n let d = 271733878;\n\n for (let i = 0; i < x.length; i += 16) {\n const olda = a;\n const oldb = b;\n const oldc = c;\n const oldd = d;\n\n a = md5ff(a, b, c, d, x[i], 7, -680876936);\n d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\n c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\n a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\n d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\n b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\n a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\n c = md5ff(c, d, a, b, x[i + 10], 17, -42063);\n b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\n d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\n c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\n\n a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\n d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\n b = md5gg(b, c, d, a, x[i], 20, -373897302);\n a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\n c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\n b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\n d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\n c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\n a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\n d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\n b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\n\n a = md5hh(a, b, c, d, x[i + 5], 4, -378558);\n d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\n c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\n b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\n d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\n c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\n a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\n d = md5hh(d, a, b, c, x[i + 0], 11, -358537222);\n c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\n b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\n a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\n c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\n b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\n\n a = md5ii(a, b, c, d, x[i], 6, -198630844);\n d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\n c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\n a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\n d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\n b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\n a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\n c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\n b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\n d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\n c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\n\n a = safeAdd(a, olda);\n b = safeAdd(b, oldb);\n c = safeAdd(c, oldc);\n d = safeAdd(d, oldd);\n }\n\n return [a, b, c, d];\n}\n\nfunction binl2hex(binarray: number[]): string {\n const hexTab = '0123456789abcdef';\n let str = '';\n for (let i = 0; i < binarray.length * 4; i++) {\n str +=\n hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) +\n hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf);\n }\n return str;\n}\n\n/**\n * Encode a string to its UTF-8 bytes. PHP's md5() operates on bytes, so to\n * match its output we must hash the UTF-8 representation \u2014 not raw UTF-16\n * code units. The previous code did `charCodeAt & 0xff`, which truncated\n * any character above U+00FF to a single low byte: U+2019 (curly `'`) was\n * hashed as 0x19 instead of its real UTF-8 form `E2 80 99`. That silently\n * broke key parity with PHP for every non-ASCII character on the page.\n */\nfunction utf8Bytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str);\n }\n // Fallback (older Node/test envs without TextEncoder).\n const out: number[] = [];\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 0x80) {\n out.push(c);\n } else if (c < 0x800) {\n out.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f));\n } else if (c >= 0xd800 && c < 0xdc00 && i + 1 < str.length) {\n const c2 = str.charCodeAt(++i);\n const cp = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n out.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f),\n );\n } else {\n out.push(\n 0xe0 | (c >> 12),\n 0x80 | ((c >> 6) & 0x3f),\n 0x80 | (c & 0x3f),\n );\n }\n }\n return new Uint8Array(out);\n}\n\nfunction bytes2binl(bytes: Uint8Array): number[] {\n const bin: number[] = [];\n for (let i = 0; i < bytes.length; i++) {\n bin[i >> 2] |= bytes[i] << ((i % 4) * 8);\n }\n return bin;\n}\n\n/**\n * Generate MD5 hash of a string.\n * Hashes the UTF-8 bytes of `str` so output matches PHP's `md5()` for any\n * input \u2014 ASCII or not.\n */\nexport function md5(str: string): string {\n const bytes = utf8Bytes(str);\n return binl2hex(binlMD5(bytes2binl(bytes), bytes.length * 8));\n}\n\n/**\n * Generate auto key matching PHP's TranslationStateManager::generateKey()\n * Format: auto_ + first 12 chars of md5 hash\n */\nexport function generateAutoKey(text: string): string {\n const trimmed = text.trim();\n return 'auto_' + md5(trimmed).substring(0, 12);\n}\n", "/**\n * Block Extractor\n * Finds translatable block elements in DOM and parses them into ContentUnit.\n * Mirrors WordPress TS BlockExtractor and edge proxy block-level approach.\n */\n\nimport type { ContentUnit } from '../content/types.js';\nimport { ExcludeFilter, ExcludePatterns } from './exclude-filter.js';\nimport { parseBlockElement } from './markup-parser.js';\nimport { generateAutoKey } from './md5.js';\n\nconst BLOCK_SELECTOR =\n 'p,h1,h2,h3,h4,h5,h6,li,td,th,label,button,figcaption,dt,dd,summary,caption';\n\n// Inline elements eligible for \"orphan\" extraction when they have no block\n// ancestor. Without this, markup like `<div><a>Transfer</a></div>` produces\n// zero translatable units because <div>/<a> are absent from BLOCK_SELECTOR\n// and the link has no <p>/<li>/etc. parent to absorb it as an indexed style.\n// Conservative on purpose: only <a>. <span>/<button> can join later if real\n// usage demands it (button is already a block tag).\nconst INLINE_BLOCK_SELECTOR = 'a';\n\n// Tags to skip (same as PHP/edge)\nconst SKIP_TAGS = new Set([\n 'SCRIPT',\n 'STYLE',\n 'CODE',\n 'PRE',\n 'TEXTAREA',\n 'NOSCRIPT',\n 'SVG',\n]);\n\n// Attributes that mark elements to skip\nconst SKIP_ATTRIBUTES = [\n 'data-lionrapid-translated', // Server already translated\n 'data-lionrapid-client', // Client already translated\n 'data-no-translate', // Explicitly marked to skip\n // Edge proxy already rendered this block with the correct translation\n // and styles. Skip in normal extraction so the client-side auto-translator\n // can't overwrite the styled DOM with a stale (or plain-text) cache entry.\n // The editor passes includeTranslated=true to bypass this and re-extract\n // edge-rendered blocks for inspection.\n 'data-lr-block',\n];\n\nexport interface ExtractedBlock {\n element: Element;\n unit: ContentUnit;\n key: string;\n}\n\nexport class BlockExtractor {\n private excludeFilter: ExcludeFilter;\n private excludeSelectors: string[];\n\n constructor(\n excludePatterns: Partial<ExcludePatterns> = {},\n excludeSelectors: string[] = [],\n minTextLength = 2\n ) {\n this.excludeFilter = new ExcludeFilter(excludePatterns, minTextLength);\n this.excludeSelectors = excludeSelectors;\n }\n\n /**\n * Extract all translatable block elements from a root.\n * @param includeTranslated - If true, include elements already marked as translated (for editor mode)\n */\n extract(root: Element | Document, includeTranslated = false): ExtractedBlock[] {\n const results: ExtractedBlock[] = [];\n const descendants = root.querySelectorAll(BLOCK_SELECTOR);\n\n // Include the root itself if it matches the block selector\n const elements: Element[] = [];\n if (root instanceof Element && root.matches(BLOCK_SELECTOR)) {\n elements.push(root);\n }\n for (let i = 0; i < descendants.length; i++) {\n elements.push(descendants[i]);\n }\n\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n // Skip if inside a SKIP_TAG ancestor\n if (this.isInsideSkipTag(el)) {\n continue;\n }\n\n // Skip if has skip attributes (unless editor mode includes translated)\n if (!includeTranslated && this.hasSkipAttribute(el)) {\n continue;\n }\n\n // Skip if matches exclude selectors\n if (this.matchesExcludeSelector(el)) {\n continue;\n }\n\n // Skip if has translate=\"no\"\n if (el.getAttribute('translate') === 'no') {\n continue;\n }\n\n // Skip nested block elements (let the inner blocks be extracted)\n if (el.querySelector(BLOCK_SELECTOR)) {\n continue;\n }\n\n // For already-translated elements, use original HTML for key + unit\n const lrBlock = el.getAttribute('data-lr-block');\n const lrOriginal = el.getAttribute('data-lr-original');\n\n let unit: ContentUnit;\n if (lrOriginal) {\n // Parse original (source) HTML \u2192 correct ContentUnit for key generation\n const temp = document.createElement(el.tagName);\n temp.innerHTML = lrOriginal;\n unit = parseBlockElement(temp);\n } else {\n unit = parseBlockElement(el);\n }\n\n // Strip indexed tags for exclude filter\n const strippedText = unit.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n\n // Apply exclude filter\n if (this.excludeFilter.shouldExclude(strippedText)) {\n continue;\n }\n\n // Key priority: data-lr-block (translated) \u2192 data-i18n (named) \u2192 auto-generate\n let key: string;\n if (lrBlock) {\n key = lrBlock;\n } else {\n const dataI18n = el.getAttribute('data-i18n');\n if (dataI18n) {\n key = dataI18n.includes(':') ? dataI18n : `common:${dataI18n}`;\n } else {\n key = generateAutoKey(unit.text);\n }\n }\n\n results.push({ element: el, unit, key });\n }\n\n this.extractOrphanInline(root, results, includeTranslated);\n\n return results;\n }\n\n /**\n * Second pass: extract inline elements (currently <a>) that have no block\n * ancestor. These would otherwise slip through both the block pass (not in\n * BLOCK_SELECTOR) and the inline-style capture (no parent block to host\n * them as `<1>...</1>`). Common shape: a `<div>` action group containing\n * only links.\n */\n private extractOrphanInline(\n root: Element | Document,\n results: ExtractedBlock[],\n includeTranslated: boolean\n ): void {\n const candidates = root.querySelectorAll(INLINE_BLOCK_SELECTOR);\n const elements: Element[] = [];\n if (root instanceof Element && root.matches(INLINE_BLOCK_SELECTOR)) {\n elements.push(root);\n }\n for (let i = 0; i < candidates.length; i++) {\n elements.push(candidates[i]);\n }\n\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n if (this.isInsideSkipTag(el)) continue;\n if (!includeTranslated && this.hasSkipAttribute(el)) continue;\n if (this.matchesExcludeSelector(el)) continue;\n if (el.getAttribute('translate') === 'no') continue;\n\n // Has a block ancestor \u2014 already captured as `<N>...</N>` by the\n // block pass (or its parent block was skipped, in which case we leave\n // it alone to avoid double-counting from a partially-skipped block).\n if (el.parentElement?.closest(BLOCK_SELECTOR)) continue;\n\n // Outer orphan wins: `<a><span>X</span></a>` \u2192 only the outer <a>.\n // (Currently INLINE_BLOCK_SELECTOR is just <a>, so this guards\n // against nested links in malformed HTML.)\n if (el.parentElement?.closest(INLINE_BLOCK_SELECTOR)) continue;\n\n // Contains a nested block \u2014 let the inner block be extracted instead.\n if (el.querySelector(BLOCK_SELECTOR)) continue;\n\n const lrOriginal = el.getAttribute('data-lr-original');\n let unit: ContentUnit;\n if (lrOriginal) {\n const temp = document.createElement(el.tagName);\n temp.innerHTML = lrOriginal;\n unit = parseBlockElement(temp);\n } else {\n unit = parseBlockElement(el);\n }\n\n const strippedText = unit.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n if (this.excludeFilter.shouldExclude(strippedText)) continue;\n\n const lrBlock = el.getAttribute('data-lr-block');\n let key: string;\n if (lrBlock) {\n key = lrBlock;\n } else {\n const dataI18n = el.getAttribute('data-i18n');\n if (dataI18n) {\n key = dataI18n.includes(':') ? dataI18n : `common:${dataI18n}`;\n } else {\n key = generateAutoKey(unit.text);\n }\n }\n\n results.push({ element: el, unit, key });\n }\n }\n\n private isInsideSkipTag(element: Element): boolean {\n let current: Element | null = element.parentElement;\n while (current) {\n // Foreign elements (SVG/MathML) report a case-preserved tagName (\"svg\",\n // not \"SVG\"), so match case-insensitively or the SVG skip never fires.\n if (SKIP_TAGS.has(current.tagName.toUpperCase())) {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n }\n\n private hasSkipAttribute(element: Element): boolean {\n let current: Element | null = element;\n while (current) {\n for (const attr of SKIP_ATTRIBUTES) {\n if (current.hasAttribute(attr)) {\n return true;\n }\n }\n current = current.parentElement;\n }\n return false;\n }\n\n private matchesExcludeSelector(element: Element): boolean {\n for (const selector of this.excludeSelectors) {\n try {\n if (element.matches(selector) || element.closest(selector)) {\n return true;\n }\n } catch {\n // Invalid selector, skip\n }\n }\n return false;\n }\n}\n", "/**\n * Attribute Extractor\n *\n * Finds translatable HTML attribute values in the DOM and parses each\n * into an AttributeUnit. Pairs with BlockExtractor (text-content side)\n * to cover everything user-visible:\n *\n * - <img alt>, <area alt>, <input type=\"image\" alt>\n * - any element [title]\n * - <input placeholder>, <textarea placeholder>\n * - <meta name=\"description\" content=\"...\">\n * - <input type=\"submit|button|reset\" value>\n *\n * Cross-stack parity: produces the same auto_ key as BlockExtractor for\n * the same trimmed text \u2014 md5(text.trim()) prefix \u2014 so a button labelled\n * \"Submit\" and a paragraph \"Submit\" collide on key (intentional reuse).\n *\n * `<input type=\"text\" value=\"...\">` is deliberately excluded because\n * `value` on a plain text input is user data, not UI copy, and would\n * corrupt form state if treated as translatable.\n */\n\nimport type { AttributeKind, AttributeUnit } from '../content/types.js';\nimport { ExcludeFilter, type ExcludePatterns } from './exclude-filter.js';\nimport { generateAutoKey } from './md5.js';\n\ninterface AttributeTarget {\n /** CSS selector used to find candidate elements */\n selector: string;\n /** The actual HTML attribute name carrying the translatable value */\n attr: string;\n /** Semantic category exposed to the translation pipeline */\n type: AttributeKind;\n}\n\n// Each target has a unique `attr`, so a single element matching multiple\n// targets (e.g. `<input placeholder title>`) yields one ExtractedAttribute\n// per attribute \u2014 no cross-target dedup needed.\nconst TARGETS: AttributeTarget[] = [\n { selector: 'img[alt], area[alt], input[type=\"image\"][alt]', attr: 'alt', type: 'alt' },\n { selector: '[title]', attr: 'title', type: 'title' },\n { selector: 'input[placeholder], textarea[placeholder]', attr: 'placeholder', type: 'placeholder' },\n { selector: 'meta[name=\"description\"][content]', attr: 'content', type: 'meta-description' },\n {\n selector:\n 'input[type=\"submit\"][value], input[type=\"button\"][value], input[type=\"reset\"][value]',\n attr: 'value',\n type: 'input-value',\n },\n];\n\n// Skip the same containers as BlockExtractor \u2014 attribute values inside\n// <script>, <style>, etc. are never user-visible UI text.\nconst SKIP_TAGS = new Set([\n 'SCRIPT',\n 'STYLE',\n 'CODE',\n 'PRE',\n 'NOSCRIPT',\n 'SVG',\n]);\n\n// Ancestor attributes that opt the element out of translation. Matches\n// BlockExtractor's contract so authors get one consistent escape hatch.\nconst SKIP_ATTRIBUTES = [\n 'data-lionrapid-translated',\n 'data-lionrapid-client',\n 'data-no-translate',\n];\n\n/**\n * Server-stamped attribute marker \u2014 when the edge or PHP layer has already\n * keyed an attribute, the element carries `data-lr-attr-{name}=\"auto_xxx\"`.\n * Client extraction reads this instead of re-hashing, eliminating the same\n * class of cross-stack parity drift `data-lr-block` solves for body text.\n */\nfunction stampAttrName(attrName: string): string {\n return `data-lr-attr-${attrName.toLowerCase()}`;\n}\n\nexport interface ExtractedAttribute {\n /** Live element carrying the attribute */\n element: Element;\n /** HTML attribute name (e.g. `alt`, `content`) */\n attrName: string;\n /** Translatable payload */\n unit: AttributeUnit;\n /** auto_ key or server-stamped key */\n key: string;\n}\n\nexport class AttributeExtractor {\n private excludeFilter: ExcludeFilter;\n private excludeSelectors: string[];\n\n constructor(\n excludePatterns: Partial<ExcludePatterns> = {},\n excludeSelectors: string[] = [],\n minTextLength = 2\n ) {\n this.excludeFilter = new ExcludeFilter(excludePatterns, minTextLength);\n this.excludeSelectors = excludeSelectors;\n }\n\n /**\n * Walk the DOM under `root` and return every translatable attribute.\n *\n * @param root Element or Document to scan\n * @param includeStamped When true, elements already carrying\n * `data-lr-attr-{name}` are returned anyway \u2014\n * the editor uses this to surface server-handled\n * attributes for inspection. The runtime keeps\n * the default `false` so it doesn't re-extract\n * what the server already keyed.\n */\n extract(root: Element | Document, includeStamped = false): ExtractedAttribute[] {\n const results: ExtractedAttribute[] = [];\n\n for (const target of TARGETS) {\n const candidates = root.querySelectorAll(target.selector);\n const all: Element[] = [];\n if (root instanceof Element && root.matches(target.selector)) {\n all.push(root);\n }\n for (let i = 0; i < candidates.length; i++) {\n all.push(candidates[i]);\n }\n\n for (let i = 0; i < all.length; i++) {\n const el = all[i];\n\n if (this.isInsideSkipTag(el)) continue;\n if (this.hasSkipAncestor(el)) continue;\n if (this.matchesExcludeSelector(el)) continue;\n if (el.getAttribute('translate') === 'no') continue;\n\n const rawValue = el.getAttribute(target.attr);\n if (rawValue === null) continue;\n\n const trimmed = rawValue.trim();\n if (this.excludeFilter.shouldExclude(trimmed)) continue;\n\n const stampName = stampAttrName(target.attr);\n const stamped = el.getAttribute(stampName);\n if (!includeStamped && stamped) {\n continue;\n }\n\n const unit: AttributeUnit = { text: rawValue, type: target.type };\n const key = stamped ?? generateAutoKey(rawValue);\n\n results.push({ element: el, attrName: target.attr, unit, key });\n }\n }\n\n return results;\n }\n\n private isInsideSkipTag(element: Element): boolean {\n let current: Element | null = element.parentElement;\n while (current) {\n // Case-insensitive: foreign elements (SVG) keep a lowercase tagName.\n if (SKIP_TAGS.has(current.tagName.toUpperCase())) return true;\n current = current.parentElement;\n }\n return false;\n }\n\n private hasSkipAncestor(element: Element): boolean {\n let current: Element | null = element;\n while (current) {\n for (const attr of SKIP_ATTRIBUTES) {\n if (current.hasAttribute(attr)) return true;\n }\n current = current.parentElement;\n }\n return false;\n }\n\n private matchesExcludeSelector(element: Element): boolean {\n for (const selector of this.excludeSelectors) {\n try {\n if (element.matches(selector) || element.closest(selector)) {\n return true;\n }\n } catch {\n // Invalid selector \u2014 skip silently, same as BlockExtractor.\n }\n }\n return false;\n }\n}\n", "/**\n * DOM Observer\n * Watches for dynamically added content using MutationObserver\n * Triggers translation of new content (AJAX, SPA navigation, etc.)\n */\n\nexport interface DOMObserverCallbacks {\n onNewContent?: (element: Element) => void;\n onNewSwitchers?: () => void;\n}\n\nexport class DOMObserver {\n private observer: MutationObserver | null = null;\n private callbacks: DOMObserverCallbacks;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private pendingElements: Set<Element> = new Set();\n private debounceMs: number;\n\n constructor(callbacks: DOMObserverCallbacks, debounceMs = 50) {\n this.callbacks = callbacks;\n this.debounceMs = debounceMs;\n }\n\n /**\n * Start observing DOM changes\n */\n start(): void {\n if (this.observer) {\n return;\n }\n\n this.observer = new MutationObserver((mutations) => {\n this.handleMutations(mutations);\n });\n\n this.observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n /**\n * Stop observing\n */\n stop(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n this.pendingElements.clear();\n }\n\n /**\n * Handle DOM mutations\n */\n private handleMutations(mutations: MutationRecord[]): void {\n let hasNewSwitchers = false;\n\n for (const mutation of mutations) {\n for (const node of Array.from(mutation.addedNodes)) {\n if (node.nodeType !== Node.ELEMENT_NODE) continue;\n\n const element = node as Element;\n\n // Check for language switchers\n if (this.hasLanguageSwitcher(element)) {\n hasNewSwitchers = true;\n }\n\n // Queue for auto-translation\n if (this.callbacks.onNewContent) {\n this.pendingElements.add(element);\n }\n }\n }\n\n // Trigger switcher callback immediately\n if (hasNewSwitchers && this.callbacks.onNewSwitchers) {\n this.callbacks.onNewSwitchers();\n }\n\n // Debounce content translation\n if (this.pendingElements.size > 0) {\n this.scheduleFlush();\n }\n }\n\n /**\n * Schedule debounced processing of pending elements\n */\n private scheduleFlush(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n this.debounceTimer = setTimeout(() => {\n this.flushPendingElements();\n }, this.debounceMs);\n }\n\n /**\n * Process all pending elements\n */\n private flushPendingElements(): void {\n if (!this.callbacks.onNewContent || this.pendingElements.size === 0) {\n return;\n }\n\n for (const element of this.pendingElements) {\n // Skip if element was removed from DOM\n if (!document.body.contains(element)) {\n continue;\n }\n this.callbacks.onNewContent(element);\n }\n\n this.pendingElements.clear();\n }\n\n /**\n * Check if element or children are language switchers\n */\n private hasLanguageSwitcher(element: Element): boolean {\n return (\n element.hasAttribute('data-lionrapid-switcher') ||\n element.querySelector('[data-lionrapid-switcher]') !== null\n );\n }\n}\n", "/**\n * Auto Translator\n * Automatically translates block-level elements in DOM content.\n * Uses ContentUnit model for key parity with WordPress TS, PHP, and edge proxy.\n *\n * Missing translations are reported via the event bus (translation:not-found),\n * picked up by MissingTranslationQueue, and synced through NetworkRepository.\n */\n\nimport type { LionRapidCore } from '../lionRapid.js';\nimport type { ContentUnit } from '../content/types.js';\nimport { BlockExtractor, ExtractedBlock } from './block-extractor.js';\nimport { AttributeExtractor, ExtractedAttribute } from './attribute-extractor.js';\nimport { ExcludePatterns } from './exclude-filter.js';\nimport { DOMObserver } from './dom-observer.js';\nimport { HTMLSerializer } from '../content/serializer/HTMLSerializer.js';\nimport { generateAutoKey } from './md5.js';\n\nconst htmlSerializer = new HTMLSerializer();\n\nexport interface AutoTranslatorConfig {\n excludePatterns?: Partial<ExcludePatterns>;\n excludeSelectors?: string[];\n minTextLength?: number;\n debounceMs?: number;\n}\n\nexport class AutoTranslator {\n private core: LionRapidCore | null = null;\n private blockExtractor: BlockExtractor;\n private attributeExtractor: AttributeExtractor;\n private domObserver: DOMObserver | null = null;\n private locale = '';\n private sourceLocale = '';\n private namespace = '';\n private debounceMs: number;\n private pendingElements: Set<Element> = new Set();\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private translatedCount = 0;\n\n constructor(config: AutoTranslatorConfig = {}) {\n this.blockExtractor = new BlockExtractor(\n config.excludePatterns,\n config.excludeSelectors,\n config.minTextLength\n );\n this.attributeExtractor = new AttributeExtractor(\n config.excludePatterns,\n config.excludeSelectors,\n config.minTextLength\n );\n this.debounceMs = config.debounceMs ?? 100;\n }\n\n /**\n * Set the core instance\n */\n setCore(core: LionRapidCore): void {\n this.core = core;\n }\n\n /**\n * Initialize locale and namespace for cache key construction\n */\n init(config: { namespace: string; locale: string; sourceLocale: string }): void {\n this.locale = config.locale;\n this.sourceLocale = config.sourceLocale;\n this.namespace = config.namespace;\n }\n\n /**\n * Update locale (after language change)\n */\n updateLocale(locale: string): void {\n this.locale = locale;\n }\n\n /**\n * Check if ready\n */\n isReady(): boolean {\n return this.core !== null;\n }\n\n /**\n * Generate auto key for text (exposed for testing)\n */\n generateAutoKey(text: string): string {\n return generateAutoKey(text);\n }\n\n /**\n * Queue an element for translation (debounced)\n */\n queueElement(element: Element): void {\n this.pendingElements.add(element);\n this.scheduleProcessing();\n }\n\n /**\n * Translate an element immediately\n */\n translateElement(element: Element): number {\n if (!this.core) {\n return 0;\n }\n\n const blockCount = this.translateBlocks(this.blockExtractor.extract(element));\n const attrCount = this.translateAttributesIn(this.attributeExtractor.extract(element));\n return blockCount + attrCount;\n }\n\n /**\n * Translate the entire page\n */\n translatePage(): number {\n return this.translateElement(document.body);\n }\n\n /**\n * Start observing DOM for dynamic content\n */\n observe(): void {\n if (this.domObserver) {\n return;\n }\n\n this.domObserver = new DOMObserver({\n onNewContent: (element) => this.queueElement(element),\n });\n this.domObserver.start();\n }\n\n /**\n * Stop observing DOM\n */\n stopObserving(): void {\n if (this.domObserver) {\n this.domObserver.stop();\n this.domObserver = null;\n }\n }\n\n /**\n * Schedule debounced processing\n */\n private scheduleProcessing(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n this.debounceTimer = setTimeout(() => {\n this.processPendingElements();\n }, this.debounceMs);\n }\n\n /**\n * Process all pending elements\n */\n private processPendingElements(): void {\n if (!this.core || this.pendingElements.size === 0) {\n return;\n }\n\n let totalTranslated = 0;\n\n for (const element of this.pendingElements) {\n // Skip if element was removed from DOM\n if (!document.body.contains(element)) {\n continue;\n }\n\n const count = this.translateElement(element);\n totalTranslated += count;\n }\n\n this.pendingElements.clear();\n this.translatedCount += totalTranslated;\n }\n\n /**\n * Translate extracted blocks using ContentUnit model\n */\n private translateBlocks(extracted: ExtractedBlock[]): number {\n if (!this.core) return 0;\n\n let count = 0;\n\n for (const { element, unit, key } of extracted) {\n // Construct full cache key: locale:namespace:key\n const fullKey = `${this.locale}:${this.namespace}:${key}`;\n\n // Look up translation from cache\n const cached = this.core.cache.get(fullKey);\n\n if (cached && cached.value !== unit.text && cached.value !== key) {\n // Translation found \u2014 save original HTML before first translation\n if (!element.hasAttribute('data-lr-original')) {\n element.setAttribute('data-lr-original', element.innerHTML);\n }\n\n // Source styles win when the cached translation lacks them. Mirrors\n // the edge proxy's `{...translation.styles, ...source.styles}` merge\n // so a stale plain-text cache entry can't strip inline wrappers\n // (`<span class=\"...\">`, `<b>`, `<a>`) that the source has.\n const cacheHasStyles = cached.styles && Object.keys(cached.styles).length > 0;\n const sourceHasStyles = Object.keys(unit.styles).length > 0;\n const hasIndexedMarkers = /<\\/?[0-9]+\\/?>/.test(cached.value);\n\n if (sourceHasStyles && !hasIndexedMarkers) {\n // Cache value is missing the indexed-tag structure needed to\n // re-attach the source styles. Don't clobber the DOM \u2014 leave\n // whatever's currently rendered (e.g. edge-rendered styled HTML)\n // and just mark the element so we don't reprocess it.\n } else {\n const styles = cacheHasStyles ? cached.styles! : unit.styles;\n const translatedUnit: ContentUnit = { text: cached.value, styles };\n element.innerHTML = htmlSerializer.serialize(translatedUnit);\n }\n element.setAttribute('data-lr-block', key);\n element.setAttribute('data-lionrapid-client', '1');\n count++;\n } else {\n // No translation \u2014 report missing via event bus\n // MissingTranslationQueue picks this up and syncs through NetworkRepository\n this.core.bus.emit('translation:not-found', {\n payload: {\n key,\n fallbackValue: unit.text,\n locale: this.sourceLocale,\n namespace: this.namespace,\n status: 404 as const,\n styles: unit.styles,\n },\n });\n }\n }\n\n return count;\n }\n\n /**\n * Translate extracted attribute units against the cache.\n *\n * Mirrors translateBlocks but for attribute values. For each hit, the\n * original attribute value is preserved in `data-lr-orig-{name}` so\n * retranslate() can restore source. The element accumulates a comma-\n * separated `data-lionrapid-client-attrs` list naming every attr the\n * client touched \u2014 so we can find them all on retranslate without\n * iterating a fixed selector set.\n *\n * Cache misses emit `translation:not-found` with empty styles, so the\n * existing MissingTranslationQueue + NetworkRepository sync queue\n * picks them up unchanged.\n */\n private translateAttributesIn(extracted: ExtractedAttribute[]): number {\n if (!this.core) return 0;\n let count = 0;\n\n for (const { element, attrName, unit, key } of extracted) {\n const fullKey = `${this.locale}:${this.namespace}:${key}`;\n const cached = this.core.cache.get(fullKey);\n\n if (cached && cached.value !== unit.text && cached.value !== key) {\n const lower = attrName.toLowerCase();\n const origAttr = `data-lr-orig-${lower}`;\n // Preserve the source value the first time we touch this attr,\n // so retranslate() can restore it even after multiple in-page\n // language switches.\n if (!element.hasAttribute(origAttr)) {\n element.setAttribute(origAttr, unit.text);\n }\n element.setAttribute(attrName, cached.value);\n element.setAttribute(`data-lr-attr-${lower}`, key);\n\n // Append to the client-attrs list (dedup so multiple passes\n // don't grow it without bound).\n const existing = element.getAttribute('data-lionrapid-client-attrs') ?? '';\n const set = new Set(existing.split(',').filter(Boolean));\n set.add(lower);\n element.setAttribute('data-lionrapid-client-attrs', Array.from(set).join(','));\n\n count++;\n } else {\n this.core.bus.emit('translation:not-found', {\n payload: {\n key,\n fallbackValue: unit.text,\n locale: this.sourceLocale,\n namespace: this.namespace,\n status: 404 as const,\n styles: {},\n },\n });\n }\n }\n\n return count;\n }\n\n /**\n * Get translated count\n */\n getTranslatedCount(): number {\n return this.translatedCount;\n }\n\n /**\n * Restore every client-translated attribute on `el` from its\n * `data-lr-orig-*` backup, then strip the stamps. Mirrors the block-side\n * restoration in retranslate() so language switch / editor reset clears\n * attributes too.\n */\n private restoreClientAttributes(el: Element): void {\n const list = el.getAttribute('data-lionrapid-client-attrs');\n if (list === null) return;\n for (const name of list.split(',').filter(Boolean)) {\n const orig = el.getAttribute(`data-lr-orig-${name}`);\n if (orig !== null) {\n el.setAttribute(name, orig);\n el.removeAttribute(`data-lr-orig-${name}`);\n }\n el.removeAttribute(`data-lr-attr-${name}`);\n }\n el.removeAttribute('data-lionrapid-client-attrs');\n }\n\n /**\n * Re-translate a single element (for editor live preview reset)\n */\n retranslateElement(element: Element): void {\n const original = element.getAttribute('data-lr-original');\n if (original !== null) element.innerHTML = original;\n element.removeAttribute('data-lionrapid-client');\n element.removeAttribute('data-lr-block');\n this.restoreClientAttributes(element);\n this.translateElement(element);\n }\n\n /**\n * Re-translate the page (after language change)\n */\n retranslate(): void {\n // Restore original HTML for all previously translated blocks\n const translatedBlocks = document.querySelectorAll('[data-lionrapid-client]');\n translatedBlocks.forEach((el) => {\n const original = el.getAttribute('data-lr-original');\n if (original !== null) {\n el.innerHTML = original;\n }\n el.removeAttribute('data-lionrapid-client');\n el.removeAttribute('data-lr-block');\n });\n\n // Restore source values for client-translated attributes. Selector\n // matches the marker the attribute pass writes; per-name lists live\n // inside that attribute so we don't need a fixed selector per kind.\n const translatedAttrs = document.querySelectorAll('[data-lionrapid-client-attrs]');\n translatedAttrs.forEach((el) => this.restoreClientAttributes(el));\n\n // Re-translate (blocks are now back to source text, so auto_keys will be correct)\n this.translatedCount = 0;\n if (this.locale !== this.sourceLocale) {\n this.translatePage();\n }\n }\n}\n", "/**\n * Language Switcher\n * Auto-generates floating language switcher UI from data-lionrapid-switcher attributes.\n * All styles are fixed-position overlays \u2014 the style only changes the visual appearance.\n *\n * Styles:\n * - floating: button showing current language \u2192 click opens dropdown menu\n * - buttons: row of language code buttons (EN, ES, FR)\n * - flags: row of flag + name buttons\n */\n\nimport type { LionRapidCore } from '../lionRapid.js';\n\nexport type SwitcherStyle = 'flags' | 'buttons' | 'floating';\n\nexport interface Language {\n code: string;\n name: string;\n flag?: string;\n}\n\n// Default language data (expandable)\nconst DEFAULT_LANGUAGES: Record<string, Language> = {\n en: { code: 'en', name: 'English', flag: '\uD83C\uDDEC\uD83C\uDDE7' },\n es: { code: 'es', name: 'Espa\u00F1ol', flag: '\uD83C\uDDEA\uD83C\uDDF8' },\n fr: { code: 'fr', name: 'Fran\u00E7ais', flag: '\uD83C\uDDEB\uD83C\uDDF7' },\n de: { code: 'de', name: 'Deutsch', flag: '\uD83C\uDDE9\uD83C\uDDEA' },\n it: { code: 'it', name: 'Italiano', flag: '\uD83C\uDDEE\uD83C\uDDF9' },\n pt: { code: 'pt', name: 'Portugu\u00EAs', flag: '\uD83C\uDDF5\uD83C\uDDF9' },\n nl: { code: 'nl', name: 'Nederlands', flag: '\uD83C\uDDF3\uD83C\uDDF1' },\n pl: { code: 'pl', name: 'Polski', flag: '\uD83C\uDDF5\uD83C\uDDF1' },\n ru: { code: 'ru', name: '\u0420\u0443\u0441\u0441\u043A\u0438\u0439', flag: '\uD83C\uDDF7\uD83C\uDDFA' },\n ja: { code: 'ja', name: '\u65E5\u672C\u8A9E', flag: '\uD83C\uDDEF\uD83C\uDDF5' },\n ko: { code: 'ko', name: '\uD55C\uAD6D\uC5B4', flag: '\uD83C\uDDF0\uD83C\uDDF7' },\n zh: { code: 'zh', name: '\u4E2D\u6587', flag: '\uD83C\uDDE8\uD83C\uDDF3' },\n ar: { code: 'ar', name: '\u0627\u0644\u0639\u0631\u0628\u064A\u0629', flag: '\uD83C\uDDF8\uD83C\uDDE6' },\n hi: { code: 'hi', name: '\u0939\u093F\u0928\u094D\u0926\u0940', flag: '\uD83C\uDDEE\uD83C\uDDF3' },\n tr: { code: 'tr', name: 'T\u00FCrk\u00E7e', flag: '\uD83C\uDDF9\uD83C\uDDF7' },\n vi: { code: 'vi', name: 'Ti\u1EBFng Vi\u1EC7t', flag: '\uD83C\uDDFB\uD83C\uDDF3' },\n th: { code: 'th', name: '\u0E44\u0E17\u0E22', flag: '\uD83C\uDDF9\uD83C\uDDED' },\n sv: { code: 'sv', name: 'Svenska', flag: '\uD83C\uDDF8\uD83C\uDDEA' },\n da: { code: 'da', name: 'Dansk', flag: '\uD83C\uDDE9\uD83C\uDDF0' },\n fi: { code: 'fi', name: 'Suomi', flag: '\uD83C\uDDEB\uD83C\uDDEE' },\n no: { code: 'no', name: 'Norsk', flag: '\uD83C\uDDF3\uD83C\uDDF4' },\n cs: { code: 'cs', name: '\u010Ce\u0161tina', flag: '\uD83C\uDDE8\uD83C\uDDFF' },\n el: { code: 'el', name: '\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC', flag: '\uD83C\uDDEC\uD83C\uDDF7' },\n he: { code: 'he', name: '\u05E2\u05D1\u05E8\u05D9\u05EA', flag: '\uD83C\uDDEE\uD83C\uDDF1' },\n id: { code: 'id', name: 'Bahasa Indonesia', flag: '\uD83C\uDDEE\uD83C\uDDE9' },\n ms: { code: 'ms', name: 'Bahasa Melayu', flag: '\uD83C\uDDF2\uD83C\uDDFE' },\n uk: { code: 'uk', name: '\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430', flag: '\uD83C\uDDFA\uD83C\uDDE6' },\n ro: { code: 'ro', name: 'Rom\u00E2n\u0103', flag: '\uD83C\uDDF7\uD83C\uDDF4' },\n hu: { code: 'hu', name: 'Magyar', flag: '\uD83C\uDDED\uD83C\uDDFA' },\n sk: { code: 'sk', name: 'Sloven\u010Dina', flag: '\uD83C\uDDF8\uD83C\uDDF0' },\n bg: { code: 'bg', name: '\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438', flag: '\uD83C\uDDE7\uD83C\uDDEC' },\n hr: { code: 'hr', name: 'Hrvatski', flag: '\uD83C\uDDED\uD83C\uDDF7' },\n sr: { code: 'sr', name: '\u0421\u0440\u043F\u0441\u043A\u0438', flag: '\uD83C\uDDF7\uD83C\uDDF8' },\n sl: { code: 'sl', name: 'Sloven\u0161\u010Dina', flag: '\uD83C\uDDF8\uD83C\uDDEE' },\n lt: { code: 'lt', name: 'Lietuvi\u0173', flag: '\uD83C\uDDF1\uD83C\uDDF9' },\n lv: { code: 'lv', name: 'Latvie\u0161u', flag: '\uD83C\uDDF1\uD83C\uDDFB' },\n et: { code: 'et', name: 'Eesti', flag: '\uD83C\uDDEA\uD83C\uDDEA' },\n};\n\n// All switcher styles are floating overlays \u2014 position: fixed with configurable corner\nconst STYLES = `\n.lionrapid-switcher {\n position: fixed;\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n}\n.lionrapid-switcher[data-position=\"top-left\"] { top: 20px; left: 20px; }\n.lionrapid-switcher[data-position=\"top-right\"] { top: 20px; right: 20px; }\n.lionrapid-switcher[data-position=\"bottom-left\"] { bottom: 20px; left: 20px; }\n.lionrapid-switcher[data-position=\"bottom-right\"] { bottom: 20px; right: 20px; }\n\n/* Floating style: button + dropdown menu */\n.lionrapid-floating-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 16px;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n font-size: 14px;\n color: #333;\n}\n.lionrapid-floating-menu {\n display: none;\n position: absolute;\n margin: 4px 0;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n overflow: hidden;\n min-width: 150px;\n}\n.lionrapid-floating-menu.open { display: block; }\n.lionrapid-floating-menu button {\n display: block;\n width: 100%;\n padding: 8px 16px;\n text-align: left;\n background: none;\n border: none;\n cursor: pointer;\n color: #333;\n white-space: nowrap;\n font-size: 14px;\n}\n.lionrapid-floating-menu button:hover { background: #f5f5f5; }\n.lionrapid-floating-menu button.active { font-weight: 700; background: #f0f0f0; }\n\n/* Buttons + Flags styles: row of buttons */\n.lionrapid-btn-row {\n display: flex;\n gap: 0;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n overflow: hidden;\n}\n.lionrapid-btn-row button {\n padding: 8px 12px;\n font-size: 14px;\n border: none;\n border-right: 1px solid #eee;\n background: #fff;\n cursor: pointer;\n color: #333;\n white-space: nowrap;\n transition: background 0.15s;\n}\n.lionrapid-btn-row button:last-child { border-right: none; }\n.lionrapid-btn-row button:hover { background: #f5f5f5; }\n.lionrapid-btn-row button.active { background: #3b82f6; color: #fff; }\n`;\n\nexport class LanguageSwitcher {\n private core: LionRapidCore | null = null;\n private languages: Language[] = [];\n private initialLocale = 'en';\n private onLanguageChange: ((locale: string) => void) | null = null;\n private stylesInjected = false;\n\n constructor() {}\n\n /**\n * Set the core instance\n */\n setCore(core: LionRapidCore): void {\n this.core = core;\n }\n\n /**\n * Set initial locale (used before core is available)\n */\n setInitialLocale(locale: string): void {\n this.initialLocale = locale;\n }\n\n /**\n * Set available languages\n */\n setLanguages(languages: Language[] | string[]): void {\n this.languages = languages.map((lang) => {\n if (typeof lang === 'string') {\n return DEFAULT_LANGUAGES[lang] || { code: lang, name: lang };\n }\n return lang;\n });\n }\n\n /**\n * Set callback for language changes\n */\n setOnLanguageChange(callback: (locale: string) => void): void {\n this.onLanguageChange = callback;\n }\n\n /**\n * Initialize all switchers on the page\n */\n initAll(): void {\n this.injectStyles();\n const switchers = document.querySelectorAll('[data-lionrapid-switcher]');\n switchers.forEach((element) => this.initSwitcher(element as HTMLElement));\n }\n\n /**\n * Initialize a single switcher element\n */\n initSwitcher(element: HTMLElement): void {\n const style = (element.dataset.lionrapidSwitcher || 'floating') as SwitcherStyle;\n const currentLocale = this.core?.getCurrentLocale() || this.initialLocale;\n\n // Clear existing content\n element.innerHTML = '';\n element.classList.add('lionrapid-switcher');\n element.setAttribute('data-no-translate', '');\n element.setAttribute('translate', 'no');\n\n // Read config from data attributes\n const position = element.dataset.lionrapidSwitcherPosition || 'top-right';\n const showFlags = element.dataset.lionrapidSwitcherShowFlags !== 'false';\n const showNames = element.dataset.lionrapidSwitcherShowNames !== 'false';\n const customCss = element.dataset.lionrapidSwitcherCustomCss || null;\n\n // Set position for CSS\n element.dataset.position = position;\n\n // Inject custom CSS if provided\n if (customCss) {\n const styleEl = document.createElement('style');\n styleEl.textContent = customCss;\n document.head.appendChild(styleEl);\n }\n\n switch (style) {\n case 'flags':\n this.renderButtonRow(element, currentLocale, true, true);\n break;\n case 'buttons':\n this.renderButtonRow(element, currentLocale, showFlags, showNames);\n break;\n case 'floating':\n default:\n this.renderFloating(element, currentLocale, position, showFlags, showNames);\n break;\n }\n }\n\n /**\n * Render floating style (button showing current language \u2192 click opens dropdown menu)\n */\n private renderFloating(\n container: HTMLElement,\n currentLocale: string,\n position: string,\n showFlags: boolean,\n showNames: boolean,\n ): void {\n // Menu position: anchor above or below button, left or right aligned\n const menuStyle: Partial<CSSStyleDeclaration> = {};\n if (position.startsWith('bottom')) {\n menuStyle.bottom = '100%';\n } else {\n menuStyle.top = '100%';\n }\n if (position.endsWith('left')) {\n menuStyle.left = '0';\n } else {\n menuStyle.right = '0';\n }\n\n const formatLabel = (lang: Language): string => {\n const flag = showFlags ? (lang.flag || '') : '';\n const name = showNames ? lang.name : lang.code.toUpperCase();\n return `${flag}${flag && name ? ' ' : ''}${name}`;\n };\n\n // Current language display\n const currentLang = this.languages.find((l) => l.code === currentLocale) || this.languages[0];\n const currentLabel = currentLang ? formatLabel(currentLang) : currentLocale;\n\n // Button\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'lionrapid-floating-btn';\n btn.setAttribute('aria-expanded', 'false');\n btn.setAttribute('aria-haspopup', 'true');\n btn.textContent = `${currentLabel} \\u25BE`;\n\n // Menu\n const menu = document.createElement('div');\n menu.className = 'lionrapid-floating-menu';\n Object.assign(menu.style, menuStyle);\n\n for (const lang of this.languages) {\n const item = document.createElement('button');\n item.type = 'button';\n item.dataset.lang = lang.code;\n item.textContent = formatLabel(lang);\n if (lang.code === currentLocale) {\n item.classList.add('active');\n }\n item.addEventListener('click', () => {\n this.handleLanguageChange(lang.code);\n btn.textContent = formatLabel(lang) + ' \\u25BE';\n menu.querySelectorAll('button').forEach((b) => {\n b.classList.toggle('active', b.dataset.lang === lang.code);\n });\n menu.classList.remove('open');\n btn.setAttribute('aria-expanded', 'false');\n });\n menu.appendChild(item);\n }\n\n // Toggle menu on button click\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n const isOpen = menu.classList.contains('open');\n menu.classList.toggle('open', !isOpen);\n btn.setAttribute('aria-expanded', String(!isOpen));\n });\n\n // Close on outside click\n document.addEventListener('click', () => {\n menu.classList.remove('open');\n btn.setAttribute('aria-expanded', 'false');\n });\n\n container.appendChild(btn);\n container.appendChild(menu);\n }\n\n /**\n * Render button row style (used for both \"buttons\" and \"flags\")\n */\n private renderButtonRow(\n container: HTMLElement,\n currentLocale: string,\n showFlags: boolean,\n showNames: boolean,\n ): void {\n const row = document.createElement('div');\n row.className = 'lionrapid-btn-row';\n\n for (const lang of this.languages) {\n const button = document.createElement('button');\n button.type = 'button';\n button.dataset.lang = lang.code;\n\n const flag = showFlags ? (lang.flag || '') : '';\n const name = showNames ? lang.name : lang.code.toUpperCase();\n button.textContent = `${flag}${flag && name ? ' ' : ''}${name}`;\n\n if (lang.code === currentLocale) {\n button.classList.add('active');\n }\n\n button.addEventListener('click', () => {\n this.handleLanguageChange(lang.code);\n row.querySelectorAll('button').forEach((btn) => {\n btn.classList.toggle('active', btn.dataset.lang === lang.code);\n });\n });\n\n row.appendChild(button);\n }\n\n container.appendChild(row);\n }\n\n /**\n * Handle language change \u2014 update all switchers on page + fire callback\n */\n private handleLanguageChange(locale: string): void {\n if (this.onLanguageChange) {\n this.onLanguageChange(locale);\n }\n\n // Update all button row states\n document.querySelectorAll('.lionrapid-btn-row button').forEach((btn) => {\n const button = btn as HTMLButtonElement;\n button.classList.toggle('active', button.dataset.lang === locale);\n });\n }\n\n /**\n * Inject minimal styles\n */\n private injectStyles(): void {\n if (this.stylesInjected) return;\n\n const styleElement = document.createElement('style');\n styleElement.textContent = STYLES;\n document.head.appendChild(styleElement);\n this.stylesInjected = true;\n }\n\n /**\n * Get language info by code\n */\n static getLanguage(code: string): Language | undefined {\n return DEFAULT_LANGUAGES[code];\n }\n}\n", "/**\n * LocalStorage Repository for persistent cache (Browser Bundle Version)\n * Implements ISyncRepository for synchronous access to localStorage\n */\n\nimport type {\n ISyncRepository,\n IStatsProvider,\n} from '../../interfaces/repository.interface.js';\nimport type { MemoryRepositoryConfig } from '../../config/repository.config.js';\nimport type { TranslationData } from '../../types/translation-data.types.js';\n\nconst STORAGE_PREFIX = 'lionrapid:';\nconst VERSION_KEY = `${STORAGE_PREFIX}version`;\nconst CURRENT_VERSION = '1';\n\n/**\n * Stored item structure with TTL support\n */\ninterface StoredItem {\n value: string;\n expiry: number | null;\n timestamp: number;\n}\n\n/**\n * Configuration options for LocalStorageRepository\n */\nexport interface LocalStorageRepositoryConfig extends MemoryRepositoryConfig {\n options?: MemoryRepositoryConfig['options'] & {\n prefix?: string;\n ttl?: number;\n maxSize?: number;\n };\n}\n\n/**\n * LocalStorage-based repository for persistent translation caching\n */\nexport class LocalStorageRepository\n implements ISyncRepository<LocalStorageRepositoryConfig>, IStatsProvider\n{\n readonly name = 'LocalStorageRepository';\n readonly type = 'memory' as const;\n readonly config: LocalStorageRepositoryConfig;\n\n private available: boolean;\n private prefix: string;\n private defaultTTL: number;\n private maxSize: number;\n\n constructor(config: LocalStorageRepositoryConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n priority: config.priority ?? 0,\n options: {\n prefix: config.options?.prefix ?? STORAGE_PREFIX,\n ttl: config.options?.ttl ?? 24 * 60 * 60 * 1000,\n maxSize: config.options?.maxSize ?? 500,\n ...config.options,\n },\n };\n\n this.prefix = this.config.options?.prefix ?? STORAGE_PREFIX;\n this.defaultTTL = this.config.options?.ttl ?? 24 * 60 * 60 * 1000;\n this.maxSize = this.config.options?.maxSize ?? 500;\n this.available = this.checkAvailability();\n\n if (this.available) {\n this.migrateIfNeeded();\n }\n }\n\n private checkAvailability(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n const testKey = `${this.prefix}__test__`;\n window.localStorage.setItem(testKey, 'test');\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n\n private migrateIfNeeded(): void {\n try {\n const storedVersion = window.localStorage.getItem(VERSION_KEY);\n if (storedVersion !== CURRENT_VERSION) {\n this.clear();\n window.localStorage.setItem(VERSION_KEY, CURRENT_VERSION);\n }\n } catch {\n // Ignore migration errors\n }\n }\n\n get(key: string): string | null {\n if (!this.available) return null;\n\n try {\n const fullKey = this.prefix + key;\n const itemStr = window.localStorage.getItem(fullKey);\n if (!itemStr) return null;\n\n const item: StoredItem = JSON.parse(itemStr);\n\n if (item.expiry !== null && Date.now() > item.expiry) {\n window.localStorage.removeItem(fullKey);\n return null;\n }\n\n return item.value;\n } catch {\n return null;\n }\n }\n\n set(key: string, value: string): void {\n if (!this.available) return;\n\n const fullKey = this.prefix + key;\n const item: StoredItem = {\n value,\n expiry: this.defaultTTL ? Date.now() + this.defaultTTL : null,\n timestamp: Date.now(),\n };\n\n try {\n const entryCount = this.getEntryCount();\n if (entryCount >= this.maxSize) {\n this.evictOldest();\n }\n\n window.localStorage.setItem(fullKey, JSON.stringify(item));\n } catch (error) {\n if (this.isQuotaError(error)) {\n this.evictOldest();\n try {\n window.localStorage.setItem(fullKey, JSON.stringify(item));\n } catch {\n // Give up silently\n }\n }\n }\n }\n\n remove(key: string): void {\n if (!this.available) return;\n\n try {\n window.localStorage.removeItem(this.prefix + key);\n } catch {\n // Ignore removal errors\n }\n }\n\n clear(): void {\n if (!this.available) return;\n\n try {\n const keysToRemove: string[] = [];\n for (let i = 0; i < window.localStorage.length; i++) {\n const key = window.localStorage.key(i);\n if (key?.startsWith(this.prefix) && key !== VERSION_KEY) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach((k) => window.localStorage.removeItem(k));\n } catch {\n // Ignore clear errors\n }\n }\n\n clearNamespace(locale: string, namespace: string): void {\n if (!this.available) return;\n\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const keyPrefix = `${locale}:${namespace}:`;\n\n try {\n const keysToRemove: string[] = [];\n for (let i = 0; i < window.localStorage.length; i++) {\n const key = window.localStorage.key(i);\n if (!key?.startsWith(this.prefix)) continue;\n\n const innerKey = key.slice(this.prefix.length);\n if (innerKey === namespaceCacheKey || innerKey.startsWith(keyPrefix)) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach((k) => window.localStorage.removeItem(k));\n } catch {\n // Ignore errors\n }\n }\n\n getNamespace(locale: string, namespace: string): TranslationData | null {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const value = this.get(namespaceCacheKey);\n if (!value) return null;\n\n try {\n return JSON.parse(value);\n } catch {\n this.remove(namespaceCacheKey);\n return null;\n }\n }\n\n setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): void {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n this.set(namespaceCacheKey, JSON.stringify(translations));\n }\n\n getEntries(): Record<string, string> {\n const entries: Record<string, string> = {};\n if (!this.available) return entries;\n\n try {\n for (let i = 0; i < window.localStorage.length; i++) {\n const fullKey = window.localStorage.key(i);\n if (!fullKey?.startsWith(this.prefix) || fullKey === VERSION_KEY) {\n continue;\n }\n\n const key = fullKey.slice(this.prefix.length);\n const value = this.get(key);\n if (value !== null) {\n entries[key] = value;\n }\n }\n } catch {\n // Ignore errors\n }\n\n return entries;\n }\n\n getConfig(): LocalStorageRepositoryConfig {\n return this.config;\n }\n\n isAvailable(): boolean {\n return this.available;\n }\n\n private getEntryCount(): number {\n if (!this.available) return 0;\n\n let count = 0;\n try {\n for (let i = 0; i < window.localStorage.length; i++) {\n const key = window.localStorage.key(i);\n if (key?.startsWith(this.prefix) && key !== VERSION_KEY) {\n count++;\n }\n }\n } catch {\n // Ignore errors\n }\n\n return count;\n }\n\n private isQuotaError(error: unknown): boolean {\n if (error instanceof DOMException) {\n return (\n error.name === 'QuotaExceededError' ||\n error.name === 'NS_ERROR_DOM_QUOTA_REACHED'\n );\n }\n return false;\n }\n\n private evictOldest(): void {\n if (!this.available) return;\n\n try {\n const entries: Array<{ key: string; timestamp: number }> = [];\n\n for (let i = 0; i < window.localStorage.length; i++) {\n const fullKey = window.localStorage.key(i);\n if (!fullKey?.startsWith(this.prefix) || fullKey === VERSION_KEY) {\n continue;\n }\n\n try {\n const itemStr = window.localStorage.getItem(fullKey);\n if (itemStr) {\n const item: StoredItem = JSON.parse(itemStr);\n entries.push({ key: fullKey, timestamp: item.timestamp });\n }\n } catch {\n window.localStorage.removeItem(fullKey);\n }\n }\n\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n const removeCount = Math.max(1, Math.floor(entries.length * 0.25));\n for (let i = 0; i < removeCount && i < entries.length; i++) {\n window.localStorage.removeItem(entries[i].key);\n }\n } catch {\n // Ignore eviction errors\n }\n }\n\n getCacheStats(): { size: number; maxSize: number; usage: string } {\n const size = this.getEntryCount();\n const usage =\n this.maxSize > 0 ? `${Math.round((size / this.maxSize) * 100)}%` : '0%';\n\n return {\n size,\n maxSize: this.maxSize,\n usage,\n };\n }\n}\n", "/**\n * CacheStorageRepository - Cache API-based persistent storage (Browser Bundle Version)\n * Implements IAsyncRepository for asynchronous access to Cache API\n */\n\nimport type { IAsyncRepository } from '../../interfaces/repository.interface.js';\nimport type { StorageRepositoryConfig } from '../../config/repository.config.js';\nimport type { TranslationData } from '../../types/translation-data.types.js';\nimport { TranslationNotFoundError } from '../../errors/translation-errors.js';\n\nconst CACHE_NAME = 'lionrapid-v1';\nconst CACHE_PREFIX = 'lionrapid:';\n\n/**\n * Stored item structure with TTL support\n */\ninterface StoredItem {\n value: string;\n expiry: number | null;\n timestamp: number;\n}\n\n/**\n * Configuration options for CacheStorageRepository\n */\nexport interface CacheStorageRepositoryConfig extends StorageRepositoryConfig {\n options?: StorageRepositoryConfig['options'] & {\n cacheName?: string;\n ttl?: number;\n };\n}\n\n/**\n * Cache API-based repository for persistent translation caching\n */\nexport class CacheStorageRepository\n implements IAsyncRepository<CacheStorageRepositoryConfig>\n{\n readonly name = 'CacheStorageRepository';\n readonly type = 'storage' as const;\n readonly config: CacheStorageRepositoryConfig;\n\n private cacheName: string;\n private defaultTTL: number;\n private available: boolean;\n\n constructor(config: CacheStorageRepositoryConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n priority: config.priority ?? 0,\n options: {\n cacheName: config.options?.cacheName ?? CACHE_NAME,\n ttl: config.options?.ttl ?? 7 * 24 * 60 * 60 * 1000,\n ...config.options,\n },\n };\n\n this.cacheName = this.config.options?.cacheName ?? CACHE_NAME;\n this.defaultTTL = this.config.options?.ttl ?? 7 * 24 * 60 * 60 * 1000;\n this.available = this.checkAvailability();\n }\n\n private checkAvailability(): boolean {\n return typeof caches !== 'undefined';\n }\n\n async get(key: string): Promise<string> {\n if (!this.available) {\n throw new TranslationNotFoundError(key);\n }\n\n try {\n const cache = await caches.open(this.cacheName);\n const response = await cache.match(CACHE_PREFIX + key);\n\n if (!response) {\n throw new TranslationNotFoundError(key);\n }\n\n const data: StoredItem = await response.json();\n\n if (data.expiry !== null && Date.now() > data.expiry) {\n await cache.delete(CACHE_PREFIX + key);\n throw new TranslationNotFoundError(key);\n }\n\n return data.value;\n } catch (error) {\n if (error instanceof TranslationNotFoundError) {\n throw error;\n }\n throw new TranslationNotFoundError(key);\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n if (!this.available) return;\n\n try {\n const cache = await caches.open(this.cacheName);\n const data: StoredItem = {\n value,\n expiry: this.defaultTTL ? Date.now() + this.defaultTTL : null,\n timestamp: Date.now(),\n };\n\n await cache.put(\n CACHE_PREFIX + key,\n new Response(JSON.stringify(data), {\n headers: { 'Content-Type': 'application/json' },\n })\n );\n } catch {\n // Silently fail - cache is non-critical\n }\n }\n\n async remove(key: string): Promise<void> {\n if (!this.available) return;\n\n try {\n const cache = await caches.open(this.cacheName);\n await cache.delete(CACHE_PREFIX + key);\n } catch {\n // Silently fail\n }\n }\n\n async clear(): Promise<void> {\n if (!this.available) return;\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n\n await Promise.all(\n keys\n .filter((request) => request.url.includes(CACHE_PREFIX))\n .map((request) => cache.delete(request))\n );\n } catch {\n // Silently fail\n }\n }\n\n async clearNamespace(locale: string, namespace: string): Promise<void> {\n if (!this.available) return;\n\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const keyPrefix = `${locale}:${namespace}:`;\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n\n await Promise.all(\n keys\n .filter((request) => {\n const url = request.url;\n const key = url.includes(CACHE_PREFIX)\n ? url.substring(url.indexOf(CACHE_PREFIX) + CACHE_PREFIX.length)\n : '';\n return key === namespaceCacheKey || key.startsWith(keyPrefix);\n })\n .map((request) => cache.delete(request))\n );\n } catch {\n // Silently fail\n }\n }\n\n async getNamespace(\n locale: string,\n namespace: string\n ): Promise<TranslationData> {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const value = await this.get(namespaceCacheKey);\n\n try {\n return JSON.parse(value);\n } catch {\n await this.remove(namespaceCacheKey);\n throw new TranslationNotFoundError(namespaceCacheKey);\n }\n }\n\n async setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): Promise<void> {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n await this.set(namespaceCacheKey, JSON.stringify(translations));\n }\n\n getConfig(): CacheStorageRepositoryConfig {\n return this.config;\n }\n\n isAvailable(): boolean {\n return this.available;\n }\n\n async getEntries(): Promise<Record<string, string>> {\n const entries: Record<string, string> = {};\n if (!this.available) return entries;\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n\n for (const request of keys) {\n const url = request.url;\n if (!url.includes(CACHE_PREFIX)) continue;\n\n const key = url.substring(\n url.indexOf(CACHE_PREFIX) + CACHE_PREFIX.length\n );\n try {\n const value = await this.get(key);\n entries[key] = value;\n } catch {\n // Skip expired or invalid entries\n }\n }\n } catch {\n // Silently fail\n }\n\n return entries;\n }\n\n async getCacheStats(): Promise<{ size: number; cacheName: string }> {\n if (!this.available) {\n return { size: 0, cacheName: this.cacheName };\n }\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n const size = keys.filter((r) => r.url.includes(CACHE_PREFIX)).length;\n\n return { size, cacheName: this.cacheName };\n } catch {\n return { size: 0, cacheName: this.cacheName };\n }\n }\n}\n", "/**\n * Auto-Init for Browser Bundle\n * Reads script tag attributes and auto-configures LionRapid\n *\n * Usage:\n * <script\n * src=\"https://cdn.lionrapid.com/lionrapid.min.js\"\n * data-api-key=\"pk_live_xxx\"\n * data-default-locale=\"en\"\n * data-namespace=\"default\"\n * data-languages=\"en,es,fr,de\"\n * ></script>\n */\n\nimport { LionRapidBuilder } from '../builder.js';\nimport { MemoryRepository } from '../repositories/memory-repository.js';\nimport { NetworkRepository } from '../repositories/network-repository.js';\nimport { AutoTranslator } from './auto-translator.js';\nimport { LanguageSwitcher } from './language-switcher.js';\nimport { LocalStorageRepository } from './storage/localstorage-repository.js';\nimport { CacheStorageRepository } from './storage/cache-storage-repository.js';\nimport {\n matchLocale,\n normalizeLocale,\n localeDir,\n LOCALE_TAG_REGEX,\n} from '../utils/locale.js';\n\nexport interface AutoInitConfig {\n apiKey: string;\n baseUrl: string;\n defaultLocale: string;\n namespace: string;\n languages: string[];\n excludeSelectors: string[];\n autoDetect: boolean;\n mode: 'full' | 'dynamic-only';\n switcherStyle?: string;\n switcherPosition?: string;\n switcherShowFlags?: boolean;\n switcherShowNames?: boolean;\n switcherCustomCss?: string;\n /** Override for the visual editor bundle URL. Defaults to the public CDN.\n * Self-hosted hosts (e.g. the WordPress plugin) point this at their own\n * vendored copy so the editor is version-locked to the host, not the CDN. */\n editorCdnUrl?: string;\n /** Offline resilience: add a never-expiring \"last known good\" cache layer that\n * is hydrated by successful fetches, so the site keeps translating with the\n * server down even after the normal caches expire. Default on; disable with\n * `data-offline=\"false\"`. */\n offline?: boolean;\n}\n\ndeclare global {\n interface Window {\n LionRapid: LionRapidInstance | undefined;\n __lionrapidConfig?: AutoInitConfig;\n }\n}\n\n/**\n * Write policy for a browser-embedded key.\n *\n * A publishable `pk_` key gets the DISCOVERY path only: page views sync\n * missing source strings so rows appear in the dashboard (the server's\n * `_SYNC_KEYS` explicitly allows publishable keys on /sync). It can never\n * write translations \u2014 the server restricts those to master/editor-session\n * keys (`_WRITE_KEYS`), which is what actually blocks the stored-XSS loop.\n *\n * Anything that isn't a pk_ key is a secret shipped to the page: it still\n * runs, but fully read-only, and is flagged so the integrator notices.\n */\nexport function resolveWritePolicy(apiKey: string): {\n syncMissing: { enabled: boolean };\n warnReadOnly: boolean;\n} {\n const isPublishable = apiKey.startsWith('pk_');\n return {\n syncMissing: { enabled: isPublishable },\n warnReadOnly: !isPublishable,\n };\n}\n\n/**\n * The config copy mirrored to `window.__lionrapidConfig` for the editor\n * bundle \u2014 with the API key stripped. The key must never sit on `window`\n * where any third-party script on the page could read it; the editor only\n * needs languages/namespace/locale from here.\n */\nexport function configForWindow(config: AutoInitConfig): AutoInitConfig {\n return { ...config, apiKey: '' };\n}\n\n/**\n * Switcher change-handling that survives the boot window. `build()` can take\n * seconds under a failing network (retry backoff); a click in that window\n * must not be silently dropped. The cookie is written and dynamic-only\n * navigation happens immediately (neither needs core); in full mode a click\n * before `attach` is remembered (last one wins) and replayed the moment the\n * core-bound apply function is attached.\n */\nexport function createDeferredLocaleHandler(effects: {\n setCookie: (locale: string) => void;\n /** non-null in dynamic-only mode \u2014 navigation replaces in-place apply */\n navigate: ((locale: string) => void) | null;\n}): {\n onChange: (locale: string) => Promise<void>;\n attach: (apply: (locale: string) => Promise<void>) => void;\n} {\n let applyLocale: ((locale: string) => Promise<void>) | null = null;\n let pendingLocale: string | null = null;\n return {\n onChange: async (locale) => {\n effects.setCookie(locale);\n if (effects.navigate) {\n effects.navigate(locale);\n return;\n }\n if (applyLocale) {\n await applyLocale(locale);\n return;\n }\n pendingLocale = locale;\n },\n attach: (apply) => {\n applyLocale = apply;\n if (pendingLocale !== null) {\n const replay = pendingLocale;\n pendingLocale = null;\n void apply(replay).catch(() => {});\n }\n },\n };\n}\n\n/**\n * Run `fn` once the DOM is parsed \u2014 immediately if it already is. Guards the\n * DOM-writing steps (switcher render, translatePage/observe) so a snippet\n * booted from `<head>` doesn't run them against a null `document.body`.\n * Network preload and `build()` are NOT gated \u2014 only DOM writes wait.\n */\nexport function onDomReady(fn: () => void): void {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', fn, { once: true });\n } else {\n fn();\n }\n}\n\nexport interface LionRapidInstance {\n t: (key: string, params?: Record<string, unknown>, defaultValue?: string) => string;\n tHtml: (key: string, params?: Record<string, unknown>, defaultValue?: string) => string;\n changeLanguage: (locale: string) => Promise<void>;\n getCurrentLocale: () => string;\n on: (event: string, callback: (payload: unknown) => void) => void;\n retranslate: () => void;\n reloadTranslations: () => Promise<void>;\n autoTranslator: AutoTranslator;\n languageSwitcher: LanguageSwitcher;\n}\n\n/**\n * Parse script tag attributes\n */\nfunction parseConfig(script: HTMLScriptElement): AutoInitConfig {\n const apiKey = script.dataset.apiKey || '';\n const baseUrl = script.dataset.baseUrl || 'https://api.lionrapid.com';\n const defaultLocale = script.dataset.defaultLocale || 'en';\n const namespace = script.dataset.namespace || 'default';\n const languages = (script.dataset.languages || defaultLocale)\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const excludeSelectors = (script.dataset.exclude || '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const autoDetect = script.dataset.autoDetect === 'true';\n const mode = (script.dataset.mode === 'dynamic-only' ? 'dynamic-only' : 'full') as AutoInitConfig['mode'];\n const switcherStyle = script.dataset.switcher && script.dataset.switcher !== 'false'\n ? script.dataset.switcher\n : undefined;\n const switcherPosition = script.dataset.switcherPosition || undefined;\n const switcherShowFlags = script.dataset.switcherShowFlags !== 'false';\n const switcherShowNames = script.dataset.switcherShowNames === 'true';\n const switcherCustomCss = script.dataset.switcherCustomCss || undefined;\n const editorCdnUrl = script.dataset.editorCdn || undefined;\n const offline = script.dataset.offline !== 'false';\n\n return {\n apiKey,\n baseUrl,\n defaultLocale,\n namespace,\n languages,\n excludeSelectors,\n autoDetect,\n mode,\n switcherStyle,\n switcherPosition,\n switcherShowFlags,\n switcherShowNames,\n switcherCustomCss,\n editorCdnUrl,\n offline,\n };\n}\n\n/**\n * Read the lionrapid_locale cookie and resolve it against the available\n * languages (full BCP-47 tags preserved \u2014 `pt-BR` is not chopped to `pt`).\n */\nfunction readLocaleCookie(availableLanguages: string[]): string | null {\n if (typeof document === 'undefined') return null;\n // Anchored to a cookie boundary \u2014 a foreign cookie merely containing the\n // name (e.g. `not_lionrapid_locale=de`) must not win.\n const match = document.cookie.match(\n /(?:^|;\\s*)lionrapid_locale=([a-z]{2,3}(?:-[a-z0-9]{2,4})*)/i,\n );\n if (!match) return null;\n return matchLocale([match[1]], availableLanguages, '') || null;\n}\n\n/**\n * Detect the browser's preferred language via BCP-47 negotiation.\n * `navigator.languages` is already preference-ordered; full tags survive.\n */\nfunction detectBrowserLanguage(availableLanguages: string[], defaultLocale: string): string {\n if (typeof navigator === 'undefined') return defaultLocale;\n\n const requested =\n navigator.languages && navigator.languages.length > 0\n ? [...navigator.languages]\n : [\n navigator.language ||\n (navigator as Navigator & { userLanguage?: string }).userLanguage ||\n '',\n ];\n\n return matchLocale(requested, availableLanguages, defaultLocale);\n}\n\n/**\n * Build a locale-prefixed URL (pure \u2014 no navigation). Strips an existing\n * locale prefix only when it's a known language, so a path like `/about-us/`\n * is never mistaken for a locale; full BCP-47 prefixes (`/pt-BR/\u2026`) are handled.\n * The default locale is served un-prefixed.\n */\nexport function buildLocaleUrl(\n pathname: string,\n search: string,\n locale: string,\n defaultLocale: string,\n availableLanguages: string[],\n): string {\n const segments = pathname.split('/'); // ['', 'pt-BR', 'about']\n const first = segments[1] ?? '';\n const hasLocalePrefix =\n LOCALE_TAG_REGEX.test(first) &&\n matchLocale([first], availableLanguages, '') !== '';\n const path = hasLocalePrefix ? '/' + segments.slice(2).join('/') : pathname;\n const prefix = locale === defaultLocale ? '' : '/' + locale;\n return prefix + (path || '/') + search;\n}\n\n/** Navigate to a locale-prefixed URL (dynamic-only mode). */\nfunction navigateToLocale(\n locale: string,\n defaultLocale: string,\n availableLanguages: string[],\n): void {\n window.location.href = buildLocaleUrl(\n window.location.pathname,\n window.location.search,\n locale,\n defaultLocale,\n availableLanguages,\n );\n}\n\n/**\n * Resolve the initial locale from the environment, preserving full BCP-47\n * tags. Dynamic-only trusts the server-set `<html lang>`; full mode uses\n * cookie \u2192 browser negotiation \u2192 default. Extracted so the precedence matrix\n * is testable without booting `autoInit`.\n */\nexport function resolveInitialLocale(config: AutoInitConfig): string {\n if (config.mode === 'dynamic-only') {\n const htmlLang =\n typeof document !== 'undefined' ? document.documentElement.lang : '';\n return htmlLang ? normalizeLocale(htmlLang) : config.defaultLocale;\n }\n const cookieLocale = readLocaleCookie(config.languages);\n if (cookieLocale) return cookieLocale;\n if (config.autoDetect) {\n return detectBrowserLanguage(config.languages, config.defaultLocale);\n }\n return config.defaultLocale;\n}\n\n/** Reflect the locale's text direction on `<html dir>` (RTL languages). */\nexport function applyLocaleDir(locale: string): void {\n if (typeof document !== 'undefined') {\n document.documentElement.dir = localeDir(locale);\n }\n}\n\n/**\n * The `<script data-api-key>` tag that configures this boot. Prefer the\n * script that is actually executing (valid here because autoInit runs at\n * script-eval time), so a page with several snippet tags configures from\n * the right one; fall back to the last matching tag when currentScript is\n * unavailable (module contexts, async boundaries) \u2014 flagged, since with two\n * or more candidates \"last wins\" is a silent guess.\n */\nexport function findConfigScript(): HTMLScriptElement | undefined {\n const current = document.currentScript;\n if (current instanceof HTMLScriptElement && current.dataset.apiKey) {\n return current;\n }\n const scripts = document.querySelectorAll('script[data-api-key]');\n if (scripts.length > 1) {\n console.warn(\n `[LionRapid] ${scripts.length} script tags with data-api-key found; using the last one`,\n );\n }\n return scripts[scripts.length - 1] as HTMLScriptElement | undefined;\n}\n\n/**\n * Initialize LionRapid from script tag\n */\nasync function autoInit(): Promise<void> {\n const script = findConfigScript();\n\n if (!script) {\n console.warn('[LionRapid] No script tag with data-api-key found');\n return;\n }\n\n const config = parseConfig(script);\n // Mirror config for the editor bundle, but never expose the key on window.\n window.__lionrapidConfig = configForWindow(config);\n\n if (!config.apiKey) {\n console.warn('[LionRapid] Missing data-api-key attribute');\n return;\n }\n\n // Hard gate: the browser runs read-only. A non-publishable key means a\n // secret was shipped to the page \u2014 run anyway, but flag it loudly.\n const writePolicy = resolveWritePolicy(config.apiKey);\n if (writePolicy.warnReadOnly) {\n console.error(\n '[LionRapid] data-api-key must be a publishable pk_ key; running read-only',\n );\n }\n\n // Determine initial locale\n const initialLocale = resolveInitialLocale(config);\n\n // Reflect text direction for RTL locales on <html dir> before first paint.\n applyLocaleDir(initialLocale);\n\n // Create language switcher immediately (no core dependency for rendering)\n const languageSwitcher = new LanguageSwitcher();\n languageSwitcher.setLanguages(config.languages);\n languageSwitcher.setInitialLocale(initialLocale);\n\n // Render switcher as soon as DOM is ready (don't wait for network)\n const renderSwitcher = () => {\n // In full mode, auto-create floating container from script tag config\n // In dynamic-only mode, server (WP/edge) provides the container via HTML\n if (config.mode !== 'dynamic-only') {\n if (config.switcherStyle && !document.querySelector('[data-lionrapid-switcher]')) {\n const container = document.createElement('div');\n container.dataset.lionrapidSwitcher = config.switcherStyle;\n if (config.switcherPosition) {\n container.dataset.lionrapidSwitcherPosition = config.switcherPosition;\n }\n if (!config.switcherShowFlags) {\n container.dataset.lionrapidSwitcherShowFlags = 'false';\n }\n if (!config.switcherShowNames) {\n container.dataset.lionrapidSwitcherShowNames = 'false';\n }\n if (config.switcherCustomCss) {\n container.dataset.lionrapidSwitcherCustomCss = config.switcherCustomCss;\n }\n document.body.appendChild(container);\n }\n }\n // Always init: injects CSS, hydrates any [data-lionrapid-switcher] elements\n languageSwitcher.initAll();\n };\n\n onDomReady(renderSwitcher);\n\n // Language changes are accepted from the first paint: cookie + dynamic-only\n // navigation immediately, in-place retranslation replayed once core is up.\n const localeHandler = createDeferredLocaleHandler({\n setCookie: (locale) => {\n document.cookie = `lionrapid_locale=${locale}; path=/; max-age=31536000; SameSite=Lax`;\n },\n navigate:\n config.mode === 'dynamic-only'\n ? (locale) => navigateToLocale(locale, config.defaultLocale, config.languages)\n : null,\n });\n languageSwitcher.setOnLanguageChange(localeHandler.onChange);\n\n try {\n // Build LionRapid with all cache layers\n const builder = LionRapidBuilder.init({\n defaultLocale: initialLocale,\n namespace: config.namespace,\n })\n .use(new MemoryRepository({ enabled: true }))\n .use(new LocalStorageRepository({ enabled: true }))\n .use(new CacheStorageRepository({ enabled: true }));\n\n // Offline resilience floor: a never-expiring \"last known good\" cache layer,\n // hydrated by successful fetches. Checked AFTER the TTL'd caches and BEFORE\n // the network, so the site keeps translating with the server down even once\n // the normal caches expire.\n // - ttl must be huge \u2014 the handlers treat ttl=0 as \"expire immediately\".\n // - a DISTINCT cacheName is essential: CacheStorageRepository keys by\n // cacheName (it ignores `prefix`), so without this the floor would share\n // the default store and the 7d cache's expiry would delete its entries.\n if (config.offline !== false) {\n builder.use(\n new CacheStorageRepository({\n enabled: true,\n options: {\n ttl: Number.MAX_SAFE_INTEGER,\n cacheName: 'lionrapid-offline-v1',\n },\n })\n );\n }\n\n const core = await builder\n .use(\n new NetworkRepository({\n enabled: true,\n options: {\n baseUrl: config.baseUrl,\n apiKey: config.apiKey,\n // pk_ keys sync missing source strings (discovery); anything else\n // runs read-only \u2014 see resolveWritePolicy.\n syncMissing: writePolicy.syncMissing,\n preloadNamespaces: [\n {\n locale: initialLocale,\n namespace: config.namespace,\n eager: true,\n },\n ],\n },\n })\n )\n .build();\n\n // Create auto translator\n const autoTranslator = new AutoTranslator({\n excludeSelectors: config.excludeSelectors,\n });\n autoTranslator.setCore(core);\n autoTranslator.init({\n namespace: config.namespace,\n locale: initialLocale,\n sourceLocale: config.defaultLocale,\n });\n\n // Wire up core to switcher now that it's ready; a click that arrived\n // during build() replays here.\n languageSwitcher.setCore(core);\n localeHandler.attach(async (locale) => {\n await core.changeLanguage(locale, {\n preloadNamespaces: [config.namespace],\n });\n applyLocaleDir(locale);\n autoTranslator.updateLocale(locale);\n autoTranslator.retranslate();\n });\n\n // === Reactive translation reload ===\n const RETRY_DELAYS = [2000, 8000, 30000]; // backoff: 2s, 8s, 30s\n const REVALIDATE_STALE_MS = 60_000; // 60s before background revalidation\n let hasPendingTranslations = false;\n let retryTimers: ReturnType<typeof setTimeout>[] = [];\n let lastRevalidatedAt = Date.now();\n\n const reloadTranslations = async (): Promise<void> => {\n await core.reloadNamespace(config.namespace);\n autoTranslator.translatePage();\n lastRevalidatedAt = Date.now();\n };\n\n const cancelRetries = () => {\n retryTimers.forEach(t => clearTimeout(t));\n retryTimers = [];\n };\n\n // After sync: schedule backoff retries\n core.bus.on('sync:batch:complete', () => {\n hasPendingTranslations = true;\n cancelRetries();\n RETRY_DELAYS.forEach(delay => {\n retryTimers.push(\n setTimeout(() => reloadTranslations().catch(() => {}), delay)\n );\n });\n });\n\n // On tab focus: reload if pending, or background revalidate if stale (>60s)\n // The revalidation is cheap \u2014 server returns 304 if nothing changed\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState !== 'visible') return;\n\n if (hasPendingTranslations) {\n hasPendingTranslations = false;\n cancelRetries();\n reloadTranslations().catch(() => {});\n } else if (Date.now() - lastRevalidatedAt > REVALIDATE_STALE_MS) {\n reloadTranslations().catch(() => {});\n }\n });\n\n // Expose global API\n const instance: LionRapidInstance = {\n t: (key, params, defaultValue) => core.t(key, params || {}, defaultValue),\n tHtml: (key, params, defaultValue) => core.tHtml(key, params || {}, defaultValue),\n changeLanguage: async (locale) => {\n await core.changeLanguage(locale, {\n preloadNamespaces: [config.namespace],\n });\n applyLocaleDir(locale);\n autoTranslator.updateLocale(locale);\n autoTranslator.retranslate();\n languageSwitcher.initAll();\n },\n getCurrentLocale: () => core.getCurrentLocale(),\n on: (event, callback) => core.bus.on(event as keyof typeof core.bus, callback),\n retranslate: () => autoTranslator.retranslate(),\n reloadTranslations,\n autoTranslator,\n languageSwitcher,\n };\n\n window.LionRapid = instance;\n\n // Detect editor mode (snippet case). Edge proxy and WordPress inject the\n // editor server-side, so skip if either kind of editor script is already\n // present to avoid double-loading.\n const editorParam = new URLSearchParams(window.location.search).get('__lr_editor');\n if (editorParam && !document.querySelector('script[data-grant], script[data-lr-editor]')) {\n const editorScript = document.createElement('script');\n editorScript.src = config.editorCdnUrl\n || 'https://cdn.lionrapid.com/lionrapid.editor.min.js';\n editorScript.dataset.grant = editorParam;\n editorScript.dataset.locale = core.getCurrentLocale();\n editorScript.dataset.api = config.baseUrl;\n editorScript.async = true;\n document.body.appendChild(editorScript);\n }\n\n // Start auto-translation once the DOM is ready \u2014 a <head>-script boot\n // would otherwise run translatePage()/observe() against a null\n // document.body. Core build + network preload already ran above.\n onDomReady(() => {\n if (config.mode !== 'dynamic-only') {\n autoTranslator.translatePage();\n }\n autoTranslator.observe();\n });\n } catch (error) {\n console.error('[LionRapid] Initialization failed:', error);\n }\n}\n\n// Auto-run on script load\nautoInit();\n\nexport { autoInit, parseConfig };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,MAAK,WAAL,kBAAKA,cAAL;AACL,IAAAA,oBAAA,WAAQ,KAAR;AACA,IAAAA,oBAAA,UAAO,KAAP;AACA,IAAAA,oBAAA,UAAO,KAAP;AACA,IAAAA,oBAAA,WAAQ,KAAR;AACA,IAAAA,oBAAA,UAAO,KAAP;AALU,WAAAA;AAAA,KAAA;;;ACWZ,MAAM,OACJ,OAAO,YAAY,eAAe,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAGjE,MAAM,gBAAgB,KAAK,aAAa;AACxC,MAAM,iBAAiB,KAAK,aAAa;AACzC,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,gBAAgB,KAAK,kBAAkB;AAC7C,MAAM,uBAAuB,KAAK,mCAAmC;AAQrE,WAAS,sBAAqC;AAC5C,QAAI;AACF,UAAI,OAAO,iBAAiB,aAAa;AACvC,cAAM,IAAI,aAAa,QAAQ,qBAAqB;AACpD,YAAI,KAAK,OAAO,MAAM,SAAU,QAAO;AAAA,MACzC;AAAA,IACF,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT;AASA,MAAM,gBAAgB,oBAAoB,KAAK,KAAK,aAAa;AAK1D,MAAM,SAAS;AAAA;AAAA,IAEpB,OAAO;AAAA;AAAA,IAEP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA;AAAA,IAER,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,cAAc;AAAA;AAAA,IAEd,MAAM;AAAA,IACN,KAAK;AAAA,IACL,WAAW;AAAA,EACb;AAcA,MAAM,oBAAN,MAAM,mBAAkB;AAAA,IAGtB,YAAY,SAA8B,CAAC,GAAG;AAF9C,0BAAQ;AAGN,WAAK,SAAS;AAAA,QACZ,OAAO,KAAK,mBAAmB;AAAA,QAC/B,SAAS,KAAK,oBAAoB;AAAA,QAClC,QAAQ,GAAG,OAAO,gBAAgB,WAAI,IAAI,OAAO,eAAe,WAAW;AAAA,QAC3E,iBAAiB,iBAAiB,CAAC;AAAA,QACnC,WAAW,KAAK,gBAAgB;AAAA,QAChC,GAAG;AAAA,MACL;AAAA,IACF;AAAA,IAEA,UAAU,QAAqC;AAC7C,WAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO;AAAA,IAC5C;AAAA,IAEA,MAAM,SAAiB,MAAsB;AAC3C,UAAI,CAAC,KAAK,OAAO,WAAW,KAAK,OAAO,sBAAwB;AAChE,WAAK,mBAAoB,SAAS,IAAI;AAAA,IACxC;AAAA,IAEA,KAAK,SAAiB,MAAsB;AAC1C,UAAI,KAAK,OAAO,qBAAuB;AACvC,WAAK,kBAAmB,SAAS,IAAI;AAAA,IACvC;AAAA,IAEA,KAAK,SAAiB,MAAsB;AAC1C,WAAK,kBAAmB,SAAS,IAAI;AAAA,IACvC;AAAA,IAEA,MAAM,SAAiB,MAAsB;AAC3C,WAAK,mBAAoB,SAAS,IAAI;AAAA,IACxC;AAAA,IAEA,KAAK,OAA2B;AAC9B,UAAI,CAAC,wBAAwB,cAAe,QAAO,MAAM;AAAA,MAAC;AAE1D,YAAM,QAAQ,iBAAiB,YAAY,IAAI,IAAI;AACnD,aAAO,MAAM;AACX,YAAI,gBAAgB;AAClB,gBAAM,WAAW,YAAY,IAAI,IAAI;AACrC,eAAK,MAAM,gBAAM,KAAK,KAAK,SAAS,QAAQ,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAAA,IAEQ,IAAI,OAAiB,SAAiB,MAAsB;AAClE,UAAI,CAAC,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,MAAO;AAEvD,YAAM,YAAY,SAAS,KAAK;AAChC,YAAM,aAAa,KAAK,cAAc,KAAK;AAC3C,YAAM,WAAW,KAAK,OAAO,kBAAkB,KAAK,YAAY,IAAI;AAEpE,YAAM,aAAa,KAAK;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,cAAQ,OAAO;AAAA,QACb;AACE,kBAAQ,MAAM,UAAU;AACxB;AAAA,QACF;AACE,kBAAQ,KAAK,UAAU;AACvB;AAAA,QACF;AACE,kBAAQ,KAAK,UAAU;AACvB;AAAA,QACF;AACE,kBAAQ,IAAI,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,IAEQ,oBACN,OACA,OACA,WACA,SACA,UACA,MACQ;AACR,UAAI,CAAC,KAAK,OAAO,WAAW;AAC1B,cAAMC,gBAAe,WACjB,KAAK,SAAS,QAAQ,IAAI,SAAS,UAAU,MAC7C;AACJ,YAAI,aAAa,GAAG,KAAK,OAAO,MAAM,IAAI,KAAK,IAAI,SAAS,IAAI,OAAO,GAAGA,aAAY;AACtF,YAAI,SAAS,QAAW;AACtB,wBAAc,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,QACxC;AACA,eAAO;AAAA,MACT;AAEA,YAAM,aAAa,KAAK,cAAc,KAAK;AAC3C,YAAM,QAAQ,OAAO;AAErB,YAAM,gBAAgB,GAAG,OAAO,IAAI,GAAG,OAAO,MAAM,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK;AACjF,YAAM,eAAe;AACrB,YAAM,eAAe,GAAG,UAAU,GAAG,OAAO,IAAI,GAAG,SAAS,GAAG,KAAK;AACpE,YAAM,iBAAiB,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK;AAEtD,YAAM,eAAe,WACjB,GAAG,OAAO,GAAG,GAAG,OAAO,YAAY,KAAK,SAAS,QAAQ,IAAI,SAAS,UAAU,IAAI,KAAK,KACzF;AAEJ,YAAM,WACJ,SAAS,SACL,GAAG,OAAO,GAAG,GAAG,OAAO,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,GAAG,KAAK,KAC3D;AAEN,aAAO,GAAG,aAAa,IAAI,YAAY,IAAI,YAAY,IAAI,cAAc,GAAG,YAAY,GAAG,QAAQ;AAAA,IACrG;AAAA,IAEQ,cAAc,OAAyB;AAC7C,cAAQ,OAAO;AAAA,QACb;AACE,iBAAO,OAAO;AAAA,QAChB;AACE,iBAAO,OAAO;AAAA,QAChB;AACE,iBAAO,OAAO;AAAA,QAChB;AACE,iBAAO,OAAO;AAAA,QAChB;AACE,iBAAO,OAAO;AAAA,MAClB;AAAA,IACF;AAAA,IAEQ,cAAc,OAAyB;AAC7C,cAAQ,OAAO;AAAA,QACb;AACE,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACX;AAAA,IACF;AAAA,IAEQ,cAA+B;AACrC,UAAI;AACF,cAAM,QAAQ,IAAI,MAAM,EAAE;AAC1B,YAAI,CAAC,MAAO,QAAO;AAEnB,cAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,gBAAM,OAAO,MAAM,CAAC;AACpB,cAAI,QAAQ,CAAC,KAAK,SAAS,WAAW,KAAK,CAAC,KAAK,SAAS,QAAQ,GAAG;AACnE,mBAAO,KAAK,eAAe,IAAI;AAAA,UACjC;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,eAAe,MAA+B;AACpD,UAAI,QAAQ,KAAK,MAAM,mCAAmC;AAC1D,UAAI,OAAO;AACT,eAAO;AAAA,UACL,cAAc,MAAM,CAAC;AAAA,UACrB,UAAU,KAAK,gBAAgB,MAAM,CAAC,CAAC;AAAA,UACvC,YAAY,SAAS,MAAM,CAAC,GAAG,EAAE;AAAA,QACnC;AAAA,MACF;AAEA,cAAQ,KAAK,MAAM,uBAAuB;AAC1C,UAAI,OAAO;AACT,eAAO;AAAA,UACL,UAAU,KAAK,gBAAgB,MAAM,CAAC,CAAC;AAAA,UACvC,YAAY,SAAS,MAAM,CAAC,GAAG,EAAE;AAAA,QACnC;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IAEQ,gBAAgB,UAA0B;AAChD,YAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,aAAO,MAAM,MAAM,SAAS,CAAC,KAAK;AAAA,IACpC;AAAA,IAEA,SAAS,MAAc,OAAoC;AACzD,UAAI,CAAC,KAAK,OAAO,UAAW,QAAO;AACnC,aAAO,GAAG,OAAO,KAAK,CAAC,GAAG,IAAI,GAAG,OAAO,KAAK;AAAA,IAC/C;AAAA,IAEA,YAA2B;AACzB,aAAO;AAAA,IACT;AAAA,IAEA,oBACE,aACA,cACmB;AACnB,aAAO,IAAI,mBAAkB;AAAA,QAC3B,GAAG,KAAK;AAAA,QACR;AAAA,QACA,cAAc,gBAAgB;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,IAEQ,qBAA+B;AACrC,cAAQ,cAAc,YAAY,GAAG;AAAA,QACnC,KAAK;AACH;AAAA,QACF,KAAK;AACH;AAAA,QACF,KAAK;AACH;AAAA,QACF,KAAK;AACH;AAAA,QACF,KAAK;AACH;AAAA,QACF;AAEE;AAAA,MACJ;AAAA,IACF;AAAA,IAEQ,sBAA+B;AACrC,UAAI,kBAAkB,OAAQ,QAAO;AACrC,aAAO;AAAA,IACT;AAAA,IAEQ,kBAA2B;AACjC,UAAI,MAAO,QAAO;AAElB,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,MACT;AAEA,UACE,OAAO,YAAY,eACnB,QAEA;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAM,OAAO,MAAM;AAAA,EAAC;AACpB,MAAM,iBAAiB,MAAM,MAAM;AAAA,EAAC;AAG7B,MAAM,SAAS,gBAClB;AAAA,IACE,WAAW;AAAA,IACX,OAAO;AAAA;AAAA,IACP,MAAM;AAAA;AAAA,IACN,MAAM,CAAC,SAAiB,SAAmB;AACzC,cAAQ,KAAK,yCAAwB,OAAO,IAAI,QAAQ,EAAE;AAAA,IAC5D;AAAA,IACA,OAAO,CAAC,SAAiB,SAAmB;AAC1C,cAAQ,MAAM,mCAAuB,OAAO,IAAI,QAAQ,EAAE;AAAA,IAC5D;AAAA,IACA,MAAM;AAAA,IACN,UAAU,CAAC,SAAiB;AAAA,IAC5B,WAAW,MAAM;AAAA,IACjB,qBAAqB,CAAC,aAAqB,kBAA2B;AAAA,MACpE,WAAW;AAAA,MACX,OAAO;AAAA;AAAA,MACP,MAAM;AAAA;AAAA,MACN,MAAM,CAAC,SAAiB,SAAmB;AACzC,cAAM,SAAS,GAAG,gBAAgB,WAAI,IAAI,WAAW;AACrD,gBAAQ,KAAK,GAAG,MAAM,iBAAO,OAAO,IAAI,QAAQ,EAAE;AAAA,MACpD;AAAA,MACA,OAAO,CAAC,SAAiB,SAAmB;AAC1C,cAAM,SAAS,GAAG,gBAAgB,WAAI,IAAI,WAAW;AACrD,gBAAQ,MAAM,GAAG,MAAM,WAAM,OAAO,IAAI,QAAQ,EAAE;AAAA,MACpD;AAAA,MACA,MAAM;AAAA,MACN,UAAU,CAAC,SAAiB;AAAA,MAC5B,WAAW,MAAM;AAAA,MACjB,qBAAqB;AAAA,IACvB;AAAA,EACF,IACA,IAAI,kBAAkB;AAAA,IACpB,aAAa;AAAA,IACb,cAAc;AAAA,EAChB,CAAC;;;ACtWE,MAAM,mBAAmB;AAMhC,MAAM,gBAAgB,oBAAI,IAAI,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI,CAAC;AAGrD,WAAS,cAAc,KAAqB;AACjD,WAAO,IAAI,MAAM,GAAG,EAAE,CAAC,EAAG,YAAY;AAAA,EACxC;AAOO,WAAS,gBAAgB,KAAqB;AACnD,UAAM,UAAU,IAAI,KAAK;AACzB,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,QAAQ,MAAM,GAAG;AACzC,UAAM,MAAM,CAAC,KAAK,YAAY,CAAC;AAC/B,eAAW,OAAO,MAAM;AACtB,UAAI,IAAI,WAAW,GAAG;AACpB,YAAI,KAAK,IAAI,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,MAC5D,WAAW,IAAI,WAAW,GAAG;AAC3B,YAAI,KAAK,IAAI,YAAY,CAAC;AAAA,MAC5B,OAAO;AACL,YAAI,KAAK,IAAI,YAAY,CAAC;AAAA,MAC5B;AAAA,IACF;AACA,WAAO,IAAI,KAAK,GAAG;AAAA,EACrB;AAYO,WAAS,YACd,WACA,WACA,UACQ;AACR,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,UAAM,QAAQ,UAAU,IAAI,CAAC,SAAS;AAAA,MACpC;AAAA,MACA,OAAO,gBAAgB,GAAG,EAAE,YAAY;AAAA,IAC1C,EAAE;AACF,eAAW,OAAO,WAAW;AAC3B,UAAI,CAAC,IAAK;AACV,YAAM,WAAW,gBAAgB,GAAG,EAAE,YAAY;AAClD,YAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,QAAQ;AACpD,UAAI,MAAO,QAAO,MAAM;AACxB,YAAM,UAAU,cAAc,GAAG;AACjC,YAAM,YAAY,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,OAAO;AACvD,UAAI,UAAW,QAAO,UAAU;AAAA,IAClC;AACA,WAAO;AAAA,EACT;AAyBO,WAAS,UAAU,KAA4B;AACpD,WAAO,cAAc,IAAI,cAAc,GAAG,CAAC,IAAI,QAAQ;AAAA,EACzD;;;AC5FO,MAAM,eAAN,MAAmB;AAAA,IAAnB;AAEL;AAAA,0BAAQ,kBAAiB,oBAAI,IAG3B;AAIF;AAAA;AAAA,0BAAQ,aACN,OAAO,YAAY,eACnB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKF,GACE,OACA,UACM;AACN,UAAI,CAAC,KAAK,eAAe,IAAI,KAAK,GAAG;AACnC,aAAK,eAAe,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,MAC1C;AAGA,YAAM,YAAY,KAAK,eAAe,IAAI,KAAK;AAG/C,gBAAU,IAAI,QAAQ;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA,IAKA,IACE,OACA,UACM;AACN,YAAM,YAAY,KAAK,eAAe,IAAI,KAAK;AAG/C,UAAI,WAAW;AACb,kBAAU,OAAO,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,KACE,OACA,UACM;AACN,YAAM,YAAY,KAAK,eAAe,IAAI,KAAK;AAG/C,UAAI,WAAW;AACb,kBAAU,QAAQ,cAAY;AAC5B,cAAI;AACF,qBAAS,QAAQ;AAAA,UACnB,SAAS,OAAO;AACd,oBAAQ,MAAM,+BAA+B,OAAO,KAAK,CAAC,KAAK,KAAK;AAAA,UACtE;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,aAAqD,OAAmB;AACtE,aACE,KAAK,eAAe,IAAI,KAAK,KAAK,KAAK,eAAe,IAAI,KAAK,EAAG,OAAO;AAAA,IAE7E;AAAA,IAEA,cAAoB;AAClB,WAAK,eAAe,MAAM;AAAA,IAC5B;AAAA;AAAA;AAAA;AAAA,IAKQ,cACN,WACA,OACA,OACkB;AAClB,aAAO;AAAA,QACL;AAAA,QACA,WAAW,YAAY,IAAI;AAAA,QAC3B;AAAA,QACA,GAAG;AAAA,MACL;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,UACN,OACA,SACA,WACA,OACM;AACN,WAAK,KAAK,OAAO;AAAA,QACf,SAAS,KAAK,cAAc,WAAW,KAAK;AAAA,QAC5C;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKA,YAAY,SAA6B,SAAkB;AACzD,YAAM,YAAY,CAAC,aAAa;AAChC,YAAM,eAAe,UAAU,CAAC,GAAG,WAAW,OAAO,IAAI;AAEzD,aAAO;AAAA,QACL,SAAS,MAAM;AACb,eAAK,KAAK,uBAAuB;AAAA,YAC/B,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,WAAW,SAAS,CAAC;AAAA,YACjE,SAAS,EAAE,KAAK,QAAQ,SAAS;AAAA,UACnC,CAAC;AAAA,QACH;AAAA,QAEA,SAAS,CAAC,UAAkB;AAC1B,eAAK,KAAK,uBAAuB;AAAA,YAC/B,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,cAAc,SAAS,CAAC;AAAA,YACpE,SAAS,EAAE,KAAK,QAAQ,UAAU,MAAM;AAAA,UAC1C,CAAC;AAAA,QACH;AAAA,QAEA,UAAU,CAAC,UAAkB;AAC3B,eAAK,KAAK,wBAAwB;AAAA,YAChC,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,WAAW,UAAU,CAAC;AAAA,YAClE,SAAS,EAAE,KAAK,QAAQ,UAAU,MAAM;AAAA,UAC1C,CAAC;AAAA,QACH;AAAA,QAEA,SAAS,CAAC,eAAuB,QAAgB,cAAsB;AACrE,eAAK,KAAK,uBAAuB;AAAA,YAC/B,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,WAAW,SAAS,CAAC;AAAA,YACjE,SAAS;AAAA,cACP,KAAK,QAAQ;AAAA,cACb;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QAEA,UAAU,CAAC,eAAuB,QAAgB,cAAsB;AACtE,eAAK,KAAK,yBAAyB;AAAA,YACjC,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,WAAW,WAAW,CAAC;AAAA,YACnE,SAAS;AAAA,cACP,KAAK,QAAQ;AAAA,cACb;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,YACV;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QAEA,QAAQ,CAAC,eAAuB,QAAgB,cAAsB;AACpE,eAAK,KAAK,sBAAsB;AAAA,YAC9B,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,WAAW,QAAQ,CAAC;AAAA,YAChE,SAAS;AAAA,cACP,KAAK,QAAQ;AAAA,cACb;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,YACV;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,SAAsC,QAAgB;AACzD,YAAM,YAAY,CAAC,QAAQ,MAAM;AAEjC,aAAO;AAAA,QACL,UAAU,MAAM;AACd,cAAI,OAAO,YAAY,SAAU;AACjC,eAAK,KAAK,kBAAkB;AAAA,YAC1B,SAAS,KAAK,cAAc,QAAQ,IAAI;AAAA,cACtC,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF,CAAC;AAAA,YACD,SAAS,EAAE,KAAK,QAAQ,UAAU,OAAO;AAAA,UAC3C,CAAC;AAAA,QACH;AAAA,QAEA,YAAY,CAAC,UAAkB;AAC7B,cAAI,OAAO,YAAY,SAAU;AACjC,eAAK,KAAK,oBAAoB;AAAA,YAC5B,SAAS,KAAK,cAAc,QAAQ,IAAI;AAAA,cACtC,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF,CAAC;AAAA,YACD,SAAS,EAAE,KAAK,QAAQ,UAAU,OAAO,OAAO;AAAA,UAClD,CAAC;AAAA,QACH;AAAA,QAEA,SAAS,MAAM;AACb,cAAI,OAAO,YAAY,SAAU;AACjC,eAAK,KAAK,iBAAiB;AAAA,YACzB,SAAS,KAAK,cAAc,QAAQ,IAAI;AAAA,cACtC,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF,CAAC;AAAA,YACD,SAAS,EAAE,KAAK,QAAQ,UAAU,OAAO;AAAA,UAC3C,CAAC;AAAA,QACH;AAAA,QAEA,UAAU,CAAC,UAAkB;AAC3B,cAAI,OAAO,YAAY,SAAU;AACjC,eAAK,KAAK,kBAAkB;AAAA,YAC1B,SAAS,KAAK,cAAc,QAAQ,IAAI;AAAA,cACtC,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF,CAAC;AAAA,YACD,SAAS,EAAE,KAAK,QAAQ,UAAU,OAAO,OAAO;AAAA,UAClD,CAAC;AAAA,QACH;AAAA,QAEA,YAAY,CAAC,UAAkB;AAC7B,gBAAM,KAAK,OAAO,YAAY,WAAW,WAAW,QAAQ;AAC5D,gBAAM,MAAM,OAAO,YAAY,WAAW,UAAU,QAAQ;AAC5D,eAAK,KAAK,oBAAoB;AAAA,YAC5B,SAAS,KAAK,cAAc,IAAI,CAAC,GAAG,WAAW,OAAO,SAAS,CAAC;AAAA,YAChE,SAAS,EAAE,KAAU,OAAO,OAAO;AAAA,UACrC,CAAC;AAAA,QACH;AAAA,QAEA,OAAO,CAAC,UAAiB;AACvB,cAAI,OAAO,YAAY,SAAU;AACjC,eAAK,KAAK,cAAc;AAAA,YACtB,SAAS,KAAK,cAAc,QAAQ,IAAI,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,YAC/D,SAAS,EAAE,KAAK,QAAQ,UAAU,QAAQ,MAAM;AAAA,UAClD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,QAAQ,SAAsC,QAAiB;AAC7D,YAAM,MAAM,OAAO,YAAY,WAAW,UAAU,QAAQ;AAC5D,YAAM,YAAY,OAAO,YAAY,WAAW,YAAY,QAAQ;AACpE,YAAM,YAAY,CAAC,WAAW,UAAU,SAAS;AAEjD,aAAO;AAAA,QACL,OAAO,MAAM;AACX,eAAK,KAAK,yBAAyB;AAAA,YACjC,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,YAC9D,SAAS,EAAE,IAAI;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,QAEA,SAAS,CAAC,UAAkB;AAC1B,eAAK,KAAK,2BAA2B;AAAA,YACnC,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,SAAS,CAAC;AAAA,YAChE,SAAS,EAAE,KAAK,OAAO,QAAQ,UAAU,MAAM;AAAA,UACjD,CAAC;AAAA,QACH;AAAA,QAEA,OAAO,CAAC,OAAgB,WAAoB;AAC1C,eAAK,KAAK,yBAAyB;AAAA,YACjC,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,YAC9D,SAAS;AAAA,cACP;AAAA,cACA,QAAQ,UAAU;AAAA,cAClB;AAAA,cACA,GAAI,UAAU,EAAE,OAAO;AAAA,YACzB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QAEA,OAAO,CAAC,SAAiB,SAAiB,WAAoB;AAC5D,eAAK,KAAK,iBAAiB;AAAA,YACzB,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,YAC9D,SAAS,EAAE,KAAK,SAAS,SAAS,GAAI,UAAU,EAAE,OAAO,EAAG;AAAA,UAC9D,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAU;AACR,YAAM,YAAY,CAAC,SAAS;AAC5B,YAAM,WAAW,SAAS,KAAK,IAAI,CAAC;AAEpC,aAAO;AAAA,QACL,KAAK,CAAC,SAAkD;AACtD,eAAK,KAAK,eAAe;AAAA,YACvB,SAAS,KAAK,cAAc,UAAU,CAAC,GAAG,WAAW,KAAK,CAAC;AAAA,YAC3D,SAAS,EAAE,KAAK;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,QAEA,YAAY,CAAC,QAAgB,cAAsB;AACjD,eAAK,KAAK,uBAAuB;AAAA,YAC/B,SAAS,KAAK,cAAc,UAAU;AAAA,cACpC,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF,CAAC;AAAA,YACD,SAAS,EAAE,QAAQ,UAAU;AAAA,UAC/B,CAAC;AAAA,QACH;AAAA,QAEA,WAAW,CAAC,cAAwB,YAAsB;AACxD,eAAK,KAAK,sBAAsB;AAAA,YAC9B,SAAS,KAAK,cAAc,UAAU;AAAA,cACpC,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF,CAAC;AAAA,YACD,SAAS,EAAE,cAAc,QAAQ;AAAA,UACnC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,SAAS,WAAmB,WAAmB;AAC7C,YAAM,YAAY,eAAe,KAAK,IAAI,CAAC;AAC3C,YAAM,YAAY,CAAC,YAAY,QAAQ;AAEvC,aAAO;AAAA,QACL,OAAO,MAAM;AACX,eAAK,KAAK,yBAAyB;AAAA,YACjC,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,YAC9D,SAAS,EAAE,WAAW,UAAU;AAAA,UAClC,CAAC;AAAA,QACH;AAAA,QAEA,UAAU,MAAM;AACd,eAAK,KAAK,2BAA2B;AAAA,YACnC,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,UAAU,CAAC;AAAA,YACjE,SAAS,EAAE,WAAW,WAAW,KAAK,UAAU,SAAS,EAAE;AAAA,UAC7D,CAAC;AAAA,QACH;AAAA,QAEA,OAAO,CAAC,UAAiB;AACvB,eAAK,KAAK,yBAAyB;AAAA,YACjC,SAAS,KAAK,cAAc,WAAW,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,YAC9D,SAAS,EAAE,WAAW,WAAW,MAAM;AAAA,UACzC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,WAAoB,QAAgB,OAAkC;AAE1E,UAAI,CAAC,KAAK,UAAW,QAAO,EAAE,OAAO,MAAM;AAAA,MAAC,GAAG,UAAU,MAAM;AAAA,MAAC,EAAE;AAElE,aAAO;AAAA,QACL,OAAO,MAAM;AACX,iBAAO,MAAM,mBAAY,SAAS,cAAc,MAAM,EAAE;AAAA,QAC1D;AAAA,QAEA,UAAU,MAAM;AACd,iBAAO;AAAA,YACL,gBAAW,SAAS,cAAc,OAAO,gBAAgB,CAAC;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;;;ACxYO,MAAM,eAAN,MAAmB;AAAA,IAKxB,YAAY,cAA4B;AAJxC,0BAAQ,iBAAiC,CAAC;AAC1C,0BAAQ,gBAA+B,CAAC;AACxC,0BAAQ;AAGN,WAAK,MAAM;AAAA,IACb;AAAA,IAEA,eAAe,SAA6B;AAC1C,UAAI,CAAC,QAAQ,QAAS;AACtB,WAAK,aAAa,KAAK,OAAO;AAC9B,WAAK,qBAAqB,KAAK,YAAY;AAC3C,aAAO,MAAM,uBAAuB,QAAQ,IAAI,EAAE;AAAA,IACpD;AAAA,IAEA,WAAW,SAAuD;AAChE,iBAAW,WAAW,KAAK,cAAc;AACvC,YAAI;AACF,gBAAM,SAAS,QAAQ,OAAO,OAAO;AACrC,cAAI,WAAW,QAAQ,OAAO,OAAO;AACnC,mBAAO,MAAM,aAAa,QAAQ,IAAI,KAAK,OAAO,QAAQ,KAAK;AAC/D,mBAAO;AAAA,UACT;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,KAAK,yBAAyB,QAAQ,IAAI,KAAK,KAAK;AAC3D,gBAAM,UAAU,KAAK,IAAI,KAAK,SAAS,QAAQ,IAAI;AACnD,kBAAQ,MAAM,KAAc;AAC5B;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,qBACN,SACA,QACA,gBACM;AACN,YAAM,iBAAiB,KAAK;AAC5B,UAAI,eAAe,WAAW,EAAG;AACjC,aAAO,MAAM,aAAa,eAAe,MAAM,kBAAkB;AAGjE,qBAAe,QAAQ,aAAW;AAChC,YAAI;AACF,kBAAQ,KAAK,SAAS,MAAM;AAC5B,iBAAO,MAAM,oBAAoB,QAAQ,IAAI,EAAE;AAAA,QACjD,SAAS,OAAO;AACd,iBAAO,KAAK,4BAA4B,QAAQ,IAAI,KAAK,KAAK;AAC9D,gBAAM,UAAU,KAAK,IAAI,KAAK,SAAS,QAAQ,IAAI;AACnD,kBAAQ,MAAM,KAAc;AAAA,QAC9B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEQ,8BACN,cACA,SACM;AACN,YAAM,iBAAiB,KAAK,aAAa;AAAA,QACvC,OAAK,EAAE,SAAS,YAAY,EAAE;AAAA,MAChC;AAEA,UAAI,eAAe,WAAW,EAAG;AAEjC,aAAO;AAAA,QACL,uBAAuB,eAAe,MAAM;AAAA,MAC9C;AAGA,qBAAe,QAAQ,aAAW;AAChC,YAAI;AACF,kBAAQ,cAAe,cAAc,OAAO;AAC5C,iBAAO,MAAM,8BAA8B,QAAQ,IAAI,IAAI;AAAA,YACzD,QAAQ,QAAQ;AAAA,YAChB,WAAW,QAAQ;AAAA,UACrB,CAAC;AAAA,QACH,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,sCAAsC,QAAQ,IAAI;AAAA,YAClD;AAAA,UACF;AACA,gBAAM,UAAU,KAAK,IAAI;AAAA,YACvB,GAAG,QAAQ,MAAM,IAAI,QAAQ,SAAS;AAAA,YACtC,QAAQ;AAAA,UACV;AACA,kBAAQ,MAAM,KAAc;AAAA,QAC9B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,gBAAgB,SAA8B;AAC5C,UAAI,CAAC,QAAQ,QAAS;AACtB,WAAK,cAAc,KAAK,OAAO;AAC/B,WAAK,qBAAqB,KAAK,aAAa;AAE5C,aAAO,MAAM,wBAAwB,QAAQ,IAAI,EAAE;AAAA,IACrD;AAAA,IAEA,MAAM,YACJ,SACmC;AACnC,iBAAW,WAAW,KAAK,eAAe;AACxC,YAAI;AACF,iBAAO,MAAM,mBAAmB,QAAQ,IAAI,EAAE;AAC9C,gBAAM,SAAS,MAAM,QAAQ,OAAO,OAAO;AAG3C,cAAI,OAAO,SAAS,OAAO,WAAW,KAAK;AAEzC,mBAAO,MAAM,cAAc,QAAQ,IAAI,KAAK,OAAO,QAAQ,KAAK;AAGhE,gBAAI,OAAO,iBAAiB;AAC1B,qBAAO;AAAA,gBACL,4BAA4B,OAAO,gBAAgB,MAAM,IAAI,OAAO,gBAAgB,SAAS;AAAA,cAC/F;AACA,oBAAM,KAAK,wBAAwB,OAAO,gBAAgB,MAAM;AAAA,gBAC9D,QAAQ,OAAO,gBAAgB;AAAA,gBAC/B,WAAW,OAAO,gBAAgB;AAAA,cACpC,CAAC;AACD,qBAAO;AAAA,YACT;AAGA,kBAAM,KAAK,sBAAsB,SAAS,QAAQ,OAAO;AACzD,iBAAK,qBAAqB,SAAS,QAAQ,OAAO;AAElD,mBAAO;AAAA,UACT;AAGA,iBAAO;AAAA,YACL,WAAW,QAAQ,IAAI,+BAA+B,OAAO,MAAM;AAAA,UACrE;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,KAAK,WAAW,QAAQ,IAAI,YAAY,KAAK;AACpD,gBAAM,UAAU,KAAK,IAAI,KAAK,SAAS,QAAQ,IAAI;AACnD,kBAAQ,MAAM,KAAc;AAC5B;AAAA,QACF;AAAA,MACF;AACA,aAAO,MAAM,2CAA2C,QAAQ,QAAQ,EAAE;AAC1E,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAc,sBACZ,SACA,QACA,eACe;AACf,YAAM,cAAc,KAAK,cAAc,QAAQ,aAAa;AAG5D,YAAM,kBAAkB,KAAK,cAC1B,MAAM,GAAG,WAAW,EACpB,OAAO,OAAK,EAAE,SAAS,SAAS;AAEnC,UAAI,gBAAgB,WAAW,EAAG;AAElC,aAAO,MAAM,aAAa,gBAAgB,MAAM,mBAAmB;AAGnE,YAAM,eAAe,gBAAgB,IAAI,OAAM,YAAW;AACxD,YAAI;AACF,gBAAM,QAAQ,KAAK,SAAS,MAAM;AAClC,iBAAO,MAAM,qBAAqB,QAAQ,IAAI,EAAE;AAAA,QAClD,SAAS,OAAO;AACd,iBAAO,KAAK,6BAA6B,QAAQ,IAAI,KAAK,KAAK;AAC/D,gBAAM,UAAU,KAAK,IAAI,KAAK,SAAS,QAAQ,IAAI;AACnD,kBAAQ,MAAM,KAAc;AAAA,QAC9B;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,YAAY;AAAA,IACvC;AAAA,IAEA,MAAc,+BACZ,cACA,SACe;AACf,YAAM,kBAAkB,KAAK,cAAc;AAAA,QACzC,OAAK,EAAE,SAAS,aAAa,EAAE;AAAA,MACjC;AAEA,UAAI,gBAAgB,WAAW,EAAG;AAElC,aAAO;AAAA,QACL,uBAAuB,gBAAgB,MAAM;AAAA,MAC/C;AAGA,YAAM,eAAe,gBAAgB,IAAI,OAAM,YAAW;AACxD,YAAI;AACF,gBAAM,QAAQ,cAAe,cAAc,OAAO;AAClD,iBAAO,MAAM,+BAA+B,QAAQ,IAAI,IAAI;AAAA,YAC1D,QAAQ,QAAQ;AAAA,YAChB,WAAW,QAAQ;AAAA,UACrB,CAAC;AAAA,QACH,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,uCAAuC,QAAQ,IAAI;AAAA,YACnD;AAAA,UACF;AACA,gBAAM,UAAU,KAAK,IAAI;AAAA,YACvB,GAAG,QAAQ,MAAM,IAAI,QAAQ,SAAS;AAAA,YACtC,QAAQ;AAAA,UACV;AACA,kBAAQ,MAAM,KAAc;AAAA,QAC9B;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,YAAY;AAAA,IACvC;AAAA,IAEA,MAAM,wBACJ,cACA,SACe;AACf,WAAK,8BAA8B,cAAc,OAAO;AACxD,YAAM,KAAK,+BAA+B,cAAc,OAAO;AAAA,IACjE;AAAA,IAEA,kBAAkC;AAChC,aAAO,CAAC,GAAG,KAAK,YAAY;AAAA,IAC9B;AAAA,IAEA,mBAAoC;AAClC,aAAO,CAAC,GAAG,KAAK,aAAa;AAAA,IAC/B;AAAA;AAAA;AAAA;AAAA,IAKA,eAQE;AACA,aAAO;AAAA,QACL,QAAQ,KAAK,aAAa,SAAS,KAAK,cAAc;AAAA,QACtD,UAAU;AAAA,UACR,GAAG,KAAK,aAAa,IAAI,QAAM;AAAA,YAC7B,MAAM,EAAE;AAAA,YACR,UAAU,EAAE;AAAA,YACZ,MAAM,EAAE;AAAA,YACR,SAAS,EAAE;AAAA,UACb,EAAE;AAAA,UACF,GAAG,KAAK,cAAc,IAAI,QAAM;AAAA,YAC9B,MAAM,EAAE;AAAA,YACR,UAAU,EAAE;AAAA,YACZ,MAAM,EAAE;AAAA,YACR,SAAS,EAAE;AAAA,UACb,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,SAAS,SAAsC;AAC7C,aACE,KAAK,aAAa,KAAK,OAAK,EAAE,WAAW,OAAO,MAAM,IAAI,KAC1D,KAAK,cAAc,KAAK,OAAK,EAAE,WAAW,OAAO,MAAM,IAAI;AAAA,IAE/D;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,aAAkC;AAEhC,YAAM,UAA+B,CAAC;AAGtC,YAAM,cAAc,CAAC,GAAG,KAAK,cAAc,GAAG,KAAK,aAAa;AAChE,iBAAW,WAAW,aAAa;AACjC,YAAI,QAAQ,YAAY;AACtB,kBAAQ,QAAQ,IAAI,IAAI,QAAQ,WAAW;AAAA,QAC7C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,UAAyB;AAE7B,YAAM,cAAc,CAAC,GAAG,KAAK,cAAc,GAAG,KAAK,aAAa;AAEhE,YAAM,kBAAkB,YAAY,IAAI,OAAM,YAAW;AACvD,YAAI;AACF,gBAAM,QAAQ,UAAU;AACxB,iBAAO,MAAM,sBAAsB,QAAQ,IAAI,EAAE;AAAA,QACnD,SAAS,OAAO;AACd,iBAAO,KAAK,8BAA8B,QAAQ,IAAI,IAAI,KAAK;AAAA,QACjE;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,eAAe;AAGxC,WAAK,eAAe,CAAC;AACrB,WAAK,gBAAgB,CAAC;AAAA,IACxB;AAAA,IAEQ,qBACN,UACM;AACN,YAAM,wBAAwB,SAAS,KAAK,OAAK,EAAE,WAAW,CAAC;AAE/D,UAAI,uBAAuB;AACzB,iBAAS,KAAK,CAAC,GAAG,MAAM;AACtB,gBAAM,YAAY,EAAE,YAAY,OAAO;AACvC,gBAAM,YAAY,EAAE,YAAY,OAAO;AACvC,iBAAO,YAAY;AAAA,QACrB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,MAAM,cACJ,QACA,WACiC;AACjC,iBAAW,WAAW,KAAK,eAAe;AACxC,YAAI,QAAQ,SAAS,UAAW;AAChC,YAAI;AACF,iBAAO;AAAA,YACL,6BAA6B,MAAM,IAAI,SAAS,SAAS,QAAQ,IAAI;AAAA,UACvE;AACA,gBAAM,SAAS,MAAM,QAAQ,gBAAgB,QAAQ,SAAS;AAC9D,cAAI,UAAU,OAAO,QAAQ,OAAO,WAAW,KAAK;AAClD,mBAAO;AAAA,cACL,qBAAqB,MAAM,IAAI,SAAS,SAAS,QAAQ,IAAI;AAAA,YAC/D;AACA,kBAAM,KAAK,+BAA+B,OAAO,MAAM;AAAA,cACrD;AAAA,cACA;AAAA,YACF,CAAC;AACD,iBAAK,8BAA8B,OAAO,MAAM;AAAA,cAC9C;AAAA,cACA;AAAA,YACF,CAAC;AACD,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,6BAA6B,MAAM,IAAI,SAAS,SAAS,QAAQ,IAAI;AAAA,YACrE;AAAA,UACF;AACA,gBAAM,UAAU,KAAK,IAAI,KAAK,GAAG,MAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AACpE,kBAAQ,MAAM,KAAc;AAC5B;AAAA,QACF;AAAA,MACF;AACA,aAAO,MAAM,gCAAgC,MAAM,IAAI,SAAS,EAAE;AAClE,aAAO;AAAA,IACT;AAAA,IAEA,aAAmB;AACjB,YAAM,cAAc,CAAC,GAAG,KAAK,cAAc,GAAG,KAAK,aAAa;AAEhE,iBAAW,WAAW,aAAa;AACjC,YAAI;AACF,kBAAQ,UAAU;AAClB,iBAAO,MAAM,8BAA8B,QAAQ,IAAI,EAAE;AAAA,QAC3D,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,sCAAsC,QAAQ,IAAI;AAAA,YAClD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,gCAAgC;AAAA,IAC/C;AAAA;AAAA;AAAA;AAAA,IAKA,eAAe,QAAgB,WAAyB;AAEtD,iBAAW,WAAW,KAAK,cAAc;AACvC,YAAI;AACF,kBAAQ,iBAAiB,QAAQ,SAAS;AAAA,QAC5C,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,0CAA0C,QAAQ,IAAI;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,sBAAsB,MAAM,IAAI,SAAS,EAAE;AAAA,IAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,SAAS,KAAa,OAAe,QAAyC;AAG5E,iBAAW,WAAW,KAAK,cAAc;AACvC,YAAI,QAAQ,SAAS,YAAY,QAAQ,UAAU;AACjD,cAAI;AACF,oBAAQ,SAAS,KAAK,OAAO,MAAM;AAAA,UACrC,SAAS,OAAO;AACd,mBAAO,KAAK,mCAAmC,QAAQ,IAAI,IAAI,KAAK;AAAA,UACtE;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,cAAc,GAAG,EAAE;AAAA,IAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,iBAAiB,mBAAmD;AAElE,iBAAW,WAAW,KAAK,cAAc;AACvC,YAAI,QAAQ,SAAS,UAAU;AAC7B,cAAI;AACF,kBAAM,UAAU,QAAQ,aAAa;AACrC,gBAAI,WAAW,QAAQ,iBAAiB,GAAG;AACzC,oBAAM,OAAO,QAAQ,iBAAiB;AAEtC,kBAAI,OAAO,SAAS,UAAU;AAC5B,uBAAO,KAAK,MAAM,IAAI;AAAA,cACxB;AACA,qBAAO;AAAA,YACT;AAAA,UACF,SAAS,OAAO;AACd,mBAAO,MAAM,qCAAqC,QAAQ,IAAI,KAAK,KAAK;AAAA,UAC1E;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;;;AChdO,WAAS,kBAAkB,KAAiC;AAEjE,UAAM,aAAa,IAAI,QAAQ,GAAG;AAElC,QAAI,aAAa,KAAK,aAAa,IAAI,SAAS,GAAG;AAEjD,YAAM,YAAY,IAAI,UAAU,GAAG,UAAU;AAC7C,YAAM,WAAW,IAAI,UAAU,aAAa,CAAC;AAE7C,aAAO;AAAA,QACL,aAAa;AAAA,QACb;AAAA,QACA;AAAA,QACA,sBAAsB;AAAA,MACxB;AAAA,IACF;AAGA,WAAO;AAAA,MACL,aAAa;AAAA,MACb,UAAU;AAAA,MACV,sBAAsB;AAAA,IACxB;AAAA,EACF;;;ACxBO,WAAS,yBACd,WACA,eACA,kBACoB;AAEpB,UAAM,qBAAqB,UAAU,uBACjC,UAAU,YACV;AAEJ,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW;AAAA,IACb;AAAA,EACF;;;ACRO,WAAS,iBACd,WACA,SACS;AACT,QAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,QAAQ,SAAS,GAAG,KAAK,CAAC,QAAQ,SAAS,GAAG,GAAG;AACpD,aAAO,UAAU,OAAO;AAAA,IAC1B;AAGA,QAAI;AACF,YAAM,OAAO,aAAa,OAAO;AACjC,UAAI,UAAmB;AAEvB,iBAAW,OAAO,MAAM;AACtB,YAAI,YAAY,QAAQ,YAAY,QAAW;AAC7C,iBAAO;AAAA,YACL,kEAA2D,OAAO;AAAA,UACpE;AACA,iBAAO;AAAA,QACT;AAEA,YAAI,OAAO,QAAQ,UAAU;AAE3B,cAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,mBAAO;AAAA,cACL,sCAA+B,GAAG,aAAa,OAAO;AAAA,YACxD;AACA,mBAAO;AAAA,UACT;AACA,oBAAU,QAAQ,GAAG;AAAA,QACvB,OAAO;AAEL,cAAI,OAAO,YAAY,UAAU;AAC/B,mBAAO;AAAA,cACL,sCAA+B,GAAG,cAAc,OAAO;AAAA,YACzD;AACA,mBAAO;AAAA,UACT;AACA,oBAAW,QAAoC,GAAG;AAAA,QACpD;AAAA,MACF;AAEA,aAAO;AAAA,QACL,kCAA2B,OAAO,WAAM,OAAO,YAAY,WAAW,aAAa,OAAO;AAAA,MAC5F;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,MAAM,8CAAuC,OAAO,MAAM,KAAK;AACtE,aAAO;AAAA,IACT;AAAA,EACF;AASO,WAAS,aAAa,SAAsC;AACjE,UAAM,OAA4B,CAAC;AACnC,QAAI,aAAa;AACjB,QAAI,aAAa;AAEjB,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAM,OAAO,QAAQ,CAAC;AAEtB,UAAI,SAAS,OAAO,CAAC,YAAY;AAE/B,YAAI,YAAY;AACd,eAAK,KAAK,UAAU;AACpB,uBAAa;AAAA,QACf;AAAA,MACF,WAAW,SAAS,KAAK;AAEvB,YAAI,YAAY;AACd,eAAK,KAAK,UAAU;AACpB,uBAAa;AAAA,QACf;AACA,qBAAa;AAAA,MACf,WAAW,SAAS,OAAO,YAAY;AAErC,YAAI,YAAY;AACd,gBAAM,QAAQ,SAAS,YAAY,EAAE;AACrC,cAAI,CAAC,MAAM,KAAK,GAAG;AACjB,iBAAK,KAAK,KAAK;AAAA,UACjB,OAAO;AAEL,iBAAK,KAAK,UAAU;AAAA,UACtB;AACA,uBAAa;AAAA,QACf;AACA,qBAAa;AAAA,MACf,OAAO;AAEL,sBAAc;AAAA,MAChB;AAAA,IACF;AAGA,QAAI,YAAY;AACd,WAAK,KAAK,UAAU;AAAA,IACtB;AAEA,WAAO;AAAA,EACT;AAMO,WAAS,yBACd,QACA,WACA,KACQ;AACR,UAAM,QAAQ,CAAC,MAAM;AACrB,QAAI,WAAW;AACb,YAAM,KAAK,SAAS;AAAA,IACtB;AACA,UAAM,KAAK,GAAG;AACd,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AAKO,WAAS,wBACd,QACA,WACQ;AACR,WAAO,IAAI,MAAM,IAAI,SAAS;AAAA,EAChC;AAqDO,WAAS,oBACd,cACA,SAAS,IACT,QACA,WACwB;AACxB,UAAM,YAAoC,CAAC;AAE3C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACvD,YAAM,UAAU,SAAS,GAAG,MAAM,IAAI,GAAG,KAAK;AAC9C,YAAM,WAAW,yBAAyB,QAAQ,WAAW,OAAO;AAEpE,UAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,YAAY,OAAO;AAGvF,kBAAU,QAAQ,IAAI,KAAK,UAAU,KAAK;AAAA,MAC5C,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AAEtD,eAAO;AAAA,UACL;AAAA,UACA,oBAAoB,OAAkC,SAAS,QAAQ,SAAS;AAAA,QAClF;AAAA,MACF,OAAO;AAEL,kBAAU,QAAQ,IAAI,KAAK,UAAU,EAAE,MAAM,OAAO,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC;AAAA,MAC1E;AAAA,IACF;AAEA,WAAO;AAAA,EACT;;;AC9NO,WAAS,0BACd,KACA,eACA,sBACA,sBACA,kBACoB;AACpB,UAAM,YAAY,YAAY,IAAI;AAGlC,UAAM,EAAE,cAAc,OAAO,IAAI;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAGA,UAAM,YAAY,kBAAkB,GAAG;AAGvC,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,qBAAqB;AAAA,MACzB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAEA,UAAM,oBAAoB,QAAQ,YAC9B,wBAAwB,QAAQ,QAAQ,QAAQ,SAAS,IACzD;AAGJ,UAAM,KAAK,GAAG,kBAAkB,IAAI,SAAS;AAE7C,WAAO;AAAA,MACL;AAAA;AAAA,MACA,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,sBAAsB;AAAA,MACtB,UAAU,UAAU;AAAA,MACpB,sBAAsB,UAAU;AAAA,MAChC,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,QAAQ;AAAA,MACR,WAAW,QAAQ;AAAA;AAAA,MACnB;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAKO,WAAS,uBACd,aACA,YAC6D;AAC7D,QAAI;AACJ,QAAI;AAMJ,UAAM,aACJ,OAAO,YAAY,eACnB;AACF,QACE,OAAO,gBAAgB,YACvB,OAAO,eAAe,YACtB,YACA;AACA,cAAQ;AAAA,QACN;AAAA,MAGF;AAAA,IACF;AAEA,QAAI,OAAO,gBAAgB,UAAU;AAEnC,qBAAe;AACf,UAAI,OAAO,eAAe,UAAU;AAClC,iBAAS;AAAA,MACX;AAAA,IACF,WAAW,OAAO,gBAAgB,UAAU;AAE1C,eAAS;AACT,UAAI,OAAO,eAAe,UAAU;AAClC,uBAAe;AAAA,MACjB;AAAA,IACF;AAEA,WAAO,EAAE,cAAc,OAAO;AAAA,EAChC;;;ACnFO,MAAM,cAAN,MAA0C;AAAA,IAW/C,YACE,cACA,YACA;AAbF,0BAAS;AACT,0BAAS,WAAU;AACnB,0BAAS;AACT,0BAAS,QAAO;AAChB,0BAAS;AACT,0BAAQ,UAAS,oBAAI,IAAoB;AACzC,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AAMN,WAAK,MAAM;AACX,WAAK,aAAa;AAClB,WAAK,OAAO,WAAW;AACvB,YAAM,SAAS,WAAW,UAAU;AACpC,WAAK,UAAU,OAAO,WAAW;AACjC,WAAK,WAAW,OAAO,YAAY;AACnC,WAAK,MAAM,OAAO,SAAS,OAAO,KAAK,KAAK;AAAA,IAC9C;AAAA,IAEA,gBAA+D;AAC7D,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,OAAO,SAAgD;AACrD,YAAM,YAAY,KAAK,IAAI;AAC3B,aAAO,MAAM,gBAAgB,QAAQ,QAAQ,EAAE;AAC/C,YAAM,UAAU,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI;AAChD,cAAQ,SAAS;AAEjB,YAAM,eAAe,KAAK,gBAAgB,OAAO;AACjD,UAAI,iBAAiB,MAAM;AACzB,eAAO,MAAM,cAAc,QAAQ,QAAQ,EAAE;AAC7C,gBAAQ,WAAW,aAAa,IAAI;AACpC,eAAO,KAAK,aAAa,cAAc,UAAU,KAAK,WAAW,IAAI;AAAA,MACvE;AAGA,UAAI,QAAQ,SAAS,SAAS,GAAG,KAAK,QAAQ,WAAW;AACvD,cAAM,kBAAkB,KAAK,mBAAmB,OAAO;AACvD,YAAI,oBAAoB,MAAM;AAC5B,iBAAO,MAAM,kBAAkB,QAAQ,QAAQ,EAAE;AACjD,kBAAQ,WAAW,gBAAgB,IAAI;AACvC,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,eAAe,QAAQ,QAAQ,EAAE;AAC9C,cAAQ,QAAQ;AAGhB,aAAO,KAAK;AAAA,QACV,EAAE,MAAM,QAAQ,sBAAsB,QAAQ,UAAU,QAAQ,CAAC,EAAE;AAAA,QACnE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,KAAK,SAA6B,QAAiC;AACjE,UAAI,CAAC,OAAO,MAAO;AACnB,YAAM,UAAU,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI;AAGhD,YAAM,cAAiC;AAAA,QACrC,MAAM,OAAO;AAAA,QACb,QAAQ,OAAO,UAAU,CAAC;AAAA,MAC5B;AACA,WAAK,WAAW,QAAQ,oBAAoB,KAAK,UAAU,WAAW,CAAC;AAEvE,aAAO,MAAM,mBAAmB,QAAQ,QAAQ,EAAE;AAClD,cAAQ,WAAW,OAAO,KAAK;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA,IAKA,cACE,cACA,SACM;AACN,UAAI,CAAC,QAAQ,UAAW;AACxB,YAAM,UAAU,KAAK,IAAI;AAAA,QACvB,QAAQ,SAAS,MAAM,QAAQ;AAAA,QAC/B,KAAK;AAAA,MACP;AAGA,YAAM,oBAAoB;AAAA,QACxB,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AACA,WAAK,WAAW,mBAAmB,KAAK,UAAU,YAAY,CAAC;AAG/D,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAEA,iBAAW,CAAC,SAAS,SAAS,KAAK,OAAO,QAAQ,SAAS,GAAG;AAC5D,aAAK,WAAW,SAAS,SAAS;AAAA,MACpC;AACA,cAAQ,WAAW,KAAK,UAAU,YAAY,CAAC;AAAA,IACjD;AAAA;AAAA;AAAA;AAAA;AAAA,IAMQ,gBAAgB,SAAuD;AAE7E,UAAI,KAAK,kBAAkB,QAAQ,kBAAkB,GAAG;AACtD,eAAO;AAAA,MACT;AAEA,YAAM,cAAc,KAAK,WAAW,IAAI,QAAQ,kBAAkB;AAClE,UAAI,CAAC,YAAa,QAAO;AAEzB,WAAK,WAAW,QAAQ,kBAAkB;AAG1C,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,WAAW;AACrC,YAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;AAClD,iBAAO;AAAA,YACL,MAAM,OAAO,OAAO,IAAI;AAAA,YACxB,QAAQ,OAAO,UAAU,CAAC;AAAA,UAC5B;AAAA,QACF;AAEA,eAAO,EAAE,MAAM,aAAa,QAAQ,CAAC,EAAE;AAAA,MACzC,QAAQ;AAEN,eAAO,EAAE,MAAM,aAAa,QAAQ,CAAC,EAAE;AAAA,MACzC;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMQ,mBAAmB,SAAuD;AAChF,UAAI,CAAC,QAAQ,UAAW,QAAO;AAE/B,YAAM,oBAAoB;AAAA,QACxB,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAGA,UAAI,KAAK,kBAAkB,iBAAiB,GAAG;AAC7C,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,KAAK,WAAW,IAAI,iBAAiB;AAC3D,UAAI,CAAC,cAAe,QAAO;AAC3B,WAAK,WAAW,iBAAiB;AAEjC,UAAI;AACF,cAAM,eAAe,KAAK,MAAM,aAAa;AAC7C,cAAM,QAAQ,iBAAiB,cAAc,QAAQ,QAAQ;AAE7D,YAAI,UAAU,QAAQ,UAAU,QAAW;AAEzC,cAAI;AAEJ,cAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,OAAO;AAElE,0BAAc;AAAA,cACZ,MAAM,OAAQ,MAA4B,IAAI;AAAA,cAC9C,QAAS,MAAgD,UAAU,CAAC;AAAA,YACtE;AAAA,UACF,OAAO;AAEL,0BAAc,EAAE,MAAM,OAAO,KAAK,GAAG,QAAQ,CAAC,EAAE;AAAA,UAClD;AAGA,eAAK,WAAW,QAAQ,oBAAoB,KAAK,UAAU,WAAW,CAAC;AAEvE,iBAAO,MAAM,0BAA0B,QAAQ,QAAQ,EAAE;AACzD,iBAAO;AAAA,QACT;AAAA,MACF,SAAS,OAAO;AAEd,eAAO;AAAA,UACL,oCAAoC,iBAAiB;AAAA,UACrD;AAAA,QACF;AACA,aAAK,WAAW,OAAO,iBAAiB;AACxC,aAAK,OAAO,OAAO,iBAAiB;AAAA,MACtC;AAEA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA,IAMQ,aACN,aACA,QACA,QACA,WACA,QACmB;AACnB,aAAO;AAAA,QACL,OAAO,YAAY;AAAA,QACnB,QAAQ,YAAY;AAAA,QACpB;AAAA,QACA;AAAA,QACA,UAAU,KAAK,IAAI,IAAI;AAAA,QACvB,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,MACvC;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMQ,kBAAkB,UAA2B;AACnD,YAAM,YAAY,KAAK,OAAO,IAAI,QAAQ;AAC1C,UAAI,aAAa,KAAK,IAAI,IAAI,YAAY,KAAK,KAAK;AAClD,aAAK,WAAW,OAAO,QAAQ;AAC/B,aAAK,OAAO,OAAO,QAAQ;AAC3B,eAAO,MAAM,gBAAgB,QAAQ,EAAE;AACvC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKQ,WAAW,UAAkB,OAAqB;AACxD,WAAK,WAAW,IAAI,UAAU,KAAK;AACnC,WAAK,OAAO,IAAI,UAAU,KAAK,IAAI,CAAC;AAAA,IACtC;AAAA;AAAA;AAAA;AAAA,IAKQ,WAAW,UAAwB;AACzC,WAAK,OAAO,IAAI,UAAU,KAAK,IAAI,CAAC;AAAA,IACtC;AAAA;AAAA;AAAA;AAAA,IAKA,aAGE;AACA,YAAM,UAGF,CAAC;AACL,YAAM,MAAM,KAAK,IAAI;AAErB,iBAAW,CAAC,KAAK,SAAS,KAAK,KAAK,OAAO,QAAQ,GAAG;AACpD,cAAM,MAAM,MAAM;AAClB,cAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG;AAC5C,gBAAQ,GAAG,IAAI,EAAE,WAAW,KAAK,UAAU;AAAA,MAC7C;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,aAAa;AACX,UAAI,KAAK,WAAW,eAAe,QAAW;AAC5C,eAAO,KAAK,WAAW,WAAW;AAAA,MACpC;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,eAAe,QAAgB,WAAyB;AACtD,YAAM,oBAAoB,wBAAwB,QAAQ,SAAS;AACnE,YAAM,YAAY,GAAG,MAAM,IAAI,SAAS;AAGxC,WAAK,WAAW,OAAO,iBAAiB;AACxC,WAAK,OAAO,OAAO,iBAAiB;AAGpC,YAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAI,SAAS;AACX,mBAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACtC,cAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,iBAAK,WAAW,OAAO,GAAG;AAC1B,iBAAK,OAAO,OAAO,GAAG;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,sBAAsB,MAAM,IAAI,SAAS,EAAE;AAAA,IAC1D;AAAA,IAEA,UAAgB;AACd,WAAK,WAAW,MAAM;AACtB,WAAK,OAAO,MAAM;AAAA,IACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,SAAS,KAAa,OAAe,QAAyC;AAC5E,YAAM,cAAiC;AAAA,QACrC,MAAM;AAAA,QACN,QAAQ,UAAU,CAAC;AAAA,MACrB;AACA,WAAK,WAAW,KAAK,KAAK,UAAU,WAAW,CAAC;AAChD,aAAO,MAAM,qBAAqB,GAAG,EAAE;AAAA,IACzC;AAAA,EACF;;;ACnVO,MAAM,eAAN,MAA4C;AAAA,IAWjD,YACE,cACA,YACA;AAbF,0BAAS;AACT,0BAAS,WAAU;AACnB,0BAAS;AACT,0BAAS,QAAO;AAChB,0BAAS;AACT,0BAAQ,UAAS,oBAAI,IAAoB;AACzC,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AAMN,WAAK,MAAM;AACX,WAAK,aAAa;AAClB,WAAK,OAAO,WAAW;AACvB,YAAM,SAAS,WAAW,UAAU;AACpC,WAAK,UAAU,OAAO,WAAW;AACjC,WAAK,WAAW,OAAO,YAAY;AACnC,WAAK,MAAM,OAAO,SAAS,OAAO,KAAK,KAAK;AAAA,IAC9C;AAAA,IAEA,gBAA+D;AAC7D,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,OAAO,SAAyD;AACpE,YAAM,YAAY,KAAK,IAAI;AAC3B,aAAO,MAAM,iBAAiB,QAAQ,QAAQ,EAAE;AAChD,YAAM,UAAU,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI;AAEhD,YAAM,eAAe,MAAM,KAAK,gBAAgB,OAAO;AACvD,UAAI,iBAAiB,MAAM;AACzB,eAAO,MAAM,cAAc,QAAQ,QAAQ,EAAE;AAC7C,gBAAQ,WAAW,aAAa,IAAI;AACpC,eAAO,KAAK,aAAa,cAAc,WAAW,KAAK,WAAW,IAAI;AAAA,MACxE;AAGA,UAAI,QAAQ,SAAS,SAAS,GAAG,KAAK,QAAQ,WAAW;AACvD,cAAM,kBAAkB,MAAM,KAAK,mBAAmB,OAAO;AAC7D,YAAI,oBAAoB,MAAM;AAC5B,iBAAO,MAAM,kBAAkB,QAAQ,QAAQ,EAAE;AACjD,kBAAQ,WAAW,gBAAgB,IAAI;AACvC,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,eAAe,QAAQ,QAAQ,EAAE;AAC9C,cAAQ,QAAQ;AAGhB,aAAO,KAAK;AAAA,QACV,EAAE,MAAM,QAAQ,sBAAsB,QAAQ,UAAU,QAAQ,CAAC,EAAE;AAAA,QACnE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,KACJ,SACA,QACe;AACf,UAAI,CAAC,OAAO,MAAO;AACnB,YAAM,UAAU,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI;AAGhD,YAAM,cAAiC;AAAA,QACrC,MAAM,OAAO;AAAA,QACb,QAAQ,OAAO,UAAU,CAAC;AAAA,MAC5B;AACA,YAAM,KAAK,WAAW,QAAQ,oBAAoB,KAAK,UAAU,WAAW,CAAC;AAE7E,aAAO,MAAM,mBAAmB,QAAQ,QAAQ,EAAE;AAClD,cAAQ,WAAW,OAAO,KAAK;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,cACJ,cACA,SACe;AACf,UAAI,CAAC,QAAQ,UAAW;AACxB,YAAM,UAAU,KAAK,IAAI;AAAA,QACvB,QAAQ,SAAS,MAAM,QAAQ;AAAA,QAC/B,KAAK;AAAA,MACP;AACA,YAAM,WAAW,OAAO,KAAK,YAAY,EAAE;AAC3C,aAAO;AAAA,QACL,qBAAqB,QAAQ,MAAM,IAAI,QAAQ,SAAS,KAAK,QAAQ;AAAA,MACvE;AAGA,YAAM,oBAAoB;AAAA,QACxB,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AACA,YAAM,KAAK,WAAW,mBAAmB,KAAK,UAAU,YAAY,CAAC;AAGrE,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAEA,UAAI,aAAa;AACjB,iBAAW,CAAC,SAAS,SAAS,KAAK,OAAO,QAAQ,SAAS,GAAG;AAC5D,cAAM,KAAK,WAAW,SAAS,SAAS;AACxC;AAAA,MACF;AAEA,aAAO,MAAM,UAAU,UAAU,wBAAwB;AACzD,cAAQ,WAAW,KAAK,UAAU,YAAY,CAAC;AAAA,IACjD;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,gBACZ,SACmC;AAEnC,UAAI,MAAM,KAAK,kBAAkB,QAAQ,kBAAkB,GAAG;AAC5D,eAAO;AAAA,MACT;AAEA,YAAM,cAAc,MAAM,KAAK,WAAW,IAAI,QAAQ,kBAAkB;AACxE,UAAI,CAAC,YAAa,QAAO;AAEzB,WAAK,WAAW,QAAQ,kBAAkB;AAG1C,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,WAAW;AACrC,YAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;AAClD,iBAAO;AAAA,YACL,MAAM,OAAO,OAAO,IAAI;AAAA,YACxB,QAAQ,OAAO,UAAU,CAAC;AAAA,UAC5B;AAAA,QACF;AAEA,eAAO,EAAE,MAAM,aAAa,QAAQ,CAAC,EAAE;AAAA,MACzC,QAAQ;AAEN,eAAO,EAAE,MAAM,aAAa,QAAQ,CAAC,EAAE;AAAA,MACzC;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,mBACZ,SACmC;AACnC,UAAI,CAAC,QAAQ,UAAW,QAAO;AAE/B,YAAM,oBAAoB;AAAA,QACxB,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAGA,UAAI,MAAM,KAAK,kBAAkB,iBAAiB,GAAG;AACnD,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,MAAM,KAAK,WAAW,IAAI,iBAAiB;AACjE,UAAI,CAAC,cAAe,QAAO;AAC3B,WAAK,WAAW,iBAAiB;AAEjC,UAAI;AACF,cAAM,eAAe,KAAK,MAAM,aAAa;AAC7C,cAAM,QAAQ,iBAAiB,cAAc,QAAQ,QAAQ;AAE7D,YAAI,UAAU,QAAQ,UAAU,QAAW;AAEzC,cAAI;AAEJ,cAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,OAAO;AAElE,0BAAc;AAAA,cACZ,MAAM,OAAQ,MAA4B,IAAI;AAAA,cAC9C,QAAS,MAAgD,UAAU,CAAC;AAAA,YACtE;AAAA,UACF,OAAO;AAEL,0BAAc,EAAE,MAAM,OAAO,KAAK,GAAG,QAAQ,CAAC,EAAE;AAAA,UAClD;AAGA,gBAAM,KAAK,WAAW,QAAQ,oBAAoB,KAAK,UAAU,WAAW,CAAC;AAE7E,iBAAO,MAAM,0BAA0B,QAAQ,QAAQ,EAAE;AACzD,iBAAO;AAAA,QACT;AAAA,MACF,SAAS,OAAO;AAEd,eAAO;AAAA,UACL,oCAAoC,iBAAiB;AAAA,UACrD;AAAA,QACF;AACA,cAAM,KAAK,WAAW,OAAO,iBAAiB;AAC9C,aAAK,OAAO,OAAO,iBAAiB;AAAA,MACtC;AAEA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA,IAMQ,aACN,aACA,QACA,QACA,WACA,QACmB;AACnB,aAAO;AAAA,QACL,OAAO,YAAY;AAAA,QACnB,QAAQ,YAAY;AAAA,QACpB;AAAA,QACA;AAAA,QACA,UAAU,KAAK,IAAI,IAAI;AAAA,QACvB,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,MACvC;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,kBAAkB,UAAoC;AAClE,YAAM,YAAY,KAAK,OAAO,IAAI,QAAQ;AAC1C,UAAI,aAAa,KAAK,IAAI,IAAI,YAAY,KAAK,KAAK;AAClD,cAAM,KAAK,WAAW,OAAO,QAAQ;AACrC,aAAK,OAAO,OAAO,QAAQ;AAC3B,eAAO,MAAM,gBAAgB,QAAQ,EAAE;AACvC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAc,WAAW,UAAkB,OAA8B;AACvE,YAAM,KAAK,WAAW,IAAI,UAAU,KAAK;AACzC,WAAK,OAAO,IAAI,UAAU,KAAK,IAAI,CAAC;AAAA,IACtC;AAAA;AAAA;AAAA;AAAA,IAKQ,WAAW,UAAwB;AACzC,WAAK,OAAO,IAAI,UAAU,KAAK,IAAI,CAAC;AAAA,IACtC;AAAA;AAAA;AAAA;AAAA,IAKA,aAGE;AACA,YAAM,UAGF,CAAC;AACL,YAAM,MAAM,KAAK,IAAI;AAErB,iBAAW,CAAC,KAAK,SAAS,KAAK,KAAK,OAAO,QAAQ,GAAG;AACpD,cAAM,MAAM,MAAM;AAClB,cAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG;AAC5C,gBAAQ,GAAG,IAAI,EAAE,WAAW,KAAK,UAAU;AAAA,MAC7C;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,UAAyB;AAC7B,YAAM,KAAK,WAAW,MAAM;AAC5B,WAAK,OAAO,MAAM;AAAA,IACpB;AAAA,IAEA,aAAiD;AAC/C,UAAI,KAAK,WAAW,eAAe,QAAW;AAC5C,eAAO,KAAK,WAAW,WAAW;AAAA,MACpC;AAAA,IACF;AAAA,EACF;;;ACrVO,MAAM,mBAAN,cAA+B,MAAM;AAAA,IAC1C,YACkB,KACA,QAChB,SACA;AACA,YAAM,OAAO;AAJG;AACA;AAIhB,WAAK,OAAO,KAAK,YAAY;AAE7B,UAAI,MAAM,mBAAmB;AAC3B,cAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAMO,MAAM,2BAAN,cAAuC,iBAAiB;AAAA,IAC7D,YAAY,KAAa;AACvB,YAAM,KAAK,KAAK,0BAA0B,GAAG,EAAE;AAAA,IACjD;AAAA,EACF;AAMO,MAAM,yBAAN,cAAqC,iBAAiB;AAAA,IAC3D,YACE,KACgB,YAChB;AACA,YAAM,KAAK,KAAK,uBAAuB,GAAG,EAAE;AAF5B;AAAA,IAGlB;AAAA,EACF;AAMO,MAAM,cAAN,cAA0B,iBAAiB;AAAA,IAChD,YAAY,KAAa,QAAgB;AACvC,YAAM,KAAK,QAAQ,gBAAgB,MAAM,KAAK,GAAG,EAAE;AAAA,IACrD;AAAA,EACF;AAMO,MAAM,eAAN,cAA2B,MAAM;AAAA,IACtC,YAAY,SAAiC,OAAiB;AAC5D,YAAM,OAAO;AAD8B;AAE3C,WAAK,OAAO;AACZ,UAAI,MAAM,mBAAmB;AAC3B,cAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAYO,WAAS,iBAAiB,OAAyB;AACxD,WAAO,iBAAiB,eAAe,iBAAiB;AAAA,EAC1D;;;ACtDO,MAAM,iBAAN,MAA8C;AAAA,IAYnD,YAAY,cAA4B,YAA8B;AAXtE;AACA,0BAAS;AACT,0BAAS;AACT,0BAAS,WAAU;AACnB,0BAAS,QAAO;AAChB,0BAAS;AACT,0BAAQ;AAER,0BAAQ;AACR,0BAAQ;AAGN,WAAK,MAAM;AACX,WAAK,aAAa;AAClB,WAAK,OAAO,WAAW;AACvB,YAAM,SAAS,WAAW,UAAU;AACpC,WAAK,UAAU,OAAO,WAAW;AACjC,WAAK,WAAW,OAAO,YAAY;AACnC,WAAK,aAAa,OAAO,SAAS,WAAW;AAC7C,WAAK,aAAa,OAAO,SAAS,cAAc;AAAA,IAClD;AAAA,IAEA,aAA4B;AAC1B,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,IAEA,gBAA+D;AAC7D,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,MAAM,OAAO,SAAyD;AACpE,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,gBAAgB,QAAQ,sBAAsB,QAAQ;AAE5D,UAAI,CAAC,KAAK,SAAS;AACjB,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,KAAK,IAAI,QAAQ,SAAS,KAAK,IAAI;AACtD,iBAAW,MAAM;AACjB,aAAO,MAAM,mBAAmB,QAAQ,QAAQ,EAAE;AAGlD,UAAI;AACF,cAAM,cAAc,MAAM,KAAK;AAAA,UAC7B,QAAQ;AAAA,QACV;AAEA,eAAO,MAAM,gBAAgB,QAAQ,QAAQ,EAAE;AAC/C,mBAAW,QAAQ,YAAY,IAAI;AAGnC,eAAO,KAAK;AAAA,UACV,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAY;AAAA,QACd;AAAA,MACF,SAAS,OAAO;AAEd,YAAI,iBAAiB,4BAA4B,QAAQ,WAAW;AAClE,iBAAO;AAAA,YACL,+CAA+C,QAAQ,QAAQ;AAAA,UACjE;AACA,iBAAO,KAAK,oBAAoB,SAAS,eAAe,WAAW,UAAU;AAAA,QAC/E;AAGA,YAAI,iBAAiB,wBAAwB;AAC3C,iBAAO,MAAM,6BAA6B,QAAQ,QAAQ,EAAE;AAC5D,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAGA,eAAO,MAAM,kBAAkB,QAAQ,QAAQ,IAAI,KAAK;AACxD,mBAAW,MAAM,KAAc;AAE/B,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,MAAc,oBACZ,SACA,eACA,WAEA,YAC4B;AAC5B,UAAI;AACF,cAAM,kBAAkB,MAAM,KAAK;AAAA,UACjC,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAEA,YAAI,mBAAmB,gBAAgB,MAAM;AAC3C,gBAAM,cAAc;AAAA,YAClB,gBAAgB;AAAA,YAChB,QAAQ;AAAA,UACV;AAEA,cAAI,gBAAgB,UAAa,gBAAgB,MAAM;AAErD,gBAAI;AACJ,gBAAI,SAAmC,CAAC;AAExC,gBAAI,OAAO,gBAAgB,YAAY,gBAAgB,QAAQ,UAAU,aAAa;AAEpF,oBAAM,cAAc;AACpB,8BAAgB,OAAO,YAAY,IAAI;AACvC,uBAAS,YAAY,UAAU,CAAC;AAAA,YAClC,OAAO;AAEL,8BAAgB,OAAO,WAAW;AAAA,YACpC;AAEA,mBAAO,MAAM,0BAA0B,QAAQ,QAAQ,eAAe,OAAO,KAAK,MAAM,EAAE,SAAS,CAAC,EAAE;AACtG,uBAAW,QAAQ,aAAa;AAEhC,mBAAO,KAAK;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,gBACE,QAAQ,QAAQ;AAAA,gBAChB,WAAW,QAAQ;AAAA,gBACnB,MAAM,gBAAgB;AAAA,cACxB;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,QAAQ,IAAI,yBAAyB,QAAQ,QAAQ;AAC3D,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,SAAS,SAAS;AAEhB,eAAO,MAAM,0BAA0B,QAAQ,QAAQ,IAAI,OAAO;AAElE,YAAI,mBAAmB,0BAA0B;AAC/C,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,YAAI,mBAAmB,wBAAwB;AAC7C,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,MAAM,OAAgB;AACjC,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,cACJ,QACA,WACiC;AACjC,YAAM,YAAY,KAAK,IAAI;AAE3B,UAAI,CAAC,KAAK,SAAS;AACjB,eAAO,KAAK,sBAAsB,MAAM,YAAY,GAAG,SAAS;AAAA,MAClE;AAEA,UAAI;AACF,cAAM,OAAO,MAAM,KAAK,uBAAuB,QAAQ,SAAS;AAGhE,YAAI,SAAS,MAAM;AACjB,iBAAO,MAAM,mCAAmC,MAAM,IAAI,SAAS,EAAE;AACrE,iBAAO,KAAK,sBAAsB,MAAM,WAAW,KAAK,SAAS;AAAA,QACnE;AAEA,eAAO,MAAM,6BAA6B,MAAM,IAAI,SAAS,EAAE;AAC/D,eAAO,KAAK,sBAAsB,MAAM,WAAW,KAAK,SAAS;AAAA,MACnE,SAAS,OAAO;AACd,YAAI,iBAAiB,wBAAwB;AAC3C,iBAAO,MAAM,2BAA2B,MAAM,IAAI,SAAS,EAAE;AAE7D,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,YAAI,iBAAiB,0BAA0B;AAC7C,iBAAO,MAAM,gCAAgC,MAAM,IAAI,SAAS,EAAE;AAElE,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,eAAO,MAAM,4BAA4B,MAAM,IAAI,SAAS,IAAI,KAAK;AAErE,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,uBACZ,QACA,WACiC;AACjC,aAAO,KAAK;AAAA,QACV,MAAM,KAAK,WAAW,aAAa,QAAQ,SAAS;AAAA,QACpD,GAAG,MAAM,IAAI,SAAS;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,KACJ,SACA,QACe;AAEf,WAAK;AACL,WAAK;AAAA,IACP;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,gBAAgB,UAAmC;AAC/D,aAAO,KAAK;AAAA,QACV,MAAM,KAAK,WAAW,IAAI,QAAQ;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,MAAc,2BAA2B,UAAwC;AAE/E,YAAM,OAAO,KAAK;AAClB,UAAI,OAAO,KAAK,mBAAmB,YAAY;AAE7C,cAAM,OAAO,MAAM,KAAK,gBAAgB,QAAQ;AAChD,eAAO,EAAE,MAAM,QAAQ,CAAC,EAAE;AAAA,MAC5B;AAEA,aAAO,KAAK;AAAA,QACV,MAAM,KAAK,eAAe,QAAQ;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,MAAM,IAA2B;AACvC,aAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AAAA,IACvD;AAAA,IAEQ,iBAAiB,SAAyB;AAChD,YAAM,YAAY,KAAK;AACvB,YAAM,mBAAmB,YAAY,KAAK,IAAI,GAAG,UAAU,CAAC;AAC5D,YAAM,WAAW;AAGjB,YAAM,SAAS,KAAK,OAAO,IAAI,MAAM;AAErC,aAAO,KAAK,IAAI,mBAAmB,QAAQ,QAAQ;AAAA,IACrD;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,UACZ,WACA,YACA,oBACA,UAAU,GACE;AACZ,YAAM,aAAa,KAAK,IAAI,QAAQ,YAAY,WAAW;AAE3D,UAAI;AACF,eAAO,MAAM,UAAU;AAAA,MACzB,SAAS,OAAO;AAEd,YAAI,WAAW,KAAK,cAAc,iBAAiB,KAAK,GAAG;AACzD,gBAAM,QAAQ,KAAK,iBAAiB,OAAO;AAC3C,qBAAW,MAAM,SAAS,OAAQ,MAAgB,OAAO;AACzD,gBAAM,KAAK,MAAM,KAAK;AAEtB,iBAAO;AAAA,YACL,YAAY,kBAAkB,KAAK,OAAO,IAAI,KAAK,UAAU,WAAW,KAAK;AAAA,UAC/E;AACA,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,UACZ;AAAA,QACF;AAGA,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,0BACN,SACA,eACA,OACA,WACmB;AACnB,aAAO,MAAM,2BAA2B,QAAQ,QAAQ,EAAE;AAC1D,YAAM,eAAe,KAAK,IAAI,YAAY,OAAO;AACjD,mBAAa;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,aAAa;AAAA,MACvB;AAEA,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,wBACN,SACA,eACA,OACA,WAEA,YACmB;AACnB,YAAM,eAAe,KAAK,IAAI,YAAY,OAAO;AACjD,mBAAa;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,aAAa;AAAA,MACvB;AACA,iBAAW,MAAM,OAAO,GAAG;AAE3B,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,wBACN,OACA,QACA,QACA,WACA,OACA,QACA,iBAKA,QACmB;AACnB,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,KAAK,IAAI,IAAI;AAAA,QACvB,GAAI,SAAS,EAAE,MAAM;AAAA,QACrB,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,QACrC,GAAI,mBAAmB,EAAE,gBAAgB;AAAA,QACzC,GAAI,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,KAAK,EAAE,OAAO;AAAA,MAC3D;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,sBACN,MACA,QACA,QACA,WACA,OACiB;AACjB,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,KAAK,IAAI,IAAI;AAAA,QACvB,GAAI,SAAS,EAAE,MAAM;AAAA,MACvB;AAAA,IACF;AAAA,IAEA,aAAuC;AACrC,YAAM,SAAS,KAAK,WAAW,UAAU;AACzC,aAAO,OAAO,SAAS,qBAAqB,CAAC;AAAA,IAC/C;AAAA,EACF;;;ACpfO,MAAM,YAAY,oBAAI,IAAI;AAAA,IAC/B;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAM;AAAA,IAAO;AAAA,IAAS;AAAA,IAAM;AAAA,IAAO;AAAA,IACnD;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAU;AAAA,IAAS;AAAA,EAC9C,CAAC;AAED,WAAS,gBAAgB,OAAuB;AAC9C,WAAO,MAAM,QAAQ,MAAM,QAAQ;AAAA,EACrC;AAMO,WAAS,oBACd,SACA,OACQ;AACR,UAAM,MAAM,QAAQ,YAAY;AAChC,QAAI,SAAS,IAAI,GAAG;AACpB,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,gBAAU,IAAI,KAAK,YAAY,CAAC,KAAK,gBAAgB,KAAK,CAAC;AAAA,IAC7D;AACA,cAAU;AACV,WAAO;AAAA,EACT;AAMO,WAAS,eAAe,YAA4B;AACzD,UAAM,MAAM,WAAW,OAAO,OAAO;AACrC,WAAO,WAAW,MAAM,GAAG,QAAQ,KAAK,WAAW,SAAS,GAAG,EAAE,YAAY;AAAA,EAC/E;AAMO,WAAS,aAAa,QAAiC;AAC5D,eAAW,KAAK,QAAQ;AACtB,UAAI,EAAE,WAAW,MAAM,EAAG,QAAO,EAAE,MAAM,CAAC;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;;;ACbA,WAAS,eAAe,MAAsB;AAC5C,UAAM,QAAgC;AAAA,MACpC,KAAK;AAAA,MAAK,IAAI;AAAA,MAAK,IAAI;AAAA,MAAK,MAAM;AAAA,MAAK,MAAM;AAAA,MAAK,MAAM;AAAA,MACxD,OAAO;AAAA,MAAK,OAAO;AAAA,MAAK,OAAO;AAAA,MAAK,OAAO;AAAA,MAC3C,QAAQ;AAAA,MAAK,OAAO;AAAA,MAAK,OAAO;AAAA,MAAK,MAAM;AAAA,MAC3C,KAAK;AAAA,MAAK,OAAO;AAAA,IACnB;AACA,WAAO,KAAK,QAAQ,4CAA4C,CAAC,GAAG,SAAS;AAC3E,UAAI,KAAK,CAAC,MAAM,KAAK;AACnB,cAAM,KAAK,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,MAAM,MACtC,SAAS,KAAK,MAAM,CAAC,GAAG,EAAE,IAC1B,SAAS,KAAK,MAAM,CAAC,GAAG,EAAE;AAC9B,YAAI,OAAO,SAAS,EAAE,KAAK,KAAK,GAAG;AACjC,cAAI;AAAE,mBAAO,OAAO,cAAc,EAAE;AAAA,UAAG,QAAQ;AAAE,mBAAO;AAAA,UAAG;AAAA,QAC7D;AACA,eAAO;AAAA,MACT;AACA,aAAO,MAAM,KAAK,YAAY,CAAC,KAAK;AAAA,IACtC,CAAC;AAAA,EACH;AAEO,MAAM,eAAN,MAA8C;AAAA,IACnD,MAAM,OAA4B;AAGhC,UAAI,cAAc,KAAK,KAAK,GAAG;AAC7B,eAAO,EAAE,MAAM,eAAe,KAAK,GAAG,QAAQ,CAAC,EAAE;AAAA,MACnD;AAEA,YAAM,SAAmC,CAAC;AAC1C,UAAI,WAAW;AACf,YAAM,WAAkD,CAAC;AACzD,UAAI,SAAS;AACb,UAAI,MAAM;AAEV,aAAO,MAAM,MAAM,QAAQ;AACzB,cAAM,MAAM,KAAK,SAAS,OAAO,GAAG;AACpC,YAAI,CAAC,KAAK;AACR,oBAAU,MAAM,MAAM,GAAG;AACzB;AAAA,QACF;AAEA,kBAAU,MAAM,MAAM,KAAK,IAAI,UAAU;AAEzC,YAAI,IAAI,WAAW;AACjB,cAAI,WAA0B;AAC9B,mBAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,gBAAI,SAAS,CAAC,EAAE,QAAQ,IAAI,IAAI,YAAY,GAAG;AAC7C,yBAAW,SAAS,CAAC,EAAE;AACvB,uBAAS,OAAO,GAAG,CAAC;AACpB;AAAA,YACF;AAAA,UACF;AACA,cAAI,aAAa,MAAM;AACrB,sBAAU,KAAK,QAAQ;AAAA,UACzB;AAAA,QAEF,OAAO;AACL,gBAAM,UAAU,IAAI,IAAI,YAAY;AACpC,gBAAM,SAAS,UAAU,IAAI,OAAO;AACpC,gBAAM,gBAAgB,IAAI,iBAAiB;AAE3C;AACA,iBAAO,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,oBAAoB,SAAS,IAAI,KAAK,CAAC,EAAE;AAE5E,cAAI,eAAe;AACjB,sBAAU,IAAI,QAAQ;AAAA,UACxB,OAAO;AACL,sBAAU,IAAI,QAAQ;AACtB,qBAAS,KAAK,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,UACjD;AAAA,QACF;AAEA,cAAM,IAAI;AAAA,MACZ;AAEA,aAAO,SAAS,SAAS,GAAG;AAC1B,cAAM,WAAW,SAAS,IAAI;AAC9B,kBAAU,KAAK,SAAS,KAAK;AAAA,MAC/B;AAEA,aAAO,EAAE,MAAM,eAAe,MAAM,GAAG,OAAO;AAAA,IAChD;AAAA,IAEQ,SAAS,OAAe,UAAmC;AACjE,YAAM,WAAW,MAAM,QAAQ,KAAK,QAAQ;AAC5C,UAAI,aAAa,GAAI,QAAO;AAE5B,YAAM,aACJ;AACF,YAAM,YAAY,MAAM,MAAM,QAAQ;AACtC,YAAM,QAAQ,UAAU,MAAM,UAAU;AAExC,UAAI,CAAC,OAAO;AACV,YAAI,WAAW,IAAI,MAAM,QAAQ;AAC/B,iBAAO,KAAK,SAAS,OAAO,WAAW,CAAC;AAAA,QAC1C;AACA,eAAO;AAAA,MACT;AAEA,YAAM,CAAC,WAAW,cAAc,SAAS,aAAa,gBAAgB,IAAI;AAC1E,aAAO;AAAA,QACL,KAAK;AAAA,QACL,OAAO,KAAK,gBAAgB,WAAW;AAAA,QACvC,WAAW,iBAAiB;AAAA,QAC5B,eAAe,qBAAqB;AAAA,QACpC,YAAY;AAAA,QACZ,UAAU,WAAW,UAAU;AAAA,MACjC;AAAA,IACF;AAAA,IAEQ,gBAAgB,aAA6C;AACnE,YAAM,QAAgC,CAAC;AACvC,UAAI,CAAC,YAAY,KAAK,EAAG,QAAO;AAEhC,YAAM,cAAc;AACpB,UAAI;AACJ,cAAQ,QAAQ,YAAY,KAAK,WAAW,OAAO,MAAM;AACvD,cAAM,CAAC,EAAE,MAAM,cAAc,cAAc,QAAQ,IAAI;AACvD,cAAM,KAAK,YAAY,CAAC,IAAI,gBAAgB,gBAAgB,YAAY;AAAA,MAC1E;AACA,aAAO;AAAA,IACT;AAAA,EACF;;;ACnJO,MAAM,YAAY,oBAAI,IAAI;AAAA,IAC/B;AAAA,IAAK;AAAA,IAAQ;AAAA,IAAK;AAAA,IAAO;AAAA,IAAO;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAO;AAAA,IAC7D;AAAA,IAAM;AAAA,IAAK;AAAA,IAAO;AAAA,IAAO;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAK;AAAA,IAAK;AAAA,IAAQ;AAAA,IAC1D;AAAA,IAAQ;AAAA,IAAU;AAAA,IAAO;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAK;AAAA,IAAO;AAAA,EACtD,CAAC;AAOM,MAAM,aAAa,oBAAI,IAAI;AAAA,IAChC;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAY;AAAA,IAAO;AAAA,IAAU;AAAA,IAAQ;AAAA,IAC7D;AAAA,IAAQ;AAAA,IAAW;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAU;AAAA,IAAS;AAAA,EAC9D,CAAC;AAGD,MAAM,YAAY,oBAAI,IAAI,CAAC,QAAQ,OAAO,MAAM,CAAC;AA0B1C,MAAM,mBAAmB,oBAAI,IAAI;AAAA,IACtC;AAAA,IAAS;AAAA,IAAoB;AAAA,IAAe;AAAA,IAAa;AAAA,IACzD;AAAA,IAAe;AAAA,IAAkB;AAAA,IAAe;AAAA,IAChD;AAAA,IAAyB;AAAA,IAAwB;AAAA,IACjD;AAAA,IAAkB;AAAA,IAAkB;AAAA,IAAe;AAAA,EACrD,CAAC;AAOD,MAAM,sBACJ;AAEF,MAAM,eAAe,oBAAI,IAAI,CAAC,QAAQ,SAAS,UAAU,KAAK,CAAC;AAM/D,MAAM,iBAAyC;AAAA,IAC7C,KAAK;AAAA,IAAK,IAAI;AAAA,IAAK,IAAI;AAAA,IAAK,MAAM;AAAA,IAAK,MAAM;AAAA,IAAK,MAAM;AAAA,IACxD,OAAO;AAAA,IAAK,MAAM;AAAA,IAAK,KAAK;AAAA,IAAK,MAAM;AAAA,IACvC,KAAK;AAAA,IAAM,SAAS;AAAA,EACtB;AAMA,WAASC,gBAAe,OAAuB;AAC7C,WAAO,MAAM;AAAA,MACX;AAAA,MACA,CAAC,MAAM,KAAa,KAAa,SAAiB;AAChD,YAAI,IAAK,QAAO,OAAO,cAAc,SAAS,KAAK,EAAE,CAAC;AACtD,YAAI,IAAK,QAAO,OAAO,cAAc,SAAS,KAAK,EAAE,CAAC;AACtD,eAAO,eAAe,IAAI,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAGO,WAAS,WAAW,MAAsB;AAC/C,WAAO,KACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAAA,EAC1B;AAUO,WAAS,YAAY,OAA8B;AACxD,UAAM,UAAUA,gBAAe,KAAK;AAEpC,UAAM,QAAQ,QAAQ,QAAQ,0BAA0B,EAAE,EAAE,YAAY;AACxE,UAAM,SAAS,wBAAwB,KAAK,KAAK;AACjD,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,aAAa,IAAI,OAAO,CAAC,CAAC,IAAI,QAAQ;AAAA,EAC/C;AASO,WAAS,cAAc,OAA8B;AAC1D,WAAO,sBAAsB,OAAO,IAAI;AAAA,EAC1C;AAeA,WAAS,sBACP,OACA,sBACe;AACf,UAAM,UAAUC,gBAAe,KAAK;AACpC,UAAM,OAAiB,CAAC;AACxB,eAAW,eAAe,QAAQ,MAAM,GAAG,GAAG;AAC5C,YAAM,QAAQ,YAAY,QAAQ,GAAG;AACrC,UAAI,UAAU,GAAI;AAClB,YAAM,OAAO,YAAY,MAAM,GAAG,KAAK,EAAE,KAAK,EAAE,YAAY;AAC5D,YAAM,MAAM,YAAY,MAAM,QAAQ,CAAC,EAAE,KAAK;AAC9C,UAAI,CAAC,YAAY,KAAK,IAAI,EAAG;AAC7B,UAAI,wBAAwB,CAAC,iBAAiB,IAAI,IAAI,EAAG;AACzD,UAAI,QAAQ,MAAM,oBAAoB,KAAK,GAAG,EAAG;AACjD,WAAK,KAAK,GAAG,IAAI,KAAK,GAAG,EAAE;AAAA,IAC7B;AACA,WAAO,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI;AAAA,EAC7C;AAMA,MAAM,eACJ;AAQK,WAAS,mBAAmB,SAAgC;AACjE,QAAI,CAAC,QAAQ,WAAW,GAAG,EAAG,QAAO;AACrC,UAAM,UAAU,eAAe,OAAO;AACtC,QAAI,CAAC,oBAAoB,KAAK,OAAO,KAAK,CAAC,UAAU,IAAI,OAAO,GAAG;AACjE,aAAO;AAAA,IACT;AAIA,UAAM,MAAM,QAAQ,SAAS,IAAI,IAC7B,QAAQ,SAAS,IACjB,QAAQ,SAAS,GAAG,IAClB,QAAQ,SAAS,IACjB,QAAQ;AACd,UAAM,aAAa,QAAQ,MAAM,IAAI,QAAQ,QAAQ,GAAG;AAExD,UAAM,QAAgC,CAAC;AACvC,eAAW,SAAS,WAAW,SAAS,YAAY,GAAG;AACrD,YAAM,OAAO,MAAM,CAAC,EAAE,YAAY;AAClC,YAAM,QAAQ,MAAM,CAAC,KAAK,MAAM,CAAC,KAAK,MAAM,CAAC,KAAK;AAClD,UAAI,QAAQ,MAAO;AACnB,UAAI,SAAS,SAAS;AAEpB,cAAM,aAAa,cAAc,KAAK;AACtC,YAAI,eAAe,KAAM,OAAM,IAAI,IAAI;AACvC;AAAA,MACF;AACA,YAAM,UACJ,WAAW,IAAI,IAAI,KACnB,oBAAoB,KAAK,IAAI,KAC7B,oBAAoB,KAAK,IAAI;AAC/B,UAAI,CAAC,QAAS;AACd,UAAI,UAAU,IAAI,IAAI,GAAG;AACvB,YAAI,YAAY,KAAK,MAAM,KAAM;AAAA,MACnC;AACA,YAAM,IAAI,IAAI;AAAA,IAChB;AAEA,WAAO,oBAAoB,SAAS,KAAK;AAAA,EAC3C;;;ACxMO,MAAM,iBAAN,MAAoD;AAAA,IACzD,UAAU,MAA2B;AACnC,YAAM,EAAE,MAAM,OAAO,IAAI;AACzB,YAAM,aAAa;AAEnB,UAAI,SAAS;AACb,UAAI,YAAY;AAChB,UAAI;AAEJ,cAAQ,QAAQ,WAAW,KAAK,IAAI,OAAO,MAAM;AAC/C,kBAAU,WAAW,KAAK,MAAM,WAAW,MAAM,KAAK,CAAC;AAEvD,cAAM,CAAC,WAAW,cAAc,QAAQ,IAAI;AAC5C,cAAM,YAAY,OAAO,QAAQ,KAAK,CAAC;AACvC,cAAM,UAAU,aAAa,SAAS;AACtC,cAAM,WAAW,YAAY,OAAO,OAAO,mBAAmB,OAAO;AAErE,YAAI,WAAW,aAAa,MAAM;AAChC,gBAAM,UAAU,eAAe,OAAO;AACtC,gBAAM,SAAS,UAAU,IAAI,OAAO;AAEpC,cAAI,cAAc;AAChB,gBAAI,CAAC,OAAQ,WAAU,KAAK,OAAO;AAAA,UACrC,OAAO;AAGL,sBAAU;AAAA,UACZ;AAAA,QACF,OAAO;AAKL,oBAAU;AAAA,QACZ;AAEA,oBAAY,MAAM,QAAQ,UAAU;AAAA,MACtC;AAEA,gBAAU,WAAW,KAAK,MAAM,SAAS,CAAC;AAC1C,aAAO;AAAA,IACT;AAAA,EACF;;;ACLO,MAAM,eAAN,MAAmB;AAAA,IAMxB,YACE,cACA,KACA,kBACA,gBACA;AAVF,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AAQN,WAAK,eAAe;AACpB,WAAK,MAAM;AACX,WAAK,gBAAgB;AACrB,WAAK,iBAAiB;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,IAAI,KAAgC;AAClC,YAAM,UAAU,KAAK,aAAa,WAAW;AAG7C,iBAAW,eAAe,SAAS;AACjC,cAAM,iBAAiB,QAAQ,WAAW;AAC1C,YAAI,kBAAkB,OAAO,mBAAmB,UAAU;AACxD,cAAI,OAAO,gBAAgB;AACzB,kBAAM,WAAW,eAAe,GAAG;AAGnC,gBAAI;AACF,kBAAI,OAAO,aAAa,UAAU;AAChC,sBAAM,SAAS,KAAK,MAAM,QAAQ;AAClC,oBAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;AAClD,yBAAO;AAAA,oBACL,OAAO,OAAO,OAAO,IAAI;AAAA,oBACzB,QAAQ,OAAO,UAAU;AAAA,kBAC3B;AAAA,gBACF;AAEA,uBAAO,EAAE,OAAO,UAAU,QAAQ,OAAU;AAAA,cAC9C;AAEA,qBAAO;AAAA,gBACL,OAAO,KAAK,UAAU,QAAQ;AAAA,gBAC9B,QAAQ;AAAA,cACV;AAAA,YACF,QAAQ;AAEN,qBAAO;AAAA,gBACL,OAAO,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,QAAQ;AAAA,gBACxE,QAAQ;AAAA,cACV;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,IAAI,KAAa,OAAe,QAAyC;AAEvE,YAAM,CAAC,QAAQ,WAAW,GAAG,QAAQ,IAAI,IAAI,MAAM,GAAG;AACtD,YAAM,iBAAiB,SAAS,KAAK,GAAG;AAExC,UAAI,CAAC,UAAU,CAAC,aAAa,CAAC,gBAAgB;AAC5C,cAAM,IAAI;AAAA,UACR,8BAA8B,GAAG;AAAA,QACnC;AAAA,MACF;AAGA,WAAK,aAAa,SAAS,KAAK,OAAO,MAAM;AAG7C,WAAK,IAAI,KAAK,aAAa;AAAA,QACzB,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAY;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,IAAI,KAAsB;AACxB,aAAO,KAAK,IAAI,GAAG,MAAM;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA+BA,MAAM,WAAW,UAA6B,CAAC,GAAkB;AAC/D,YAAM,EAAE,WAAW,QAAQ,KAAK,WAAW,UAAU,KAAK,IAAI;AAC9D,YAAM,gBAAgB,KAAK,cAAc;AAEzC,UAAI,cAAc;AAGlB,UAAI,KAAK;AAEP,cAAM,CAAC,WAAW,YAAY,IAAI,IAAI,MAAM,GAAG;AAC/C,YAAI,aAAa,cAAc;AAC7B,eAAK,aAAa,eAAe,WAAW,YAAY;AACxD,wBAAc;AAAA,QAChB;AAAA,MACF,WAAW,aAAa,QAAQ;AAE9B,aAAK,aAAa,eAAe,QAAQ,SAAS;AAClD,sBAAc,KAAK,iBAAiB,QAAQ,SAAS;AAAA,MACvD,WAAW,WAAW;AAEpB,aAAK,aAAa,eAAe,eAAe,SAAS;AACzD,sBAAc,KAAK,iBAAiB,eAAe,SAAS;AAAA,MAC9D,WAAW,QAAQ;AAEjB,cAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,cAAM,oBAAoB,oBAAI,IAAY;AAE1C,mBAAW,eAAe,SAAS;AACjC,gBAAM,iBAAiB,QAAQ,WAAW;AAC1C,cAAI,kBAAkB,OAAO,mBAAmB,UAAU;AACxD,uBAAW,YAAY,OAAO,KAAK,cAAc,GAAG;AAClD,kBAAI,SAAS,WAAW,GAAG,MAAM,GAAG,KAAK,SAAS,WAAW,IAAI,MAAM,GAAG,GAAG;AAC3E,sBAAM,QAAQ,SAAS,QAAQ,KAAK,EAAE,EAAE,MAAM,GAAG;AACjD,oBAAI,MAAM,CAAC,GAAG;AACZ,oCAAkB,IAAI,MAAM,CAAC,CAAC;AAAA,gBAChC;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,MAAM,mBAAmB;AAClC,eAAK,aAAa,eAAe,QAAQ,EAAE;AAC3C;AAAA,QACF;AAAA,MACF,WAAW,WAAW;AAEpB,cAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,cAAM,UAAU,oBAAI,IAAyB;AAE7C,mBAAW,eAAe,SAAS;AACjC,gBAAM,iBAAiB,QAAQ,WAAW;AAC1C,cAAI,kBAAkB,OAAO,mBAAmB,UAAU;AACxD,uBAAW,YAAY,OAAO,KAAK,cAAc,GAAG;AAClD,kBAAI,UAAU,QAAQ,GAAG;AACvB,sBAAM,QAAQ,SAAS,QAAQ,KAAK,EAAE,EAAE,MAAM,GAAG;AACjD,sBAAM,cAAc,MAAM,CAAC;AAC3B,sBAAM,UAAU,MAAM,CAAC;AACvB,oBAAI,eAAe,SAAS;AAC1B,sBAAI,CAAC,QAAQ,IAAI,WAAW,GAAG;AAC7B,4BAAQ,IAAI,aAAa,oBAAI,IAAI,CAAC;AAAA,kBACpC;AACA,0BAAQ,IAAI,WAAW,EAAG,IAAI,OAAO;AACrC;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,CAAC,KAAK,UAAU,KAAK,SAAS;AACvC,qBAAW,MAAM,YAAY;AAC3B,iBAAK,aAAa,eAAe,KAAK,EAAE;AAAA,UAC1C;AAAA,QACF;AAAA,MACF,OAAO;AAEL,aAAK,aAAa,WAAW;AAC7B,sBAAc;AAAA,MAChB;AAGA,WAAK,IAAI,KAAK,oBAAoB;AAAA,QAChC,SAAS;AAAA,UACP,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAGD,UAAI,SAAS;AACX,cAAM,KAAK,uBAAuB,OAAO;AAAA,MAC3C;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,iBAAiB,QAAgB,WAA2B;AAClE,YAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,UAAI,QAAQ;AACZ,YAAM,SAAS,GAAG,MAAM,IAAI,SAAS;AACrC,YAAM,eAAe,IAAI,MAAM,IAAI,SAAS;AAE5C,iBAAW,eAAe,SAAS;AACjC,cAAM,iBAAiB,QAAQ,WAAW;AAC1C,YAAI,kBAAkB,OAAO,mBAAmB,UAAU;AACxD,qBAAW,OAAO,OAAO,KAAK,cAAc,GAAG;AAC7C,gBAAI,IAAI,WAAW,MAAM,KAAK,QAAQ,cAAc;AAClD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,MAAc,uBAAuB,SAA2C;AAC9E,YAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AACnC,YAAM,gBAAgB,KAAK,cAAc;AAEzC,UAAI,KAAK;AAEP,cAAM,CAAC,WAAW,YAAY,IAAI,IAAI,MAAM,GAAG;AAC/C,YAAI,aAAa,cAAc;AAC7B,gBAAM,KAAK,eAAe,WAAW,CAAC,YAAY,CAAC;AAAA,QACrD;AAAA,MACF,WAAW,WAAW;AAEpB,cAAM,KAAK,eAAe,UAAU,eAAe,CAAC,SAAS,CAAC;AAAA,MAChE,WAAW,QAAQ;AAAA,MAGnB;AAAA,IAEF;AAAA,EACF;;;AC7TA,MAAM,oBAAoB;AAM1B,MAAM,iBAAiB;AAEhB,MAAM,gBAAN,MAAoB;AAAA,IAwBzB,YACE,cACA,cACA,gBAAgB,MAChB,kBACA;AA5BF,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AACR,0BAAQ,uBAAsB,oBAAI,IAA2B;AAC7D;AAEA,0BAAQ,WAAU,oBAAI,IAAqB;AAG3C;AAAA,0BAAQ,cAAa,oBAAI,IAA+B;AACxD,0BAAQ,cAAa,oBAAI,IAA4B;AACrD,0BAAQ,uBAAsB;AAG9B;AAAA,0BAAQ,gBAAe,oBAAI,IAAa;AAGxC;AAAA,0BAAiB,gBAAe,IAAI,aAAa;AACjD,0BAAiB,kBAAiB,IAAI,eAAe;AAGrD;AAAA,0BAAgB;AAQd,WAAK,MAAM;AACX,WAAK,eAAe;AACpB,WAAK,gBAAgB;AACrB,WAAK,mBAAmB;AAGxB,WAAK,QAAQ,IAAI;AAAA,QACf,KAAK;AAAA,QACL,KAAK;AAAA,QACL,MAAM,KAAK;AAAA,QACX,CAAC,QAAQ,eAAe,KAAK,eAAe,QAAQ,UAAU;AAAA,MAChE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,eAAe,QAAuB;AACpC,WAAK,QAAQ,IAAI,OAAO,MAAM,MAAM;AAGpC,UAAI,KAAK,iBAAiB,MAAM,GAAG;AACjC,aAAK,wBAAwB,MAAyB;AAAA,MACxD;AAGA,UAAI,KAAK,cAAc,MAAM,GAAG;AAC9B,aAAK,aAAa,IAAI,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,wBAAwB,QAA+B;AAE7D,UAAI,OAAO,eAAe;AACxB,cAAM,mBAAmB,OAAO,cAAc;AAC9C,eAAO,QAAQ,gBAAgB,EAAE,QAAQ,CAAC,CAAC,MAAM,SAAS,MAAM;AAC9D,eAAK,WAAW,IAAI,MAAM,SAAS;AACnC,iBAAO,MAAM,uBAAuB,IAAI,SAAS,OAAO,IAAI,EAAE;AAAA,QAChE,CAAC;AAAA,MACH;AAGA,UAAI,OAAO,eAAe;AACxB,cAAM,mBAAmB,OAAO,cAAc;AAC9C,eAAO,QAAQ,gBAAgB,EAAE,QAAQ,CAAC,CAAC,MAAM,SAAS,MAAM;AAC9D,eAAK,WAAW,IAAI,MAAM,SAAS;AACnC,iBAAO,MAAM,uBAAuB,IAAI,SAAS,OAAO,IAAI,EAAE;AAAA,QAChE,CAAC;AAAA,MACH;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBA,EACE,QACG,MAKK;AACR,YAAM,CAAC,UAAU,SAAS,IAAI;AAE9B,YAAM,UAAU;AAAA,QACd;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP;AAGA,aAAO,MAAM,0BAA0B,QAAQ,QAAQ,EAAE;AACzD,YAAM,eAAe,KAAK,IAAI,YAAY,OAAO;AACjD,mBAAa,QAAQ;AAGrB,YAAM,aAAa,KAAK,aAAa,WAAW,OAAO;AACvD,UAAI,cAAc,WAAW,WAAW,KAAK;AAC3C,cAAM,SAAS,KAAK,aAAa,WAAW,OAAO,OAAO;AAC1D,eAAO;AAAA,UACL,sBAAsB,QAAQ,QAAQ,SAAS,WAAW,MAAM,KAAK,WAAW,QAAQ;AAAA,QAC1F;AACA,qBAAa,QAAQ,MAAM;AAC3B,eAAO;AAAA,MACT;AAGA,WAAK,sBAAsB,OAAO;AAGlC,YAAM,gBAAgB,QAAQ,sBAAsB,QAAQ;AAC5D,YAAM,iBAAiB,KAAK,aAAa,eAAe,OAAO;AAC/D,aAAO,MAAM,yBAAyB,QAAQ,QAAQ,EAAE;AACxD,mBAAa,SAAS,cAAc;AACpC,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwBA,MACE,QACG,MAKK;AAGR,YAAM,CAAC,UAAU,SAAS,IAAI;AAE9B,YAAM,UAAU;AAAA,QACd;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP;AAGA,aAAO,MAAM,+BAA+B,QAAQ,QAAQ,EAAE;AAC9D,YAAM,eAAe,KAAK,IAAI,YAAY,OAAO;AACjD,mBAAa,QAAQ;AAGrB,YAAM,aAAa,KAAK,aAAa,WAAW,OAAO;AACvD,UAAI,cAAc,WAAW,WAAW,KAAK;AAC3C,cAAM,SAAS,KAAK,mBAAmB,WAAW,OAAO,SAAS,WAAW,MAAM;AACnF,eAAO;AAAA,UACL,2BAA2B,QAAQ,QAAQ,SAAS,WAAW,MAAM;AAAA,QACvE;AACA,qBAAa,QAAQ,MAAM;AAC3B,eAAO;AAAA,MACT;AAGA,WAAK,sBAAsB,OAAO;AAGlC,YAAM,gBAAgB,QAAQ,sBAAsB,QAAQ;AAC5D,YAAM,iBAAiB,KAAK,mBAAmB,eAAe,OAAO;AACrE,aAAO,MAAM,8BAA8B,QAAQ,QAAQ,EAAE;AAC7D,mBAAa,SAAS,cAAc;AACpC,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASQ,mBACN,OACA,SACA,cACQ;AAER,YAAM,gBAAgB,KAAK,wBAAwB,OAAO,OAAO;AAGjE,UAAI,KAAK,oBAAoB,aAAa,GAAG;AAE3C,cAAM,SAAS,gBAAgB,KAAK,uBAAuB,OAAO;AAClE,cAAM,OAAoB;AAAA,UACxB,MAAM;AAAA,UACN;AAAA,QACF;AACA,eAAO,KAAK,eAAe,UAAU,IAAI;AAAA,MAC3C;AAGA,UAAI,KAAK,aAAa,aAAa,GAAG;AACpC,cAAM,OAAO,KAAK,aAAa,MAAM,aAAa;AAClD,eAAO,KAAK,eAAe,UAAU,IAAI;AAAA,MAC3C;AAGA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYQ,aAAa,OAAe,SAAqC;AAGvE,UAAI,KAAK,oBAAoB,KAAK,GAAG;AACnC,eAAO,KAAK,oBAAoB,OAAO,OAAO;AAAA,MAChD;AAGA,UAAI,KAAK,aAAa,KAAK,GAAG;AAC5B,eAAO,KAAK,iBAAiB,OAAO,OAAO;AAAA,MAC7C;AAGA,aAAO,KAAK,wBAAwB,OAAO,OAAO;AAAA,IACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUQ,oBAAoB,OAAwB;AAClD,aAAO,kBAAkB,KAAK,KAAK;AAAA,IACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUQ,oBACN,OACA,SACQ;AAER,YAAM,gBAAgB,KAAK,wBAAwB,OAAO,OAAO;AAGjE,aAAO,cAAc,QAAQ,mBAAmB,EAAE;AAAA,IACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUQ,uBACN,SAC0B;AAC1B,UAAI,CAAC,QAAQ,WAAW;AACtB,eAAO,CAAC;AAAA,MACV;AAEA,UAAI;AAEF,cAAM,oBAAoB;AAAA,UACxB,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAGA,cAAM,gBAAgB,KAAK,aAAa,iBAAiB,iBAAiB;AAC1E,YAAI,CAAC,eAAe;AAClB,iBAAO,CAAC;AAAA,QACV;AAGA,cAAM,WAAW,iBAAiB,eAAe,QAAQ,QAAQ;AAEjE,YAAI,YAAY,OAAO,aAAa,YAAY,YAAY,UAAU;AACpE,gBAAM,cAAc;AACpB,iBAAO,YAAY;AAAA,QACrB;AAEA,eAAO,CAAC;AAAA,MACV,SAAS,OAAO;AACd,eAAO,MAAM,gCAAgC,QAAQ,QAAQ,KAAK,KAAK;AACvE,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUQ,iBAAiB,OAAe,SAAqC;AAC3E,UAAI;AAEF,cAAM,OAAO,KAAK,aAAa,MAAM,KAAK;AAG1C,cAAM,gBAAgB,KAAK,wBAAwB,KAAK,MAAM,OAAO;AAGrE,eAAO,cAAc,QAAQ,mBAAmB,EAAE;AAAA,MACpD,SAAS,OAAO;AACd,eAAO,KAAK,sCAAsC,KAAK,MAAM,KAAK;AAElE,eAAO,KAAK,wBAAwB,OAAO,OAAO;AAAA,MACpD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAyBO,wBACL,OACA,iBACA,QACA,KACQ;AAER,UAAI;AACJ,UAAI;AACJ,UAAI;AAEJ,UAAI,mBAAmB,cAAc,iBAAiB;AAEpD,cAAM,UAAU;AAChB,iBAAS,QAAQ;AACjB,yBAAiB,QAAQ;AACzB,sBAAc,QAAQ;AAAA,MACxB,OAAO;AAEL,iBAAS;AACT,yBAAiB,UAAU,KAAK;AAChC,sBAAc;AAAA,MAChB;AAEA,UAAI,iBAAiB;AAErB,UAAI;AAEF,yBAAiB,KAAK;AAAA,UACpB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAIA,YAAI,KAAK,WAAW,IAAI,aAAa,GAAG;AACtC,gBAAM,uBAAuB,KAAK,WAAW,IAAI,aAAa;AAC9D,2BAAiB;AAAA,YACf;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,WACE,CAAC,KAAK,uBACN,UACA,OAAO,KAAK,MAAM,EAAE,SAAS,KAC7B,eAAe,SAAS,GAAG,GAC3B;AAGA,eAAK,sBAAsB;AAE3B,kBAAQ;AAAA,YACN;AAAA,UAIF;AAAA,QACF;AAGA,YAAI,KAAK,WAAW,OAAO,GAAG;AAC5B,qBAAW,CAAC,MAAM,SAAS,KAAK,KAAK,WAAW,QAAQ,GAAG;AACzD,gBAAI;AACF,+BAAiB,UAAU,gBAAgB,QAAQ,WAAW;AAAA,YAChE,SAAS,OAAO;AACd,qBAAO,KAAK,aAAa,IAAI,YAAY,KAAK;AAAA,YAChD;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,MACT,SAAS,OAAO;AACd,eAAO,KAAK,sCAAsC,KAAK,MAAM,KAAK;AAClE,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBA,eACE,KACA,QACA,cACa;AAEb,YAAM,UAAU;AAAA,QACd;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP;AAGA,YAAM,aAAa,KAAK,aAAa,WAAW,OAAO;AACvD,YAAM,WACJ,cAAc,WAAW,WAAW,MAChC,WAAW,QACX,QAAQ,sBAAsB,QAAQ;AAG5C,UAAI,CAAC,cAAc,WAAW,WAAW,KAAK;AAC5C,aAAK,sBAAsB,OAAO;AAAA,MACpC;AAGA,aAAO,KAAK,aAAa,MAAM,QAAQ;AAAA,IACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,mBAAmB,MAAc,QAA0C;AACzE,aAAO,KAAK,wBAAwB,MAAM,QAAQ,KAAK,aAAa;AAAA,IACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,aAAa,OAAwB;AACnC,aAAO,eAAe,KAAK,KAAK;AAAA,IAClC;AAAA;AAAA;AAAA;AAAA,IAKQ,0BACN,OACA,QACA,gBACQ;AACR,YAAM,kBAA0B;AAGhC,YAAM,WAAW,CACf,MAC2B,OAAO,GAAG,UAAU;AAGjD,YAAM,aAAa,CACjB,MAC6B,OAAO,GAAG,YAAY;AAGrD,UAAI,KAAK,WAAW,IAAI,QAAQ,KAAK,SAAS,MAAM,GAAG;AACrD,cAAM,kBAAkB,KAAK,WAAW,IAAI,QAAQ;AACpD,YAAI;AACF,gBAAM,eAAe;AAAA,YACnB;AAAA,YACA;AAAA,YACA,KAAK;AAAA,YACL;AAAA,UACF;AACA,cAAI,iBAAiB,OAAO,eAAe,GAAG;AAC5C,mBAAO;AAAA,UACT;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,KAAK,6BAA6B,KAAK;AAAA,QAChD;AAAA,MACF;AAGA,UAAI,KAAK,WAAW,IAAI,SAAS,KAAK,WAAW,MAAM,GAAG;AACxD,cAAM,mBAAmB,KAAK,WAAW,IAAI,SAAS;AACtD,YAAI;AACF,gBAAM,gBAAgB;AAAA,YACpB;AAAA,YACA;AAAA,YACA,KAAK;AAAA,YACL;AAAA,UACF;AACA,cAAI,kBAAkB,OAAO,eAAe,GAAG;AAC7C,mBAAO;AAAA,UACT;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,KAAK,8BAA8B,KAAK;AAAA,QACjD;AAAA,MACF;AAEA,aAAO,OAAO,eAAe;AAAA,IAC/B;AAAA;AAAA;AAAA;AAAA,IAKQ,sBAAsB,SAAmC;AAC/D,aAAO,MAAM,oBAAoB,QAAQ,QAAQ,EAAE;AACnD,YAAM,WAAW,QAAQ;AAEzB,UAAI,CAAC,KAAK,oBAAoB,IAAI,QAAQ,GAAG;AAC3C,cAAM,UAAU,KAAK,aAClB,YAAY,OAAO,EACnB,KAAK,YAAU;AACd,cAAI,UAAU,OAAO,OAAO;AAC1B,mBAAO,MAAM,WAAW,QAAQ,QAAQ,OAAO,OAAO,KAAK,GAAG;AAAA,UAChE,OAAO;AACL,mBAAO,MAAM,cAAc,QAAQ,QAAQ,EAAE;AAAA,UAC/C;AAAA,QACF,CAAC,EACA,MAAM,WAAS;AACd,iBAAO,KAAK,2BAA2B,QAAQ,QAAQ,IAAI,KAAK;AAAA,QAClE,CAAC;AAEH,aAAK,oBAAoB,IAAI,UAAU,OAAO;AAC9C,gBAAQ,QAAQ,MAAM,KAAK,oBAAoB,OAAO,QAAQ,CAAC;AAAA,MACjE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,mBAA2B;AACzB,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKA,oBAAoB,WAA0B;AAC5C,WAAK,mBAAmB;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA,IAKA,sBAA0C;AACxC,aAAO,KAAK;AAAA,IACd;AAAA;AAAA,IAGA,aAAkC;AAChC,aAAO,KAAK,aAAa,WAAW;AAAA,IACtC;AAAA,IAEA,SAAS,KAAsB;AAC7B,YAAM,UAAU;AAAA,QACd;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP;AAEA,aAAO,KAAK,aAAa,SAAS,OAAO;AAAA,IAC3C;AAAA;AAAA,IAGA,sBAA2B;AACzB,aAAO,KAAK,aAAa,aAAa;AAAA,IACxC;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,eACJ,WACA,SAIe;AACf,YAAM,YAAY,KAAK;AAEvB,UAAI,cAAc,WAAW;AAC3B,eAAO,MAAM,2BAA2B,SAAS,EAAE;AACnD;AAAA,MACF;AAEA,YAAM,QAAQ,SAAS,SAAS;AAChC,YAAM,cAAc,KAAK,IAAI,SAAS,WAAW,SAAS;AAE1D,UAAI;AACF,eAAO,KAAK,oBAAoB,SAAS,WAAM,SAAS,EAAE;AAC1D,eAAO,MAAM,2BAA2B;AAAA,UACtC;AAAA,UACA,mBAAmB,SAAS;AAAA,QAC9B,CAAC;AAED,oBAAY,MAAM;AAElB,aAAK,gBAAgB;AAErB,YAAI,OAAO;AACT,gBAAM,KAAK,WAAW;AACtB,eAAK,kCAAkC,SAAS;AAAA,QAClD;AAEA,YAAI,SAAS,mBAAmB,QAAQ;AACtC,gBAAM,KAAK,eAAe,WAAW,QAAQ,iBAAiB;AAAA,QAChE;AAEA,oBAAY,SAAS;AAErB,eAAO,KAAK,qBAAqB,SAAS,EAAE;AAAA,MAC9C,SAAS,OAAO;AACd,eAAO,MAAM,2BAA2B,KAAK;AAC7C,oBAAY,MAAM,KAAc;AAChC,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,MAAc,aAA4B;AACxC,WAAK,aAAa,WAAW;AAC7B,aAAO,MAAM,6BAA6B,KAAK,aAAa,EAAE;AAAA,IAChE;AAAA,IAEQ,kCAAkC,WAAyB;AACjE,UAAI,eAAe;AAEnB,iBAAW,OAAO,KAAK,oBAAoB,KAAK,GAAG;AACjD,YAAI,IAAI,SAAS,GAAG,SAAS,GAAG,GAAG;AACjC,eAAK,oBAAoB,OAAO,GAAG;AACnC;AAAA,QACF;AAAA,MACF;AAEA,UAAI,eAAe,GAAG;AACpB,eAAO;AAAA,UACL,WAAW,YAAY,6BAA6B,SAAS;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAc,eACZ,QACA,YACe;AACf,aAAO,MAAM,cAAc,WAAW,MAAM,mBAAmB,MAAM,EAAE;AAEvE,YAAM,kBAAkB,WAAW,IAAI,OAAM,cAAa;AACxD,YAAI;AACF,gBAAM,KAAK,aAAa,gBAAgB,QAAQ,SAAS;AACzD,iBAAO,MAAM,cAAc,MAAM,IAAI,SAAS,EAAE;AAAA,QAClD,SAAS,OAAO;AACd,iBAAO,KAAK,qBAAqB,MAAM,IAAI,SAAS,KAAK,KAAK;AAAA,QAChE;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,eAAe;AAAA,IAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,MAAM,gBAAgB,WAAmB,QAAgC;AACvE,YAAM,eAAe,UAAU,KAAK;AACpC,aAAO,MAAM,wBAAwB,YAAY,IAAI,SAAS,EAAE;AAGhE,YAAM,KAAK,MAAM,WAAW;AAAA,QAC1B;AAAA,QACA,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,aAAO,KAAK,uBAAuB,YAAY,IAAI,SAAS,EAAE;AAAA,IAChE;AAAA;AAAA,IAGQ,iBAAiB,QAA0B;AACjD,aAAO,OAAO,aAAa;AAAA,QAAK,SAC9B,CAAC,cAAc,cAAc,iBAAiB,SAAS,EAAE,SAAS,GAAG;AAAA,MACvE;AAAA,IACF;AAAA,IAEQ,cAAc,QAA0B;AAC9C,aAAO,OAAO,aAAa;AAAA,QAAK,SAC9B;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,SAAS,GAAG;AAAA,MAChB;AAAA,IACF;AAAA,EACF;;;AC10BO,MAAM,mBAAN,MAEP;AAAA,IAQE,YAAY,QAAgC;AAP5C,0BAAS,QAAO;AAChB,0BAAS,QAAO;AAChB,0BAAS,UAAiC,CAAC;AAC3C,0BAAQ,SAAQ,oBAAI,IAAoB;AACxC,0BAAQ,eAAc,oBAAI,IAAoB;AAC9C,0BAAQ,WAAkB;AAGxB,WAAK,SAAS;AACd,WAAK,UAAU,KAAK,OAAO,SAAS,WAAW;AAAA,IACjD;AAAA,IAEA,IAAI,KAA4B;AAC9B,YAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,UAAI,UAAU,QAAW;AAEvB,aAAK,YAAY,IAAI,KAAK,KAAK,IAAI,CAAC;AACpC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IAEA,IAAI,KAAa,OAAqB;AACpC,UAAI,KAAK,MAAM,QAAQ,KAAK,WAAW,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG;AAC3D,aAAK,YAAY;AAAA,MACnB;AAEA,WAAK,MAAM,IAAI,KAAK,KAAK;AACzB,WAAK,YAAY,IAAI,KAAK,KAAK,IAAI,CAAC;AAAA,IACtC;AAAA,IAEA,OAAO,KAAmB;AACxB,WAAK,MAAM,OAAO,GAAG;AACrB,WAAK,YAAY,OAAO,GAAG;AAAA,IAC7B;AAAA,IAEA,QAAc;AACZ,WAAK,MAAM,MAAM;AACjB,WAAK,YAAY,MAAM;AAAA,IACzB;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,eAAe,QAAgB,WAAyB;AACtD,YAAM,oBAAoB,wBAAwB,QAAQ,SAAS;AACnE,YAAM,YAAY,GAAG,MAAM,IAAI,SAAS;AAGxC,WAAK,MAAM,OAAO,iBAAiB;AACnC,WAAK,YAAY,OAAO,iBAAiB;AAGzC,iBAAW,OAAO,KAAK,MAAM,KAAK,GAAG;AACnC,YAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,eAAK,MAAM,OAAO,GAAG;AACrB,eAAK,YAAY,OAAO,GAAG;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,IAEA,aAAa,QAAgB,WAA2C;AACtE,YAAM,oBAAoB,wBAAwB,QAAQ,SAAS;AACnE,YAAM,gBAAgB,KAAK,MAAM,IAAI,iBAAiB;AACtD,UAAI,CAAC,cAAe,QAAO;AAE3B,UAAI;AACF,eAAO,KAAK,MAAM,aAAa;AAAA,MACjC,SAAS,OAAO;AACd,aAAK,MAAM,OAAO,iBAAiB;AACnC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,aACE,QACA,WACA,cACM;AACN,YAAM,oBAAoB,wBAAwB,QAAQ,SAAS;AACnE,WAAK,MAAM,IAAI,mBAAmB,KAAK,UAAU,YAAY,CAAC;AAAA,IAChE;AAAA,IAEQ,cAAoB;AAC1B,UAAI,YAAY;AAChB,UAAI,aAAa,KAAK,IAAI;AAE1B,iBAAW,CAAC,KAAK,IAAI,KAAK,KAAK,YAAY,QAAQ,GAAG;AACpD,YAAI,OAAO,YAAY;AACrB,uBAAa;AACb,sBAAY;AAAA,QACd;AAAA,MACF;AAEA,UAAI,WAAW;AACb,aAAK,MAAM,OAAO,SAAS;AAC3B,aAAK,YAAY,OAAO,SAAS;AAAA,MACnC;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAIA,aAAqC;AACnC,YAAM,UAAkC,CAAC;AACzC,iBAAW,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG;AAC/C,gBAAQ,GAAG,IAAI;AAAA,MACjB;AACA,aAAO;AAAA,IACT;AAAA,IAEA,YAAoC;AAClC,aAAO,KAAK;AAAA,IACd;AAAA,EACF;;;AC9FO,MAAM,mBAAN,MAEP;AAAA,IAME,YAAY,QAAsB,SAAiC,CAAC,GAAG;AALvE,0BAAS,QAAO;AAChB,0BAAS,QAAO;AAChB,0BAAS;AACT,0BAAiB;AAGf,WAAK,SAAS;AAAA,QACZ,SAAS,OAAO,WAAW;AAAA,QAC3B,UAAU,OAAO,YAAY;AAAA;AAAA,QAC7B,SAAS;AAAA,UACP,KAAK,OAAO;AAAA,UACZ,SAAS,OAAO;AAAA,UAChB,GAAG,OAAO;AAAA,QACZ;AAAA,MACF;AACA,WAAK,MAAM,IAAI,iBAAiB,EAAE,SAAS,EAAE,SAAS,OAAO,iBAAiB,EAAE,CAAC;AAEjF,iBAAW,CAAC,QAAQ,UAAU,KAAK,OAAO,QAAQ,MAAM,GAAG;AACzD,mBAAW,CAAC,WAAW,YAAY,KAAK,OAAO,QAAQ,UAAU,GAAG;AAClE,eAAK,IAAI,aAAa,QAAQ,WAAW,YAAY;AACrD,gBAAM,OAAO;AAAA,YACX;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,qBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,EAAG,MAAK,IAAI,IAAI,KAAK,KAAK;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,IAEA,IAAI,KAA4B;AAC9B,aAAO,KAAK,IAAI,IAAI,GAAG;AAAA,IACzB;AAAA,IAEA,aAAa,QAAgB,WAA2C;AACtE,aAAO,KAAK,IAAI,aAAa,QAAQ,SAAS;AAAA,IAChD;AAAA,IAEA,aAAqC;AACnC,aAAO,KAAK,IAAI,WAAW;AAAA,IAC7B;AAAA,IAEA,YAAoC;AAClC,aAAO,KAAK;AAAA,IACd;AAAA;AAAA,IAGA,MAAY;AAAA,IAAC;AAAA,IACb,SAAe;AAAA,IAAC;AAAA,IAChB,QAAc;AAAA,IAAC;AAAA,IACf,eAAqB;AAAA,IAAC;AAAA,EACxB;;;AC/DA,MAAM,cAAc;AAEb,MAAM,0BAAN,MAA8B;AAAA,IAQnC,YACE,YACA,QACA,cACA;AAXF,0BAAQ,SAA6C,oBAAI,IAAI;AAC7D,0BAAQ,iBAAuC;AAC/C,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AACR,0BAAQ,kBAAsC,oBAAI,IAAI;AAOpD,WAAK,aAAa;AAClB,WAAK,SAAS;AACd,WAAK,eAAe,gBAAgB;AAEpC,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO,MAAM,qCAAqC;AAAA,MACpD,OAAO;AACL,eAAO;AAAA,UACL,qCAAqC,OAAO,UAAU,iBAAiB,OAAO,SAAS;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,IAAI,MAAoC;AACtC,UAAI,CAAC,KAAK,OAAO,QAAS;AAG1B,YAAM,WAAW,GAAG,KAAK,MAAM,IAAI,KAAK,SAAS,IAAI,KAAK,GAAG;AAG7D,YAAM,WAAW,KAAK,eAAe,IAAI,QAAQ;AACjD,UAAI,YAAY,KAAK,IAAI,IAAI,WAAW,aAAa;AACnD,eAAO,MAAM,iCAAiC,QAAQ,EAAE;AACxD;AAAA,MACF;AAGA,WAAK,MAAM,IAAI,UAAU,IAAI;AAE7B,aAAO;AAAA,QACL,+BAA+B,QAAQ,iBAAiB,KAAK,MAAM,IAAI;AAAA,MACzE;AAGA,UAAI,KAAK,eAAe;AACtB,qBAAa,KAAK,aAAa;AAC/B,aAAK,gBAAgB;AAAA,MACvB;AAGA,UAAI,KAAK,MAAM,QAAQ,KAAK,OAAO,WAAW;AAC5C,eAAO,MAAM,uBAAuB,KAAK,OAAO,SAAS,aAAa;AACtE,aAAK,MAAM;AACX;AAAA,MACF;AAGA,WAAK,gBAAgB,WAAW,MAAM;AACpC,aAAK,MAAM;AAAA,MACb,GAAG,KAAK,OAAO,UAAU;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,QAAc;AACZ,UAAI,KAAK,MAAM,SAAS,EAAG;AAG3B,YAAM,MAAM,KAAK,IAAI;AACrB,iBAAW,CAAC,KAAK,EAAE,KAAK,KAAK,gBAAgB;AAC3C,YAAI,MAAM,MAAM,YAAa,MAAK,eAAe,OAAO,GAAG;AAAA,MAC7D;AAGA,YAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,UAAU,IAAI,OAAO;AAAA,QACxE,KAAK;AAAA,QACL,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,MACf,EAAE;AAEF,YAAM,YAAY,MAAM;AAGxB,WAAK,MAAM,MAAM;AAGjB,UAAI,KAAK,eAAe;AACtB,qBAAa,KAAK,aAAa;AAC/B,aAAK,gBAAgB;AAAA,MACvB;AAEA,aAAO,MAAM,YAAY,SAAS,uBAAuB;AAGzD,WAAK,UAAU,KAAK,EAAE,MAAM,WAAS;AACnC,eAAO,KAAK,kBAAkB,SAAS,0BAA0B,KAAK;AAAA,MACxE,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,UACZ,OACe;AACf,UAAI;AAEF,cAAM,YAAY,MAAM,KAAK,UAAQ,KAAK,UAAU,OAAO,KAAK,KAAK,MAAM,EAAE,SAAS,CAAC;AAEvF,YAAI,aAAa,0BAA0B,KAAK,YAAY;AAC1D,gBAAM,mBAAmB,MAAM,IAAI,WAAS;AAAA,YAC1C,KAAK,KAAK;AAAA,YACV,OAAO,EAAE,MAAM,KAAK,OAAO,QAAQ,KAAK,UAAU,CAAC,EAAE;AAAA,UACvD,EAAE;AACF,gBACE,KAAK,WAKL,qBAAqB,gBAAgB;AACvC,iBAAO,MAAM,UAAU,MAAM,MAAM,qCAAqC;AAAA,QAC1E,WAAW,cAAc,KAAK,YAAY;AAExC,gBAAM,aAAa,MAAM,IAAI,WAAS,EAAE,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM,EAAE;AAC3E,gBACE,KAAK,WAKL,SAAS,UAAU;AACrB,iBAAO,MAAM,UAAU,MAAM,MAAM,uBAAuB;AAAA,QAC5D,OAAO;AAEL,iBAAO;AAAA,YACL;AAAA,UACF;AACA,gBAAM,KAAK,iBAAiB,KAAK;AAAA,QACnC;AAEA,cAAM,MAAM,KAAK,IAAI;AACrB,cAAM,aAAuB,CAAC;AAC9B,mBAAW,QAAQ,OAAO;AACxB,eAAK,eAAe,IAAI,KAAK,KAAK,GAAG;AACrC,qBAAW,KAAK,KAAK,GAAG;AAAA,QAC1B;AAGA,YAAI,KAAK,cAAc;AACrB,eAAK,aAAa,KAAK,uBAAuB;AAAA,YAC5C,SAAS,EAAE,OAAO,MAAM,QAAQ,MAAM,WAAW;AAAA,UACnD,CAAC;AAAA,QACH;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,sBAAsB,KAAK;AACxC,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,MAAc,iBACZ,OACe;AACf,YAAM,eAAe,MAAM,IAAI,OAAM,SAAQ;AAC3C,YAAI;AACF,gBAAM,KAAK,WAAW,IAAI,KAAK,KAAK,KAAK,KAAK;AAC9C,iBAAO,MAAM,WAAW,KAAK,GAAG,EAAE;AAAA,QACpC,SAAS,OAAO;AACd,iBAAO,KAAK,kBAAkB,KAAK,GAAG,KAAK,KAAK;AAAA,QAClD;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,YAAY;AAAA,IACvC;AAAA;AAAA;AAAA;AAAA,IAKA,eAAuB;AACrB,aAAO,KAAK,MAAM;AAAA,IACpB;AAAA;AAAA;AAAA;AAAA,IAKA,WAKE;AACA,aAAO;AAAA,QACL,WAAW,KAAK,MAAM;AAAA,QACtB,SAAS,KAAK,OAAO;AAAA,QACrB,YAAY,KAAK,OAAO;AAAA,QACxB,WAAW,KAAK,OAAO;AAAA,MACzB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAgB;AACd,UAAI,KAAK,eAAe;AACtB,qBAAa,KAAK,aAAa;AAC/B,aAAK,gBAAgB;AAAA,MACvB;AAGA,WAAK,MAAM,MAAM;AACjB,WAAK,eAAe,MAAM;AAE1B,aAAO,MAAM,mCAAmC;AAAA,IAClD;AAAA,EACF;;;ACxNO,WAAS,qBAAqB,OAAyB;AAC5D,WAAO,EACL,iBAAiB,4BACjB,iBAAiB;AAAA,EAErB;AAEO,MAAM,mBAAN,MAAM,kBAAiB;AAAA,IAQ5B,YAAY,QAA6B;AAPzC,0BAAQ;AACR,0BAAQ,WAAqB,CAAC;AAC9B,0BAAQ,oBAAsC,CAAC;AAC/C,0BAAQ,qBAAwC,CAAC;AACjD,0BAAQ,gBAAmC,CAAC;AAC5C,0BAAQ,aAA4C;AAGlD,WAAK,SAAS;AAAA,QACZ,eAAe,OAAO,iBAAiB;AAAA,QACvC,WAAW,OAAO,aAAa;AAAA,MACjC;AAAA,IACF;AAAA,IAEA,OAAO,KAAK,SAA8B,CAAC,GAAqB;AAC9D,aAAO,IAAI,kBAAiB,MAAM;AAAA,IACpC;AAAA,IAEQ,eAAe,QAA2C;AAChE,WAAK,iBAAiB,KAAK,MAAM;AACjC,aAAO;AAAA,IACT;AAAA,IAEQ,gBAAgB,SAA6C;AACnE,WAAK,kBAAkB,KAAK,OAAO;AACnC,aAAO;AAAA,IACT;AAAA,IAEQ,WAAW,SAA6C;AAC9D,WAAK,aAAa,KAAK,OAAO;AAC9B,aAAO;AAAA,IACT;AAAA,IAEA,IACE,UACkB;AAClB,cAAQ,SAAS,MAAM;AAAA,QACrB,KAAK;AACH,eAAK,QAAQ,KAAK,QAAQ;AAC1B;AAAA,QACF,KAAK;AACH,eAAK,eAAe,QAAQ;AAC5B;AAAA,QACF,KAAK;AACH,eAAK,gBAAgB,QAAQ;AAC7B;AAAA,QACF,KAAK;AACH,eAAK,WAAW,QAAQ;AACxB;AAAA,MACJ;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,gBAAgB,QAAsB,WAAW,KAAuB;AACtE,aAAO,KAAK,IAAI,IAAI,iBAAiB,QAAQ,EAAE,SAAS,CAAC,CAAC;AAAA,IAC5D;AAAA,IAEA,MAAM,QAAgC;AACpC,YAAM,eAAe,IAAI,aAAa;AACtC,YAAM,WAAW,aAAa,QAAQ;AAEtC,aAAO,KAAK,iBAAiB;AAC7B,aAAO,MAAM,kBAAkB,KAAK,MAAM;AAC1C,eAAS,WAAW,KAAK,OAAO,eAAgB,KAAK,OAAO,SAAU;AAEtE,YAAM,eAAe,IAAI,aAAa,YAAY;AAElD,iBAAW,YAAY,KAAK,kBAAkB;AAC5C,YAAI,CAAC,SAAS,UAAU,EAAE,QAAS;AACnC,cAAM,cAAc,IAAI,YAAY,cAAc,QAAQ;AAC1D,iBAAS,IAAI,MAAM;AACnB,qBAAa,eAAe,WAAW;AAAA,MACzC;AAEA,iBAAW,aAAa,KAAK,mBAAmB;AAC9C,YAAI,CAAC,UAAU,UAAU,EAAE,QAAS;AACpC,cAAM,eAAe,IAAI,aAAa,cAAc,SAAS;AAC7D,iBAAS,IAAI,OAAO;AACpB,qBAAa,gBAAgB,YAAY;AAAA,MAC3C;AAGA,UAAI,eAAsC;AAC1C,iBAAW,eAAe,KAAK,cAAc;AAC3C,YACE,CAAC,YAAY,UAAU,EAAE,WACzB,CAAC,YAAY,UAAU,EAAE,SAAS;AAElC;AACF,cAAM,iBAAiB,IAAI,eAAe,cAAc,WAAW;AACnE,YAAI,CAAC,cAAc;AACjB,yBAAe;AAAA,QACjB;AACA,iBAAS,IAAI,SAAS;AACtB,qBAAa,gBAAgB,cAAc;AAG3C,cAAM,SAAS,YAAY,UAAU;AACrC,YAAI,OAAO,SAAS,aAAa,SAAS;AACxC,eAAK,YAAY,IAAI,wBAAwB,aAAa;AAAA,YACxD,SAAS,OAAO,QAAQ,YAAY;AAAA,YACpC,YAAY,OAAO,QAAQ,YAAY,cAAc;AAAA,YACrD,WAAW,OAAO,QAAQ,YAAY,aAAa;AAAA,UACrD,GAAG,YAAY;AAIf,uBAAa,GAAG,yBAAyB,cAAY;AACnD,gBAAI,KAAK,WAAW;AAClB,mBAAK,UAAU,IAAI;AAAA,gBACjB,KAAK,SAAS,QAAQ;AAAA,gBACtB,eAAe,SAAS,QAAQ;AAAA,gBAChC,QAAQ,SAAS,QAAQ;AAAA,gBACzB,QAAQ,SAAS,QAAQ;AAAA,gBACzB,WAAW,SAAS,QAAQ;AAAA,cAC9B,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AAED,iBAAO,KAAK,kCAAkC;AAC9C,iBAAO,MAAM,qBAAqB,OAAO,QAAQ,WAAW;AAAA,QAC9D;AAAA,MACF;AAEA,aAAO,MAAM,2BAA2B;AAGxC,YAAM,SAAS,IAAI;AAAA,QACjB;AAAA,QACA;AAAA,QACA,KAAK,OAAO;AAAA,QACZ,KAAK,OAAO;AAAA,MACd;AAGA,iBAAW,UAAU,KAAK,SAAS;AACjC,iBAAS,IAAI,QAAQ;AACrB,cAAM,OAAO,WAAW,EAAE,MAAM,QAAQ,KAAK,aAAa,CAAC;AAC3D,eAAO,eAAe,MAAM;AAC5B,eAAO,KAAK,uBAAuB,OAAO,IAAI,EAAE;AAChD,eAAO,MAAM,mBAAmB,OAAO,OAAO,IAAI,OAAO,YAAY;AAAA,MACvE;AAEA,YAAM,YAAY,aAAa,aAAa;AAG5C,UAAI,cAAc;AAChB,cAAM,KAAK,kBAAkB,cAAc,YAAY;AAAA,MACzD;AACA,aAAO,KAAK,mBAAmB;AAC/B,eAAS;AAAA,QACP,UAAU,SAAS,IAAI,OAAK,EAAE,IAAI;AAAA,QAClC,KAAK,QAAQ,IAAI,OAAK,EAAE,IAAI;AAAA,MAC9B;AAEA,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,MAAc,kBACZ,gBACA,cACe;AACf,YAAM,gBAAgB,eACnB,WAAW,EACX,OAAO,YAAU,OAAO,UAAU,KAAK;AAE1C,UAAI,CAAC,iBAAiB,cAAc,WAAW,GAAG;AAChD;AAAA,MACF;AAEA,aAAO,KAAK,cAAc,cAAc,MAAM,aAAa;AAC3D,aAAO,MAAM,mBAAmB;AAAA,QAC9B,YAAY,cAAc,IAAI,OAAK,GAAG,EAAE,MAAM,IAAI,EAAE,SAAS,EAAE;AAAA,MACjE,CAAC;AAED,UAAI,eAAe;AACnB,YAAM,iBAAiB,CAAC,cAAsB,UAAmB;AAC/D,YAAI,CAAC,qBAAqB,KAAK,KAAK,aAAc;AAClD,uBAAe;AAEf,gBAAQ;AAAA,UACN,+CAA+C,YAAY;AAAA,UAE3D;AAAA,QACF;AAAA,MACF;AACA,YAAM,WAAW,cAAc,IAAI,OAAM,kBAAiB;AACxD,cAAM,eAAe,GAAG,cAAc,MAAM,IAAI,cAAc,SAAS;AACvE,YAAI;AACF,gBAAM,SAAS,MAAM,eAAe;AAAA,YAClC,cAAc;AAAA,YACd,cAAc;AAAA,UAChB;AAEA,cAAI,UAAU,OAAO,QAAQ,OAAO,WAAW,KAAK;AAClD,kBAAM,UAAU;AAAA,cACd,QAAQ,cAAc;AAAA,cACtB,WAAW,cAAc;AAAA,YAC3B;AAEA,kBAAM,aAAa,wBAAwB,OAAO,MAAM,OAAO;AAC/D,mBAAO,MAAM,cAAc,YAAY,EAAE;AACzC;AAAA,UACF;AAIA,cAAI,QAAQ,OAAO;AACjB,2BAAe,cAAc,OAAO,KAAK;AACzC,mBAAO,KAAK,mBAAmB,YAAY,IAAI,OAAO,KAAK;AAAA,UAC7D;AAAA,QACF,SAAS,OAAO;AACd,yBAAe,cAAc,KAAK;AAClC,iBAAO,KAAK,mBAAmB,YAAY,IAAI,KAAK;AAAA,QACtD;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,WAAW,QAAQ;AACjC,aAAO,KAAK,sBAAsB;AAAA,IACpC;AAAA,EACF;;;AC/OO,MAAM,qBAAN,MAAM,mBAEb;AAAA,IAqCE,YAAY,SAAkC,CAAC,GAAG;AApClD,0BAAS,QAAO;AAChB,0BAAS,QAAO;AAChB,0BAAS,UAAkC,CAAC;AAW5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAQ,sBAAqB,oBAAI,IAA+B;AAahE;AAAA;AAAA;AAAA;AAAA,0BAAiB,qBAAoB;AAAA,QACnC,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,mBAAmB;AAAA,QACnB,mBAAmB;AAAA,MACrB;AAGE,WAAK,SAAS;AAAA,QACZ,SAAS;AAAA,UACP,SAAS,OAAO,SAAS,WAAW;AAAA,UACpC,SAAS,OAAO,SAAS,WAAW;AAAA,UACpC,SAAS,OAAO,SAAS,WAAW,CAAC;AAAA,QACvC;AAAA,QACA,GAAG;AAAA,MACL;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,MAAM,IAAI,KAA8B;AACtC,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,cAAM,IAAI,aAAa,yBAAyB;AAAA,MAClD;AAEA,YAAM,MAAM,KAAK,SAAS,kBAAkB,EAAE,IAAI,CAAC;AACnD,aAAO,MAAM,YAAY,GAAG,EAAE;AAE9B,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,KAAK;AAElD,YAAI,CAAC,SAAS,IAAI;AAChB,eAAK,gBAAgB,UAAU,GAAG;AAAA,QACpC;AAEA,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAO,MAAM,sBAAsB,IAAI;AAGvC,cAAM,cAAc,KAAK,aAAa,KAAK,MAAM,GAAG,KAC/C,KAAK,aAAa,GAAG,KACrB,OAAO,OAAO,KAAK,YAAY,EAAE,CAAC;AAEvC,eAAO,MAAM,gCAAgC,GAAG,MAAM,WAAW;AACjE,YAAI,CAAC,aAAa;AAChB,gBAAM,IAAI,yBAAyB,GAAG;AAAA,QACxC;AAGA,YAAI,OAAO,gBAAgB,YAAY,UAAU,aAAa;AAC5D,iBAAO,MAAM,sBAAsB,YAAY,IAAI,GAAG;AACtD,iBAAO,YAAY;AAAA,QACrB;AAEA,eAAO,OAAO,WAAW;AAAA,MAC3B,SAAS,OAAO;AACd,aAAK,kBAAkB,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,MAAM,eAAe,KAAmC;AACtD,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,cAAM,IAAI,aAAa,yBAAyB;AAAA,MAClD;AAEA,YAAM,MAAM,KAAK,SAAS,kBAAkB,EAAE,IAAI,CAAC;AACnD,aAAO,MAAM,wBAAwB,GAAG,EAAE;AAE1C,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,KAAK;AAElD,YAAI,CAAC,SAAS,IAAI;AAChB,eAAK,gBAAgB,UAAU,GAAG;AAAA,QACpC;AAEA,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAO,MAAM,sBAAsB,IAAI;AAGvC,cAAM,cAAc,KAAK,aAAa,KAAK,MAAM,GAAG,KAC/C,KAAK,aAAa,GAAG,KACrB,OAAO,OAAO,KAAK,YAAY,EAAE,CAAC;AAEvC,YAAI,CAAC,aAAa;AAChB,gBAAM,IAAI,yBAAyB,GAAG;AAAA,QACxC;AAGA,YAAI,OAAO,gBAAgB,YAAY,UAAU,aAAa;AAE5D,iBAAO,MAAM,oBAAoB,GAAG,YAAY,YAAY,IAAI,cAAc,YAAY,MAAM;AAChG,iBAAO;AAAA,YACL,MAAM,YAAY;AAAA,YAClB,QAAQ,YAAY,UAAU,CAAC;AAAA,UACjC;AAAA,QACF;AAGA,eAAO,MAAM,qBAAqB,GAAG,OAAO,WAAW,eAAe;AACtE,eAAO;AAAA,UACL,MAAM,OAAO,WAAW;AAAA,UACxB,QAAQ,CAAC;AAAA,QACX;AAAA,MACF,SAAS,OAAO;AACd,aAAK,kBAAkB,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,MAAM,aACJ,QACA,WACiC;AACjC,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,cAAM,IAAI,aAAa,yBAAyB;AAAA,MAClD;AAEA,UAAI;AACF,eAAQ,MAAM,KAAK,kBAAkB,QAAQ,SAAS;AAAA,MACxD,SAAS,OAAO;AACd,aAAK,kBAAkB,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,MAAc,kBACZ,QACA,WACA,mBAAmB,MACe;AAClC,YAAM,MAAM,KAAK,SAAS,gBAAgB,EAAE,QAAQ,UAAU,CAAC;AAC/D,aAAO,MAAM,sBAAsB,GAAG,EAAE;AAExC,YAAM,eAAe,GAAG,MAAM,IAAI,SAAS;AAE3C,YAAM,WAAW,mBAAmB,KAAK,YAAY,YAAY,IAAI;AACrE,YAAM,eAAuC,CAAC;AAC9C,UAAI,UAAU;AACZ,qBAAa,eAAe,IAAI,MAAM,SAAS,OAAO;AAAA,MACxD;AAEA,YAAM,WAAW,MAAM,KAAK,YAAY,KAAK,OAAO,QAAW,YAAY;AAE3E,UAAI,SAAS,WAAW,KAAK;AAC3B,YAAI,UAAU;AAGZ,iBAAO,MAAM,aAAa,YAAY,sCAAsC;AAC5E,iBAAO,SAAS;AAAA,QAClB;AAEA,eAAO,MAAM,aAAa,YAAY,qDAAgD;AACtF,eAAO,KAAK,kBAAkB,QAAQ,WAAW,KAAK;AAAA,MACxD;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,aAAK,gBAAgB,UAAU,YAAY;AAAA,MAC7C;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,MAAM,sBAAsB,IAAI;AAEvC,UAAI,CAAC,KAAK,cAAc;AACtB,cAAM,IAAI,yBAAyB,YAAY;AAAA,MACjD;AAEA,YAAM,UAAU,KAAK,MAAM,WAAW,OAAO,OAAO,KAAK,KAAK,OAAO,IAAI;AACzE,UAAI,SAAS;AACX,aAAK,YAAY,cAAc,EAAE,SAAS,cAAc,KAAK,aAAa,CAAC;AAAA,MAC7E;AAEA,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,IAAI,KAAa,OAA8B;AACnD,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AACA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,kBAAkB,EAAE,IAAI,CAAC;AACnD,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,OAAO;AAAA,UAClD,aAAa;AAAA,QACf,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,EAAE;AAAA,QAClE;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,2BAA2B,GAAG,MAAM,KAAK;AACtD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,MAAM,aACJ,QACA,WACA,cACe;AACf,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AACA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,gBAAgB,EAAE,QAAQ,UAAU,CAAC;AAC/D,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,OAAO;AAAA,UAClD;AAAA,QACF,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,EAAE;AAAA,QAChE;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,+BAA+B,MAAM,IAAI,SAAS;AAAA,UAClD;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,SAAS,OAA6D;AAC1E,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AAEA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,UAAU;AACpC,eAAO,MAAM,mBAAmB,GAAG,KAAK,MAAM,MAAM,SAAS;AAE7D,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,QAAQ;AAAA,UACnD,cAAc;AAAA,QAChB,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,EAAE;AAAA,QAC5D;AAEA,eAAO,MAAM,0BAA0B,MAAM,MAAM,QAAQ;AAAA,MAC7D,SAAS,OAAO;AACd,eAAO,MAAM,2BAA2B,MAAM,MAAM,WAAW,KAAK;AACpE,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAeA,MAAM,yBACJ,QACA,WACiC;AACjC,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,cAAM,IAAI,aAAa,yBAAyB;AAAA,MAClD;AAEA,UAAI;AAEF,eAAQ,MAAM,KAAK,kBAAkB,QAAQ,SAAS;AAAA,MACxD,SAAS,OAAO;AACd,aAAK,kBAAkB,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,MAAM,eAAe,KAAa,MAAkC;AAClE,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AAEA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,kBAAkB,EAAE,IAAI,CAAC;AACnD,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,OAAO;AAAA,UAClD,aAAa;AAAA,UACb,QAAQ;AAAA;AAAA,QACV,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,EAAE;AAAA,QAClE;AAEA,eAAO,MAAM,8BAA8B,GAAG,GAAG;AAAA,MACnD,SAAS,OAAO;AACd,eAAO,MAAM,sCAAsC,GAAG,MAAM,KAAK;AACjE,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,MAAM,qBACJ,OACe;AACf,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AAEA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,UAAU;AACpC,eAAO;AAAA,UACL,gCAAgC,GAAG,KAAK,MAAM,MAAM;AAAA,QACtD;AAEA,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,QAAQ;AAAA,UACnD,cAAc;AAAA,UACd,QAAQ;AAAA;AAAA,QACV,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,sCAAsC,SAAS,MAAM,EAAE;AAAA,QACzE;AAEA,eAAO,MAAM,sCAAsC,MAAM,MAAM,QAAQ;AAAA,MACzE,SAAS,OAAO;AACd,eAAO;AAAA,UACL,uCAAuC,MAAM,MAAM;AAAA,UACnD;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,OAAO,KAA4B;AACvC,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AACA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,qBAAqB,EAAE,IAAI,CAAC;AACtD,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,QAAQ;AAErD,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,QACpE;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,8BAA8B,GAAG,MAAM,KAAK;AACzD,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,QAAuB;AAC3B,UAAI,CAAC,KAAK,QAAQ,SAAS,SAAS;AAClC,eAAO,MAAM,yBAAyB;AACtC,eAAO,QAAQ,OAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC5D;AACA,UAAI;AACF,cAAM,MAAM,KAAK,SAAS,mBAAmB;AAC7C,cAAM,WAAW,MAAM,KAAK,YAAY,KAAK,QAAQ;AAErD,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,QACpE;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,qBAAqB,KAAK;AACvC,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,YAAqC;AACnC,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKQ,YAAY,cAAqD;AACvE,YAAM,MAAM,KAAK,mBAAmB,IAAI,YAAY;AACpD,UAAI,IAAK,QAAO;AAChB,UAAI;AACF,qBAAa,WAAW,mBAAkB,wBAAwB,YAAY;AAC9E,cAAM,MAAM,aAAa,QAAQ,mBAAkB,kBAAkB,YAAY;AACjF,YAAI,KAAK;AACP,gBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cACE,UACA,OAAO,OAAO,YAAY,YAC1B,OAAO,QAAQ,SAAS,KACxB,OAAO,gBACP,OAAO,OAAO,iBAAiB,UAC/B;AACA,iBAAK,mBAAmB,IAAI,cAAc,MAAM;AAChD,mBAAO;AAAA,UACT;AACA,uBAAa,WAAW,mBAAkB,kBAAkB,YAAY;AAAA,QAC1E;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA,IAIQ,YAAY,cAAsB,UAAmC;AAC3E,WAAK,mBAAmB,IAAI,cAAc,QAAQ;AAClD,UAAI;AACF,qBAAa;AAAA,UACX,mBAAkB,kBAAkB;AAAA,UACpC,KAAK,UAAU,QAAQ;AAAA,QACzB;AACA,qBAAa,WAAW,mBAAkB,wBAAwB,YAAY;AAAA,MAChF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASQ,gBAAgB,UAAoB,KAAoB;AAC9D,aAAO,MAAM,iBAAiB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAEtE,UAAI,SAAS,WAAW,KAAK;AAC3B,cAAM,IAAI,yBAAyB,GAAG;AAAA,MACxC;AAEA,UAAI,SAAS,WAAW,KAAK;AAC3B,cAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AACrD,cAAM,IAAI;AAAA,UACR;AAAA,UACA,aAAa,SAAS,YAAY,EAAE,IAAI,MAAO;AAAA,QACjD;AAAA,MACF;AAEA,UAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AACnD,cAAM,IAAI,YAAY,KAAK,SAAS,MAAM;AAAA,MAC5C;AAGA,YAAM,IAAI,aAAa,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IAC1E;AAAA;AAAA;AAAA;AAAA;AAAA,IAMQ,kBAAkB,OAAuB;AAE/C,UACE,iBAAiB,4BACjB,iBAAiB,0BACjB,iBAAiB,eACjB,iBAAiB,cACjB;AACA,cAAM;AAAA,MACR;AAGA,YAAM,IAAI,aAAa,0BAA0B,KAAK;AAAA,IACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASQ,SACN,UACA,SAAiC,CAAC,GAC1B;AACR,YAAM,UAAU,KAAK,OAAO,SAAS,WAAW;AAGhD,UAAI,mBACF,KAAK,OAAO,SAAS,YAAY,QAAQ,KACzC,KAAK,kBAAkB,QAAQ;AAGjC,UAAI,CAAC,iBAAiB,WAAW,GAAG,GAAG;AACrC,2BAAmB,IAAI,gBAAgB;AAAA,MACzC;AAIA,UAAI,OAAO;AACX,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,cAAM,cAAc,IAAI,OAAO,IAAI,GAAG,IAAI,GAAG;AAC7C,eAAO,KAAK,QAAQ,aAAa,mBAAmB,KAAK,CAAC;AAAA,MAC5D;AAEA,aAAO,GAAG,OAAO,GAAG,IAAI;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA,IAKA,MAAc,YACZ,KACA,QACA,MACA,cACmB;AACnB,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,UAAU,KAAK,OAAO,SAAS,WAAW;AAChD,YAAM,YAAY;AAAA,QAChB,MAAM,WAAW,MAAM;AAAA,QACvB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,UAAkC;AAAA,UACtC,gBAAgB;AAAA,UAChB,GAAG,KAAK,OAAO,SAAS;AAAA,UACxB,GAAG;AAAA,QACL;AAEA,YAAI,KAAK,OAAO,SAAS,QAAQ;AAC/B,kBAAQ,eAAe,IAAI,UAAU,KAAK,OAAO,QAAQ,MAAM;AAAA,QACjE;AAEA,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC;AAAA,UACA;AAAA,UACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,UACpC,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,eAAO;AAAA,MACT,UAAE;AACA,qBAAa,SAAS;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAlmBE;AAAA,gBAnBW,oBAmBa,mBAAkB;AAI1C;AAAA;AAAA,gBAvBW,oBAuBa,yBAAwB;AAvB3C,MAAM,oBAAN;;;ACnBP,MAAM,mBAAoC;AAAA,IACxC,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAGA,MAAM,WAAW;AAAA,IACf,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AAEO,MAAM,gBAAN,MAAoB;AAAA,IAIzB,YAAY,WAAqC,CAAC,GAAG,gBAAgB,GAAG;AAHxE,0BAAQ;AACR,0BAAQ;AAGN,WAAK,WAAW,EAAE,GAAG,kBAAkB,GAAG,SAAS;AACnD,WAAK,gBAAgB;AAAA,IACvB;AAAA;AAAA;AAAA;AAAA,IAKA,cAAc,MAAuB;AACnC,YAAM,UAAU,KAAK,KAAK;AAG1B,UAAI,QAAQ,SAAS,KAAK,eAAe;AACvC,eAAO;AAAA,MACT;AAGA,UAAI,KAAK,SAAS,UAAU,SAAS,MAAM,KAAK,OAAO,GAAG;AACxD,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,SAAS,QAAQ,SAAS,IAAI,KAAK,OAAO,GAAG;AACpD,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,SAAS,WAAW,SAAS,OAAO,KAAK,OAAO,GAAG;AAC1D,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,SAAS,UAAU,SAAS,MAAM,KAAK,OAAO,GAAG;AACxD,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAAA,EACF;;;ACjDO,WAAS,kBAAkB,SAA+B;AAC/D,UAAM,SAAmC,CAAC;AAC1C,QAAI,WAAW;AAEf,aAAS,KAAK,MAAoB;AAChC,UAAI,KAAK,aAAa,KAAK,WAAW;AACpC,eAAO,KAAK,aAAa;AAAA,MAC3B;AAEA,UAAI,KAAK,aAAa,KAAK,cAAc;AACvC,eAAO;AAAA,MACT;AAEA,YAAM,KAAK;AACX,YAAM,MAAM,GAAG,QAAQ,YAAY;AAGnC,YAAM,QAAgC,CAAC;AACvC,eAAS,IAAI,GAAG,IAAI,GAAG,WAAW,QAAQ,KAAK;AAC7C,cAAM,OAAO,GAAG,WAAW,CAAC;AAC5B,cAAM,KAAK,KAAK,YAAY,CAAC,IAAI,KAAK;AAAA,MACxC;AAEA;AACA,YAAM,MAAM;AACZ,aAAO,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,oBAAoB,KAAK,KAAK,CAAC,EAAE;AAE/D,UAAI,UAAU,IAAI,GAAG,GAAG;AACtB,eAAO,IAAI,GAAG;AAAA,MAChB;AAEA,UAAI,QAAQ;AACZ,eAAS,IAAI,GAAG,IAAI,KAAK,WAAW,QAAQ,KAAK;AAC/C,iBAAS,KAAK,KAAK,WAAW,CAAC,CAAC;AAAA,MAClC;AACA,aAAO,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG;AAAA,IACjC;AAEA,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,QAAQ,WAAW,QAAQ,KAAK;AAClD,cAAQ,KAAK,QAAQ,WAAW,CAAC,CAAC;AAAA,IACpC;AAEA,WAAO,EAAE,MAAM,OAAO;AAAA,EACxB;;;ACtDA,WAAS,QAAQ,GAAW,GAAmB;AAC7C,UAAM,OAAO,IAAI,UAAW,IAAI;AAChC,UAAM,OAAO,KAAK,OAAO,KAAK,OAAO,OAAO;AAC5C,WAAQ,OAAO,KAAO,MAAM;AAAA,EAC9B;AAEA,WAAS,cAAc,KAAa,KAAqB;AACvD,WAAQ,OAAO,MAAQ,QAAS,KAAK;AAAA,EACvC;AAEA,WAAS,OACP,GACA,GACA,GACA,GACA,GACA,GACQ;AACR,WAAO,QAAQ,cAAc,QAAQ,QAAQ,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AAAA,EAC3E;AAEA,WAAS,MACP,GACA,GACA,GACA,GACA,GACA,GACA,GACQ;AACR,WAAO,OAAQ,IAAI,IAAM,CAAC,IAAI,GAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACjD;AAEA,WAAS,MACP,GACA,GACA,GACA,GACA,GACA,GACA,GACQ;AACR,WAAO,OAAQ,IAAI,IAAM,IAAI,CAAC,GAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACjD;AAEA,WAAS,MACP,GACA,GACA,GACA,GACA,GACA,GACA,GACQ;AACR,WAAO,OAAO,IAAI,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACxC;AAEA,WAAS,MACP,GACA,GACA,GACA,GACA,GACA,GACA,GACQ;AACR,WAAO,OAAO,KAAK,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EAC3C;AAEA,WAAS,QAAQ,GAAa,KAAuB;AACnD,MAAE,OAAO,CAAC,KAAK,OAAQ,MAAM;AAC7B,OAAK,MAAM,OAAQ,KAAM,KAAK,EAAE,IAAI;AAEpC,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AAER,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,IAAI;AACrC,YAAM,OAAO;AACb,YAAM,OAAO;AACb,YAAM,OAAO;AACb,YAAM,OAAO;AAEb,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,UAAU;AACzC,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,SAAS;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,SAAS;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,MAAM;AAC3C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW;AAChD,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW;AAChD,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU;AAE/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,WAAW;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,UAAU;AAC1C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,QAAQ;AAC5C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,SAAS;AAC5C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,SAAS;AAC5C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW;AAEhD,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,OAAO;AAC1C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,WAAW;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW;AAChD,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,SAAS;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,QAAQ;AAC5C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAE9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,UAAU;AACzC,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW;AAChD,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,SAAS;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,UAAU;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,QAAQ;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS;AAC9C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU;AAC/C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,UAAU;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW;AAChD,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,SAAS;AAC7C,UAAI,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,UAAU;AAE9C,UAAI,QAAQ,GAAG,IAAI;AACnB,UAAI,QAAQ,GAAG,IAAI;AACnB,UAAI,QAAQ,GAAG,IAAI;AACnB,UAAI,QAAQ,GAAG,IAAI;AAAA,IACrB;AAEA,WAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,EACpB;AAEA,WAAS,SAAS,UAA4B;AAC5C,UAAM,SAAS;AACf,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,SAAS,SAAS,GAAG,KAAK;AAC5C,aACE,OAAO,OAAQ,SAAS,KAAK,CAAC,KAAO,IAAI,IAAK,IAAI,IAAM,EAAG,IAC3D,OAAO,OAAQ,SAAS,KAAK,CAAC,KAAO,IAAI,IAAK,IAAM,EAAG;AAAA,IAC3D;AACA,WAAO;AAAA,EACT;AAUA,WAAS,UAAU,KAAyB;AAC1C,QAAI,OAAO,gBAAgB,aAAa;AACtC,aAAO,IAAI,YAAY,EAAE,OAAO,GAAG;AAAA,IACrC;AAEA,UAAM,MAAgB,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,UAAI,IAAI,KAAM;AACZ,YAAI,KAAK,CAAC;AAAA,MACZ,WAAW,IAAI,MAAO;AACpB,YAAI,KAAK,MAAQ,KAAK,GAAI,MAAQ,IAAI,EAAK;AAAA,MAC7C,WAAW,KAAK,SAAU,IAAI,SAAU,IAAI,IAAI,IAAI,QAAQ;AAC1D,cAAM,KAAK,IAAI,WAAW,EAAE,CAAC;AAC7B,cAAM,KAAK,SAAY,IAAI,SAAW,OAAO,KAAK;AAClD,YAAI;AAAA,UACF,MAAQ,MAAM;AAAA,UACd,MAAS,MAAM,KAAM;AAAA,UACrB,MAAS,MAAM,IAAK;AAAA,UACpB,MAAQ,KAAK;AAAA,QACf;AAAA,MACF,OAAO;AACL,YAAI;AAAA,UACF,MAAQ,KAAK;AAAA,UACb,MAAS,KAAK,IAAK;AAAA,UACnB,MAAQ,IAAI;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,WAAW,GAAG;AAAA,EAC3B;AAEA,WAAS,WAAW,OAA6B;AAC/C,UAAM,MAAgB,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAI,KAAK,CAAC,KAAK,MAAM,CAAC,KAAO,IAAI,IAAK;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAOO,WAAS,IAAI,KAAqB;AACvC,UAAM,QAAQ,UAAU,GAAG;AAC3B,WAAO,SAAS,QAAQ,WAAW,KAAK,GAAG,MAAM,SAAS,CAAC,CAAC;AAAA,EAC9D;AAMO,WAAS,gBAAgB,MAAsB;AACpD,UAAM,UAAU,KAAK,KAAK;AAC1B,WAAO,UAAU,IAAI,OAAO,EAAE,UAAU,GAAG,EAAE;AAAA,EAC/C;;;AC1OA,MAAM,iBACJ;AAQF,MAAM,wBAAwB;AAG9B,MAAM,YAAY,oBAAI,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,MAAM,kBAAkB;AAAA,IACtB;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,EACF;AAQO,MAAM,iBAAN,MAAqB;AAAA,IAI1B,YACE,kBAA4C,CAAC,GAC7C,mBAA6B,CAAC,GAC9B,gBAAgB,GAChB;AAPF,0BAAQ;AACR,0BAAQ;AAON,WAAK,gBAAgB,IAAI,cAAc,iBAAiB,aAAa;AACrE,WAAK,mBAAmB;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,QAAQ,MAA0B,oBAAoB,OAAyB;AAC7E,YAAM,UAA4B,CAAC;AACnC,YAAM,cAAc,KAAK,iBAAiB,cAAc;AAGxD,YAAM,WAAsB,CAAC;AAC7B,UAAI,gBAAgB,WAAW,KAAK,QAAQ,cAAc,GAAG;AAC3D,iBAAS,KAAK,IAAI;AAAA,MACpB;AACA,eAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,iBAAS,KAAK,YAAY,CAAC,CAAC;AAAA,MAC9B;AAEA,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,cAAM,KAAK,SAAS,CAAC;AAGrB,YAAI,KAAK,gBAAgB,EAAE,GAAG;AAC5B;AAAA,QACF;AAGA,YAAI,CAAC,qBAAqB,KAAK,iBAAiB,EAAE,GAAG;AACnD;AAAA,QACF;AAGA,YAAI,KAAK,uBAAuB,EAAE,GAAG;AACnC;AAAA,QACF;AAGA,YAAI,GAAG,aAAa,WAAW,MAAM,MAAM;AACzC;AAAA,QACF;AAGA,YAAI,GAAG,cAAc,cAAc,GAAG;AACpC;AAAA,QACF;AAGA,cAAM,UAAU,GAAG,aAAa,eAAe;AAC/C,cAAM,aAAa,GAAG,aAAa,kBAAkB;AAErD,YAAI;AACJ,YAAI,YAAY;AAEd,gBAAM,OAAO,SAAS,cAAc,GAAG,OAAO;AAC9C,eAAK,YAAY;AACjB,iBAAO,kBAAkB,IAAI;AAAA,QAC/B,OAAO;AACL,iBAAO,kBAAkB,EAAE;AAAA,QAC7B;AAGA,cAAM,eAAe,KAAK,KAAK,QAAQ,mBAAmB,EAAE;AAG5D,YAAI,KAAK,cAAc,cAAc,YAAY,GAAG;AAClD;AAAA,QACF;AAGA,YAAI;AACJ,YAAI,SAAS;AACX,gBAAM;AAAA,QACR,OAAO;AACL,gBAAM,WAAW,GAAG,aAAa,WAAW;AAC5C,cAAI,UAAU;AACZ,kBAAM,SAAS,SAAS,GAAG,IAAI,WAAW,UAAU,QAAQ;AAAA,UAC9D,OAAO;AACL,kBAAM,gBAAgB,KAAK,IAAI;AAAA,UACjC;AAAA,QACF;AAEA,gBAAQ,KAAK,EAAE,SAAS,IAAI,MAAM,IAAI,CAAC;AAAA,MACzC;AAEA,WAAK,oBAAoB,MAAM,SAAS,iBAAiB;AAEzD,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASQ,oBACN,MACA,SACA,mBACM;AACN,YAAM,aAAa,KAAK,iBAAiB,qBAAqB;AAC9D,YAAM,WAAsB,CAAC;AAC7B,UAAI,gBAAgB,WAAW,KAAK,QAAQ,qBAAqB,GAAG;AAClE,iBAAS,KAAK,IAAI;AAAA,MACpB;AACA,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,iBAAS,KAAK,WAAW,CAAC,CAAC;AAAA,MAC7B;AAEA,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,cAAM,KAAK,SAAS,CAAC;AAErB,YAAI,KAAK,gBAAgB,EAAE,EAAG;AAC9B,YAAI,CAAC,qBAAqB,KAAK,iBAAiB,EAAE,EAAG;AACrD,YAAI,KAAK,uBAAuB,EAAE,EAAG;AACrC,YAAI,GAAG,aAAa,WAAW,MAAM,KAAM;AAK3C,YAAI,GAAG,eAAe,QAAQ,cAAc,EAAG;AAK/C,YAAI,GAAG,eAAe,QAAQ,qBAAqB,EAAG;AAGtD,YAAI,GAAG,cAAc,cAAc,EAAG;AAEtC,cAAM,aAAa,GAAG,aAAa,kBAAkB;AACrD,YAAI;AACJ,YAAI,YAAY;AACd,gBAAM,OAAO,SAAS,cAAc,GAAG,OAAO;AAC9C,eAAK,YAAY;AACjB,iBAAO,kBAAkB,IAAI;AAAA,QAC/B,OAAO;AACL,iBAAO,kBAAkB,EAAE;AAAA,QAC7B;AAEA,cAAM,eAAe,KAAK,KAAK,QAAQ,mBAAmB,EAAE;AAC5D,YAAI,KAAK,cAAc,cAAc,YAAY,EAAG;AAEpD,cAAM,UAAU,GAAG,aAAa,eAAe;AAC/C,YAAI;AACJ,YAAI,SAAS;AACX,gBAAM;AAAA,QACR,OAAO;AACL,gBAAM,WAAW,GAAG,aAAa,WAAW;AAC5C,cAAI,UAAU;AACZ,kBAAM,SAAS,SAAS,GAAG,IAAI,WAAW,UAAU,QAAQ;AAAA,UAC9D,OAAO;AACL,kBAAM,gBAAgB,KAAK,IAAI;AAAA,UACjC;AAAA,QACF;AAEA,gBAAQ,KAAK,EAAE,SAAS,IAAI,MAAM,IAAI,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,IAEQ,gBAAgB,SAA2B;AACjD,UAAI,UAA0B,QAAQ;AACtC,aAAO,SAAS;AAGd,YAAI,UAAU,IAAI,QAAQ,QAAQ,YAAY,CAAC,GAAG;AAChD,iBAAO;AAAA,QACT;AACA,kBAAU,QAAQ;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,iBAAiB,SAA2B;AAClD,UAAI,UAA0B;AAC9B,aAAO,SAAS;AACd,mBAAW,QAAQ,iBAAiB;AAClC,cAAI,QAAQ,aAAa,IAAI,GAAG;AAC9B,mBAAO;AAAA,UACT;AAAA,QACF;AACA,kBAAU,QAAQ;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,uBAAuB,SAA2B;AACxD,iBAAW,YAAY,KAAK,kBAAkB;AAC5C,YAAI;AACF,cAAI,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,QAAQ,GAAG;AAC1D,mBAAO;AAAA,UACT;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;;;ACjOA,MAAM,UAA6B;AAAA,IACjC,EAAE,UAAU,iDAAiD,MAAM,OAAO,MAAM,MAAM;AAAA,IACtF,EAAE,UAAU,WAAW,MAAM,SAAS,MAAM,QAAQ;AAAA,IACpD,EAAE,UAAU,6CAA6C,MAAM,eAAe,MAAM,cAAc;AAAA,IAClG,EAAE,UAAU,qCAAqC,MAAM,WAAW,MAAM,mBAAmB;AAAA,IAC3F;AAAA,MACE,UACE;AAAA,MACF,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAIA,MAAMC,aAAY,oBAAI,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,MAAMC,mBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAQA,WAAS,cAAc,UAA0B;AAC/C,WAAO,gBAAgB,SAAS,YAAY,CAAC;AAAA,EAC/C;AAaO,MAAM,qBAAN,MAAyB;AAAA,IAI9B,YACE,kBAA4C,CAAC,GAC7C,mBAA6B,CAAC,GAC9B,gBAAgB,GAChB;AAPF,0BAAQ;AACR,0BAAQ;AAON,WAAK,gBAAgB,IAAI,cAAc,iBAAiB,aAAa;AACrE,WAAK,mBAAmB;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,QAAQ,MAA0B,iBAAiB,OAA6B;AAC9E,YAAM,UAAgC,CAAC;AAEvC,iBAAW,UAAU,SAAS;AAC5B,cAAM,aAAa,KAAK,iBAAiB,OAAO,QAAQ;AACxD,cAAM,MAAiB,CAAC;AACxB,YAAI,gBAAgB,WAAW,KAAK,QAAQ,OAAO,QAAQ,GAAG;AAC5D,cAAI,KAAK,IAAI;AAAA,QACf;AACA,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,cAAI,KAAK,WAAW,CAAC,CAAC;AAAA,QACxB;AAEA,iBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,gBAAM,KAAK,IAAI,CAAC;AAEhB,cAAI,KAAK,gBAAgB,EAAE,EAAG;AAC9B,cAAI,KAAK,gBAAgB,EAAE,EAAG;AAC9B,cAAI,KAAK,uBAAuB,EAAE,EAAG;AACrC,cAAI,GAAG,aAAa,WAAW,MAAM,KAAM;AAE3C,gBAAM,WAAW,GAAG,aAAa,OAAO,IAAI;AAC5C,cAAI,aAAa,KAAM;AAEvB,gBAAM,UAAU,SAAS,KAAK;AAC9B,cAAI,KAAK,cAAc,cAAc,OAAO,EAAG;AAE/C,gBAAM,YAAY,cAAc,OAAO,IAAI;AAC3C,gBAAM,UAAU,GAAG,aAAa,SAAS;AACzC,cAAI,CAAC,kBAAkB,SAAS;AAC9B;AAAA,UACF;AAEA,gBAAM,OAAsB,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;AAChE,gBAAM,MAAM,WAAW,gBAAgB,QAAQ;AAE/C,kBAAQ,KAAK,EAAE,SAAS,IAAI,UAAU,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,QAChE;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IAEQ,gBAAgB,SAA2B;AACjD,UAAI,UAA0B,QAAQ;AACtC,aAAO,SAAS;AAEd,YAAID,WAAU,IAAI,QAAQ,QAAQ,YAAY,CAAC,EAAG,QAAO;AACzD,kBAAU,QAAQ;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,gBAAgB,SAA2B;AACjD,UAAI,UAA0B;AAC9B,aAAO,SAAS;AACd,mBAAW,QAAQC,kBAAiB;AAClC,cAAI,QAAQ,aAAa,IAAI,EAAG,QAAO;AAAA,QACzC;AACA,kBAAU,QAAQ;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,uBAAuB,SAA2B;AACxD,iBAAW,YAAY,KAAK,kBAAkB;AAC5C,YAAI;AACF,cAAI,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,QAAQ,GAAG;AAC1D,mBAAO;AAAA,UACT;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;;;ACpLO,MAAM,cAAN,MAAkB;AAAA,IAOvB,YAAY,WAAiC,aAAa,IAAI;AAN9D,0BAAQ,YAAoC;AAC5C,0BAAQ;AACR,0BAAQ,iBAAsD;AAC9D,0BAAQ,mBAAgC,oBAAI,IAAI;AAChD,0BAAQ;AAGN,WAAK,YAAY;AACjB,WAAK,aAAa;AAAA,IACpB;AAAA;AAAA;AAAA;AAAA,IAKA,QAAc;AACZ,UAAI,KAAK,UAAU;AACjB;AAAA,MACF;AAEA,WAAK,WAAW,IAAI,iBAAiB,CAAC,cAAc;AAClD,aAAK,gBAAgB,SAAS;AAAA,MAChC,CAAC;AAED,WAAK,SAAS,QAAQ,SAAS,MAAM;AAAA,QACnC,WAAW;AAAA,QACX,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKA,OAAa;AACX,UAAI,KAAK,UAAU;AACjB,aAAK,SAAS,WAAW;AACzB,aAAK,WAAW;AAAA,MAClB;AACA,UAAI,KAAK,eAAe;AACtB,qBAAa,KAAK,aAAa;AAC/B,aAAK,gBAAgB;AAAA,MACvB;AACA,WAAK,gBAAgB,MAAM;AAAA,IAC7B;AAAA;AAAA;AAAA;AAAA,IAKQ,gBAAgB,WAAmC;AACzD,UAAI,kBAAkB;AAEtB,iBAAW,YAAY,WAAW;AAChC,mBAAW,QAAQ,MAAM,KAAK,SAAS,UAAU,GAAG;AAClD,cAAI,KAAK,aAAa,KAAK,aAAc;AAEzC,gBAAM,UAAU;AAGhB,cAAI,KAAK,oBAAoB,OAAO,GAAG;AACrC,8BAAkB;AAAA,UACpB;AAGA,cAAI,KAAK,UAAU,cAAc;AAC/B,iBAAK,gBAAgB,IAAI,OAAO;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAGA,UAAI,mBAAmB,KAAK,UAAU,gBAAgB;AACpD,aAAK,UAAU,eAAe;AAAA,MAChC;AAGA,UAAI,KAAK,gBAAgB,OAAO,GAAG;AACjC,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,gBAAsB;AAC5B,UAAI,KAAK,eAAe;AACtB,qBAAa,KAAK,aAAa;AAAA,MACjC;AAEA,WAAK,gBAAgB,WAAW,MAAM;AACpC,aAAK,qBAAqB;AAAA,MAC5B,GAAG,KAAK,UAAU;AAAA,IACpB;AAAA;AAAA;AAAA;AAAA,IAKQ,uBAA6B;AACnC,UAAI,CAAC,KAAK,UAAU,gBAAgB,KAAK,gBAAgB,SAAS,GAAG;AACnE;AAAA,MACF;AAEA,iBAAW,WAAW,KAAK,iBAAiB;AAE1C,YAAI,CAAC,SAAS,KAAK,SAAS,OAAO,GAAG;AACpC;AAAA,QACF;AACA,aAAK,UAAU,aAAa,OAAO;AAAA,MACrC;AAEA,WAAK,gBAAgB,MAAM;AAAA,IAC7B;AAAA;AAAA;AAAA;AAAA,IAKQ,oBAAoB,SAA2B;AACrD,aACE,QAAQ,aAAa,yBAAyB,KAC9C,QAAQ,cAAc,2BAA2B,MAAM;AAAA,IAE3D;AAAA,EACF;;;AClHA,MAAM,iBAAiB,IAAI,eAAe;AASnC,MAAM,iBAAN,MAAqB;AAAA,IAa1B,YAAY,SAA+B,CAAC,GAAG;AAZ/C,0BAAQ,QAA6B;AACrC,0BAAQ;AACR,0BAAQ;AACR,0BAAQ,eAAkC;AAC1C,0BAAQ,UAAS;AACjB,0BAAQ,gBAAe;AACvB,0BAAQ,aAAY;AACpB,0BAAQ;AACR,0BAAQ,mBAAgC,oBAAI,IAAI;AAChD,0BAAQ,iBAAsD;AAC9D,0BAAQ,mBAAkB;AAGxB,WAAK,iBAAiB,IAAI;AAAA,QACxB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,WAAK,qBAAqB,IAAI;AAAA,QAC5B,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,WAAK,aAAa,OAAO,cAAc;AAAA,IACzC;AAAA;AAAA;AAAA;AAAA,IAKA,QAAQ,MAA2B;AACjC,WAAK,OAAO;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,QAA2E;AAC9E,WAAK,SAAS,OAAO;AACrB,WAAK,eAAe,OAAO;AAC3B,WAAK,YAAY,OAAO;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA,IAKA,aAAa,QAAsB;AACjC,WAAK,SAAS;AAAA,IAChB;AAAA;AAAA;AAAA;AAAA,IAKA,UAAmB;AACjB,aAAO,KAAK,SAAS;AAAA,IACvB;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAgB,MAAsB;AACpC,aAAO,gBAAgB,IAAI;AAAA,IAC7B;AAAA;AAAA;AAAA;AAAA,IAKA,aAAa,SAAwB;AACnC,WAAK,gBAAgB,IAAI,OAAO;AAChC,WAAK,mBAAmB;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA,IAKA,iBAAiB,SAA0B;AACzC,UAAI,CAAC,KAAK,MAAM;AACd,eAAO;AAAA,MACT;AAEA,YAAM,aAAa,KAAK,gBAAgB,KAAK,eAAe,QAAQ,OAAO,CAAC;AAC5E,YAAM,YAAY,KAAK,sBAAsB,KAAK,mBAAmB,QAAQ,OAAO,CAAC;AACrF,aAAO,aAAa;AAAA,IACtB;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAwB;AACtB,aAAO,KAAK,iBAAiB,SAAS,IAAI;AAAA,IAC5C;AAAA;AAAA;AAAA;AAAA,IAKA,UAAgB;AACd,UAAI,KAAK,aAAa;AACpB;AAAA,MACF;AAEA,WAAK,cAAc,IAAI,YAAY;AAAA,QACjC,cAAc,CAAC,YAAY,KAAK,aAAa,OAAO;AAAA,MACtD,CAAC;AACD,WAAK,YAAY,MAAM;AAAA,IACzB;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAsB;AACpB,UAAI,KAAK,aAAa;AACpB,aAAK,YAAY,KAAK;AACtB,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,qBAA2B;AACjC,UAAI,KAAK,eAAe;AACtB,qBAAa,KAAK,aAAa;AAAA,MACjC;AAEA,WAAK,gBAAgB,WAAW,MAAM;AACpC,aAAK,uBAAuB;AAAA,MAC9B,GAAG,KAAK,UAAU;AAAA,IACpB;AAAA;AAAA;AAAA;AAAA,IAKQ,yBAA+B;AACrC,UAAI,CAAC,KAAK,QAAQ,KAAK,gBAAgB,SAAS,GAAG;AACjD;AAAA,MACF;AAEA,UAAI,kBAAkB;AAEtB,iBAAW,WAAW,KAAK,iBAAiB;AAE1C,YAAI,CAAC,SAAS,KAAK,SAAS,OAAO,GAAG;AACpC;AAAA,QACF;AAEA,cAAM,QAAQ,KAAK,iBAAiB,OAAO;AAC3C,2BAAmB;AAAA,MACrB;AAEA,WAAK,gBAAgB,MAAM;AAC3B,WAAK,mBAAmB;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA,IAKQ,gBAAgB,WAAqC;AAC3D,UAAI,CAAC,KAAK,KAAM,QAAO;AAEvB,UAAI,QAAQ;AAEZ,iBAAW,EAAE,SAAS,MAAM,IAAI,KAAK,WAAW;AAE9C,cAAM,UAAU,GAAG,KAAK,MAAM,IAAI,KAAK,SAAS,IAAI,GAAG;AAGvD,cAAM,SAAS,KAAK,KAAK,MAAM,IAAI,OAAO;AAE1C,YAAI,UAAU,OAAO,UAAU,KAAK,QAAQ,OAAO,UAAU,KAAK;AAEhE,cAAI,CAAC,QAAQ,aAAa,kBAAkB,GAAG;AAC7C,oBAAQ,aAAa,oBAAoB,QAAQ,SAAS;AAAA,UAC5D;AAMA,gBAAM,iBAAiB,OAAO,UAAU,OAAO,KAAK,OAAO,MAAM,EAAE,SAAS;AAC5E,gBAAM,kBAAkB,OAAO,KAAK,KAAK,MAAM,EAAE,SAAS;AAC1D,gBAAM,oBAAoB,iBAAiB,KAAK,OAAO,KAAK;AAE5D,cAAI,mBAAmB,CAAC,mBAAmB;AAAA,UAK3C,OAAO;AACL,kBAAM,SAAS,iBAAiB,OAAO,SAAU,KAAK;AACtD,kBAAM,iBAA8B,EAAE,MAAM,OAAO,OAAO,OAAO;AACjE,oBAAQ,YAAY,eAAe,UAAU,cAAc;AAAA,UAC7D;AACA,kBAAQ,aAAa,iBAAiB,GAAG;AACzC,kBAAQ,aAAa,yBAAyB,GAAG;AACjD;AAAA,QACF,OAAO;AAGL,eAAK,KAAK,IAAI,KAAK,yBAAyB;AAAA,YAC1C,SAAS;AAAA,cACP;AAAA,cACA,eAAe,KAAK;AAAA,cACpB,QAAQ,KAAK;AAAA,cACb,WAAW,KAAK;AAAA,cAChB,QAAQ;AAAA,cACR,QAAQ,KAAK;AAAA,YACf;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBQ,sBAAsB,WAAyC;AACrE,UAAI,CAAC,KAAK,KAAM,QAAO;AACvB,UAAI,QAAQ;AAEZ,iBAAW,EAAE,SAAS,UAAU,MAAM,IAAI,KAAK,WAAW;AACxD,cAAM,UAAU,GAAG,KAAK,MAAM,IAAI,KAAK,SAAS,IAAI,GAAG;AACvD,cAAM,SAAS,KAAK,KAAK,MAAM,IAAI,OAAO;AAE1C,YAAI,UAAU,OAAO,UAAU,KAAK,QAAQ,OAAO,UAAU,KAAK;AAChE,gBAAM,QAAQ,SAAS,YAAY;AACnC,gBAAM,WAAW,gBAAgB,KAAK;AAItC,cAAI,CAAC,QAAQ,aAAa,QAAQ,GAAG;AACnC,oBAAQ,aAAa,UAAU,KAAK,IAAI;AAAA,UAC1C;AACA,kBAAQ,aAAa,UAAU,OAAO,KAAK;AAC3C,kBAAQ,aAAa,gBAAgB,KAAK,IAAI,GAAG;AAIjD,gBAAM,WAAW,QAAQ,aAAa,6BAA6B,KAAK;AACxE,gBAAM,MAAM,IAAI,IAAI,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO,CAAC;AACvD,cAAI,IAAI,KAAK;AACb,kBAAQ,aAAa,+BAA+B,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG,CAAC;AAE7E;AAAA,QACF,OAAO;AACL,eAAK,KAAK,IAAI,KAAK,yBAAyB;AAAA,YAC1C,SAAS;AAAA,cACP;AAAA,cACA,eAAe,KAAK;AAAA,cACpB,QAAQ,KAAK;AAAA,cACb,WAAW,KAAK;AAAA,cAChB,QAAQ;AAAA,cACR,QAAQ,CAAC;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA,IAKA,qBAA6B;AAC3B,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQQ,wBAAwB,IAAmB;AACjD,YAAM,OAAO,GAAG,aAAa,6BAA6B;AAC1D,UAAI,SAAS,KAAM;AACnB,iBAAW,QAAQ,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO,GAAG;AAClD,cAAM,OAAO,GAAG,aAAa,gBAAgB,IAAI,EAAE;AACnD,YAAI,SAAS,MAAM;AACjB,aAAG,aAAa,MAAM,IAAI;AAC1B,aAAG,gBAAgB,gBAAgB,IAAI,EAAE;AAAA,QAC3C;AACA,WAAG,gBAAgB,gBAAgB,IAAI,EAAE;AAAA,MAC3C;AACA,SAAG,gBAAgB,6BAA6B;AAAA,IAClD;AAAA;AAAA;AAAA;AAAA,IAKA,mBAAmB,SAAwB;AACzC,YAAM,WAAW,QAAQ,aAAa,kBAAkB;AACxD,UAAI,aAAa,KAAM,SAAQ,YAAY;AAC3C,cAAQ,gBAAgB,uBAAuB;AAC/C,cAAQ,gBAAgB,eAAe;AACvC,WAAK,wBAAwB,OAAO;AACpC,WAAK,iBAAiB,OAAO;AAAA,IAC/B;AAAA;AAAA;AAAA;AAAA,IAKA,cAAoB;AAElB,YAAM,mBAAmB,SAAS,iBAAiB,yBAAyB;AAC5E,uBAAiB,QAAQ,CAAC,OAAO;AAC/B,cAAM,WAAW,GAAG,aAAa,kBAAkB;AACnD,YAAI,aAAa,MAAM;AACrB,aAAG,YAAY;AAAA,QACjB;AACA,WAAG,gBAAgB,uBAAuB;AAC1C,WAAG,gBAAgB,eAAe;AAAA,MACpC,CAAC;AAKD,YAAM,kBAAkB,SAAS,iBAAiB,+BAA+B;AACjF,sBAAgB,QAAQ,CAAC,OAAO,KAAK,wBAAwB,EAAE,CAAC;AAGhE,WAAK,kBAAkB;AACvB,UAAI,KAAK,WAAW,KAAK,cAAc;AACrC,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAAA,EACF;;;ACxVA,MAAM,oBAA8C;AAAA,IAClD,IAAI,EAAE,MAAM,MAAM,MAAM,WAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,cAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,eAAY,MAAM,qBAAO;AAAA,IACjD,IAAI,EAAE,MAAM,MAAM,MAAM,WAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,YAAY,MAAM,qBAAO;AAAA,IACjD,IAAI,EAAE,MAAM,MAAM,MAAM,gBAAa,MAAM,qBAAO;AAAA,IAClD,IAAI,EAAE,MAAM,MAAM,MAAM,cAAc,MAAM,qBAAO;AAAA,IACnD,IAAI,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,qBAAO;AAAA,IAC/C,IAAI,EAAE,MAAM,MAAM,MAAM,8CAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,sBAAO,MAAM,qBAAO;AAAA,IAC5C,IAAI,EAAE,MAAM,MAAM,MAAM,sBAAO,MAAM,qBAAO;AAAA,IAC5C,IAAI,EAAE,MAAM,MAAM,MAAM,gBAAM,MAAM,qBAAO;AAAA,IAC3C,IAAI,EAAE,MAAM,MAAM,MAAM,8CAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,wCAAU,MAAM,qBAAO;AAAA,IAC/C,IAAI,EAAE,MAAM,MAAM,MAAM,gBAAU,MAAM,qBAAO;AAAA,IAC/C,IAAI,EAAE,MAAM,MAAM,MAAM,wBAAc,MAAM,qBAAO;AAAA,IACnD,IAAI,EAAE,MAAM,MAAM,MAAM,sBAAO,MAAM,qBAAO;AAAA,IAC5C,IAAI,EAAE,MAAM,MAAM,MAAM,WAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,qBAAO;AAAA,IAC9C,IAAI,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,qBAAO;AAAA,IAC9C,IAAI,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,qBAAO;AAAA,IAC9C,IAAI,EAAE,MAAM,MAAM,MAAM,qBAAW,MAAM,qBAAO;AAAA,IAChD,IAAI,EAAE,MAAM,MAAM,MAAM,oDAAY,MAAM,qBAAO;AAAA,IACjD,IAAI,EAAE,MAAM,MAAM,MAAM,kCAAS,MAAM,qBAAO;AAAA,IAC9C,IAAI,EAAE,MAAM,MAAM,MAAM,oBAAoB,MAAM,qBAAO;AAAA,IACzD,IAAI,EAAE,MAAM,MAAM,MAAM,iBAAiB,MAAM,qBAAO;AAAA,IACtD,IAAI,EAAE,MAAM,MAAM,MAAM,gEAAc,MAAM,qBAAO;AAAA,IACnD,IAAI,EAAE,MAAM,MAAM,MAAM,kBAAU,MAAM,qBAAO;AAAA,IAC/C,IAAI,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,qBAAO;AAAA,IAC/C,IAAI,EAAE,MAAM,MAAM,MAAM,mBAAc,MAAM,qBAAO;AAAA,IACnD,IAAI,EAAE,MAAM,MAAM,MAAM,0DAAa,MAAM,qBAAO;AAAA,IAClD,IAAI,EAAE,MAAM,MAAM,MAAM,YAAY,MAAM,qBAAO;AAAA,IACjD,IAAI,EAAE,MAAM,MAAM,MAAM,wCAAU,MAAM,qBAAO;AAAA,IAC/C,IAAI,EAAE,MAAM,MAAM,MAAM,yBAAe,MAAM,qBAAO;AAAA,IACpD,IAAI,EAAE,MAAM,MAAM,MAAM,iBAAY,MAAM,qBAAO;AAAA,IACjD,IAAI,EAAE,MAAM,MAAM,MAAM,iBAAY,MAAM,qBAAO;AAAA,IACjD,IAAI,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,qBAAO;AAAA,EAChD;AAGA,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+ER,MAAM,mBAAN,MAAuB;AAAA,IAO5B,cAAc;AANd,0BAAQ,QAA6B;AACrC,0BAAQ,aAAwB,CAAC;AACjC,0BAAQ,iBAAgB;AACxB,0BAAQ,oBAAsD;AAC9D,0BAAQ,kBAAiB;AAAA,IAEV;AAAA;AAAA;AAAA;AAAA,IAKf,QAAQ,MAA2B;AACjC,WAAK,OAAO;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKA,iBAAiB,QAAsB;AACrC,WAAK,gBAAgB;AAAA,IACvB;AAAA;AAAA;AAAA;AAAA,IAKA,aAAa,WAAwC;AACnD,WAAK,YAAY,UAAU,IAAI,CAAC,SAAS;AACvC,YAAI,OAAO,SAAS,UAAU;AAC5B,iBAAO,kBAAkB,IAAI,KAAK,EAAE,MAAM,MAAM,MAAM,KAAK;AAAA,QAC7D;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKA,oBAAoB,UAA0C;AAC5D,WAAK,mBAAmB;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA,IAKA,UAAgB;AACd,WAAK,aAAa;AAClB,YAAM,YAAY,SAAS,iBAAiB,2BAA2B;AACvE,gBAAU,QAAQ,CAAC,YAAY,KAAK,aAAa,OAAsB,CAAC;AAAA,IAC1E;AAAA;AAAA;AAAA;AAAA,IAKA,aAAa,SAA4B;AACvC,YAAM,QAAS,QAAQ,QAAQ,qBAAqB;AACpD,YAAM,gBAAgB,KAAK,MAAM,iBAAiB,KAAK,KAAK;AAG5D,cAAQ,YAAY;AACpB,cAAQ,UAAU,IAAI,oBAAoB;AAC1C,cAAQ,aAAa,qBAAqB,EAAE;AAC5C,cAAQ,aAAa,aAAa,IAAI;AAGtC,YAAM,WAAW,QAAQ,QAAQ,6BAA6B;AAC9D,YAAM,YAAY,QAAQ,QAAQ,+BAA+B;AACjE,YAAM,YAAY,QAAQ,QAAQ,+BAA+B;AACjE,YAAM,YAAY,QAAQ,QAAQ,8BAA8B;AAGhE,cAAQ,QAAQ,WAAW;AAG3B,UAAI,WAAW;AACb,cAAM,UAAU,SAAS,cAAc,OAAO;AAC9C,gBAAQ,cAAc;AACtB,iBAAS,KAAK,YAAY,OAAO;AAAA,MACnC;AAEA,cAAQ,OAAO;AAAA,QACb,KAAK;AACH,eAAK,gBAAgB,SAAS,eAAe,MAAM,IAAI;AACvD;AAAA,QACF,KAAK;AACH,eAAK,gBAAgB,SAAS,eAAe,WAAW,SAAS;AACjE;AAAA,QACF,KAAK;AAAA,QACL;AACE,eAAK,eAAe,SAAS,eAAe,UAAU,WAAW,SAAS;AAC1E;AAAA,MACJ;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,eACN,WACA,eACA,UACA,WACA,WACM;AAEN,YAAM,YAA0C,CAAC;AACjD,UAAI,SAAS,WAAW,QAAQ,GAAG;AACjC,kBAAU,SAAS;AAAA,MACrB,OAAO;AACL,kBAAU,MAAM;AAAA,MAClB;AACA,UAAI,SAAS,SAAS,MAAM,GAAG;AAC7B,kBAAU,OAAO;AAAA,MACnB,OAAO;AACL,kBAAU,QAAQ;AAAA,MACpB;AAEA,YAAM,cAAc,CAAC,SAA2B;AAC9C,cAAM,OAAO,YAAa,KAAK,QAAQ,KAAM;AAC7C,cAAM,OAAO,YAAY,KAAK,OAAO,KAAK,KAAK,YAAY;AAC3D,eAAO,GAAG,IAAI,GAAG,QAAQ,OAAO,MAAM,EAAE,GAAG,IAAI;AAAA,MACjD;AAGA,YAAM,cAAc,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa,KAAK,KAAK,UAAU,CAAC;AAC5F,YAAM,eAAe,cAAc,YAAY,WAAW,IAAI;AAG9D,YAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,aAAa,iBAAiB,OAAO;AACzC,UAAI,aAAa,iBAAiB,MAAM;AACxC,UAAI,cAAc,GAAG,YAAY;AAGjC,YAAM,OAAO,SAAS,cAAc,KAAK;AACzC,WAAK,YAAY;AACjB,aAAO,OAAO,KAAK,OAAO,SAAS;AAEnC,iBAAW,QAAQ,KAAK,WAAW;AACjC,cAAM,OAAO,SAAS,cAAc,QAAQ;AAC5C,aAAK,OAAO;AACZ,aAAK,QAAQ,OAAO,KAAK;AACzB,aAAK,cAAc,YAAY,IAAI;AACnC,YAAI,KAAK,SAAS,eAAe;AAC/B,eAAK,UAAU,IAAI,QAAQ;AAAA,QAC7B;AACA,aAAK,iBAAiB,SAAS,MAAM;AACnC,eAAK,qBAAqB,KAAK,IAAI;AACnC,cAAI,cAAc,YAAY,IAAI,IAAI;AACtC,eAAK,iBAAiB,QAAQ,EAAE,QAAQ,CAAC,MAAM;AAC7C,cAAE,UAAU,OAAO,UAAU,EAAE,QAAQ,SAAS,KAAK,IAAI;AAAA,UAC3D,CAAC;AACD,eAAK,UAAU,OAAO,MAAM;AAC5B,cAAI,aAAa,iBAAiB,OAAO;AAAA,QAC3C,CAAC;AACD,aAAK,YAAY,IAAI;AAAA,MACvB;AAGA,UAAI,iBAAiB,SAAS,CAAC,MAAM;AACnC,UAAE,gBAAgB;AAClB,cAAM,SAAS,KAAK,UAAU,SAAS,MAAM;AAC7C,aAAK,UAAU,OAAO,QAAQ,CAAC,MAAM;AACrC,YAAI,aAAa,iBAAiB,OAAO,CAAC,MAAM,CAAC;AAAA,MACnD,CAAC;AAGD,eAAS,iBAAiB,SAAS,MAAM;AACvC,aAAK,UAAU,OAAO,MAAM;AAC5B,YAAI,aAAa,iBAAiB,OAAO;AAAA,MAC3C,CAAC;AAED,gBAAU,YAAY,GAAG;AACzB,gBAAU,YAAY,IAAI;AAAA,IAC5B;AAAA;AAAA;AAAA;AAAA,IAKQ,gBACN,WACA,eACA,WACA,WACM;AACN,YAAM,MAAM,SAAS,cAAc,KAAK;AACxC,UAAI,YAAY;AAEhB,iBAAW,QAAQ,KAAK,WAAW;AACjC,cAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,eAAO,OAAO;AACd,eAAO,QAAQ,OAAO,KAAK;AAE3B,cAAM,OAAO,YAAa,KAAK,QAAQ,KAAM;AAC7C,cAAM,OAAO,YAAY,KAAK,OAAO,KAAK,KAAK,YAAY;AAC3D,eAAO,cAAc,GAAG,IAAI,GAAG,QAAQ,OAAO,MAAM,EAAE,GAAG,IAAI;AAE7D,YAAI,KAAK,SAAS,eAAe;AAC/B,iBAAO,UAAU,IAAI,QAAQ;AAAA,QAC/B;AAEA,eAAO,iBAAiB,SAAS,MAAM;AACrC,eAAK,qBAAqB,KAAK,IAAI;AACnC,cAAI,iBAAiB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;AAC9C,gBAAI,UAAU,OAAO,UAAU,IAAI,QAAQ,SAAS,KAAK,IAAI;AAAA,UAC/D,CAAC;AAAA,QACH,CAAC;AAED,YAAI,YAAY,MAAM;AAAA,MACxB;AAEA,gBAAU,YAAY,GAAG;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA,IAKQ,qBAAqB,QAAsB;AACjD,UAAI,KAAK,kBAAkB;AACzB,aAAK,iBAAiB,MAAM;AAAA,MAC9B;AAGA,eAAS,iBAAiB,2BAA2B,EAAE,QAAQ,CAAC,QAAQ;AACtE,cAAM,SAAS;AACf,eAAO,UAAU,OAAO,UAAU,OAAO,QAAQ,SAAS,MAAM;AAAA,MAClE,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKQ,eAAqB;AAC3B,UAAI,KAAK,eAAgB;AAEzB,YAAM,eAAe,SAAS,cAAc,OAAO;AACnD,mBAAa,cAAc;AAC3B,eAAS,KAAK,YAAY,YAAY;AACtC,WAAK,iBAAiB;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA,IAKA,OAAO,YAAY,MAAoC;AACrD,aAAO,kBAAkB,IAAI;AAAA,IAC/B;AAAA,EACF;;;AC3XA,MAAM,iBAAiB;AACvB,MAAM,cAAc,GAAG,cAAc;AACrC,MAAM,kBAAkB;AAyBjB,MAAM,yBAAN,MAEP;AAAA,IAUE,YAAY,SAAuC,CAAC,GAAG;AATvD,0BAAS,QAAO;AAChB,0BAAS,QAAO;AAChB,0BAAS;AAET,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AAGN,WAAK,SAAS;AAAA,QACZ,SAAS,OAAO,WAAW;AAAA,QAC3B,UAAU,OAAO,YAAY;AAAA,QAC7B,SAAS;AAAA,UACP,QAAQ,OAAO,SAAS,UAAU;AAAA,UAClC,KAAK,OAAO,SAAS,OAAO,KAAK,KAAK,KAAK;AAAA,UAC3C,SAAS,OAAO,SAAS,WAAW;AAAA,UACpC,GAAG,OAAO;AAAA,QACZ;AAAA,MACF;AAEA,WAAK,SAAS,KAAK,OAAO,SAAS,UAAU;AAC7C,WAAK,aAAa,KAAK,OAAO,SAAS,OAAO,KAAK,KAAK,KAAK;AAC7D,WAAK,UAAU,KAAK,OAAO,SAAS,WAAW;AAC/C,WAAK,YAAY,KAAK,kBAAkB;AAExC,UAAI,KAAK,WAAW;AAClB,aAAK,gBAAgB;AAAA,MACvB;AAAA,IACF;AAAA,IAEQ,oBAA6B;AACnC,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,MACT;AAEA,UAAI;AACF,cAAM,UAAU,GAAG,KAAK,MAAM;AAC9B,eAAO,aAAa,QAAQ,SAAS,MAAM;AAC3C,eAAO,aAAa,WAAW,OAAO;AACtC,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEQ,kBAAwB;AAC9B,UAAI;AACF,cAAM,gBAAgB,OAAO,aAAa,QAAQ,WAAW;AAC7D,YAAI,kBAAkB,iBAAiB;AACrC,eAAK,MAAM;AACX,iBAAO,aAAa,QAAQ,aAAa,eAAe;AAAA,QAC1D;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,IAAI,KAA4B;AAC9B,UAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,UAAI;AACF,cAAM,UAAU,KAAK,SAAS;AAC9B,cAAM,UAAU,OAAO,aAAa,QAAQ,OAAO;AACnD,YAAI,CAAC,QAAS,QAAO;AAErB,cAAM,OAAmB,KAAK,MAAM,OAAO;AAE3C,YAAI,KAAK,WAAW,QAAQ,KAAK,IAAI,IAAI,KAAK,QAAQ;AACpD,iBAAO,aAAa,WAAW,OAAO;AACtC,iBAAO;AAAA,QACT;AAEA,eAAO,KAAK;AAAA,MACd,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,IAAI,KAAa,OAAqB;AACpC,UAAI,CAAC,KAAK,UAAW;AAErB,YAAM,UAAU,KAAK,SAAS;AAC9B,YAAM,OAAmB;AAAA,QACvB;AAAA,QACA,QAAQ,KAAK,aAAa,KAAK,IAAI,IAAI,KAAK,aAAa;AAAA,QACzD,WAAW,KAAK,IAAI;AAAA,MACtB;AAEA,UAAI;AACF,cAAM,aAAa,KAAK,cAAc;AACtC,YAAI,cAAc,KAAK,SAAS;AAC9B,eAAK,YAAY;AAAA,QACnB;AAEA,eAAO,aAAa,QAAQ,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA,MAC3D,SAAS,OAAO;AACd,YAAI,KAAK,aAAa,KAAK,GAAG;AAC5B,eAAK,YAAY;AACjB,cAAI;AACF,mBAAO,aAAa,QAAQ,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA,UAC3D,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO,KAAmB;AACxB,UAAI,CAAC,KAAK,UAAW;AAErB,UAAI;AACF,eAAO,aAAa,WAAW,KAAK,SAAS,GAAG;AAAA,MAClD,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,QAAc;AACZ,UAAI,CAAC,KAAK,UAAW;AAErB,UAAI;AACF,cAAM,eAAyB,CAAC;AAChC,iBAAS,IAAI,GAAG,IAAI,OAAO,aAAa,QAAQ,KAAK;AACnD,gBAAM,MAAM,OAAO,aAAa,IAAI,CAAC;AACrC,cAAI,KAAK,WAAW,KAAK,MAAM,KAAK,QAAQ,aAAa;AACvD,yBAAa,KAAK,GAAG;AAAA,UACvB;AAAA,QACF;AACA,qBAAa,QAAQ,CAAC,MAAM,OAAO,aAAa,WAAW,CAAC,CAAC;AAAA,MAC/D,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,eAAe,QAAgB,WAAyB;AACtD,UAAI,CAAC,KAAK,UAAW;AAErB,YAAM,oBAAoB,IAAI,MAAM,IAAI,SAAS;AACjD,YAAM,YAAY,GAAG,MAAM,IAAI,SAAS;AAExC,UAAI;AACF,cAAM,eAAyB,CAAC;AAChC,iBAAS,IAAI,GAAG,IAAI,OAAO,aAAa,QAAQ,KAAK;AACnD,gBAAM,MAAM,OAAO,aAAa,IAAI,CAAC;AACrC,cAAI,CAAC,KAAK,WAAW,KAAK,MAAM,EAAG;AAEnC,gBAAM,WAAW,IAAI,MAAM,KAAK,OAAO,MAAM;AAC7C,cAAI,aAAa,qBAAqB,SAAS,WAAW,SAAS,GAAG;AACpE,yBAAa,KAAK,GAAG;AAAA,UACvB;AAAA,QACF;AACA,qBAAa,QAAQ,CAAC,MAAM,OAAO,aAAa,WAAW,CAAC,CAAC;AAAA,MAC/D,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,aAAa,QAAgB,WAA2C;AACtE,YAAM,oBAAoB,IAAI,MAAM,IAAI,SAAS;AACjD,YAAM,QAAQ,KAAK,IAAI,iBAAiB;AACxC,UAAI,CAAC,MAAO,QAAO;AAEnB,UAAI;AACF,eAAO,KAAK,MAAM,KAAK;AAAA,MACzB,QAAQ;AACN,aAAK,OAAO,iBAAiB;AAC7B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,aACE,QACA,WACA,cACM;AACN,YAAM,oBAAoB,IAAI,MAAM,IAAI,SAAS;AACjD,WAAK,IAAI,mBAAmB,KAAK,UAAU,YAAY,CAAC;AAAA,IAC1D;AAAA,IAEA,aAAqC;AACnC,YAAM,UAAkC,CAAC;AACzC,UAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,UAAI;AACF,iBAAS,IAAI,GAAG,IAAI,OAAO,aAAa,QAAQ,KAAK;AACnD,gBAAM,UAAU,OAAO,aAAa,IAAI,CAAC;AACzC,cAAI,CAAC,SAAS,WAAW,KAAK,MAAM,KAAK,YAAY,aAAa;AAChE;AAAA,UACF;AAEA,gBAAM,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM;AAC5C,gBAAM,QAAQ,KAAK,IAAI,GAAG;AAC1B,cAAI,UAAU,MAAM;AAClB,oBAAQ,GAAG,IAAI;AAAA,UACjB;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,YAA0C;AACxC,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,cAAuB;AACrB,aAAO,KAAK;AAAA,IACd;AAAA,IAEQ,gBAAwB;AAC9B,UAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,UAAI,QAAQ;AACZ,UAAI;AACF,iBAAS,IAAI,GAAG,IAAI,OAAO,aAAa,QAAQ,KAAK;AACnD,gBAAM,MAAM,OAAO,aAAa,IAAI,CAAC;AACrC,cAAI,KAAK,WAAW,KAAK,MAAM,KAAK,QAAQ,aAAa;AACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,aAAO;AAAA,IACT;AAAA,IAEQ,aAAa,OAAyB;AAC5C,UAAI,iBAAiB,cAAc;AACjC,eACE,MAAM,SAAS,wBACf,MAAM,SAAS;AAAA,MAEnB;AACA,aAAO;AAAA,IACT;AAAA,IAEQ,cAAoB;AAC1B,UAAI,CAAC,KAAK,UAAW;AAErB,UAAI;AACF,cAAM,UAAqD,CAAC;AAE5D,iBAAS,IAAI,GAAG,IAAI,OAAO,aAAa,QAAQ,KAAK;AACnD,gBAAM,UAAU,OAAO,aAAa,IAAI,CAAC;AACzC,cAAI,CAAC,SAAS,WAAW,KAAK,MAAM,KAAK,YAAY,aAAa;AAChE;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,UAAU,OAAO,aAAa,QAAQ,OAAO;AACnD,gBAAI,SAAS;AACX,oBAAM,OAAmB,KAAK,MAAM,OAAO;AAC3C,sBAAQ,KAAK,EAAE,KAAK,SAAS,WAAW,KAAK,UAAU,CAAC;AAAA,YAC1D;AAAA,UACF,QAAQ;AACN,mBAAO,aAAa,WAAW,OAAO;AAAA,UACxC;AAAA,QACF;AAEA,gBAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAEhD,cAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,SAAS,IAAI,CAAC;AACjE,iBAAS,IAAI,GAAG,IAAI,eAAe,IAAI,QAAQ,QAAQ,KAAK;AAC1D,iBAAO,aAAa,WAAW,QAAQ,CAAC,EAAE,GAAG;AAAA,QAC/C;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,gBAAkE;AAChE,YAAM,OAAO,KAAK,cAAc;AAChC,YAAM,QACJ,KAAK,UAAU,IAAI,GAAG,KAAK,MAAO,OAAO,KAAK,UAAW,GAAG,CAAC,MAAM;AAErE,aAAO;AAAA,QACL;AAAA,QACA,SAAS,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,EACF;;;AC7TA,MAAM,aAAa;AACnB,MAAM,eAAe;AAwBd,MAAM,yBAAN,MAEP;AAAA,IASE,YAAY,SAAuC,CAAC,GAAG;AARvD,0BAAS,QAAO;AAChB,0BAAS,QAAO;AAChB,0BAAS;AAET,0BAAQ;AACR,0BAAQ;AACR,0BAAQ;AAGN,WAAK,SAAS;AAAA,QACZ,SAAS,OAAO,WAAW;AAAA,QAC3B,UAAU,OAAO,YAAY;AAAA,QAC7B,SAAS;AAAA,UACP,WAAW,OAAO,SAAS,aAAa;AAAA,UACxC,KAAK,OAAO,SAAS,OAAO,IAAI,KAAK,KAAK,KAAK;AAAA,UAC/C,GAAG,OAAO;AAAA,QACZ;AAAA,MACF;AAEA,WAAK,YAAY,KAAK,OAAO,SAAS,aAAa;AACnD,WAAK,aAAa,KAAK,OAAO,SAAS,OAAO,IAAI,KAAK,KAAK,KAAK;AACjE,WAAK,YAAY,KAAK,kBAAkB;AAAA,IAC1C;AAAA,IAEQ,oBAA6B;AACnC,aAAO,OAAO,WAAW;AAAA,IAC3B;AAAA,IAEA,MAAM,IAAI,KAA8B;AACtC,UAAI,CAAC,KAAK,WAAW;AACnB,cAAM,IAAI,yBAAyB,GAAG;AAAA,MACxC;AAEA,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,WAAW,MAAM,MAAM,MAAM,eAAe,GAAG;AAErD,YAAI,CAAC,UAAU;AACb,gBAAM,IAAI,yBAAyB,GAAG;AAAA,QACxC;AAEA,cAAM,OAAmB,MAAM,SAAS,KAAK;AAE7C,YAAI,KAAK,WAAW,QAAQ,KAAK,IAAI,IAAI,KAAK,QAAQ;AACpD,gBAAM,MAAM,OAAO,eAAe,GAAG;AACrC,gBAAM,IAAI,yBAAyB,GAAG;AAAA,QACxC;AAEA,eAAO,KAAK;AAAA,MACd,SAAS,OAAO;AACd,YAAI,iBAAiB,0BAA0B;AAC7C,gBAAM;AAAA,QACR;AACA,cAAM,IAAI,yBAAyB,GAAG;AAAA,MACxC;AAAA,IACF;AAAA,IAEA,MAAM,IAAI,KAAa,OAA8B;AACnD,UAAI,CAAC,KAAK,UAAW;AAErB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,OAAmB;AAAA,UACvB;AAAA,UACA,QAAQ,KAAK,aAAa,KAAK,IAAI,IAAI,KAAK,aAAa;AAAA,UACzD,WAAW,KAAK,IAAI;AAAA,QACtB;AAEA,cAAM,MAAM;AAAA,UACV,eAAe;AAAA,UACf,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;AAAA,YACjC,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAChD,CAAC;AAAA,QACH;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,KAA4B;AACvC,UAAI,CAAC,KAAK,UAAW;AAErB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,MAAM,OAAO,eAAe,GAAG;AAAA,MACvC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,MAAM,QAAuB;AAC3B,UAAI,CAAC,KAAK,UAAW;AAErB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,OAAO,MAAM,MAAM,KAAK;AAE9B,cAAM,QAAQ;AAAA,UACZ,KACG,OAAO,CAAC,YAAY,QAAQ,IAAI,SAAS,YAAY,CAAC,EACtD,IAAI,CAAC,YAAY,MAAM,OAAO,OAAO,CAAC;AAAA,QAC3C;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,QAAgB,WAAkC;AACrE,UAAI,CAAC,KAAK,UAAW;AAErB,YAAM,oBAAoB,IAAI,MAAM,IAAI,SAAS;AACjD,YAAM,YAAY,GAAG,MAAM,IAAI,SAAS;AAExC,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,OAAO,MAAM,MAAM,KAAK;AAE9B,cAAM,QAAQ;AAAA,UACZ,KACG,OAAO,CAAC,YAAY;AACnB,kBAAM,MAAM,QAAQ;AACpB,kBAAM,MAAM,IAAI,SAAS,YAAY,IACjC,IAAI,UAAU,IAAI,QAAQ,YAAY,IAAI,aAAa,MAAM,IAC7D;AACJ,mBAAO,QAAQ,qBAAqB,IAAI,WAAW,SAAS;AAAA,UAC9D,CAAC,EACA,IAAI,CAAC,YAAY,MAAM,OAAO,OAAO,CAAC;AAAA,QAC3C;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IAEA,MAAM,aACJ,QACA,WAC0B;AAC1B,YAAM,oBAAoB,IAAI,MAAM,IAAI,SAAS;AACjD,YAAM,QAAQ,MAAM,KAAK,IAAI,iBAAiB;AAE9C,UAAI;AACF,eAAO,KAAK,MAAM,KAAK;AAAA,MACzB,QAAQ;AACN,cAAM,KAAK,OAAO,iBAAiB;AACnC,cAAM,IAAI,yBAAyB,iBAAiB;AAAA,MACtD;AAAA,IACF;AAAA,IAEA,MAAM,aACJ,QACA,WACA,cACe;AACf,YAAM,oBAAoB,IAAI,MAAM,IAAI,SAAS;AACjD,YAAM,KAAK,IAAI,mBAAmB,KAAK,UAAU,YAAY,CAAC;AAAA,IAChE;AAAA,IAEA,YAA0C;AACxC,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,cAAuB;AACrB,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,MAAM,aAA8C;AAClD,YAAM,UAAkC,CAAC;AACzC,UAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,OAAO,MAAM,MAAM,KAAK;AAE9B,mBAAW,WAAW,MAAM;AAC1B,gBAAM,MAAM,QAAQ;AACpB,cAAI,CAAC,IAAI,SAAS,YAAY,EAAG;AAEjC,gBAAM,MAAM,IAAI;AAAA,YACd,IAAI,QAAQ,YAAY,IAAI,aAAa;AAAA,UAC3C;AACA,cAAI;AACF,kBAAM,QAAQ,MAAM,KAAK,IAAI,GAAG;AAChC,oBAAQ,GAAG,IAAI;AAAA,UACjB,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,gBAA8D;AAClE,UAAI,CAAC,KAAK,WAAW;AACnB,eAAO,EAAE,MAAM,GAAG,WAAW,KAAK,UAAU;AAAA,MAC9C;AAEA,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,SAAS;AAC9C,cAAM,OAAO,MAAM,MAAM,KAAK;AAC9B,cAAM,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,IAAI,SAAS,YAAY,CAAC,EAAE;AAE9D,eAAO,EAAE,MAAM,WAAW,KAAK,UAAU;AAAA,MAC3C,QAAQ;AACN,eAAO,EAAE,MAAM,GAAG,WAAW,KAAK,UAAU;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;;;AC/KO,WAAS,mBAAmB,QAGjC;AACA,UAAM,gBAAgB,OAAO,WAAW,KAAK;AAC7C,WAAO;AAAA,MACL,aAAa,EAAE,SAAS,cAAc;AAAA,MACtC,cAAc,CAAC;AAAA,IACjB;AAAA,EACF;AAQO,WAAS,gBAAgB,QAAwC;AACtE,WAAO,EAAE,GAAG,QAAQ,QAAQ,GAAG;AAAA,EACjC;AAUO,WAAS,4BAA4B,SAO1C;AACA,QAAI,cAA0D;AAC9D,QAAI,gBAA+B;AACnC,WAAO;AAAA,MACL,UAAU,OAAO,WAAW;AAC1B,gBAAQ,UAAU,MAAM;AACxB,YAAI,QAAQ,UAAU;AACpB,kBAAQ,SAAS,MAAM;AACvB;AAAA,QACF;AACA,YAAI,aAAa;AACf,gBAAM,YAAY,MAAM;AACxB;AAAA,QACF;AACA,wBAAgB;AAAA,MAClB;AAAA,MACA,QAAQ,CAAC,UAAU;AACjB,sBAAc;AACd,YAAI,kBAAkB,MAAM;AAC1B,gBAAM,SAAS;AACf,0BAAgB;AAChB,eAAK,MAAM,MAAM,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAQO,WAAS,WAAW,IAAsB;AAC/C,QAAI,SAAS,eAAe,WAAW;AACrC,eAAS,iBAAiB,oBAAoB,IAAI,EAAE,MAAM,KAAK,CAAC;AAAA,IAClE,OAAO;AACL,SAAG;AAAA,IACL;AAAA,EACF;AAiBA,WAAS,YAAY,QAA2C;AAC9D,UAAM,SAAS,OAAO,QAAQ,UAAU;AACxC,UAAM,UAAU,OAAO,QAAQ,WAAW;AAC1C,UAAM,gBAAgB,OAAO,QAAQ,iBAAiB;AACtD,UAAM,YAAY,OAAO,QAAQ,aAAa;AAC9C,UAAM,aAAa,OAAO,QAAQ,aAAa,eAC5C,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACjB,UAAM,oBAAoB,OAAO,QAAQ,WAAW,IACjD,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACjB,UAAM,aAAa,OAAO,QAAQ,eAAe;AACjD,UAAM,OAAQ,OAAO,QAAQ,SAAS,iBAAiB,iBAAiB;AACxE,UAAM,gBAAgB,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,UACzE,OAAO,QAAQ,WACf;AACJ,UAAM,mBAAmB,OAAO,QAAQ,oBAAoB;AAC5D,UAAM,oBAAoB,OAAO,QAAQ,sBAAsB;AAC/D,UAAM,oBAAoB,OAAO,QAAQ,sBAAsB;AAC/D,UAAM,oBAAoB,OAAO,QAAQ,qBAAqB;AAC9D,UAAM,eAAe,OAAO,QAAQ,aAAa;AACjD,UAAM,UAAU,OAAO,QAAQ,YAAY;AAE3C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAMA,WAAS,iBAAiB,oBAA6C;AACrE,QAAI,OAAO,aAAa,YAAa,QAAO;AAG5C,UAAM,QAAQ,SAAS,OAAO;AAAA,MAC5B;AAAA,IACF;AACA,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,oBAAoB,EAAE,KAAK;AAAA,EAC5D;AAMA,WAAS,sBAAsB,oBAA8B,eAA+B;AAC1F,QAAI,OAAO,cAAc,YAAa,QAAO;AAE7C,UAAM,YACJ,UAAU,aAAa,UAAU,UAAU,SAAS,IAChD,CAAC,GAAG,UAAU,SAAS,IACvB;AAAA,MACE,UAAU,YACP,UAAoD,gBACrD;AAAA,IACJ;AAEN,WAAO,YAAY,WAAW,oBAAoB,aAAa;AAAA,EACjE;AAQO,WAAS,eACd,UACA,QACA,QACA,eACA,oBACQ;AACR,UAAM,WAAW,SAAS,MAAM,GAAG;AACnC,UAAM,QAAQ,SAAS,CAAC,KAAK;AAC7B,UAAM,kBACJ,iBAAiB,KAAK,KAAK,KAC3B,YAAY,CAAC,KAAK,GAAG,oBAAoB,EAAE,MAAM;AACnD,UAAM,OAAO,kBAAkB,MAAM,SAAS,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;AACnE,UAAM,SAAS,WAAW,gBAAgB,KAAK,MAAM;AACrD,WAAO,UAAU,QAAQ,OAAO;AAAA,EAClC;AAGA,WAAS,iBACP,QACA,eACA,oBACM;AACN,WAAO,SAAS,OAAO;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAQO,WAAS,qBAAqB,QAAgC;AACnE,QAAI,OAAO,SAAS,gBAAgB;AAClC,YAAM,WACJ,OAAO,aAAa,cAAc,SAAS,gBAAgB,OAAO;AACpE,aAAO,WAAW,gBAAgB,QAAQ,IAAI,OAAO;AAAA,IACvD;AACA,UAAM,eAAe,iBAAiB,OAAO,SAAS;AACtD,QAAI,aAAc,QAAO;AACzB,QAAI,OAAO,YAAY;AACrB,aAAO,sBAAsB,OAAO,WAAW,OAAO,aAAa;AAAA,IACrE;AACA,WAAO,OAAO;AAAA,EAChB;AAGO,WAAS,eAAe,QAAsB;AACnD,QAAI,OAAO,aAAa,aAAa;AACnC,eAAS,gBAAgB,MAAM,UAAU,MAAM;AAAA,IACjD;AAAA,EACF;AAUO,WAAS,mBAAkD;AAChE,UAAM,UAAU,SAAS;AACzB,QAAI,mBAAmB,qBAAqB,QAAQ,QAAQ,QAAQ;AAClE,aAAO;AAAA,IACT;AACA,UAAM,UAAU,SAAS,iBAAiB,sBAAsB;AAChE,QAAI,QAAQ,SAAS,GAAG;AACtB,cAAQ;AAAA,QACN,eAAe,QAAQ,MAAM;AAAA,MAC/B;AAAA,IACF;AACA,WAAO,QAAQ,QAAQ,SAAS,CAAC;AAAA,EACnC;AAKA,iBAAe,WAA0B;AACvC,UAAM,SAAS,iBAAiB;AAEhC,QAAI,CAAC,QAAQ;AACX,cAAQ,KAAK,mDAAmD;AAChE;AAAA,IACF;AAEA,UAAM,SAAS,YAAY,MAAM;AAEjC,WAAO,oBAAoB,gBAAgB,MAAM;AAEjD,QAAI,CAAC,OAAO,QAAQ;AAClB,cAAQ,KAAK,4CAA4C;AACzD;AAAA,IACF;AAIA,UAAM,cAAc,mBAAmB,OAAO,MAAM;AACpD,QAAI,YAAY,cAAc;AAC5B,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB,qBAAqB,MAAM;AAGjD,mBAAe,aAAa;AAG5B,UAAM,mBAAmB,IAAI,iBAAiB;AAC9C,qBAAiB,aAAa,OAAO,SAAS;AAC9C,qBAAiB,iBAAiB,aAAa;AAG/C,UAAM,iBAAiB,MAAM;AAG3B,UAAI,OAAO,SAAS,gBAAgB;AAClC,YAAI,OAAO,iBAAiB,CAAC,SAAS,cAAc,2BAA2B,GAAG;AAChF,gBAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,oBAAU,QAAQ,oBAAoB,OAAO;AAC7C,cAAI,OAAO,kBAAkB;AAC3B,sBAAU,QAAQ,4BAA4B,OAAO;AAAA,UACvD;AACA,cAAI,CAAC,OAAO,mBAAmB;AAC7B,sBAAU,QAAQ,6BAA6B;AAAA,UACjD;AACA,cAAI,CAAC,OAAO,mBAAmB;AAC7B,sBAAU,QAAQ,6BAA6B;AAAA,UACjD;AACA,cAAI,OAAO,mBAAmB;AAC5B,sBAAU,QAAQ,6BAA6B,OAAO;AAAA,UACxD;AACA,mBAAS,KAAK,YAAY,SAAS;AAAA,QACrC;AAAA,MACF;AAEA,uBAAiB,QAAQ;AAAA,IAC3B;AAEA,eAAW,cAAc;AAIzB,UAAM,gBAAgB,4BAA4B;AAAA,MAChD,WAAW,CAAC,WAAW;AACrB,iBAAS,SAAS,oBAAoB,MAAM;AAAA,MAC9C;AAAA,MACA,UACE,OAAO,SAAS,iBACZ,CAAC,WAAW,iBAAiB,QAAQ,OAAO,eAAe,OAAO,SAAS,IAC3E;AAAA,IACR,CAAC;AACD,qBAAiB,oBAAoB,cAAc,QAAQ;AAE3D,QAAI;AAEF,YAAM,UAAU,iBAAiB,KAAK;AAAA,QACpC,eAAe;AAAA,QACf,WAAW,OAAO;AAAA,MACpB,CAAC,EACE,IAAI,IAAI,iBAAiB,EAAE,SAAS,KAAK,CAAC,CAAC,EAC3C,IAAI,IAAI,uBAAuB,EAAE,SAAS,KAAK,CAAC,CAAC,EACjD,IAAI,IAAI,uBAAuB,EAAE,SAAS,KAAK,CAAC,CAAC;AAUpD,UAAI,OAAO,YAAY,OAAO;AAC5B,gBAAQ;AAAA,UACN,IAAI,uBAAuB;AAAA,YACzB,SAAS;AAAA,YACT,SAAS;AAAA,cACP,KAAK,OAAO;AAAA,cACZ,WAAW;AAAA,YACb;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,QAChB;AAAA,QACC,IAAI,kBAAkB;AAAA,UACpB,SAAS;AAAA,UACT,SAAS;AAAA,YACP,SAAS,OAAO;AAAA,YAChB,QAAQ,OAAO;AAAA;AAAA;AAAA,YAGf,aAAa,YAAY;AAAA,YACzB,mBAAmB;AAAA,cACjB;AAAA,gBACE,QAAQ;AAAA,gBACR,WAAW,OAAO;AAAA,gBAClB,OAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,EACC,MAAM;AAGT,YAAM,iBAAiB,IAAI,eAAe;AAAA,QACxC,kBAAkB,OAAO;AAAA,MAC3B,CAAC;AACD,qBAAe,QAAQ,IAAI;AAC3B,qBAAe,KAAK;AAAA,QAClB,WAAW,OAAO;AAAA,QAClB,QAAQ;AAAA,QACR,cAAc,OAAO;AAAA,MACvB,CAAC;AAID,uBAAiB,QAAQ,IAAI;AAC7B,oBAAc,OAAO,OAAO,WAAW;AACrC,cAAM,KAAK,eAAe,QAAQ;AAAA,UAChC,mBAAmB,CAAC,OAAO,SAAS;AAAA,QACtC,CAAC;AACD,uBAAe,MAAM;AACrB,uBAAe,aAAa,MAAM;AAClC,uBAAe,YAAY;AAAA,MAC7B,CAAC;AAGD,YAAM,eAAe,CAAC,KAAM,KAAM,GAAK;AACvC,YAAM,sBAAsB;AAC5B,UAAI,yBAAyB;AAC7B,UAAI,cAA+C,CAAC;AACpD,UAAI,oBAAoB,KAAK,IAAI;AAEjC,YAAM,qBAAqB,YAA2B;AACpD,cAAM,KAAK,gBAAgB,OAAO,SAAS;AAC3C,uBAAe,cAAc;AAC7B,4BAAoB,KAAK,IAAI;AAAA,MAC/B;AAEA,YAAM,gBAAgB,MAAM;AAC1B,oBAAY,QAAQ,OAAK,aAAa,CAAC,CAAC;AACxC,sBAAc,CAAC;AAAA,MACjB;AAGA,WAAK,IAAI,GAAG,uBAAuB,MAAM;AACvC,iCAAyB;AACzB,sBAAc;AACd,qBAAa,QAAQ,WAAS;AAC5B,sBAAY;AAAA,YACV,WAAW,MAAM,mBAAmB,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC,GAAG,KAAK;AAAA,UAC9D;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAID,eAAS,iBAAiB,oBAAoB,MAAM;AAClD,YAAI,SAAS,oBAAoB,UAAW;AAE5C,YAAI,wBAAwB;AAC1B,mCAAyB;AACzB,wBAAc;AACd,6BAAmB,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QACrC,WAAW,KAAK,IAAI,IAAI,oBAAoB,qBAAqB;AAC/D,6BAAmB,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QACrC;AAAA,MACF,CAAC;AAGD,YAAM,WAA8B;AAAA,QAClC,GAAG,CAAC,KAAK,QAAQ,iBAAiB,KAAK,EAAE,KAAK,UAAU,CAAC,GAAG,YAAY;AAAA,QACxE,OAAO,CAAC,KAAK,QAAQ,iBAAiB,KAAK,MAAM,KAAK,UAAU,CAAC,GAAG,YAAY;AAAA,QAChF,gBAAgB,OAAO,WAAW;AAChC,gBAAM,KAAK,eAAe,QAAQ;AAAA,YAChC,mBAAmB,CAAC,OAAO,SAAS;AAAA,UACtC,CAAC;AACD,yBAAe,MAAM;AACrB,yBAAe,aAAa,MAAM;AAClC,yBAAe,YAAY;AAC3B,2BAAiB,QAAQ;AAAA,QAC3B;AAAA,QACA,kBAAkB,MAAM,KAAK,iBAAiB;AAAA,QAC9C,IAAI,CAAC,OAAO,aAAa,KAAK,IAAI,GAAG,OAAgC,QAAQ;AAAA,QAC7E,aAAa,MAAM,eAAe,YAAY;AAAA,QAC9C;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,aAAO,YAAY;AAKnB,YAAM,cAAc,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,aAAa;AACjF,UAAI,eAAe,CAAC,SAAS,cAAc,4CAA4C,GAAG;AACxF,cAAM,eAAe,SAAS,cAAc,QAAQ;AACpD,qBAAa,MAAM,OAAO,gBACrB;AACL,qBAAa,QAAQ,QAAQ;AAC7B,qBAAa,QAAQ,SAAS,KAAK,iBAAiB;AACpD,qBAAa,QAAQ,MAAM,OAAO;AAClC,qBAAa,QAAQ;AACrB,iBAAS,KAAK,YAAY,YAAY;AAAA,MACxC;AAKA,iBAAW,MAAM;AACf,YAAI,OAAO,SAAS,gBAAgB;AAClC,yBAAe,cAAc;AAAA,QAC/B;AACA,uBAAe,QAAQ;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,sCAAsC,KAAK;AAAA,IAC3D;AAAA,EACF;AAGA,WAAS;",
4
+ "sourcesContent": ["/**\n * Browser Bundle Entry Point\n * Auto-init bundle for non-developer usage with script tag\n *\n * Usage:\n * <script\n * src=\"https://cdn.lionrapid.com/lionrapid.min.js\"\n * data-api-key=\"pk_live_xxx\"\n * ></script>\n */\n\n// Core exports for advanced usage\nexport { LionRapidBuilder } from '../builder.js';\nexport { LionRapidCore } from '../lionRapid.js';\nexport { MemoryRepository, NetworkRepository } from '../repositories/index.js';\n\n// Browser-specific exports\nexport { AutoTranslator } from './auto-translator.js';\nexport type { AutoTranslatorConfig } from './auto-translator.js';\n\nexport { LanguageSwitcher } from './language-switcher.js';\nexport type { Language, SwitcherStyle } from './language-switcher.js';\n\nexport { BlockExtractor } from './block-extractor.js';\nexport type { ExtractedBlock } from './block-extractor.js';\n\nexport { AttributeExtractor } from './attribute-extractor.js';\nexport type { ExtractedAttribute } from './attribute-extractor.js';\n\nexport { parseBlockElement } from './markup-parser.js';\n\nexport { ExcludeFilter } from './exclude-filter.js';\nexport type { ExcludePatterns } from './exclude-filter.js';\n\nexport { DOMObserver } from './dom-observer.js';\nexport type { DOMObserverCallbacks } from './dom-observer.js';\n\n\nexport { md5, generateAutoKey } from './md5.js';\n\n// Storage exports\nexport { LocalStorageRepository } from './storage/localstorage-repository.js';\nexport type { LocalStorageRepositoryConfig } from './storage/localstorage-repository.js';\n\nexport { CacheStorageRepository } from './storage/cache-storage-repository.js';\nexport type { CacheStorageRepositoryConfig } from './storage/cache-storage-repository.js';\n\n// Auto-init (runs on script load)\nexport { autoInit, parseConfig } from './auto-init.js';\nexport type { AutoInitConfig, LionRapidInstance } from './auto-init.js';\n", "export enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n NONE = 4,\n}\n\nexport interface LoggerConfig {\n level?: LogLevel;\n enabled?: boolean;\n prefix?: string;\n showLineNumbers?: boolean;\n useColors?: boolean;\n}\n\nexport interface PackageLoggerConfig extends LoggerConfig {\n packageName?: string;\n packageEmoji?: string;\n}\n", "import type { LoggerConfig } from '../config/logger.config.js';\nimport { LogLevel } from '../config/logger.config.js';\n\n// Browser-safe env access \u2014 `process` is a Node global and is undeclared\n// in browser contexts, so a bare `process.env.NODE_ENV` throws\n// `ReferenceError: process is not defined` when this module is imported\n// directly into a browser (e.g., a Vite/Webpack project that doesn't\n// pre-bundle deps from node_modules, or `<script type=module>` consumers).\n// Bundlers like esbuild/Vite still statically substitute `process.env.X`\n// inside the conditional at build time; in unbundled environments we\n// fall back to an empty object so reads are `undefined`, never throw.\nconst _ENV: Record<string, string | undefined> =\n typeof process !== 'undefined' && process.env ? process.env : {};\n\n// Build-time constants for dead code elimination\nconst IS_PRODUCTION = _ENV.NODE_ENV === 'production';\nconst IS_DEVELOPMENT = _ENV.NODE_ENV === 'development';\nconst IS_CI = _ENV.CI === 'true';\nconst LIONRAPID_DEV = _ENV.LIONRAPID_DEV === 'true';\nconst PERFORMANCE_TRACKING = _ENV.LIONRAPID_PERFORMANCE_TRACKING === 'true';\n\n/**\n * Read a runtime log-level override from localStorage in browser contexts.\n * Lets a developer flip on verbose logging without a rebuild via\n * localStorage.LIONRAPID_LOG_LEVEL = 'DEBUG'\n * Returns null on SSR or restrictive sandboxes.\n */\nfunction readBrowserLogLevel(): string | null {\n try {\n if (typeof localStorage !== 'undefined') {\n const v = localStorage.getItem('LIONRAPID_LOG_LEVEL');\n if (v && typeof v === 'string') return v;\n }\n } catch {\n // localStorage unavailable (privacy mode, file://, etc.) \u2014 ignore\n }\n return null;\n}\n\n// Environment-specific configuration.\n// Default is WARN \u2014 quiet by default. Customers consuming the published\n// ESM bundles via npm don't get noisy debug/info chatter on every page load.\n// Override via:\n// - build-time: process.env.LOG_LEVEL=DEBUG\n// - runtime (browser): localStorage.LIONRAPID_LOG_LEVEL = 'DEBUG'\n// - runtime (programmatic): logger.configure({ level: LogLevel.DEBUG })\nconst LOG_LEVEL_ENV = readBrowserLogLevel() || _ENV.LOG_LEVEL || 'WARN';\n\n/**\n * ANSI color codes for terminal output\n */\nexport const Colors = {\n // Reset\n RESET: '\\x1b[0m',\n // Foreground colors\n BLACK: '\\x1b[30m',\n RED: '\\x1b[31m',\n GREEN: '\\x1b[32m',\n YELLOW: '\\x1b[33m',\n BLUE: '\\x1b[34m',\n MAGENTA: '\\x1b[35m',\n CYAN: '\\x1b[36m',\n WHITE: '\\x1b[37m',\n ORANGE: '\\x1b[38;5;208m',\n // Bright foreground colors\n BRIGHT_BLACK: '\\x1b[90m',\n BRIGHT_RED: '\\x1b[91m',\n BRIGHT_GREEN: '\\x1b[92m',\n BRIGHT_YELLOW: '\\x1b[93m',\n BRIGHT_BLUE: '\\x1b[94m',\n BRIGHT_MAGENTA: '\\x1b[95m',\n BRIGHT_CYAN: '\\x1b[96m',\n BRIGHT_WHITE: '\\x1b[97m',\n // Styles\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m',\n UNDERLINE: '\\x1b[4m',\n} as const;\n\nexport interface CallSite {\n fileName: string;\n lineNumber: number;\n functionName?: string;\n}\n\nexport interface PackageLoggerConfig extends LoggerConfig {\n packageName?: string;\n packageEmoji?: string;\n}\n\n// Development logger class - completely eliminated in production\nclass DevelopmentLogger {\n private config: Required<LoggerConfig>;\n\n constructor(config: PackageLoggerConfig = {}) {\n this.config = {\n level: this.getLogLevelFromEnv(),\n enabled: this.shouldEnableLogging(),\n prefix: `${config.packageEmoji || '\uD83D\uDCE6'} ${config.packageName || 'LionRapid'}`,\n showLineNumbers: LIONRAPID_DEV && !IS_CI,\n useColors: this.shouldUseColors(),\n ...config,\n };\n }\n\n configure(config: Partial<LoggerConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n debug(message: string, data?: unknown): void {\n if (!this.config.enabled || this.config.level > LogLevel.DEBUG) return;\n this.log(LogLevel.DEBUG, message, data);\n }\n\n info(message: string, data?: unknown): void {\n if (this.config.level > LogLevel.INFO) return;\n this.log(LogLevel.INFO, message, data);\n }\n\n warn(message: string, data?: unknown): void {\n this.log(LogLevel.WARN, message, data);\n }\n\n error(message: string, data?: unknown): void {\n this.log(LogLevel.ERROR, message, data);\n }\n\n time(label: string): () => void {\n if (!PERFORMANCE_TRACKING || IS_PRODUCTION) return () => {};\n\n const start = IS_DEVELOPMENT ? performance.now() : 0;\n return () => {\n if (IS_DEVELOPMENT) {\n const duration = performance.now() - start;\n this.debug(`\u23F1\uFE0F ${label}: ${duration.toFixed(2)}ms`, { duration });\n }\n };\n }\n\n private log(level: LogLevel, message: string, data?: unknown): void {\n if (!this.config.enabled || level < this.config.level) return;\n\n const levelName = LogLevel[level];\n const levelEmoji = this.getLevelEmoji(level);\n const callSite = this.config.showLineNumbers ? this.getCallSite() : null;\n\n const logMessage = this.buildColoredMessage(\n level,\n levelEmoji,\n levelName,\n message,\n callSite,\n data\n );\n\n switch (level) {\n case LogLevel.ERROR:\n console.error(logMessage);\n break;\n case LogLevel.WARN:\n console.warn(logMessage);\n break;\n case LogLevel.INFO:\n console.info(logMessage);\n break;\n default:\n console.log(logMessage);\n }\n }\n\n private buildColoredMessage(\n level: LogLevel,\n emoji: string,\n levelName: string,\n message: string,\n callSite: CallSite | null,\n data?: unknown\n ): string {\n if (!this.config.useColors) {\n const locationInfo = callSite\n ? ` (${callSite.fileName}:${callSite.lineNumber})`\n : '';\n let logMessage = `${this.config.prefix} ${emoji} ${levelName} ${message}${locationInfo}`;\n if (data !== undefined) {\n logMessage += ` ${JSON.stringify(data)}`;\n }\n return logMessage;\n }\n\n const levelColor = this.getLevelColor(level);\n const reset = Colors.RESET;\n\n const coloredPrefix = `${Colors.BOLD}${Colors.ORANGE}${this.config.prefix}${reset}`;\n const coloredEmoji = emoji;\n const coloredLevel = `${levelColor}${Colors.BOLD}${levelName}${reset}`;\n const coloredMessage = `${levelColor}${message}${reset}`;\n\n const locationInfo = callSite\n ? `${Colors.DIM}${Colors.BRIGHT_BLACK} (${callSite.fileName}:${callSite.lineNumber})${reset}`\n : '';\n\n const dataInfo =\n data !== undefined\n ? `${Colors.DIM}${Colors.CYAN} ${JSON.stringify(data)}${reset}`\n : '';\n\n return `${coloredPrefix} ${coloredEmoji} ${coloredLevel} ${coloredMessage}${locationInfo}${dataInfo}`;\n }\n\n private getLevelColor(level: LogLevel): string {\n switch (level) {\n case LogLevel.DEBUG:\n return Colors.BRIGHT_GREEN;\n case LogLevel.INFO:\n return Colors.BRIGHT_CYAN;\n case LogLevel.WARN:\n return Colors.BRIGHT_YELLOW;\n case LogLevel.ERROR:\n return Colors.BRIGHT_RED;\n default:\n return Colors.BRIGHT_BLACK;\n }\n }\n\n private getLevelEmoji(level: LogLevel): string {\n switch (level) {\n case LogLevel.DEBUG:\n return '\uD83D\uDD0D';\n case LogLevel.INFO:\n return '\u2139\uFE0F';\n case LogLevel.WARN:\n return '\u26A0\uFE0F';\n case LogLevel.ERROR:\n return '\u274C';\n default:\n return '\uD83D\uDCDD';\n }\n }\n\n private getCallSite(): CallSite | null {\n try {\n const stack = new Error().stack;\n if (!stack) return null;\n\n const lines = stack.split('\\n');\n for (let i = 3; i < lines.length; i++) {\n const line = lines[i];\n if (line && !line.includes('logger.ts') && !line.includes('Logger')) {\n return this.parseStackLine(line);\n }\n }\n } catch {\n // Ignore errors\n }\n return null;\n }\n\n private parseStackLine(line: string): CallSite | null {\n let match = line.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n return {\n functionName: match[1],\n fileName: this.extractFileName(match[2]),\n lineNumber: parseInt(match[3], 10),\n };\n }\n\n match = line.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (match) {\n return {\n fileName: this.extractFileName(match[1]),\n lineNumber: parseInt(match[2], 10),\n };\n }\n\n return null;\n }\n\n private extractFileName(filePath: string): string {\n const parts = filePath.split('/');\n return parts[parts.length - 1] || filePath;\n }\n\n colorize(text: string, color: keyof typeof Colors): string {\n if (!this.config.useColors) return text;\n return `${Colors[color]}${text}${Colors.RESET}`;\n }\n\n getColors(): typeof Colors {\n return Colors;\n }\n\n createPackageLogger(\n packageName: string,\n packageEmoji?: string\n ): DevelopmentLogger {\n return new DevelopmentLogger({\n ...this.config,\n packageName,\n packageEmoji: packageEmoji || '\uD83D\uDCE6',\n });\n }\n\n private getLogLevelFromEnv(): LogLevel {\n switch (LOG_LEVEL_ENV.toUpperCase()) {\n case 'DEBUG':\n return LogLevel.DEBUG;\n case 'INFO':\n return LogLevel.INFO;\n case 'WARN':\n return LogLevel.WARN;\n case 'ERROR':\n return LogLevel.ERROR;\n case 'NONE':\n return LogLevel.NONE;\n default:\n // Unknown level \u2192 quiet fallback (WARN).\n return LogLevel.WARN;\n }\n }\n\n private shouldEnableLogging(): boolean {\n if (LOG_LEVEL_ENV === 'NONE') return false;\n return true;\n }\n\n private shouldUseColors(): boolean {\n if (IS_CI) return false;\n // Check if we're in a browser environment\n if (typeof window !== 'undefined') {\n return true; // Browsers support console colors\n }\n // Node.js environment\n if (\n typeof process !== 'undefined' &&\n process.stdout &&\n !process.stdout.isTTY\n ) {\n return false;\n }\n return IS_DEVELOPMENT;\n }\n}\n\n// Production no-op functions - these create completely eliminatable calls\nconst noop = () => {};\nconst noopWithReturn = () => () => {};\n\n// Export logger with build-time method elimination\nexport const logger = IS_PRODUCTION\n ? {\n configure: noop,\n debug: noop, // \u2190 This eliminates the call completely\n info: noop, // \u2190 This eliminates the call completely\n warn: (message: string, data?: unknown) => {\n console.warn(`\uD83E\uDD81 LionRapid Core \u26A0\uFE0F ${message}`, data || '');\n },\n error: (message: string, data?: unknown) => {\n console.error(`\uD83E\uDD81 LionRapid Core \u274C ${message}`, data || '');\n },\n time: noopWithReturn,\n colorize: (text: string) => text,\n getColors: () => Colors,\n createPackageLogger: (packageName: string, packageEmoji?: string) => ({\n configure: noop,\n debug: noop, // \u2190 Package logger debug also eliminated\n info: noop, // \u2190 Package logger info also eliminated\n warn: (message: string, data?: unknown) => {\n const prefix = `${packageEmoji || '\uD83D\uDCE6'} ${packageName}`;\n console.warn(`${prefix} \u26A0\uFE0F ${message}`, data || '');\n },\n error: (message: string, data?: unknown) => {\n const prefix = `${packageEmoji || '\uD83D\uDCE6'} ${packageName}`;\n console.error(`${prefix} \u274C ${message}`, data || '');\n },\n time: noopWithReturn,\n colorize: (text: string) => text,\n getColors: () => Colors,\n createPackageLogger: noop,\n }),\n }\n : new DevelopmentLogger({\n packageName: 'LionRapid Core',\n packageEmoji: '\uD83E\uDD81',\n });\n\n// Export Logger class for type compatibility\nexport const Logger = IS_PRODUCTION\n ? function Logger() {\n return logger;\n }\n : DevelopmentLogger;\n\n// Factory function with build-time elimination\nexport const createPackageLogger = (config: PackageLoggerConfig) => {\n if (IS_PRODUCTION) {\n const prefix = `${config.packageEmoji || '\uD83D\uDCE6'} ${config.packageName || 'LionRapid'}`;\n return {\n configure: noop,\n debug: noop, // \u2190 All debug calls eliminated\n info: noop, // \u2190 All info calls eliminated\n warn: (message: string, data?: unknown) => {\n console.warn(`${prefix} \u26A0\uFE0F ${message}`, data || '');\n },\n error: (message: string, data?: unknown) => {\n console.error(`${prefix} \u274C ${message}`, data || '');\n },\n time: noopWithReturn,\n colorize: (text: string) => text,\n getColors: () => Colors,\n createPackageLogger: noop,\n };\n }\n return new DevelopmentLogger(config);\n};\n\n// Performance measurement helper - eliminated in production\nexport const measure = (name: string) => {\n if (IS_PRODUCTION) {\n return {\n start: noop,\n end: noop,\n elapsed: () => 0,\n };\n }\n\n let startTime: number;\n return {\n start: () => {\n if (IS_DEVELOPMENT) {\n startTime = performance.now();\n logger.debug(`\u23F1\uFE0F ${name} - started`);\n }\n },\n end: () => {\n if (IS_DEVELOPMENT) {\n const duration = performance.now() - startTime;\n logger.debug(`\u23F1\uFE0F ${name} - completed in ${duration.toFixed(2)}ms`);\n return duration;\n }\n return 0;\n },\n elapsed: () => (IS_DEVELOPMENT ? performance.now() - startTime : 0),\n };\n};\n", "/**\n * Shared BCP-47 locale utilities \u2014 pure, Node-safe (no DOM).\n *\n * Aligns the browser runtime with the rest of the stack (see the locale\n * standard):\n * - tm-server accepts BCP-47, canonicalizes to ISO 639-2, and TRUNCATES the\n * region on the content API (`pt-BR \u2192 por`); it does NO cross-locale\n * fallback.\n * - `@lionrapid/edge` already preserves full tags with the grammar mirrored\n * below and negotiates Accept-Language by q-weight.\n *\n * Core previously chopped every tag to its 2-letter primary subtag, so a\n * configured `data-languages=\"pt-BR,\u2026\"` never matched a detected `pt-BR`\n * (it became `pt`) and fell back to the default. These helpers preserve the\n * full tag for matching / URLs / display while still negotiating down to the\n * primary subtag when that is the best available match \u2014 the same rule edge\n * uses, so the two packages agree.\n *\n * @module utils/locale\n */\n\n/**\n * Same locale grammar as `@lionrapid/edge`'s `LOCALE_BODY`, for cross-package\n * parity: 2\u20133 letter language + zero or more `-XXXX` subtags (script/region/\n * variant), each 2\u20134 alphanumerics. Anchored, case-insensitive.\n */\nexport const LOCALE_TAG_REGEX = /^[a-z]{2,3}(?:-[a-z0-9]{2,4})*$/i;\n\n/**\n * RTL languages \u2014 mirrors tm-server's `RTL_ISO639_2 = {ara,fas,heb,urd,yid}`\n * by their ISO 639-1 primary subtags, so client `dir` matches `is_rtl`.\n */\nconst RTL_LANGUAGES = new Set(['ar', 'fa', 'he', 'ur', 'yi']);\n\n/** The primary language subtag, lowercased: `pt-BR \u2192 pt`, `ZH-Hant \u2192 zh`. */\nexport function primarySubtag(tag: string): string {\n return tag.split('-')[0]!.toLowerCase();\n}\n\n/**\n * Canonicalize BCP-47 casing: language lowercase, script Title-case (4 chars),\n * region UPPERCASE (2 chars). `pt-br \u2192 pt-BR`, `ZH-hant \u2192 zh-Hant`. Casing\n * only \u2014 subtags are not validated here (that's `matchLocale`/the grammar).\n */\nexport function normalizeLocale(tag: string): string {\n const trimmed = tag.trim();\n if (!trimmed) return trimmed;\n const [lang, ...rest] = trimmed.split('-');\n const out = [lang.toLowerCase()];\n for (const sub of rest) {\n if (sub.length === 4) {\n out.push(sub[0].toUpperCase() + sub.slice(1).toLowerCase()); // script\n } else if (sub.length === 2) {\n out.push(sub.toUpperCase()); // region (alpha-2)\n } else {\n out.push(sub.toLowerCase()); // variant / numeric region / other\n }\n }\n return out.join('-');\n}\n\n/**\n * Negotiate a locale: for each requested tag (in preference order), return the\n * best `available` match \u2014 exact full tag (case-insensitive) first, then an\n * available entry equal to the requested tag's bare primary subtag. Returns\n * `fallback` when nothing matches. Mirrors edge's `detectFromAcceptLanguage`\n * matching so both packages resolve identically.\n *\n * Note (matches edge + the server): a bare requested `pt` does NOT match an\n * available `pt-BR` \u2014 region-specific availability is not silently widened.\n */\nexport function matchLocale(\n requested: string[],\n available: string[],\n fallback: string,\n): string {\n if (available.length === 0) return fallback;\n const avail = available.map((raw) => ({\n raw,\n lower: normalizeLocale(raw).toLowerCase(),\n }));\n for (const req of requested) {\n if (!req) continue;\n const reqLower = normalizeLocale(req).toLowerCase();\n const exact = avail.find((a) => a.lower === reqLower);\n if (exact) return exact.raw;\n const primary = primarySubtag(req);\n const byPrimary = avail.find((a) => a.lower === primary);\n if (byPrimary) return byPrimary.raw;\n }\n return fallback;\n}\n\n/**\n * Parse an `Accept-Language` header into tags ordered by q-weight (desc).\n * `fr;q=0.8,en;q=0.9 \u2192 ['en','fr']`. Missing q defaults to 1.0; a malformed q\n * sinks to the tail; `*` and empty tags are dropped.\n */\nexport function parseAcceptLanguage(header: string): string[] {\n return header\n .split(',')\n .map((part) => {\n const [tag, ...params] = part.trim().split(';');\n const qParam = params.find((p) => p.trim().startsWith('q='));\n const q = qParam ? parseFloat(qParam.trim().slice(2)) : 1;\n return { tag: tag.trim(), q: Number.isNaN(q) ? 0 : q };\n })\n .filter((x) => x.tag.length > 0 && x.tag !== '*')\n .sort((a, b) => b.q - a.q)\n .map((x) => x.tag);\n}\n\n/**\n * Text direction for a locale \u2014 `'rtl'` for Arabic/Persian/Hebrew/Urdu/\n * Yiddish, else `'ltr'`. Mirrors tm-server `is_rtl`.\n */\nexport function localeDir(tag: string): 'ltr' | 'rtl' {\n return RTL_LANGUAGES.has(primarySubtag(tag)) ? 'rtl' : 'ltr';\n}\n", "/**\n * Enhanced event emitter with language change helpers\n * filepath: /home/janrau/tm-integration/packages/core/src/base/event-emitter.ts\n */\n\nimport type {\n LionRapidEventEnvelope,\n LionRapidEventPayloads,\n LionRapidContext,\n} from '../types/lionRapid.types.js';\nimport type { TranslationRequest } from '../types/translation.types.js';\nimport { logger } from '../utils/logger.js';\nimport { localeDir } from '../utils/locale.js';\n\n// \u2705 Type-safe listener function type\ntype EventListener<T extends Record<string, unknown>, K extends keyof T> = (\n envelope: LionRapidEventEnvelope<T, K>\n) => void;\n\n// \u2705 Type-safe listener storage\n// type EventListenerMap = {\n// [K in keyof LionRapidEventPayloads]: Set<\n// EventListener<LionRapidEventPayloads, K>\n// >;\n// };\n\nexport class EventEmitter {\n // \u2705 Properly typed event listeners without `any`\n private eventListeners = new Map<\n keyof LionRapidEventPayloads,\n Set<EventListener<LionRapidEventPayloads, keyof LionRapidEventPayloads>>\n >();\n\n // Browser-safe: `process` is undeclared in browsers; guard before reading.\n // Bundlers still substitute `process.env.NODE_ENV` at build time.\n private debugMode: boolean =\n typeof process !== 'undefined' &&\n process.env?.NODE_ENV === 'development';\n\n /**\n * Subscribe to events (PUBLIC API) - Fully type-safe\n */\n on<K extends keyof LionRapidEventPayloads>(\n event: K,\n listener: EventListener<LionRapidEventPayloads, K>\n ): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n\n // \u2705 Type assertion is safe here because we control the map structure\n const listeners = this.eventListeners.get(event) as Set<\n EventListener<LionRapidEventPayloads, K>\n >;\n listeners.add(listener);\n }\n\n /**\n * Unsubscribe from events (PUBLIC API) - Fully type-safe\n */\n off<K extends keyof LionRapidEventPayloads>(\n event: K,\n listener: EventListener<LionRapidEventPayloads, K>\n ): void {\n const listeners = this.eventListeners.get(event) as\n | Set<EventListener<LionRapidEventPayloads, K>>\n | undefined;\n if (listeners) {\n listeners.delete(listener);\n }\n }\n\n /**\n * \u2705 Type-safe emit with proper generic constraint\n */\n emit<K extends keyof LionRapidEventPayloads>(\n event: K,\n envelope: LionRapidEventEnvelope<LionRapidEventPayloads, K>\n ): void {\n const listeners = this.eventListeners.get(event) as\n | Set<EventListener<LionRapidEventPayloads, K>>\n | undefined;\n if (listeners) {\n listeners.forEach(listener => {\n try {\n listener(envelope);\n } catch (error) {\n console.error(`Error in event listener for ${String(event)}:`, error);\n }\n });\n }\n }\n\n hasListeners<K extends keyof LionRapidEventPayloads>(event: K): boolean {\n return (\n this.eventListeners.has(event) && this.eventListeners.get(event)!.size > 0\n );\n }\n\n clearEvents(): void {\n this.eventListeners.clear();\n }\n\n /**\n * \u2705 Create base context once per request\n */\n private createContext(\n requestId: string,\n trace: string[],\n extra?: Partial<LionRapidContext>\n ): LionRapidContext {\n return {\n requestId,\n timestamp: performance.now(),\n trace,\n ...extra,\n };\n }\n\n /**\n * \u2705 Type-safe event emission helper\n */\n private emitEvent<K extends keyof LionRapidEventPayloads>(\n event: K,\n payload: LionRapidEventPayloads[K],\n requestId: string,\n trace: string[]\n ): void {\n this.emit(event, {\n context: this.createContext(requestId, trace),\n payload,\n });\n }\n\n /**\n * \u2705 Translation event builder with proper typing\n */\n translation(request: TranslationRequest, handler?: string) {\n const baseTrace = ['translation'];\n const handlerTrace = handler ? [...baseTrace, handler] : baseTrace;\n\n return {\n request: () => {\n this.emit('translation:request', {\n context: this.createContext(request.id, [...baseTrace, 'request']),\n payload: { key: request.cleanKey },\n });\n },\n\n success: (value: string) => {\n this.emit('translation:success', {\n context: this.createContext(request.id, [...handlerTrace, 'success']),\n payload: { key: request.cleanKey, value },\n });\n },\n\n fallback: (value: string) => {\n this.emit('translation:fallback', {\n context: this.createContext(request.id, [...baseTrace, 'fallback']),\n payload: { key: request.cleanKey, value },\n });\n },\n\n missing: (fallbackValue: string, locale: string, namespace: string) => {\n this.emit('translation:missing', {\n context: this.createContext(request.id, [...baseTrace, 'missing']),\n payload: {\n key: request.cleanKey,\n fallbackValue,\n locale,\n namespace,\n },\n });\n },\n\n notFound: (fallbackValue: string, locale: string, namespace: string) => {\n this.emit('translation:not-found', {\n context: this.createContext(request.id, [...baseTrace, 'not-found']),\n payload: {\n key: request.cleanKey,\n fallbackValue,\n locale,\n namespace,\n status: 404 as const,\n },\n });\n },\n\n locked: (fallbackValue: string, locale: string, namespace: string) => {\n this.emit('translation:locked', {\n context: this.createContext(request.id, [...baseTrace, 'locked']),\n payload: {\n key: request.cleanKey,\n fallbackValue,\n locale,\n namespace,\n status: 423 as const,\n },\n });\n },\n };\n }\n\n /**\n * \u2705 Repository event builder with better typing\n */\n repo(request: TranslationRequest | string, source: string) {\n const baseTrace = ['repo', source];\n\n return {\n getStart: () => {\n if (typeof request === 'string') return;\n this.emit('repo:get:start', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'get',\n 'start',\n ]),\n payload: { key: request.cleanKey, source },\n });\n },\n\n getSuccess: (value: string) => {\n if (typeof request === 'string') return;\n this.emit('repo:get:success', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'get',\n 'success',\n ]),\n payload: { key: request.cleanKey, value, source },\n });\n },\n\n getMiss: () => {\n if (typeof request === 'string') return;\n this.emit('repo:get:miss', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'get',\n 'miss',\n ]),\n payload: { key: request.cleanKey, source },\n });\n },\n\n setStart: (value: string) => {\n if (typeof request === 'string') return;\n this.emit('repo:set:start', {\n context: this.createContext(request.id, [\n ...baseTrace,\n 'set',\n 'start',\n ]),\n payload: { key: request.cleanKey, value, source },\n });\n },\n\n setSuccess: (value: string) => {\n const id = typeof request === 'string' ? 'system' : request.id;\n const key = typeof request === 'string' ? request : request.cleanKey;\n this.emit('repo:set:success', {\n context: this.createContext(id, [...baseTrace, 'set', 'success']),\n payload: { key: key, value, source },\n });\n },\n\n error: (error: Error) => {\n if (typeof request === 'string') return;\n this.emit('repo:error', {\n context: this.createContext(request.id, [...baseTrace, 'error']),\n payload: { key: request.cleanKey, source, error },\n });\n },\n };\n }\n\n /**\n * \u2705 Network event builder\n */\n network(request: TranslationRequest | string, method?: string) {\n const key = typeof request === 'string' ? request : request.cleanKey;\n const requestId = typeof request === 'string' ? 'network' : request.id;\n const baseTrace = ['network', method || 'request'];\n\n return {\n start: () => {\n this.emit('network:request:start', {\n context: this.createContext(requestId, [...baseTrace, 'start']),\n payload: { key },\n });\n },\n\n success: (value: string) => {\n this.emit('network:request:success', {\n context: this.createContext(requestId, [...baseTrace, 'success']),\n payload: { key, value, method: method || 'GET' },\n });\n },\n\n error: (error: unknown, status?: number) => {\n this.emit('network:request:error', {\n context: this.createContext(requestId, [...baseTrace, 'error']),\n payload: {\n key,\n method: method || 'GET',\n error,\n ...(status && { status }),\n },\n });\n },\n\n retry: (attempt: number, delayMs: number, reason?: string) => {\n this.emit('network:retry', {\n context: this.createContext(requestId, [...baseTrace, 'retry']),\n payload: { key, attempt, delayMs, ...(reason && { reason }) },\n });\n },\n };\n }\n\n /**\n * \u2705 Builder event builder\n */\n builder() {\n const baseTrace = ['builder'];\n const systemId = `build-${Date.now()}`;\n\n return {\n use: (type: 'plugin' | 'sync' | 'async' | 'network') => {\n this.emit('builder:use', {\n context: this.createContext(systemId, [...baseTrace, 'use']),\n payload: { type },\n });\n },\n\n buildStart: (locale: string, namespace: string) => {\n this.emit('builder:build:start', {\n context: this.createContext(systemId, [\n ...baseTrace,\n 'build',\n 'start',\n ]),\n payload: { locale, namespace },\n });\n },\n\n buildDone: (repositories: string[], plugins: string[]) => {\n this.emit('builder:build:done', {\n context: this.createContext(systemId, [\n ...baseTrace,\n 'build',\n 'done',\n ]),\n payload: { repositories, plugins },\n });\n },\n };\n }\n\n /**\n * \u2705 Language change event builder\n */\n language(oldLocale: string, newLocale: string) {\n const requestId = `lang-change-${Date.now()}`;\n const baseTrace = ['language', 'change'];\n\n return {\n start: () => {\n this.emit('language:change:start', {\n context: this.createContext(requestId, [...baseTrace, 'start']),\n payload: { oldLocale, newLocale },\n });\n },\n\n complete: () => {\n this.emit('language:change:success', {\n context: this.createContext(requestId, [...baseTrace, 'complete']),\n payload: { oldLocale, newLocale, dir: localeDir(newLocale) },\n });\n },\n\n error: (error: Error) => {\n this.emit('language:change:error', {\n context: this.createContext(requestId, [...baseTrace, 'error']),\n payload: { oldLocale, newLocale, error },\n });\n },\n };\n }\n\n /**\n * \u2705 Cache operations (debug only)\n */\n cache(operation: 'clear', reason: string, stats?: { clearedCount: number }) {\n // Only emit in debug mode\n if (!this.debugMode) return { start: () => {}, complete: () => {} };\n\n return {\n start: () => {\n logger.debug(`\uD83E\uDDF9 Cache ${operation} starting: ${reason}`);\n },\n\n complete: () => {\n logger.debug(\n `\u2705 Cache ${operation} complete: ${stats?.clearedCount || 0} entries`\n );\n },\n };\n }\n}\n", "/**\n * Array-based handler chain implementation\n * Much simpler than linked list approach\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport type {\n IAsyncHandler,\n ISyncHandler,\n} from '../interfaces/handler.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n TranslationContext,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger } from '../utils/logger.js';\n\nexport class HandlerChain {\n private asyncHandlers: IAsyncHandler[] = [];\n private syncHandlers: ISyncHandler[] = [];\n private bus: EventEmitter;\n\n constructor(eventEmitter: EventEmitter) {\n this.bus = eventEmitter;\n }\n\n addSyncHandler(handler: ISyncHandler): void {\n if (!handler.enabled) return;\n this.syncHandlers.push(handler);\n this.sortHandlersIfNeeded(this.syncHandlers);\n logger.debug(`Sync handler added: ${handler.name}`);\n }\n\n handleSync(request: TranslationRequest): TranslationResult | null {\n for (const handler of this.syncHandlers) {\n try {\n const result = handler.lookup(request);\n if (result !== null && result.value) {\n logger.debug(`Sync hit: ${handler.name} (${result.duration}ms)`);\n return result;\n }\n } catch (error) {\n logger.warn(`Sync lookup failed in ${handler.name}:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n continue;\n }\n }\n return null;\n }\n\n private saveToMemoryHandlers(\n request: TranslationRequest,\n result: TranslationResult,\n _sourceHandler: IAsyncHandler\n ): void {\n const memoryHandlers = this.syncHandlers;\n if (memoryHandlers.length === 0) return;\n logger.debug(`Saving to ${memoryHandlers.length} memory handlers`);\n\n // Result already contains value and styles from source handler\n memoryHandlers.forEach(handler => {\n try {\n handler.save(request, result);\n logger.debug(`Saved to memory: ${handler.name}`);\n } catch (error) {\n logger.warn(`Failed to save to memory ${handler.name}:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n }\n });\n }\n\n private saveNamespaceToMemoryHandlers(\n translations: TranslationData,\n context: TranslationContext\n ): void {\n const memoryHandlers = this.syncHandlers.filter(\n h => h.type === 'memory' && h.saveNamespace\n );\n\n if (memoryHandlers.length === 0) return;\n\n logger.debug(\n `Saving namespace to ${memoryHandlers.length} memory handlers`\n );\n\n // \u2705 Save to memory handlers (sync)\n memoryHandlers.forEach(handler => {\n try {\n handler.saveNamespace!(translations, context);\n logger.debug(`Namespace saved to memory: ${handler.name}`, {\n locale: context.locale,\n namespace: context.namespace,\n });\n } catch (error) {\n logger.warn(\n `Failed to save namespace to memory ${handler.name}:`,\n error\n );\n const repoBus = this.bus.repo(\n `${context.locale}:${context.namespace}`,\n handler.name\n );\n repoBus.error(error as Error);\n }\n });\n }\n\n addAsyncHandler(handler: IAsyncHandler): void {\n if (!handler.enabled) return;\n this.asyncHandlers.push(handler);\n this.sortHandlersIfNeeded(this.asyncHandlers);\n\n logger.debug(`Async handler added: ${handler.name}`);\n }\n\n async handleAsync(\n request: TranslationRequest\n ): Promise<TranslationResult | null> {\n for (const handler of this.asyncHandlers) {\n try {\n logger.debug(`Trying handler: ${handler.name}`);\n const result = await handler.lookup(request);\n\n // Check if we got a successful result (not fallback)\n if (result.value && result.status === 200) {\n // Found translation - save to all storage handlers that come before this one\n logger.debug(`Async hit: ${handler.name} (${result.duration}ms)`);\n\n // If a full namespace was loaded during lookup, save it first\n if (result.namespaceLoaded) {\n logger.debug(\n `Saving loaded namespace: ${result.namespaceLoaded.locale}:${result.namespaceLoaded.namespace}`\n );\n await this.saveNamespaceToHandlers(result.namespaceLoaded.data, {\n locale: result.namespaceLoaded.locale,\n namespace: result.namespaceLoaded.namespace,\n });\n return result;\n }\n\n // Save to storage and memory handlers (styles included in result)\n await this.saveToStorageHandlers(request, result, handler);\n this.saveToMemoryHandlers(request, result, handler);\n\n return result;\n }\n\n // If we got a fallback result (404, 423, error), continue to next handler\n logger.debug(\n `Handler ${handler.name} returned fallback (status: ${result.status})`\n );\n } catch (error) {\n logger.warn(`Handler ${handler.name} failed:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n continue;\n }\n }\n logger.debug(`No async handlers found translation for ${request.cleanKey}`);\n return null; // Not found in any handler\n }\n\n /**\n * Save translation to all storage handlers that come before the source handler\n */\n private async saveToStorageHandlers(\n request: TranslationRequest,\n result: TranslationResult,\n sourceHandler: IAsyncHandler\n ): Promise<void> {\n const sourceIndex = this.asyncHandlers.indexOf(sourceHandler);\n\n // Get all storage handlers with higher priority (lower index) than source\n const storageHandlers = this.asyncHandlers\n .slice(0, sourceIndex)\n .filter(h => h.type === 'storage');\n\n if (storageHandlers.length === 0) return;\n\n logger.debug(`Saving to ${storageHandlers.length} storage handlers`);\n\n // Result already contains value and styles from source handler\n const savePromises = storageHandlers.map(async handler => {\n try {\n await handler.save(request, result);\n logger.debug(`Saved to storage: ${handler.name}`);\n } catch (error) {\n logger.warn(`Failed to save to storage ${handler.name}:`, error);\n const repoBus = this.bus.repo(request, handler.name);\n repoBus.error(error as Error);\n }\n });\n\n await Promise.allSettled(savePromises);\n }\n\n private async saveNamespaceToStorageHandlers(\n translations: TranslationData,\n context: TranslationContext\n ): Promise<void> {\n const storageHandlers = this.asyncHandlers.filter(\n h => h.type === 'storage' && h.saveNamespace\n );\n\n if (storageHandlers.length === 0) return;\n\n logger.debug(\n `Saving namespace to ${storageHandlers.length} storage handlers`\n );\n\n // \u2705 Save to storage handlers (async/parallel)\n const savePromises = storageHandlers.map(async handler => {\n try {\n await handler.saveNamespace!(translations, context);\n logger.debug(`Namespace saved to storage: ${handler.name}`, {\n locale: context.locale,\n namespace: context.namespace,\n });\n } catch (error) {\n logger.warn(\n `Failed to save namespace to storage ${handler.name}:`,\n error\n );\n const repoBus = this.bus.repo(\n `${context.locale}:${context.namespace}`,\n handler.name\n );\n repoBus.error(error as Error);\n }\n });\n\n await Promise.allSettled(savePromises);\n }\n\n async saveNamespaceToHandlers(\n translations: TranslationData,\n context: TranslationContext\n ): Promise<void> {\n this.saveNamespaceToMemoryHandlers(translations, context);\n await this.saveNamespaceToStorageHandlers(translations, context);\n }\n\n getSyncHandlers(): ISyncHandler[] {\n return [...this.syncHandlers];\n }\n\n getAsyncHandlers(): IAsyncHandler[] {\n return [...this.asyncHandlers];\n }\n\n /**\n * Get chain info for debugging\n */\n getChainInfo(): {\n length: number;\n handlers: Array<{\n name: string;\n priority: number;\n type: 'memory' | 'storage' | 'network' | 'fallback';\n enabled: boolean | undefined;\n }>;\n } {\n return {\n length: this.syncHandlers.length + this.asyncHandlers.length,\n handlers: [\n ...this.syncHandlers.map(h => ({\n name: h.name,\n priority: h.priority,\n type: h.type,\n enabled: h.enabled,\n })),\n ...this.asyncHandlers.map(h => ({\n name: h.name,\n priority: h.priority,\n type: h.type,\n enabled: h.enabled,\n })),\n ],\n };\n }\n\n /**\n * Check if any handler has cached data\n */\n isCached(request: TranslationRequest): boolean {\n return (\n this.syncHandlers.some(h => h.isCached?.(request) === true) ||\n this.asyncHandlers.some(h => h.isCached?.(request) === true)\n );\n }\n\n /**\n * Get combined cache entries\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getEntries(): Record<string, any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const entries: Record<string, any> = {};\n\n // \u2705 Fix: Use proper arrays instead of this.handlers\n const allHandlers = [...this.syncHandlers, ...this.asyncHandlers];\n for (const handler of allHandlers) {\n if (handler.getEntries) {\n entries[handler.name] = handler.getEntries();\n }\n }\n return entries;\n }\n\n /**\n * Destroy all handlers\n */\n async destroy(): Promise<void> {\n // \u2705 Fix: Use proper arrays instead of this.handlers\n const allHandlers = [...this.syncHandlers, ...this.asyncHandlers];\n\n const destroyPromises = allHandlers.map(async handler => {\n try {\n await handler.destroy?.();\n logger.debug(`Handler destroyed: ${handler.name}`);\n } catch (error) {\n logger.warn(`Failed to destroy handler: ${handler.name}`, error);\n }\n });\n\n await Promise.allSettled(destroyPromises);\n\n // Clear handler arrays\n this.syncHandlers = [];\n this.asyncHandlers = [];\n }\n\n private sortHandlersIfNeeded(\n handlers: ISyncHandler[] | IAsyncHandler[]\n ): void {\n const hasExplicitPriorities = handlers.some(h => h.priority > 0);\n\n if (hasExplicitPriorities) {\n handlers.sort((a, b) => {\n const priorityA = a.priority || Number.MAX_SAFE_INTEGER;\n const priorityB = b.priority || Number.MAX_SAFE_INTEGER;\n return priorityA - priorityB;\n });\n }\n }\n\n async loadNamespace(\n locale: string,\n namespace: string\n ): Promise<TranslationData | null> {\n for (const handler of this.asyncHandlers) {\n if (handler.type !== 'network') continue;\n try {\n logger.debug(\n `Trying to load namespace: ${locale}:${namespace} from ${handler.name}`\n );\n const result = await handler.loadNamespace?.(locale, namespace);\n if (result && result.data && result.status === 200) {\n logger.debug(\n `Loaded namespace: ${locale}:${namespace} from ${handler.name}`\n );\n await this.saveNamespaceToStorageHandlers(result.data, {\n namespace,\n locale,\n });\n this.saveNamespaceToMemoryHandlers(result.data, {\n namespace,\n locale,\n });\n return result.data;\n }\n } catch (error) {\n logger.warn(\n `Failed to load namespace: ${locale}:${namespace} from ${handler.name}`,\n error\n );\n const repoBus = this.bus.repo(`${locale}:${namespace}`, handler.name);\n repoBus.error(error as Error);\n continue;\n }\n }\n logger.debug(`No handlers found namespace: ${locale}:${namespace}`);\n return null;\n }\n\n clearCache(): void {\n const allHandlers = [...this.syncHandlers, ...this.asyncHandlers];\n\n for (const handler of allHandlers) {\n try {\n handler.destroy?.();\n logger.debug(`Cache cleared for handler: ${handler.name}`);\n } catch (error) {\n logger.warn(\n `Failed to clear cache for handler: ${handler.name}`,\n error\n );\n }\n }\n\n logger.debug('Cache cleared for all handlers');\n }\n\n /**\n * Clear cache entries for a specific namespace\n */\n clearNamespace(locale: string, namespace: string): void {\n // Clear from sync handlers (memory)\n for (const handler of this.syncHandlers) {\n try {\n handler.clearNamespace?.(locale, namespace);\n } catch (error) {\n logger.warn(\n `Failed to clear namespace for handler: ${handler.name}`,\n error\n );\n }\n }\n\n logger.debug(`Cleared namespace: ${locale}:${namespace}`);\n }\n\n /**\n * Set a value directly in the cache (for optimistic updates)\n * Bypasses the normal handler flow to directly set values in memory handlers\n * Stores as ContentUnit (text + styles) for consistency\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @param value - Translation value\n * @param styles - Optional styles for indexed tags\n */\n setCache(key: string, value: string, styles?: Record<string, string[]>): void {\n // Save to memory handlers using the dedicated setCache method\n // Handler stores as ContentUnit JSON internally\n for (const handler of this.syncHandlers) {\n if (handler.type === 'memory' && handler.setCache) {\n try {\n handler.setCache(key, value, styles);\n } catch (error) {\n logger.warn(`Failed to set cache in handler: ${handler.name}`, error);\n }\n }\n }\n\n logger.debug(`Cache set: ${key}`);\n }\n\n /**\n * Get namespace data from cache for ContentUnit style lookup\n *\n * Used by t() to retrieve styles for indexed tags at render time.\n *\n * @param namespaceCacheKey - Cache key in format @locale:namespace\n * @returns Parsed namespace data or null if not found\n */\n getNamespaceData(namespaceCacheKey: string): TranslationData | null {\n // Try to get from memory handlers first (sync)\n for (const handler of this.syncHandlers) {\n if (handler.type === 'memory') {\n try {\n const entries = handler.getEntries?.();\n if (entries && entries[namespaceCacheKey]) {\n const data = entries[namespaceCacheKey];\n // Parse if it's a string (JSON)\n if (typeof data === 'string') {\n return JSON.parse(data);\n }\n return data;\n }\n } catch (error) {\n logger.debug(`Error getting namespace data from ${handler.name}:`, error);\n }\n }\n }\n return null;\n }\n}\n", "import type { ParsedNamespaceKey } from '../types/translation.types.js';\n/**\n * Namespace parsing utilities for translation keys\n * Supports patterns like: 'common:welcome', 'user.profile.name', 'errors:validation.required'\n */\n\n\n/**\n * Parse namespace from translation key\n * Supports: 'namespace:key' pattern\n * Future: Could support other patterns like 'namespace.key' or 'namespace/key'\n * \n * @param key - Translation key (e.g., 'common:welcome' or 'welcome')\n * @returns Parsed namespace information\n */\nexport function parseNamespaceKey(key: string): ParsedNamespaceKey {\n // Simple namespace pattern: 'namespace:key'\n const colonIndex = key.indexOf(':');\n \n if (colonIndex > 0 && colonIndex < key.length - 1) {\n // Has explicit namespace\n const namespace = key.substring(0, colonIndex);\n const cleanKey = key.substring(colonIndex + 1);\n \n return {\n originalKey: key,\n namespace,\n cleanKey,\n hasExplicitNamespace: true\n };\n }\n \n // No namespace found\n return {\n originalKey: key,\n cleanKey: key,\n hasExplicitNamespace: false\n };\n}\n\n/**\n * Create a full namespaced key\n * \n * @param key - Clean translation key\n * @param namespace - Namespace to prepend\n * @returns Namespaced key (e.g., 'common:welcome')\n */\nexport function createNamespacedKey(key: string, namespace?: string): string {\n if (!namespace) return key;\n return `${namespace}:${key}`;\n}\n\n/**\n * Validate namespace format\n * \n * @param namespace - Namespace to validate\n * @returns Whether namespace is valid\n */\nexport function isValidNamespace(namespace: string): boolean {\n // Simple validation: alphanumeric, underscore, hyphen\n return /^[a-zA-Z0-9_-]+$/.test(namespace);\n}", "/**\n * Translation context creation utilities\n */\n\nimport type { TranslationContext, ParsedNamespaceKey } from '../types/translation.types.js';\n\n/**\n * Create translation context with namespace resolution\n * \n * @param parsedKey - Parsed namespace key information\n * @param currentLocale - Current locale\n * @param defaultNamespace - Default namespace if none specified\n * @returns Complete translation context\n */\nexport function createTranslationContext(\n parsedKey: ParsedNamespaceKey,\n currentLocale: string,\n defaultNamespace?: string\n): TranslationContext {\n // Use explicit namespace if provided, otherwise use default\n const effectiveNamespace = parsedKey.hasExplicitNamespace\n ? parsedKey.namespace\n : defaultNamespace;\n\n return {\n locale: currentLocale,\n namespace: effectiveNamespace\n };\n}\n\n/**\n * Check if two contexts are equivalent (for caching)\n * \n * @param context1 - First context\n * @param context2 - Second context \n * @returns Whether contexts are equivalent\n */\nexport function areContextsEquivalent(\n context1: TranslationContext, \n context2: TranslationContext\n): boolean {\n return (\n context1.locale === context2.locale &&\n context1.namespace === context2.namespace\n );\n}", "/**\n * Translation value processing utilities\n * Handles simple strings, nested objects, pluralization, and context\n */\n\n// import type { TranslationParams } from '../types/translation.types.js';\n// import { interpolateParams } from './translation-utils.js';\nimport { logger } from './logger.js';\n\n\n/**\n * \u2705 Resolve nested key path in translation object\n */\n/**\n * \u2705 Resolve nested key from namespace object\n * Examples:\n * - resolveNestedKey({user: {profile: {name: \"John\"}}}, \"user.profile.name\") \u2192 \"John\"\n * - resolveNestedKey({items: [{name: \"Apple\"}]}, \"items[0].name\") \u2192 \"Apple\"\n * - resolveNestedKey({welcome: \"Hello\"}, \"welcome\") \u2192 \"Hello\"\n */\nexport function resolveNestedKey(\n namespace: Record<string, unknown>,\n keyPath: string\n): unknown {\n if (!namespace || !keyPath) {\n return undefined;\n }\n\n // Handle simple key (no nesting)\n if (!keyPath.includes('.') && !keyPath.includes('[')) {\n return namespace[keyPath];\n }\n\n // Handle nested key navigation\n try {\n const keys = parseKeyPath(keyPath);\n let current: unknown = namespace;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n logger.debug(\n `\uD83D\uDD0D Nested key resolution stopped at null/undefined for: ${keyPath}`\n );\n return undefined;\n }\n\n if (typeof key === 'number') {\n // Array index access\n if (!Array.isArray(current)) {\n logger.debug(\n `\uD83D\uDD0D Expected array for index ${key} in path: ${keyPath}`\n );\n return undefined;\n }\n current = current[key];\n } else {\n // Object property access\n if (typeof current !== 'object') {\n logger.debug(\n `\uD83D\uDD0D Expected object for key '${key}' in path: ${keyPath}`\n );\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n }\n\n logger.debug(\n `\uD83D\uDD0D Nested key resolved: ${keyPath} \u2192 ${typeof current === 'object' ? '[Object]' : current}`\n );\n return current;\n } catch (error) {\n logger.debug(`\uD83D\uDD0D Nested key resolution error for '${keyPath}':`, error);\n return undefined;\n }\n}\n\n/**\n * \u2705 Parse key path into array of keys/indices\n * Examples:\n * - \"user.profile.name\" \u2192 [\"user\", \"profile\", \"name\"]\n * - \"items[0].name\" \u2192 [\"items\", 0, \"name\"]\n * - \"settings.ui.theme\" \u2192 [\"settings\", \"ui\", \"theme\"]\n */\nexport function parseKeyPath(keyPath: string): (string | number)[] {\n const keys: (string | number)[] = [];\n let currentKey = '';\n let inBrackets = false;\n\n for (let i = 0; i < keyPath.length; i++) {\n const char = keyPath[i];\n\n if (char === '.' && !inBrackets) {\n // End of current key\n if (currentKey) {\n keys.push(currentKey);\n currentKey = '';\n }\n } else if (char === '[') {\n // Start of array index\n if (currentKey) {\n keys.push(currentKey);\n currentKey = '';\n }\n inBrackets = true;\n } else if (char === ']' && inBrackets) {\n // End of array index\n if (currentKey) {\n const index = parseInt(currentKey, 10);\n if (!isNaN(index)) {\n keys.push(index);\n } else {\n // Non-numeric index, treat as string\n keys.push(currentKey);\n }\n currentKey = '';\n }\n inBrackets = false;\n } else {\n // Regular character\n currentKey += char;\n }\n }\n\n // Add remaining key\n if (currentKey) {\n keys.push(currentKey);\n }\n\n return keys;\n}\n\n\n/**\n * \u2705 Create individual cache key: locale:namespace:key\n */\nexport function createIndividualCacheKey(\n locale: string,\n namespace: string | undefined,\n key: string\n): string {\n const parts = [locale];\n if (namespace) {\n parts.push(namespace);\n }\n parts.push(key);\n return parts.join(':');\n}\n\n/**\n * \u2705 Create namespace cache key: @locale:namespace\n */\nexport function createNamespaceCacheKey(\n locale: string,\n namespace: string\n): string {\n return `@${locale}:${namespace}`;\n}\n\n/**\n * \u2705 Check if key is namespace cache entry\n */\nexport function isNamespaceCacheKey(key: string): boolean {\n return key.startsWith('@');\n}\n\n/**\n * \u2705 Parse namespace cache key\n */\nexport function parseNamespaceCacheKey(\n key: string\n): { locale: string; namespace: string } | null {\n if (!key.startsWith('@')) return null;\n\n const parts = key.substring(1).split(':');\n if (parts.length !== 2) return null;\n\n const [locale, namespace] = parts;\n return { locale, namespace };\n}\n\n/**\n * \u2705 Parse individual cache key\n */\nexport function parseIndividualCacheKey(\n key: string\n): { locale: string; namespace?: string; translationKey: string } | null {\n if (key.startsWith('@')) return null;\n\n const parts = key.split(':');\n if (parts.length < 2) return null;\n\n if (parts.length === 2) {\n const [locale, translationKey] = parts;\n return { locale, translationKey };\n }\n\n if (parts.length === 3) {\n const [locale, namespace, translationKey] = parts;\n return { locale, namespace, translationKey };\n }\n\n return null;\n}\n\n/**\n * \u2705 Flatten nested translations for caching individual keys\n * Handles both ICU MessageFormat strings and structured objects\n * Stores full ContentUnit as JSON - includes both text and styles\n */\nexport function flattenTranslations(\n translations: Record<string, unknown>,\n prefix = '',\n locale: string,\n namespace: string\n): Record<string, string> {\n const flattened: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(translations)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const cacheKey = createIndividualCacheKey(locale, namespace, fullKey);\n\n if (typeof value === 'object' && value !== null && 'text' in value && 'styles' in value) {\n // Server returns ContentUnit format: { text, styles }\n // Store as JSON to preserve both text and styles\n flattened[cacheKey] = JSON.stringify(value);\n } else if (typeof value === 'object' && value !== null) {\n // Nested object - flatten recursively\n Object.assign(\n flattened,\n flattenTranslations(value as Record<string, unknown>, fullKey, locale, namespace)\n );\n } else {\n // Fallback for plain strings - wrap in ContentUnit format\n flattened[cacheKey] = JSON.stringify({ text: String(value), styles: {} });\n }\n }\n\n return flattened;\n}\n", "/**\n * Enhanced translation process flow utilities\n * Organizes the step-by-step translation resolution process with i18n features\n */\n\nimport type { TranslationRequest } from '../types/translation.types.js';\nimport { createTranslationContext } from './context-utils.js';\nimport { parseNamespaceKey } from './namespace-utils.js';\nimport {\n createIndividualCacheKey,\n createNamespaceCacheKey,\n} from './translation-value-utils.js';\n\n/**\n * \u2705 Enhanced: Parse and prepare translation request with cache keys\n * This is the entry point that organizes all the parsing logic\n */\nexport function prepareTranslationRequest(\n key: string,\n currentLocale: string,\n defaultValueOrParams?: string | Record<string, unknown>,\n paramsOrDefaultValue?: Record<string, unknown> | string,\n defaultNamespace?: string\n): TranslationRequest {\n const startTime = performance.now();\n\n // Parse flexible parameters\n const { defaultValue, params } = parseTranslationParams(\n defaultValueOrParams,\n paramsOrDefaultValue\n );\n\n // Parse namespace from key\n const parsedKey = parseNamespaceKey(key);\n\n // Create translation context\n const context = createTranslationContext(\n parsedKey,\n currentLocale,\n defaultNamespace\n );\n\n // \u2705 Generate cache keys using unified pattern\n const individualCacheKey = createIndividualCacheKey(\n context.locale,\n context.namespace,\n parsedKey.cleanKey\n );\n\n const namespaceCacheKey = context.namespace\n ? createNamespaceCacheKey(context.locale, context.namespace)\n : undefined;\n\n // Generate unique ID for the request (could be a hash or UUID)\n const id = `${individualCacheKey}-${startTime}`;\n\n return {\n id, // Unique request ID\n originalKey: key,\n originalParams: defaultValueOrParams,\n originalDefaultValue: paramsOrDefaultValue,\n cleanKey: parsedKey.cleanKey,\n hasExplicitNamespace: parsedKey.hasExplicitNamespace,\n parsedParams: params,\n parsedDefaultValue: defaultValue,\n locale: currentLocale,\n namespace: context.namespace, // \u2705 Use effective namespace (explicit or default)\n individualCacheKey, // \u2705 Ready-to-use cache key\n namespaceCacheKey, // \u2705 Ready-to-use namespace key\n startTime,\n };\n}\n\n/**\n * Parse flexible translation parameters\n */\nexport function parseTranslationParams(\n secondParam?: string | Record<string, unknown>,\n thirdParam?: Record<string, unknown> | string\n): { defaultValue?: string; params?: Record<string, unknown> } {\n let defaultValue: string | undefined;\n let params: Record<string, unknown> | undefined;\n\n // Runtime validation: Warn if both params are objects (likely misuse).\n // process is Node-only; browsers throw ReferenceError without the typeof\n // guard. Treat \"no process\" as \"not production\" so the dev warning still\n // fires in browser dev environments.\n const _isNotProd =\n typeof process === 'undefined' ||\n process.env?.NODE_ENV !== 'production';\n if (\n typeof secondParam === 'object' &&\n typeof thirdParam === 'object' &&\n _isNotProd\n ) {\n console.warn(\n '[LionRapid] Warning: Both secondParam and thirdParam are objects. ' +\n 'Expected pattern: t(key, params, defaultValue) or t(key, defaultValue, params). ' +\n 'Second object will be ignored as it cannot be a defaultValue.'\n );\n }\n\n if (typeof secondParam === 'string') {\n // t(key, defaultValue) or t(key, defaultValue, params)\n defaultValue = secondParam;\n if (typeof thirdParam === 'object') {\n params = thirdParam;\n }\n } else if (typeof secondParam === 'object') {\n // t(key, params) or t(key, params, defaultValue)\n params = secondParam;\n if (typeof thirdParam === 'string') {\n defaultValue = thirdParam;\n }\n }\n\n return { defaultValue, params };\n}\n", "/**\n * Simplified memory cache handler\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport { ISyncHandler } from '../interfaces/handler.interface.js';\nimport {\n IStatsProvider,\n ISyncRepository,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n TranslationContext,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger } from '../utils/index.js';\nimport {\n createNamespaceCacheKey,\n flattenTranslations,\n resolveNestedKey,\n} from '../utils/translation-value-utils.js';\n\n/**\n * Parsed cache entry containing both text and styles\n */\ninterface CachedContentUnit {\n text: string;\n styles: Record<string, string[]>;\n}\n\n/**\n * Simple memory cache handler\n */\nexport class SyncHandler implements ISyncHandler {\n readonly name: string;\n readonly version = '1.0.0';\n readonly priority: number;\n readonly type = 'memory' as const;\n readonly enabled: boolean;\n private ttlMap = new Map<string, number>();\n private ttl: number;\n private repository: ISyncRepository & IStatsProvider;\n private bus: EventEmitter;\n\n constructor(\n eventEmitter: EventEmitter,\n repository: ISyncRepository & IStatsProvider\n ) {\n this.bus = eventEmitter;\n this.repository = repository;\n this.name = repository.name;\n const config = repository.getConfig();\n this.enabled = config.enabled ?? true;\n this.priority = config.priority ?? 0;\n this.ttl = config.options?.ttl ?? 30 * 60 * 1000; // Default 30 minutes\n }\n\n getSourceType(): 'memory' | 'storage' | 'network' | 'fallback' {\n return 'memory';\n }\n\n /**\n * Simple lookup implementation\n * Returns ContentUnit with both text and styles\n */\n lookup(request: TranslationRequest): TranslationResult {\n const startTime = Date.now();\n logger.debug(`Sync lookup: ${request.cleanKey}`);\n const repoBus = this.bus.repo(request, this.name);\n repoBus.getStart();\n\n const directResult = this.tryDirectLookup(request);\n if (directResult !== null) {\n logger.debug(`Cache hit: ${request.cleanKey}`);\n repoBus.getSuccess(directResult.text);\n return this.createResult(directResult, 'memory', 200, startTime, true);\n }\n\n // Try namespace lookup for nested keys\n if (request.cleanKey.includes('.') && request.namespace) {\n const namespaceResult = this.tryNamespaceLookup(request);\n if (namespaceResult !== null) {\n logger.debug(`Namespace hit: ${request.cleanKey}`);\n repoBus.getSuccess(namespaceResult.text);\n return this.createResult(\n namespaceResult,\n 'memory',\n 200,\n startTime,\n true\n );\n }\n }\n\n logger.debug(`Cache miss: ${request.cleanKey}`);\n repoBus.getMiss();\n\n // Return fallback result (no styles for fallback)\n return this.createResult(\n { text: request.parsedDefaultValue || request.cleanKey, styles: {} },\n 'fallback',\n 404,\n startTime\n );\n }\n\n /**\n * Simple save implementation\n * Stores ContentUnit (text + styles) as JSON\n */\n save(request: TranslationRequest, result: TranslationResult): void {\n if (!result.value) return;\n const repoBus = this.bus.repo(request, this.name);\n\n // Store as ContentUnit JSON (text + styles together)\n const contentUnit: CachedContentUnit = {\n text: result.value,\n styles: result.styles || {},\n };\n this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Saved to cache: ${request.cleanKey}`);\n repoBus.setSuccess(result.value);\n }\n\n /**\n * Namespace saving implementation\n */\n saveNamespace(\n translations: TranslationData,\n context: TranslationContext\n ): void {\n if (!context.namespace) return;\n const repoBus = this.bus.repo(\n context.locale + ':' + context.namespace,\n this.name\n );\n\n // Store full namespace: @locale:namespace\n const namespaceCacheKey = createNamespaceCacheKey(\n context.locale,\n context.namespace\n );\n this.setWithTTL(namespaceCacheKey, JSON.stringify(translations));\n\n // Store flattened individual keys: locale:namespace:key\n const flattened = flattenTranslations(\n translations,\n '',\n context.locale,\n context.namespace!\n );\n\n for (const [flatKey, flatValue] of Object.entries(flattened)) {\n this.setWithTTL(flatKey, flatValue);\n }\n repoBus.setSuccess(JSON.stringify(translations));\n }\n\n /**\n * \u2705 Strategy 1: Direct cache lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private tryDirectLookup(request: TranslationRequest): CachedContentUnit | null {\n // Check TTL and expire if needed\n if (this.checkAndExpireTTL(request.individualCacheKey)) {\n return null;\n }\n\n const cachedValue = this.repository.get(request.individualCacheKey);\n if (!cachedValue) return null;\n\n this.refreshTTL(request.individualCacheKey); // Refresh TTL on access\n\n // Parse cached ContentUnit JSON\n try {\n const parsed = JSON.parse(cachedValue);\n if (typeof parsed === 'object' && 'text' in parsed) {\n return {\n text: String(parsed.text),\n styles: parsed.styles || {},\n };\n }\n // Legacy format: plain string (shouldn't happen with new data)\n return { text: cachedValue, styles: {} };\n } catch {\n // If parse fails, treat as legacy plain string\n return { text: cachedValue, styles: {} };\n }\n }\n\n /**\n * \u2705 Strategy 2: Namespace lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private tryNamespaceLookup(request: TranslationRequest): CachedContentUnit | null {\n if (!request.namespace) return null;\n\n const namespaceCacheKey = createNamespaceCacheKey(\n request.locale,\n request.namespace\n );\n\n // Check TTL for namespace\n if (this.checkAndExpireTTL(namespaceCacheKey)) {\n return null;\n }\n\n const namespaceData = this.repository.get(namespaceCacheKey);\n if (!namespaceData) return null;\n this.refreshTTL(namespaceCacheKey); // Refresh TTL on access\n\n try {\n const translations = JSON.parse(namespaceData);\n const value = resolveNestedKey(translations, request.cleanKey);\n\n if (value !== null && value !== undefined) {\n // Extract ContentUnit from namespace data\n let contentUnit: CachedContentUnit;\n\n if (typeof value === 'object' && value !== null && 'text' in value) {\n // Server ContentUnit format: { text, styles }\n contentUnit = {\n text: String((value as { text: unknown }).text),\n styles: (value as { styles?: Record<string, string[]> }).styles || {},\n };\n } else {\n // Plain string fallback\n contentUnit = { text: String(value), styles: {} };\n }\n\n // Cache the individual key for faster future access (as JSON)\n this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Cached from namespace: ${request.cleanKey}`);\n return contentUnit;\n }\n } catch (error) {\n // Invalid JSON in namespace cache\n logger.debug(\n `Invalid JSON in namespace cache: ${namespaceCacheKey}`,\n error\n );\n this.repository.remove(namespaceCacheKey);\n this.ttlMap.delete(namespaceCacheKey);\n }\n\n return null;\n }\n\n /**\n * Helper to create consistent TranslationResult objects\n * Now includes styles from ContentUnit\n */\n private createResult(\n contentUnit: CachedContentUnit,\n source: 'memory' | 'storage' | 'network' | 'fallback',\n status: number,\n startTime: number,\n cached?: boolean\n ): TranslationResult {\n return {\n value: contentUnit.text,\n styles: contentUnit.styles,\n source,\n status,\n duration: Date.now() - startTime,\n ...(cached !== undefined && { cached }),\n };\n }\n\n /**\n * Check TTL and expire if needed\n * Returns true if expired, false if still valid\n */\n private checkAndExpireTTL(cacheKey: string): boolean {\n const timestamp = this.ttlMap.get(cacheKey);\n if (timestamp && Date.now() - timestamp > this.ttl) {\n this.repository.remove(cacheKey);\n this.ttlMap.delete(cacheKey);\n logger.debug(`TTL expired: ${cacheKey}`);\n return true;\n }\n return false;\n }\n\n /**\n * Set value in repository and update TTL\n */\n private setWithTTL(cacheKey: string, value: string): void {\n this.repository.set(cacheKey, value);\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Refresh TTL on access\n */\n private refreshTTL(cacheKey: string): void {\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Get TTL information for debugging\n */\n getTTLInfo(): Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > {\n const ttlInfo: Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > = {};\n const now = Date.now();\n\n for (const [key, timestamp] of this.ttlMap.entries()) {\n const age = now - timestamp;\n const remaining = Math.max(0, this.ttl - age);\n ttlInfo[key] = { timestamp, age, remaining };\n }\n\n return ttlInfo;\n }\n\n getEntries() {\n if (this.repository.getEntries !== undefined) {\n return this.repository.getEntries();\n }\n }\n\n /**\n * Clear all entries for a specific namespace\n * Removes namespace cache entry, individual keys, and TTL entries\n */\n clearNamespace(locale: string, namespace: string): void {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n const keyPrefix = `${locale}:${namespace}:`;\n\n // Remove namespace cache entry\n this.repository.remove(namespaceCacheKey);\n this.ttlMap.delete(namespaceCacheKey);\n\n // Remove individual translation keys and their TTL entries\n const entries = this.repository.getEntries?.();\n if (entries) {\n for (const key of Object.keys(entries)) {\n if (key.startsWith(keyPrefix)) {\n this.repository.remove(key);\n this.ttlMap.delete(key);\n }\n }\n }\n\n logger.debug(`Cleared namespace: ${locale}:${namespace}`);\n }\n\n destroy(): void {\n this.repository.clear();\n this.ttlMap.clear();\n }\n\n /**\n * Direct cache set (for optimistic updates)\n * Bypasses event emission for direct cache manipulation\n * Stores as ContentUnit JSON (text + styles)\n */\n setCache(key: string, value: string, styles?: Record<string, string[]>): void {\n const contentUnit: CachedContentUnit = {\n text: value,\n styles: styles || {},\n };\n this.setWithTTL(key, JSON.stringify(contentUnit));\n logger.debug(`Direct cache set: ${key}`);\n }\n}\n", "/**\n * Simplified memory cache handler\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport { StorageRepositoryConfig } from '../config';\nimport { IAsyncHandler } from '../interfaces/handler.interface.js';\nimport {\n IAsyncRepository,\n IStatsProvider,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n TranslationContext,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger } from '../utils/index.js';\nimport {\n createNamespaceCacheKey,\n flattenTranslations,\n resolveNestedKey,\n} from '../utils/translation-value-utils.js';\n\n/**\n * Parsed cache entry containing both text and styles\n */\ninterface CachedContentUnit {\n text: string;\n styles: Record<string, string[]>;\n}\n\n/**\n * Async storage cache handler (IndexedDB, localStorage, etc.)\n */\nexport class AsyncHandler implements IAsyncHandler {\n readonly name: string;\n readonly version = '1.0.0';\n readonly priority: number;\n readonly type = 'storage' as const;\n readonly enabled: boolean;\n private ttlMap = new Map<string, number>();\n private ttl: number;\n private repository: IAsyncRepository & IStatsProvider;\n private bus: EventEmitter;\n\n constructor(\n eventEmitter: EventEmitter,\n repository: IAsyncRepository & IStatsProvider\n ) {\n this.bus = eventEmitter;\n this.repository = repository;\n this.name = repository.name;\n const config = repository.getConfig() as StorageRepositoryConfig;\n this.enabled = config.enabled ?? true;\n this.priority = config.priority ?? 0;\n this.ttl = config.options?.ttl ?? 30 * 60 * 1000; // Default 30 minutes\n }\n\n getSourceType(): 'memory' | 'storage' | 'network' | 'fallback' {\n return 'memory';\n }\n\n /**\n * Simple lookup implementation\n * Returns ContentUnit with both text and styles\n */\n async lookup(request: TranslationRequest): Promise<TranslationResult> {\n const startTime = Date.now();\n logger.debug(`Async lookup: ${request.cleanKey}`);\n const repoBus = this.bus.repo(request, this.name);\n\n const directResult = await this.tryDirectLookup(request);\n if (directResult !== null) {\n logger.debug(`Cache hit: ${request.cleanKey}`);\n repoBus.getSuccess(directResult.text);\n return this.createResult(directResult, 'storage', 200, startTime, true);\n }\n\n // Try namespace lookup for nested keys\n if (request.cleanKey.includes('.') && request.namespace) {\n const namespaceResult = await this.tryNamespaceLookup(request);\n if (namespaceResult !== null) {\n logger.debug(`Namespace hit: ${request.cleanKey}`);\n repoBus.getSuccess(namespaceResult.text);\n return this.createResult(\n namespaceResult,\n 'storage',\n 200,\n startTime,\n true\n );\n }\n }\n\n logger.debug(`Cache miss: ${request.cleanKey}`);\n repoBus.getMiss();\n\n // Return fallback result (no styles for fallback)\n return this.createResult(\n { text: request.parsedDefaultValue || request.cleanKey, styles: {} },\n 'fallback',\n 404,\n startTime\n );\n }\n\n /**\n * Simple save implementation\n * Stores ContentUnit (text + styles) as JSON\n */\n async save(\n request: TranslationRequest,\n result: TranslationResult\n ): Promise<void> {\n if (!result.value) return;\n const repoBus = this.bus.repo(request, this.name);\n\n // Store as ContentUnit JSON (text + styles together)\n const contentUnit: CachedContentUnit = {\n text: result.value,\n styles: result.styles || {},\n };\n await this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Saved to cache: ${request.cleanKey}`);\n repoBus.setSuccess(result.value);\n }\n\n /**\n * Namespace saving implementation\n */\n async saveNamespace(\n translations: TranslationData,\n context: TranslationContext\n ): Promise<void> {\n if (!context.namespace) return;\n const repoBus = this.bus.repo(\n context.locale + ':' + context.namespace,\n this.name\n );\n const keyCount = Object.keys(translations).length;\n logger.debug(\n `Saving namespace: ${context.locale}:${context.namespace} (${keyCount} keys)`\n );\n\n // Store full namespace: @locale:namespace\n const namespaceCacheKey = createNamespaceCacheKey(\n context.locale,\n context.namespace\n );\n await this.setWithTTL(namespaceCacheKey, JSON.stringify(translations));\n\n // Store flattened individual keys: locale:namespace:key\n const flattened = flattenTranslations(\n translations,\n '',\n context.locale,\n context.namespace!\n );\n\n let savedCount = 0;\n for (const [flatKey, flatValue] of Object.entries(flattened)) {\n await this.setWithTTL(flatKey, flatValue);\n savedCount++;\n }\n\n logger.debug(`Saved: ${savedCount} keys + namespace blob`);\n repoBus.setSuccess(JSON.stringify(translations));\n }\n\n /**\n * \u2705 Strategy 1: Direct cache lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private async tryDirectLookup(\n request: TranslationRequest\n ): Promise<CachedContentUnit | null> {\n // Check TTL and expire if needed\n if (await this.checkAndExpireTTL(request.individualCacheKey)) {\n return null;\n }\n\n const cachedValue = await this.repository.get(request.individualCacheKey);\n if (!cachedValue) return null;\n\n this.refreshTTL(request.individualCacheKey); // Refresh TTL on access\n\n // Parse cached ContentUnit JSON\n try {\n const parsed = JSON.parse(cachedValue);\n if (typeof parsed === 'object' && 'text' in parsed) {\n return {\n text: String(parsed.text),\n styles: parsed.styles || {},\n };\n }\n // Legacy format: plain string\n return { text: cachedValue, styles: {} };\n } catch {\n // If parse fails, treat as legacy plain string\n return { text: cachedValue, styles: {} };\n }\n }\n\n /**\n * \u2705 Strategy 2: Namespace lookup using unified pattern\n * Returns parsed ContentUnit (text + styles) or null\n */\n private async tryNamespaceLookup(\n request: TranslationRequest\n ): Promise<CachedContentUnit | null> {\n if (!request.namespace) return null;\n\n const namespaceCacheKey = createNamespaceCacheKey(\n request.locale,\n request.namespace\n );\n\n // Check TTL for namespace\n if (await this.checkAndExpireTTL(namespaceCacheKey)) {\n return null;\n }\n\n const namespaceData = await this.repository.get(namespaceCacheKey);\n if (!namespaceData) return null;\n this.refreshTTL(namespaceCacheKey); // Refresh TTL on access\n\n try {\n const translations = JSON.parse(namespaceData);\n const value = resolveNestedKey(translations, request.cleanKey);\n\n if (value !== null && value !== undefined) {\n // Extract ContentUnit from namespace data\n let contentUnit: CachedContentUnit;\n\n if (typeof value === 'object' && value !== null && 'text' in value) {\n // Server ContentUnit format: { text, styles }\n contentUnit = {\n text: String((value as { text: unknown }).text),\n styles: (value as { styles?: Record<string, string[]> }).styles || {},\n };\n } else {\n // Plain string fallback\n contentUnit = { text: String(value), styles: {} };\n }\n\n // Cache the individual key for faster future access (as JSON)\n await this.setWithTTL(request.individualCacheKey, JSON.stringify(contentUnit));\n\n logger.debug(`Cached from namespace: ${request.cleanKey}`);\n return contentUnit;\n }\n } catch (error) {\n // Invalid JSON in namespace cache\n logger.debug(\n `Invalid JSON in namespace cache: ${namespaceCacheKey}`,\n error\n );\n await this.repository.remove(namespaceCacheKey);\n this.ttlMap.delete(namespaceCacheKey);\n }\n\n return null;\n }\n\n /**\n * Helper to create consistent TranslationResult objects\n * Now includes styles from ContentUnit\n */\n private createResult(\n contentUnit: CachedContentUnit,\n source: 'memory' | 'storage' | 'network' | 'fallback',\n status: number,\n startTime: number,\n cached?: boolean\n ): TranslationResult {\n return {\n value: contentUnit.text,\n styles: contentUnit.styles,\n source,\n status,\n duration: Date.now() - startTime,\n ...(cached !== undefined && { cached }),\n };\n }\n\n /**\n * Check TTL and expire if needed (async version)\n * Returns true if expired, false if still valid\n */\n private async checkAndExpireTTL(cacheKey: string): Promise<boolean> {\n const timestamp = this.ttlMap.get(cacheKey);\n if (timestamp && Date.now() - timestamp > this.ttl) {\n await this.repository.remove(cacheKey);\n this.ttlMap.delete(cacheKey);\n logger.debug(`TTL expired: ${cacheKey}`);\n return true;\n }\n return false;\n }\n\n /**\n * Set value in repository and update TTL (async version)\n */\n private async setWithTTL(cacheKey: string, value: string): Promise<void> {\n await this.repository.set(cacheKey, value);\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Refresh TTL on access\n */\n private refreshTTL(cacheKey: string): void {\n this.ttlMap.set(cacheKey, Date.now());\n }\n\n /**\n * Get TTL information for debugging\n */\n getTTLInfo(): Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > {\n const ttlInfo: Record<\n string,\n { timestamp: number; age: number; remaining: number }\n > = {};\n const now = Date.now();\n\n for (const [key, timestamp] of this.ttlMap.entries()) {\n const age = now - timestamp;\n const remaining = Math.max(0, this.ttl - age);\n ttlInfo[key] = { timestamp, age, remaining };\n }\n\n return ttlInfo;\n }\n\n async destroy(): Promise<void> {\n await this.repository.clear();\n this.ttlMap.clear();\n }\n\n getEntries(): Record<string, string> | undefined {\n if (this.repository.getEntries !== undefined) {\n return this.repository.getEntries();\n }\n }\n}\n", "/**\n * Custom error classes for translation operations\n * Used for type-safe exception handling in repositories and handlers\n */\n\n/**\n * Base error class for all translation-related errors\n */\nexport class TranslationError extends Error {\n constructor(\n public readonly key: string,\n public readonly status: number,\n message: string\n ) {\n super(message);\n this.name = this.constructor.name;\n // Maintains proper stack trace for where our error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Translation not found in backend (HTTP 404)\n * Should be synced to backend for translators to fill in\n */\nexport class TranslationNotFoundError extends TranslationError {\n constructor(key: string) {\n super(key, 404, `Translation not found: ${key}`);\n }\n}\n\n/**\n * Translation exists but is locked/not ready (HTTP 423)\n * Should NOT be synced to backend - will retry on next app start\n */\nexport class TranslationLockedError extends TranslationError {\n constructor(\n key: string,\n public readonly retryAfter?: number\n ) {\n super(key, 423, `Translation locked: ${key}`);\n }\n}\n\n/**\n * Server error (HTTP 5xx)\n * Should trigger retry logic with exponential backoff\n */\nexport class ServerError extends TranslationError {\n constructor(key: string, status: number) {\n super(key, status, `Server error ${status}: ${key}`);\n }\n}\n\n/**\n * Network error (timeout, DNS failure, CORS, etc.)\n * Not an HTTP error - network layer failed\n */\nexport class NetworkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'NetworkError';\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Type guard to check if error is a TranslationError\n */\nexport function isTranslationError(error: unknown): error is TranslationError {\n return error instanceof TranslationError;\n}\n\n/**\n * Type guard to check if error is retryable (5xx or network)\n */\nexport function isRetryableError(error: unknown): boolean {\n return error instanceof ServerError || error instanceof NetworkError;\n}\n\n/**\n * Type guard to check if error is client error (4xx - not retryable)\n */\nexport function isClientError(error: unknown): boolean {\n return (\n error instanceof TranslationNotFoundError ||\n error instanceof TranslationLockedError\n );\n}\n", "/**\n * Simplified API handler - no automatic namespace loading\n * Namespace loading is now explicit via builder configuration\n */\n\nimport { EventEmitter } from '../base/event-emitter.js';\nimport { NetworkRepositoryConfig, PreloadNamespaces } from '../config';\nimport type { ContentUnit } from '../content/types.js';\nimport {\n isRetryableError,\n TranslationLockedError,\n TranslationNotFoundError,\n} from '../errors/translation-errors.js';\nimport { IAsyncHandler } from '../interfaces/handler.interface.js';\nimport { IAsyncRepository } from '../interfaces/repository.interface.js';\nimport { NetworkRepository } from '../repositories/network-repository.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport type {\n NamespaceResult,\n TranslationRequest,\n TranslationResult,\n} from '../types/translation.types.js';\nimport { logger, resolveNestedKey } from '../utils/index.js';\n\n/**\n * Simple API handler - only loads individual keys\n * Namespace loading is handled explicitly by builder\n */\nexport class NetworkHandler implements IAsyncHandler {\n repository: IAsyncRepository;\n readonly name: string;\n readonly priority: number;\n readonly version = '1.0.0';\n readonly type = 'network' as const;\n readonly enabled: boolean;\n private bus: EventEmitter;\n\n private retryCount: number;\n private retryDelay: number;\n\n constructor(eventEmitter: EventEmitter, repository: IAsyncRepository) {\n this.bus = eventEmitter;\n this.repository = repository;\n this.name = repository.name;\n const config = repository.getConfig() as NetworkRepositoryConfig;\n this.enabled = config.enabled ?? false;\n this.priority = config.priority ?? 0;\n this.retryCount = config.options?.retries ?? 3;\n this.retryDelay = config.options?.retryDelay ?? 1000;\n }\n\n initialize(): Promise<void> {\n return Promise.resolve();\n }\n\n getSourceType(): 'memory' | 'storage' | 'network' | 'fallback' {\n return 'network';\n }\n\n /**\n * \u2705 Lookup translation with full error handling\n * Strategy: Key first, namespace as fallback\n * Returns TranslationResult with status, source, duration, styles, and optional error\n */\n async lookup(request: TranslationRequest): Promise<TranslationResult> {\n const startTime = Date.now();\n const fallbackValue = request.parsedDefaultValue || request.cleanKey;\n\n if (!this.enabled) {\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 0,\n startTime\n );\n }\n\n const networkBus = this.bus.network(request, this.name);\n networkBus.start();\n logger.debug(`Network lookup: ${request.cleanKey}`);\n\n // Strategy 1: Try individual key lookup first (returns ContentUnit with styles)\n try {\n const contentUnit = await this.lookupContentUnitWithRetry(\n request.individualCacheKey\n );\n\n logger.debug(`Network hit: ${request.cleanKey}`);\n networkBus.success(contentUnit.text);\n\n // Return text + styles for caching\n return this.createTranslationResult(\n contentUnit.text,\n 'network',\n 200,\n startTime,\n undefined,\n false,\n undefined,\n contentUnit.styles\n );\n } catch (error) {\n // Handle 404 - key not found, try namespace fallback\n if (error instanceof TranslationNotFoundError && request.namespace) {\n logger.debug(\n `Individual key not found, trying namespace: ${request.cleanKey}`\n );\n return this.lookupFromNamespace(request, fallbackValue, startTime, networkBus);\n }\n\n // Handle 423 - locked translation\n if (error instanceof TranslationLockedError) {\n logger.debug(`Translation locked (423): ${request.cleanKey}`);\n return this.handleTranslationLocked(\n request,\n fallbackValue,\n error,\n startTime,\n networkBus\n );\n }\n\n // Handle other errors (server errors, network errors)\n logger.debug(`Network error: ${request.cleanKey}`, error);\n networkBus.error(error as Error);\n\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 0,\n startTime,\n error as Error\n );\n }\n }\n\n /**\n * Strategy 2: Namespace fallback when individual key not found\n */\n private async lookupFromNamespace(\n request: TranslationRequest,\n fallbackValue: string,\n startTime: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n networkBus: any\n ): Promise<TranslationResult> {\n try {\n const namespaceResult = await this.loadNamespace(\n request.locale,\n request.namespace!\n );\n\n if (namespaceResult && namespaceResult.data) {\n const nestedValue = resolveNestedKey(\n namespaceResult.data,\n request.cleanKey\n );\n\n if (nestedValue !== undefined && nestedValue !== null) {\n // Handle both ContentUnit format and plain strings\n let resolvedValue: string;\n let styles: Record<string, string[]> = {};\n\n if (typeof nestedValue === 'object' && nestedValue !== null && 'text' in nestedValue) {\n // ContentUnit format: { text, styles }\n const contentUnit = nestedValue as { text: unknown; styles?: Record<string, string[]> };\n resolvedValue = String(contentUnit.text);\n styles = contentUnit.styles || {};\n } else {\n // Plain string\n resolvedValue = String(nestedValue);\n }\n\n logger.debug(`Network namespace hit: ${request.cleanKey}, hasStyles=${Object.keys(styles).length > 0}`);\n networkBus.success(resolvedValue);\n\n return this.createTranslationResult(\n resolvedValue,\n 'network',\n 200,\n startTime,\n undefined,\n false,\n {\n locale: request.locale,\n namespace: request.namespace!,\n data: namespaceResult.data,\n },\n styles\n );\n }\n }\n\n // Key not found in namespace either\n const error = new TranslationNotFoundError(request.cleanKey);\n return this.handleTranslationNotFound(\n request,\n fallbackValue,\n error,\n startTime\n );\n } catch (nsError) {\n // Namespace load failed\n logger.debug(`Namespace load failed: ${request.cleanKey}`, nsError);\n\n if (nsError instanceof TranslationNotFoundError) {\n return this.handleTranslationNotFound(\n request,\n fallbackValue,\n nsError,\n startTime\n );\n }\n\n if (nsError instanceof TranslationLockedError) {\n return this.handleTranslationLocked(\n request,\n fallbackValue,\n nsError,\n startTime,\n networkBus\n );\n }\n\n networkBus.error(nsError as Error);\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 0,\n startTime,\n nsError as Error\n );\n }\n }\n\n /**\n * \u2705 Load entire namespace (used for preloading)\n * Returns NamespaceResult with status and error information\n */\n async loadNamespace(\n locale: string,\n namespace: string\n ): Promise<NamespaceResult | null> {\n const startTime = Date.now();\n\n if (!this.enabled) {\n return this.createNamespaceResult(null, 'fallback', 0, startTime);\n }\n\n try {\n const data = await this.loadNamespaceWithRetry(locale, namespace);\n\n // 304 Not Modified \u2014 cached translations are still fresh\n if (data === null) {\n logger.debug(`Network namespace not modified: ${locale}:${namespace}`);\n return this.createNamespaceResult(null, 'network', 304, startTime);\n }\n\n logger.debug(`Network namespace loaded: ${locale}:${namespace}`);\n return this.createNamespaceResult(data, 'network', 200, startTime);\n } catch (error) {\n if (error instanceof TranslationLockedError) {\n logger.debug(`Namespace locked (423): ${locale}:${namespace}`);\n\n return this.createNamespaceResult(\n null,\n 'fallback',\n 423,\n startTime,\n error\n );\n }\n\n if (error instanceof TranslationNotFoundError) {\n logger.debug(`Network namespace not found: ${locale}:${namespace}`);\n\n return this.createNamespaceResult(\n null,\n 'fallback',\n 404,\n startTime,\n error\n );\n }\n\n logger.debug(`Network namespace error: ${locale}:${namespace}`, error);\n\n return this.createNamespaceResult(\n null,\n 'fallback',\n 0,\n startTime,\n error as Error\n );\n }\n }\n\n /**\n * \u2705 Namespace lookup with retry logic\n * Throws custom errors (TranslationNotFoundError, TranslationLockedError, etc.)\n */\n private async loadNamespaceWithRetry(\n locale: string,\n namespace: string\n ): Promise<TranslationData | null> {\n return this.withRetry(\n () => this.repository.getNamespace(locale, namespace),\n `${locale}:${namespace}`,\n 'namespace request'\n );\n }\n\n /**\n * Simple save implementation (API usually doesn't save)\n */\n async save(\n request: TranslationRequest,\n result: TranslationResult\n ): Promise<void> {\n // APIs usually don't save translations, but we could implement PUT if needed\n void request;\n void result;\n }\n\n /**\n * \u2705 Lookup with retry logic for individual keys\n * Throws custom errors (TranslationNotFoundError, TranslationLockedError, etc.)\n */\n private async lookupWithRetry(cacheKey: string): Promise<string> {\n return this.withRetry(\n () => this.repository.get(cacheKey),\n cacheKey,\n 'network request'\n );\n }\n\n /**\n * \u2705 Lookup ContentUnit with retry logic for individual keys\n * Returns full ContentUnit with text and styles\n * Throws custom errors (TranslationNotFoundError, TranslationLockedError, etc.)\n */\n private async lookupContentUnitWithRetry(cacheKey: string): Promise<ContentUnit> {\n // Check if repository supports getContentUnit (NetworkRepository does)\n const repo = this.repository as NetworkRepository;\n if (typeof repo.getContentUnit !== 'function') {\n // Fallback: use get() and wrap in ContentUnit\n const text = await this.lookupWithRetry(cacheKey);\n return { text, styles: {} };\n }\n\n return this.withRetry(\n () => repo.getContentUnit(cacheKey),\n cacheKey,\n 'network content unit request'\n );\n }\n\n /**\n * Delay utility for retries\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private calculateBackoff(attempt: number): number {\n const baseDelay = this.retryDelay;\n const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);\n const maxDelay = 10000; // 10 seconds max\n\n // Add jitter to prevent thundering herd\n const jitter = Math.random() * 0.1 * exponentialDelay;\n\n return Math.min(exponentialDelay + jitter, maxDelay);\n }\n\n /**\n * Generic retry wrapper for repository operations\n * Handles retryable errors with exponential backoff\n */\n private async withRetry<T>(\n operation: () => Promise<T>,\n contextKey: string,\n contextDescription: string,\n attempt = 1\n ): Promise<T> {\n const networkBus = this.bus.network(contextKey, 'withRetry');\n\n try {\n return await operation();\n } catch (error) {\n // Retry only on retryable errors (5xx, network errors)\n if (attempt <= this.retryCount && isRetryableError(error)) {\n const delay = this.calculateBackoff(attempt);\n networkBus.retry(attempt, delay, (error as Error).message);\n await this.delay(delay);\n\n logger.debug(\n `Retrying ${contextDescription} (${attempt}/${this.retryCount}) after ${delay}ms`\n );\n return this.withRetry(\n operation,\n contextKey,\n contextDescription,\n attempt + 1\n );\n }\n\n // Don't retry client errors (404, 423)\n throw error;\n }\n }\n\n /**\n * Handle translation not found (after namespace fallback also failed)\n */\n private handleTranslationNotFound(\n request: TranslationRequest,\n fallbackValue: string,\n error: TranslationNotFoundError,\n startTime: number\n ): TranslationResult {\n logger.debug(`Network namespace miss: ${request.cleanKey}`);\n const translateBus = this.bus.translation(request);\n translateBus.notFound(\n fallbackValue,\n request.locale,\n request.namespace || 'default'\n );\n\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 404,\n startTime,\n error\n );\n }\n\n /**\n * Handle TranslationLockedError for translation lookups\n */\n private handleTranslationLocked(\n request: TranslationRequest,\n fallbackValue: string,\n error: TranslationLockedError,\n startTime: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n networkBus: any\n ): TranslationResult {\n const translateBus = this.bus.translation(request);\n translateBus.locked(\n fallbackValue,\n request.locale,\n request.namespace || 'default'\n );\n networkBus.error(error, 423);\n\n return this.createTranslationResult(\n fallbackValue,\n 'fallback',\n 423,\n startTime,\n error\n );\n }\n\n /**\n * Helper to create consistent TranslationResult objects\n */\n private createTranslationResult(\n value: string,\n source: 'network' | 'fallback' | 'storage' | 'memory',\n status: number,\n startTime: number,\n error?: Error,\n cached?: boolean,\n namespaceLoaded?: {\n locale: string;\n namespace: string;\n data: TranslationData;\n },\n styles?: Record<string, string[]>\n ): TranslationResult {\n return {\n value,\n source,\n status,\n duration: Date.now() - startTime,\n ...(error && { error }),\n ...(cached !== undefined && { cached }),\n ...(namespaceLoaded && { namespaceLoaded }),\n ...(styles && Object.keys(styles).length > 0 && { styles }),\n };\n }\n\n /**\n * Helper to create consistent NamespaceResult objects\n */\n private createNamespaceResult(\n data: TranslationData | null,\n source: 'network' | 'fallback' | 'storage' | 'memory',\n status: number,\n startTime: number,\n error?: Error\n ): NamespaceResult {\n return {\n data,\n source,\n status,\n duration: Date.now() - startTime,\n ...(error && { error }),\n };\n }\n\n getPreload(): Array<PreloadNamespaces> {\n const config = this.repository.getConfig() as NetworkRepositoryConfig;\n return config.options?.preloadNamespaces || [];\n }\n}\n", "/**\n * Canonical opening-tag format for ContentUnit `raw:` styles.\n *\n * All four parsers (edge, core HTML walker, core DOM walker, PHP) must\n * produce byte-identical output for the same source element. Rules:\n * - tag name lowercased\n * - attribute names lowercased\n * - attribute values always wrapped in double-quotes\n * - attribute insertion order preserved from source\n * - boolean attrs emitted as `attr=\"\"`\n * - void elements use the same form (no self-closing slash, no close tag emitted)\n *\n * Attribute values are stored byte-for-byte as captured from the source\n * (the source's own entity encoding is preserved \u2014 already valid HTML).\n * The serializer only re-escapes `\"` \u2192 `&quot;` so the chosen double-quote\n * delimiter stays well-formed when the source used single quotes.\n */\n\nexport const VOID_TAGS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\nfunction escapeAttrValue(value: string): string {\n return value.replace(/\"/g, '&quot;');\n}\n\n/**\n * Build the canonical opening tag string. Used by parsers to produce\n * the `raw:<...>` style content.\n */\nexport function serializeOpeningTag(\n tagName: string,\n attrs: Record<string, string>,\n): string {\n const tag = tagName.toLowerCase();\n let result = `<${tag}`;\n for (const [name, value] of Object.entries(attrs)) {\n result += ` ${name.toLowerCase()}=\"${escapeAttrValue(value)}\"`;\n }\n result += '>';\n return result;\n}\n\n/**\n * Extract the tag name from a canonical opening tag string.\n * `<span class=\"x\">` \u2192 `span`. Returns lowercase.\n */\nexport function extractTagName(rawOpenTag: string): string {\n const end = rawOpenTag.search(/[\\s>]/);\n return rawOpenTag.slice(1, end === -1 ? rawOpenTag.length : end).toLowerCase();\n}\n\n/**\n * Return the raw opening tag (the portion after `raw:`) from a style array,\n * or null if no `raw:` style is present.\n */\nexport function readRawStyle(styles: string[]): string | null {\n for (const s of styles) {\n if (s.startsWith('raw:')) return s.slice(4);\n }\n return null;\n}\n", "/**\n * Markup parser \u2014 converts HTML strings to ContentUnit (raw-only).\n *\n * Every inline element becomes an indexed tag whose style is the verbatim\n * opening tag in canonical form (see canonical-tag.ts). No element-to-\n * semantic-style mapping \u2014 wrappers round-trip exactly.\n *\n * @module content/parser/MarkupParser\n */\n\nimport type { IParser } from './IParser.js';\nimport type { ContentUnit } from '../types.js';\nimport { serializeOpeningTag, VOID_TAGS } from '../canonical-tag.js';\n\ninterface TagMatch {\n tag: string;\n attrs: Record<string, string>;\n isClosing: boolean;\n isSelfClosing: boolean;\n startIndex: number;\n endIndex: number;\n}\n\n/**\n * Parser that converts HTML markup strings to ContentUnit (raw-only).\n *\n * @example\n * ```typescript\n * const parser = new MarkupParser();\n * parser.parse('Read our <b>Terms</b>.');\n * // \u2192 { text: 'Read our <1>Terms</1>.', styles: { '1': ['raw:<b>'] } }\n * ```\n */\n/**\n * Decode named + numeric HTML entities to their literal Unicode characters.\n *\n * Why: the parser may be fed strings from several sources that historically\n * encoded entities differently \u2014 developer-authored JSX strings (`<Trans\n * defaultValue=\"It&apos;s working\">`), cached translation values that came\n * through `tHtml`, or server-rendered HTML processed by edge/WP. The other\n * three parsers in the stack (browser DOM, edge regex, PHP regex) all see\n * decoded characters by the time they hash. Decoding here so this parser\n * does too keeps `auto_` keys consistent across every entry point. Decode\n * is a no-op for entity-free input, which is the overwhelmingly common\n * case in JSX where developers type literal characters.\n *\n * Covers the named entities WordPress's wptexturize commonly emits plus\n * all numeric forms (`&#NNN;` / `&#xHHH;`). Anything else is left alone.\n */\nfunction decodeEntities(text: string): string {\n const named: Record<string, string> = {\n amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\", nbsp: ' ',\n rsquo: '\u2019', lsquo: '\u2018', rdquo: '\u201D', ldquo: '\u201C',\n hellip: '\u2026', mdash: '\u2014', ndash: '\u2013', copy: '\u00A9',\n reg: '\u00AE', trade: '\u2122',\n };\n return text.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z][a-z0-9]*);/gi, (m, body) => {\n if (body[0] === '#') {\n const cp = body[1] === 'x' || body[1] === 'X'\n ? parseInt(body.slice(2), 16)\n : parseInt(body.slice(1), 10);\n if (Number.isFinite(cp) && cp > 0) {\n try { return String.fromCodePoint(cp); } catch { return m; }\n }\n return m;\n }\n return named[body.toLowerCase()] ?? m;\n });\n}\n\nexport class MarkupParser implements IParser<string> {\n parse(input: string): ContentUnit {\n // Already indexed tags from server \u2014 still decode entities so the text\n // hashes identically regardless of which path produced it.\n if (/<\\/?[0-9]+>/.test(input)) {\n return { text: decodeEntities(input), styles: {} };\n }\n\n const styles: Record<string, string[]> = {};\n let tagIndex = 0;\n const tagStack: Array<{ tag: string; index: number }> = [];\n let result = '';\n let pos = 0;\n\n while (pos < input.length) {\n const tag = this.matchTag(input, pos);\n if (!tag) {\n result += input.slice(pos);\n break;\n }\n\n result += input.slice(pos, tag.startIndex);\n\n if (tag.isClosing) {\n let matchIdx: number | null = null;\n for (let i = tagStack.length - 1; i >= 0; i--) {\n if (tagStack[i].tag === tag.tag.toLowerCase()) {\n matchIdx = tagStack[i].index;\n tagStack.splice(i, 1);\n break;\n }\n }\n if (matchIdx !== null) {\n result += `</${matchIdx}>`;\n }\n // Stray close \u2014 drop.\n } else {\n const tagName = tag.tag.toLowerCase();\n const isVoid = VOID_TAGS.has(tagName);\n const isSelfClosing = tag.isSelfClosing || isVoid;\n\n tagIndex++;\n styles[String(tagIndex)] = [`raw:${serializeOpeningTag(tagName, tag.attrs)}`];\n\n if (isSelfClosing) {\n result += `<${tagIndex}/>`;\n } else {\n result += `<${tagIndex}>`;\n tagStack.push({ tag: tagName, index: tagIndex });\n }\n }\n\n pos = tag.endIndex;\n }\n\n while (tagStack.length > 0) {\n const unclosed = tagStack.pop()!;\n result += `</${unclosed.index}>`;\n }\n\n return { text: decodeEntities(result), styles };\n }\n\n private matchTag(input: string, startPos: number): TagMatch | null {\n const tagStart = input.indexOf('<', startPos);\n if (tagStart === -1) return null;\n\n const tagPattern =\n /^<(\\/?)([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z][a-zA-Z0-9-]*(?:=(?:\"[^\"]*\"|'[^']*'|[^\\s>]*))?)*)\\s*(\\/?)>/;\n const remaining = input.slice(tagStart);\n const match = remaining.match(tagPattern);\n\n if (!match) {\n if (tagStart + 1 < input.length) {\n return this.matchTag(input, tagStart + 1);\n }\n return null;\n }\n\n const [fullMatch, closingSlash, tagName, attrsString, selfClosingSlash] = match;\n return {\n tag: tagName,\n attrs: this.parseAttributes(attrsString),\n isClosing: closingSlash === '/',\n isSelfClosing: selfClosingSlash === '/',\n startIndex: tagStart,\n endIndex: tagStart + fullMatch.length,\n };\n }\n\n private parseAttributes(attrsString: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n if (!attrsString.trim()) return attrs;\n\n const attrPattern = /([a-zA-Z][a-zA-Z0-9-]*)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]*)))?/g;\n let match;\n while ((match = attrPattern.exec(attrsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, unquoted] = match;\n attrs[name.toLowerCase()] = doubleQuoted ?? singleQuoted ?? unquoted ?? '';\n }\n return attrs;\n }\n}\n", "/**\n * Shared allowlist HTML sanitizer \u2014 pure string functions, Node-safe (no DOM).\n *\n * One implementation for every sink that turns translation data into HTML:\n * core's HTMLSerializer/auto-translator, the editor text sinks, the snapshot\n * viewer, react `<Trans>`, and WordPress TS. The WordPress PHP port must\n * mirror `SAFE_TAGS`/`SAFE_ATTRS` exactly (see improvement-plan \u00A74 item 2).\n *\n * Threat model: translation values (and their `raw:` styles) come from the\n * server/KV and may be attacker-controlled \u2014 they are NOT guaranteed to be in\n * canonical form. Everything here is allowlist-based: unknown tags are\n * rejected, unknown attributes dropped, URL schemes checked after entity\n * decoding.\n *\n * @module content/sanitizer/HTMLSanitizer\n */\n\nimport { extractTagName, readRawStyle, serializeOpeningTag } from '../canonical-tag.js';\nimport type { ContentUnit } from '../types.js';\n\n/**\n * Inline formatting elements allowed inside translated content. Block\n * structure lives outside ContentUnit (block-level pipeline), so anything\n * that isn't inline text formatting is rejected outright.\n */\nexport const SAFE_TAGS = new Set([\n 'a', 'abbr', 'b', 'bdi', 'bdo', 'br', 'cite', 'code', 'del', 'dfn',\n 'em', 'i', 'img', 'ins', 'kbd', 'mark', 'q', 's', 'samp', 'small',\n 'span', 'strong', 'sub', 'sup', 'time', 'u', 'var', 'wbr',\n]);\n\n/**\n * Flat attribute allowlist (plus `data-*`/`aria-*` prefixes, handled in\n * `sanitizeOpeningTag`). Kept flat \u2014 not per-tag \u2014 so the PHP mirror stays\n * trivial; an allowed attribute on the wrong tag is inert.\n */\nexport const SAFE_ATTRS = new Set([\n 'alt', 'cite', 'class', 'datetime', 'dir', 'height', 'href', 'id',\n 'lang', 'loading', 'rel', 'role', 'src', 'target', 'title', 'width',\n]);\n\n/** Attributes whose values are URLs and must pass `sanitizeUrl`. */\nconst URL_ATTRS = new Set(['href', 'src', 'cite']);\n\n/**\n * CSS properties allowed through an inline `style` attribute.\n *\n * RISK NOTE \u2014 why `style` never passes through verbatim: with zero\n * JavaScript, an attacker who controls a style value can render a\n * full-viewport overlay (`position:fixed;inset:0` \u2192 pixel-perfect fake\n * login UI on the customer's real domain), fire tracking/exfiltration\n * beacons via `url(...)`, or hide and deface content. Translation data is\n * attacker-writable in our threat model, so `sanitizeStyle` re-parses the\n * declarations and keeps only the properties below: cosmetic text/font\n * properties whose value grammar cannot fetch a URL and cannot reposition\n * or restack the element (no `position`/`inset`/`display`/`z-index`/\n * `opacity`/`transform`, no `background` shorthand). A smuggled `url(...)`\n * inside an allowed property is doubly inert: the value is rejected here,\n * and these properties ignore URL values anyway.\n *\n * CONTINUOUS DEVELOPMENT: this allowlist is intentionally minimal and is\n * expected to grow deliberately as real sites surface legitimate inline\n * styling the strict set drops (tracked as a WATCH item in\n * IMPLEMENTATION.md). When extending it: (1) never add a property that\n * accepts `url()`/`image()`/`element()` values or that affects layout,\n * positioning, or stacking; (2) add both hostile and benign cases to\n * html-sanitizer.test.ts; (3) mirror the change in the WordPress PHP port.\n */\nexport const SAFE_STYLE_PROPS = new Set([\n 'color', 'background-color', 'font-family', 'font-size', 'font-style',\n 'font-weight', 'letter-spacing', 'line-height', 'text-decoration',\n 'text-decoration-color', 'text-decoration-line', 'text-decoration-style',\n 'text-transform', 'vertical-align', 'white-space', 'word-spacing',\n]);\n\n/**\n * Value-level rejections inside an otherwise-allowed declaration: URL/code\n * carriers, and backslashes because CSS escape sequences (`\\75\\72\\6c`)\n * can spell `url(` past a textual check.\n */\nconst DANGEROUS_CSS_VALUE =\n /url\\s*\\(|expression\\s*\\(|image-set\\s*\\(|element\\s*\\(|paint\\s*\\(|javascript:|\\\\|[<>{}@]/i;\n\nconst SAFE_SCHEMES = new Set(['http', 'https', 'mailto', 'tel']);\n\n/**\n * The named entities that matter for scheme smuggling (`&colon;`, `&Tab;`)\n * plus the basic set. Names are case-sensitive, as in HTML.\n */\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\", nbsp: '\u00A0',\n colon: ':', semi: ';', sol: '/', bsol: '\\\\',\n Tab: '\\t', NewLine: '\\n',\n};\n\n/**\n * Decode entities exactly once \u2014 mirroring the single decode a browser does\n * when parsing an attribute value out of HTML.\n */\nfunction decodeEntities(value: string): string {\n return value.replace(\n /&(?:#[xX]([0-9a-fA-F]+);?|#(\\d+);?|([a-zA-Z]+);)/g,\n (full, hex: string, dec: string, name: string) => {\n if (hex) return String.fromCodePoint(parseInt(hex, 16));\n if (dec) return String.fromCodePoint(parseInt(dec, 10));\n return NAMED_ENTITIES[name] ?? full;\n },\n );\n}\n\n/** HTML-escape text for safe use in element content or attribute values. */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/**\n * Validate a URL attribute value. Returns the value unchanged when safe,\n * or `null` when it must be dropped.\n *\n * Entity-decodes first, then strips the control/whitespace characters\n * browsers ignore inside a scheme (`jav\\tascript:`), then requires any\n * explicit scheme to be on the allowlist. Scheme-less (relative) URLs pass.\n */\nexport function sanitizeUrl(value: string): string | null {\n const decoded = decodeEntities(value);\n // eslint-disable-next-line no-control-regex -- stripping C0 controls/space/DEL is the point\n const probe = decoded.replace(/[\\u0000-\\u0020\\u007f]/g, '').toLowerCase();\n const scheme = /^([a-z][a-z0-9+.-]*):/.exec(probe);\n if (!scheme) return value;\n return SAFE_SCHEMES.has(scheme[1]) ? value : null;\n}\n\n/**\n * Sanitize an inline `style` attribute value by re-parsing its declarations\n * and keeping only `SAFE_STYLE_PROPS` with clean values (see the risk note\n * on `SAFE_STYLE_PROPS`). Returns the rebuilt declaration list in canonical\n * `prop: value; prop: value` form, or `null` when nothing survives \u2014 the\n * caller then drops the attribute entirely.\n */\nexport function sanitizeStyle(value: string): string | null {\n return filterCssDeclarations(value, true);\n}\n\n/**\n * Relaxed CSS profile for the snapshot viewer: keeps ANY standard property\n * (a snapshot is a full captured page \u2014 `position:fixed` navbars and layout\n * styles are legitimate and must render) but still rejects value-level\n * dangers: `url(...)` beacons, `expression()`, CSS escape smuggling. The\n * residual risk (page-authored overlay styles) is accepted for snapshots:\n * the PM is deliberately viewing arbitrary captured pages, and the editor\n * UI itself lives in a Shadow DOM host stacked above the snapshot root.\n */\nexport function sanitizeCssDeclarations(value: string): string | null {\n return filterCssDeclarations(value, false);\n}\n\nfunction filterCssDeclarations(\n value: string,\n requirePropAllowlist: boolean,\n): string | null {\n const decoded = decodeEntities(value);\n const kept: string[] = [];\n for (const declaration of decoded.split(';')) {\n const colon = declaration.indexOf(':');\n if (colon === -1) continue;\n const prop = declaration.slice(0, colon).trim().toLowerCase();\n const val = declaration.slice(colon + 1).trim();\n if (!/^[a-z-]+$/.test(prop)) continue; // also blocks --custom-prop indirection\n if (requirePropAllowlist && !SAFE_STYLE_PROPS.has(prop)) continue;\n if (val === '' || DANGEROUS_CSS_VALUE.test(val)) continue;\n kept.push(`${prop}: ${val}`);\n }\n return kept.length > 0 ? kept.join('; ') : null;\n}\n\n/**\n * Attribute scanner for a (possibly hostile, non-canonical) opening tag.\n * Handles double-quoted, single-quoted, unquoted, and bare boolean attrs.\n */\nconst ATTR_PATTERN =\n /([^\\s=/>\"']+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]*)))?/g;\n\n/**\n * Sanitize a raw opening tag (`raw:` style payload). Returns the canonical\n * rebuilt tag with only allowlisted attributes, or `null` when the element\n * itself is not allowed \u2014 callers must then drop the tag entirely (emit the\n * indexed marker verbatim / skip the element).\n */\nexport function sanitizeOpeningTag(rawOpen: string): string | null {\n if (!rawOpen.startsWith('<')) return null;\n const tagName = extractTagName(rawOpen);\n if (!/^[a-z][a-z0-9-]*$/.test(tagName) || !SAFE_TAGS.has(tagName)) {\n return null;\n }\n\n // The slice between `<tagname` and the closing `>` (or end of string \u2014\n // hostile input may be truncated).\n const end = rawOpen.endsWith('/>')\n ? rawOpen.length - 2\n : rawOpen.endsWith('>')\n ? rawOpen.length - 1\n : rawOpen.length;\n const attrSource = rawOpen.slice(1 + tagName.length, end);\n\n const attrs: Record<string, string> = {};\n for (const match of attrSource.matchAll(ATTR_PATTERN)) {\n const name = match[1].toLowerCase();\n const value = match[2] ?? match[3] ?? match[4] ?? '';\n if (name in attrs) continue; // first occurrence wins, as in HTML\n if (name === 'style') {\n // Never verbatim \u2014 re-parsed against the CSS property allowlist.\n const cleanStyle = sanitizeStyle(value);\n if (cleanStyle !== null) attrs[name] = cleanStyle;\n continue;\n }\n const allowed =\n SAFE_ATTRS.has(name) ||\n /^data-[a-z0-9-]*$/.test(name) ||\n /^aria-[a-z0-9-]*$/.test(name);\n if (!allowed) continue;\n if (URL_ATTRS.has(name)) {\n if (sanitizeUrl(value) === null) continue;\n }\n attrs[name] = value;\n }\n\n return serializeOpeningTag(tagName, attrs);\n}\n\n/**\n * Sanitize a ContentUnit at an ingest boundary: run every `raw:` style\n * through {@link sanitizeOpeningTag} so no dangerous element/attribute/scheme\n * enters the translation store. Render-time sinks (HTMLSerializer etc.)\n * sanitize again \u2014 this is the store-side half, protecting every other\n * consumer of stored units (server, MT/TM, exports, the WP PHP port).\n *\n * `text` is never modified, so `generateAutoKey(unit.text)` is unaffected \u2014\n * key parity across surfaces holds even for hostile input. A rejected\n * element's `raw:` style is dropped entirely; the indexed tag left in the\n * text is emitted by serializers as an inert marker. Returns the SAME object\n * when nothing changed, so benign units round-trip identically.\n */\nexport function sanitizeContentUnit(unit: ContentUnit): ContentUnit {\n let changed = false;\n const styles: Record<string, string[]> = {};\n\n for (const [index, styleList] of Object.entries(unit.styles)) {\n const raw = readRawStyle(styleList);\n if (raw === null) {\n styles[index] = styleList; // no raw tag \u2192 nothing to sanitize\n continue;\n }\n const safe = sanitizeOpeningTag(raw);\n if (safe === null) {\n // Element rejected \u2014 drop the raw style (keep any non-raw entries).\n changed = true;\n const rest = styleList.filter((s) => !s.startsWith('raw:'));\n if (rest.length > 0) styles[index] = rest;\n } else if (safe === raw) {\n styles[index] = styleList;\n } else {\n changed = true;\n styles[index] = styleList.map((s) => (s.startsWith('raw:') ? `raw:${safe}` : s));\n }\n }\n\n return changed ? { text: unit.text, styles } : unit;\n}\n", "/**\n * HTML serializer \u2014 converts ContentUnit back to HTML strings (raw-only).\n *\n * Every indexed tag carries a `raw:<opening tag>` style. The serializer\n * routes the stored opening tag through the shared allowlist sanitizer and\n * derives the close tag from the embedded tag name. Void elements get no\n * close tag. Text segments are HTML-escaped (ContentUnit.text holds decoded\n * Unicode \u2014 see MarkupParser.decodeEntities), so serializer output is inert\n * even when the translation value is attacker-controlled. `ContentUnit.text`\n * itself is never modified \u2014 auto_key hashing is unaffected.\n *\n * @module content/serializer/HTMLSerializer\n */\n\nimport type { ISerializer } from './ISerializer.js';\nimport type { ContentUnit } from '../types.js';\nimport { extractTagName, readRawStyle, VOID_TAGS } from '../canonical-tag.js';\nimport { escapeHtml, sanitizeOpeningTag } from '../sanitizer/HTMLSanitizer.js';\n\n/**\n * Serializer that converts ContentUnit format back to HTML strings.\n *\n * @example\n * ```typescript\n * const serializer = new HTMLSerializer();\n * serializer.serialize({\n * text: 'Read our <1>Terms</1>.',\n * styles: { '1': ['raw:<b>'] }\n * });\n * // \u2192 'Read our <b>Terms</b>.'\n * ```\n */\nexport class HTMLSerializer implements ISerializer<string> {\n serialize(unit: ContentUnit): string {\n const { text, styles } = unit;\n const tagPattern = /<(\\/?)?(\\d+)(\\/)?>/g;\n\n let result = '';\n let lastIndex = 0;\n let match;\n\n while ((match = tagPattern.exec(text)) !== null) {\n result += escapeHtml(text.slice(lastIndex, match.index));\n\n const [fullMatch, closingSlash, indexStr] = match;\n const styleList = styles[indexStr] ?? [];\n const rawOpen = readRawStyle(styleList);\n const safeOpen = rawOpen === null ? null : sanitizeOpeningTag(rawOpen);\n\n if (rawOpen && safeOpen !== null) {\n const tagName = extractTagName(rawOpen);\n const isVoid = VOID_TAGS.has(tagName);\n\n if (closingSlash) {\n if (!isVoid) result += `</${tagName}>`;\n } else {\n // Both <N> and <N/> emit the opening tag. For void tags that's the\n // complete element.\n result += safeOpen;\n }\n } else {\n // No raw style, or the sanitizer rejected the element \u2014 preserve the\n // indexed marker (parses as inert text) so the problem is visible\n // rather than silently dropping content, and never emit a close tag\n // for a rejected element.\n result += fullMatch;\n }\n\n lastIndex = match.index + fullMatch.length;\n }\n\n result += escapeHtml(text.slice(lastIndex));\n return result;\n }\n}\n", "/**\n * CacheManager - TanStack Query-inspired cache management\n *\n * Provides unified cache invalidation and optimistic update patterns.\n */\n\nimport type { EventEmitter } from '../base/event-emitter.js';\nimport type { HandlerChain } from '../handlers/handler-chain.js';\n\n/**\n * Options for cache invalidation (like TanStack's invalidateQueries)\n */\nexport interface InvalidateOptions {\n /** Invalidate by namespace */\n namespace?: string;\n /** Invalidate by locale */\n locale?: string;\n /** Invalidate specific key */\n key?: string;\n /** Custom predicate filter */\n predicate?: (key: string) => boolean;\n /** Whether to refetch after invalidation (default: true) */\n refetch?: boolean;\n}\n\n/**\n * Cached translation entry\n */\nexport interface CacheEntry {\n value: string;\n styles?: Record<string, string[]>;\n}\n\n/**\n * Cache event payloads\n */\nexport interface CacheEventPayloads {\n 'cache:invalidate': {\n filter: InvalidateOptions;\n keysCleared: number;\n refetch: boolean;\n };\n 'cache:set': {\n key: string;\n value: string;\n styles?: Record<string, string[]>;\n optimistic: boolean;\n };\n 'cache:rollback': {\n key: string;\n reason: string;\n };\n}\n\n/**\n * CacheManager - Unified cache API inspired by TanStack Query\n *\n * @example\n * ```typescript\n * // Invalidate by namespace\n * await i18n.cache.invalidate({ namespace: 'app' });\n *\n * // Optimistic update\n * const previous = i18n.cache.get('en:app:welcome');\n * i18n.cache.set('en:app:welcome', 'New value');\n * // ... if error, rollback:\n * i18n.cache.set('en:app:welcome', previous.value);\n * ```\n */\nexport class CacheManager {\n private handlerChain: HandlerChain;\n private bus: EventEmitter;\n private currentLocale: () => string;\n private loadNamespaces: (locale: string, namespaces: string[]) => Promise<void>;\n\n constructor(\n handlerChain: HandlerChain,\n bus: EventEmitter,\n getCurrentLocale: () => string,\n loadNamespaces: (locale: string, namespaces: string[]) => Promise<void>\n ) {\n this.handlerChain = handlerChain;\n this.bus = bus;\n this.currentLocale = getCurrentLocale;\n this.loadNamespaces = loadNamespaces;\n }\n\n /**\n * Get a cached translation entry\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @returns Cache entry with value and styles, or null if not found\n */\n get(key: string): CacheEntry | null {\n const entries = this.handlerChain.getEntries();\n\n // Search through all handler entries\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n if (key in handlerEntries) {\n const rawValue = handlerEntries[key];\n\n // Parse ContentUnit JSON (stored as { text, styles })\n try {\n if (typeof rawValue === 'string') {\n const parsed = JSON.parse(rawValue);\n if (typeof parsed === 'object' && 'text' in parsed) {\n return {\n value: String(parsed.text),\n styles: parsed.styles || undefined,\n };\n }\n // Legacy plain string\n return { value: rawValue, styles: undefined };\n }\n // Already an object\n return {\n value: JSON.stringify(rawValue),\n styles: undefined,\n };\n } catch {\n // If parse fails, treat as plain string\n return {\n value: typeof rawValue === 'string' ? rawValue : JSON.stringify(rawValue),\n styles: undefined,\n };\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Set a cache entry (for optimistic updates)\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @param value - Translation value\n * @param styles - Optional styles for indexed tags\n */\n set(key: string, value: string, styles?: Record<string, string[]>): void {\n // Parse the key to get locale, namespace, and translation key\n const [locale, namespace, ...keyParts] = key.split(':');\n const translationKey = keyParts.join(':');\n\n if (!locale || !namespace || !translationKey) {\n throw new Error(\n `Invalid cache key format: \"${key}\". Expected format: \"locale:namespace:key\"`\n );\n }\n\n // Use the handler chain's setCache method for optimistic updates\n this.handlerChain.setCache(key, value, styles);\n\n // Emit cache:set event\n this.bus.emit('cache:set', {\n payload: {\n key,\n value,\n styles,\n optimistic: true,\n },\n });\n }\n\n /**\n * Check if a key exists in cache\n *\n * @param key - Full cache key (e.g., 'en:app:welcome')\n * @returns true if key is cached\n */\n has(key: string): boolean {\n return this.get(key) !== null;\n }\n\n /**\n * Invalidate cache entries and optionally refetch\n *\n * Like TanStack Query's invalidateQueries, this clears matching cache entries\n * and triggers background refetch by default.\n *\n * @param options - Filter options for invalidation\n *\n * @example\n * ```typescript\n * // Invalidate all\n * await cache.invalidate();\n *\n * // Invalidate by namespace\n * await cache.invalidate({ namespace: 'app' });\n *\n * // Invalidate by locale\n * await cache.invalidate({ locale: 'es' });\n *\n * // Invalidate specific key\n * await cache.invalidate({ key: 'en:app:welcome' });\n *\n * // Invalidate with predicate\n * await cache.invalidate({ predicate: (k) => k.includes('common:') });\n *\n * // Invalidate without refetch\n * await cache.invalidate({ namespace: 'app', refetch: false });\n * ```\n */\n async invalidate(options: InvalidateOptions = {}): Promise<void> {\n const { namespace, locale, key, predicate, refetch = true } = options;\n const currentLocale = this.currentLocale();\n\n let keysCleared = 0;\n\n // Determine what to clear\n if (key) {\n // Clear specific key\n const [keyLocale, keyNamespace] = key.split(':');\n if (keyLocale && keyNamespace) {\n this.handlerChain.clearNamespace(keyLocale, keyNamespace);\n keysCleared = 1;\n }\n } else if (namespace && locale) {\n // Clear specific locale + namespace\n this.handlerChain.clearNamespace(locale, namespace);\n keysCleared = this.countClearedKeys(locale, namespace);\n } else if (namespace) {\n // Clear namespace for current locale\n this.handlerChain.clearNamespace(currentLocale, namespace);\n keysCleared = this.countClearedKeys(currentLocale, namespace);\n } else if (locale) {\n // Clear all namespaces for a specific locale\n const entries = this.handlerChain.getEntries();\n const namespacesToClear = new Set<string>();\n\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n for (const entryKey of Object.keys(handlerEntries)) {\n if (entryKey.startsWith(`${locale}:`) || entryKey.startsWith(`@${locale}:`)) {\n const parts = entryKey.replace('@', '').split(':');\n if (parts[1]) {\n namespacesToClear.add(parts[1]);\n }\n }\n }\n }\n }\n\n for (const ns of namespacesToClear) {\n this.handlerChain.clearNamespace(locale, ns);\n keysCleared++;\n }\n } else if (predicate) {\n // Clear with custom predicate\n const entries = this.handlerChain.getEntries();\n const toClear = new Map<string, Set<string>>(); // locale -> namespaces\n\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n for (const entryKey of Object.keys(handlerEntries)) {\n if (predicate(entryKey)) {\n const parts = entryKey.replace('@', '').split(':');\n const entryLocale = parts[0];\n const entryNs = parts[1];\n if (entryLocale && entryNs) {\n if (!toClear.has(entryLocale)) {\n toClear.set(entryLocale, new Set());\n }\n toClear.get(entryLocale)!.add(entryNs);\n keysCleared++;\n }\n }\n }\n }\n }\n\n for (const [loc, namespaces] of toClear) {\n for (const ns of namespaces) {\n this.handlerChain.clearNamespace(loc, ns);\n }\n }\n } else {\n // Clear all\n this.handlerChain.clearCache();\n keysCleared = -1; // Indicates all cleared\n }\n\n // Emit invalidate event\n this.bus.emit('cache:invalidate', {\n payload: {\n filter: options,\n keysCleared,\n refetch,\n },\n });\n\n // Refetch if requested\n if (refetch) {\n await this.refetchAfterInvalidate(options);\n }\n }\n\n /**\n * Count keys that would be cleared (for event reporting)\n */\n private countClearedKeys(locale: string, namespace: string): number {\n const entries = this.handlerChain.getEntries();\n let count = 0;\n const prefix = `${locale}:${namespace}:`;\n const namespaceKey = `@${locale}:${namespace}`;\n\n for (const handlerName in entries) {\n const handlerEntries = entries[handlerName];\n if (handlerEntries && typeof handlerEntries === 'object') {\n for (const key of Object.keys(handlerEntries)) {\n if (key.startsWith(prefix) || key === namespaceKey) {\n count++;\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Refetch data after invalidation\n */\n private async refetchAfterInvalidate(options: InvalidateOptions): Promise<void> {\n const { namespace, locale, key } = options;\n const currentLocale = this.currentLocale();\n\n if (key) {\n // Refetch specific namespace from key\n const [keyLocale, keyNamespace] = key.split(':');\n if (keyLocale && keyNamespace) {\n await this.loadNamespaces(keyLocale, [keyNamespace]);\n }\n } else if (namespace) {\n // Refetch namespace for specific or current locale\n await this.loadNamespaces(locale || currentLocale, [namespace]);\n } else if (locale) {\n // For locale-wide invalidation, we can't easily know which namespaces to reload\n // The app will lazy-load them as needed\n }\n // For full cache clear, lazy loading will handle refetch\n }\n}\n", "/**\n * Enhanced LionRapid Core with event-based language change and smart caching\n * filepath: /home/janrau/tm-integration/packages/core/src/lionRapid.ts\n */\nimport { EventEmitter } from './base/event-emitter.js';\nimport { HandlerChain } from './handlers/handler-chain.js';\nimport type {\n FormatterFunction,\n IEmbeddedPlugin,\n IPlugin,\n ValueProcessor,\n} from './interfaces/plugin.interface.js';\nimport type { TranslationKeys } from './types/generated.types.js';\nimport type { TranslationRequest } from './types/translation.types.js';\nimport { logger, resolveNestedKey } from './utils/index.js';\nimport { prepareTranslationRequest } from './utils/translation-flow.js';\nimport { createNamespaceCacheKey } from './utils/translation-value-utils.js';\n\n// Content module imports for ContentUnit processing\nimport type { ContentUnit } from './content/types.js';\nimport { MarkupParser } from './content/parser/MarkupParser.js';\nimport { HTMLSerializer } from './content/serializer/HTMLSerializer.js';\n\n// Cache module\nimport { CacheManager } from './cache/CacheManager.js';\n\n/**\n * Regex to detect indexed tags in a string (from server ContentUnit)\n * Matches patterns like <1>, </1>, <2>, </2>, etc.\n */\nconst INDEXED_TAG_REGEX = /<\\/?[0-9]+\\/?>/;\n\n/**\n * Regex to detect HTML tags in a string\n * Matches patterns like <b>, <a href=\"...\">, <em>, etc.\n */\nconst HTML_TAG_REGEX = /<[a-z][a-z0-9]*(?:\\s+[^>]*)?\\/?>/i;\n\nexport class LionRapidCore {\n private handlerChain: HandlerChain;\n private currentLocale: string;\n private defaultNamespace?: string;\n private pendingTranslations = new Map<string, Promise<void>>();\n bus: EventEmitter;\n\n private plugins = new Map<string, IPlugin>();\n\n // \uD83D\uDD25 EMBEDDED: Core integration maps\n private formatters = new Map<string, FormatterFunction>();\n private processors = new Map<string, ValueProcessor>();\n private warnedNoInterpolate = false;\n\n // \uD83D\uDCE1 EVENT-DRIVEN: Just track for cleanup\n private eventPlugins = new Set<IPlugin>();\n\n // \uD83D\uDCE6 CONTENT: Parser and serializer for ContentUnit processing\n private readonly markupParser = new MarkupParser();\n private readonly htmlSerializer = new HTMLSerializer();\n\n // \uD83D\uDD04 CACHE: TanStack Query-inspired cache management\n public readonly cache: CacheManager;\n\n constructor(\n eventEmitter: EventEmitter,\n handlerChain: HandlerChain,\n defaultLocale = 'en',\n defaultNamespace?: string\n ) {\n this.bus = eventEmitter;\n this.handlerChain = handlerChain;\n this.currentLocale = defaultLocale;\n this.defaultNamespace = defaultNamespace;\n\n // Initialize cache manager with dependencies\n this.cache = new CacheManager(\n this.handlerChain,\n this.bus,\n () => this.currentLocale,\n (locale, namespaces) => this.loadNamespaces(locale, namespaces)\n );\n }\n\n /**\n * \u2705 Register plugin (called by builder)\n */\n registerPlugin(plugin: IPlugin): void {\n this.plugins.set(plugin.name, plugin);\n\n // \uD83D\uDD25 EMBEDDED PLUGINS: Extract functionality for core integration\n if (this.isEmbeddedPlugin(plugin)) {\n this.integrateEmbeddedPlugin(plugin as IEmbeddedPlugin);\n }\n\n // \uD83D\uDCE1 EVENT-DRIVEN PLUGINS: Just track for cleanup\n if (this.isEventPlugin(plugin)) {\n this.eventPlugins.add(plugin);\n }\n }\n\n /**\n * \uD83D\uDD25 EMBEDDED: Integrate plugin functionality into core\n */\n private integrateEmbeddedPlugin(plugin: IEmbeddedPlugin): void {\n // Extract formatters\n if (plugin.getFormatters) {\n const pluginFormatters = plugin.getFormatters();\n Object.entries(pluginFormatters).forEach(([name, formatter]) => {\n this.formatters.set(name, formatter);\n logger.debug(`Embedded formatter: ${name} from ${plugin.name}`);\n });\n }\n\n // Extract processors\n if (plugin.getProcessors) {\n const pluginProcessors = plugin.getProcessors();\n Object.entries(pluginProcessors).forEach(([name, processor]) => {\n this.processors.set(name, processor);\n logger.debug(`Embedded processor: ${name} from ${plugin.name}`);\n });\n }\n }\n\n /**\n * \uD83D\uDCE6 TRANSLATION API - Returns PLAIN TEXT\n *\n * Strips indexed tags and returns safe plain text output.\n * For HTML output with styles, use tHtml() instead.\n *\n * @param key - Translation key\n * @param params - Optional interpolation parameters\n * @param defaultValue - Optional default value\n * @returns Plain text string (safe, no XSS risk)\n *\n * @example\n * ```typescript\n * t('welcome') // \u2192 \"Hello World\"\n * t('greeting', { name: 'John' }) // \u2192 \"Hello John\"\n * t('missing', 'Default text') // \u2192 \"Default text\" (if key missing)\n * ```\n */\n t<K extends string>(\n key: K,\n ...args: K extends keyof TranslationKeys\n ? TranslationKeys[K] extends Record<string, never>\n ? [defaultValue?: string]\n : [params: TranslationKeys[K], defaultValue?: string]\n : [params?: Record<string, unknown>, defaultValue?: string]\n ): string {\n const [firstArg, secondArg] = args;\n\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n firstArg as string | Record<string, unknown> | undefined,\n secondArg as Record<string, unknown> | string | undefined,\n this.defaultNamespace\n );\n\n // Emit request event\n logger.debug(`Translation requested: ${request.cleanKey}`);\n const translateBus = this.bus.translation(request);\n translateBus.request();\n\n // Try memory cache (sync)\n const syncResult = this.handlerChain.handleSync(request);\n if (syncResult && syncResult.status === 200) {\n const result = this.processValue(syncResult.value, request);\n logger.debug(\n `Translation found: ${request.cleanKey} from ${syncResult.source} (${syncResult.duration}ms)`\n );\n translateBus.success(result);\n return result;\n }\n\n // Cache miss - trigger background load\n this.triggerBackgroundLoad(request);\n\n // Return fallback immediately\n const fallbackValue = request.parsedDefaultValue || request.cleanKey;\n const fallbackResult = this.processValue(fallbackValue, request);\n logger.debug(`Translation fallback: ${request.cleanKey}`);\n translateBus.fallback(fallbackResult);\n return fallbackResult;\n }\n\n /**\n * \uD83D\uDCE6 HTML TRANSLATION API\n * Returns translation as HTML string with styles applied.\n *\n * Use for innerHTML, dangerouslySetInnerHTML, or server-side rendering.\n * For React components, prefer using <Trans> instead.\n *\n * @param key - Translation key\n * @param params - Optional interpolation parameters\n * @param defaultValue - Optional default value (can contain HTML)\n * @returns HTML string with styles applied\n *\n * @example\n * ```typescript\n * // Vanilla JS\n * element.innerHTML = i18n.tHtml('welcome');\n * // \u2192 \"Hello <b>World</b>\"\n *\n * // React (use sparingly)\n * <span dangerouslySetInnerHTML={{ __html: tHtml('welcome') }} />\n * ```\n */\n tHtml<K extends string>(\n key: K,\n ...args: K extends keyof TranslationKeys\n ? TranslationKeys[K] extends Record<string, never>\n ? [defaultValue?: string]\n : [params: TranslationKeys[K], defaultValue?: string]\n : [params?: Record<string, unknown>, defaultValue?: string]\n ): string {\n // Pass arguments directly to prepareTranslationRequest\n // which handles the flexible parameter parsing\n const [firstArg, secondArg] = args;\n\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n firstArg as string | Record<string, unknown> | undefined,\n secondArg as Record<string, unknown> | string | undefined,\n this.defaultNamespace\n );\n\n // Emit request event\n logger.debug(`HTML translation requested: ${request.cleanKey}`);\n const translateBus = this.bus.translation(request);\n translateBus.request();\n\n // Try memory cache (sync) - result now includes styles\n const syncResult = this.handlerChain.handleSync(request);\n if (syncResult && syncResult.status === 200) {\n const result = this.processValueAsHtml(syncResult.value, request, syncResult.styles);\n logger.debug(\n `HTML translation found: ${request.cleanKey} from ${syncResult.source}`\n );\n translateBus.success(result);\n return result;\n }\n\n // Cache miss - trigger background load\n this.triggerBackgroundLoad(request);\n\n // Return fallback immediately (processed as HTML, no styles)\n const fallbackValue = request.parsedDefaultValue || request.cleanKey;\n const fallbackResult = this.processValueAsHtml(fallbackValue, request);\n logger.debug(`HTML translation fallback: ${request.cleanKey}`);\n translateBus.fallback(fallbackResult);\n return fallbackResult;\n }\n\n /**\n * \uD83D\uDCE6 Process value as HTML (for tHtml)\n *\n * Converts indexed tags to HTML using styles from result or namespace cache.\n *\n * @internal\n */\n private processValueAsHtml(\n value: string,\n request: TranslationRequest,\n resultStyles?: Record<string, string[]>\n ): string {\n // Process ICU first\n const processedText = this.processTranslationValue(value, request);\n\n // Check for indexed tags (from server ContentUnit)\n if (this.containsIndexedTags(processedText)) {\n // Use styles from result, or fall back to namespace lookup\n const styles = resultStyles || this.getStylesFromNamespace(request);\n const unit: ContentUnit = {\n text: processedText,\n styles,\n };\n return this.htmlSerializer.serialize(unit);\n }\n\n // Check for HTML in defaultValue\n if (this.containsHtml(processedText)) {\n const unit = this.markupParser.parse(processedText);\n return this.htmlSerializer.serialize(unit);\n }\n\n // Plain text - return as-is\n return processedText;\n }\n\n /**\n * \uD83D\uDCE6 Process a value through ContentUnit or ICU pipeline\n *\n * Processing priority:\n * 1. Indexed tags (<1>...</1>) from server ContentUnit \u2192 convert to HTML at render time\n * 2. HTML tags (from defaultValue or legacy) \u2192 MarkupParser \u2192 ContentUnit \u2192 HTML\n * 3. Plain text \u2192 standard ICU processing\n *\n * @internal\n */\n private processValue(value: string, request: TranslationRequest): string {\n // Priority 1: Check for indexed tags (from server ContentUnit)\n // These need to be converted to HTML using the stored styles\n if (this.containsIndexedTags(value)) {\n return this.processIndexedValue(value, request);\n }\n\n // Priority 2: Auto-detect HTML and process through ContentUnit if found\n if (this.containsHtml(value)) {\n return this.processHtmlValue(value, request);\n }\n\n // Priority 3: Standard ICU processing for plain text\n return this.processTranslationValue(value, request);\n }\n\n /**\n * \uD83D\uDCE6 Check if a string contains indexed tags\n *\n * Used for auto-detection of server ContentUnit format.\n *\n * @param value - String to check\n * @returns true if indexed tags are detected\n */\n private containsIndexedTags(value: string): boolean {\n return INDEXED_TAG_REGEX.test(value);\n }\n\n /**\n * \uD83D\uDCE6 Process indexed value - returns PLAIN TEXT\n *\n * Strips indexed tags (<1>text</1>) \u2192 \"text\"\n * For HTML output, use tHtml() instead.\n *\n * @internal\n */\n private processIndexedValue(\n value: string,\n request: TranslationRequest\n ): string {\n // 1. Process ICU first (with indexed tags intact)\n const processedText = this.processTranslationValue(value, request);\n\n // 2. Strip indexed tags - t() returns plain text\n return processedText.replace(/<\\/?[0-9]+\\/?>/g, '');\n }\n\n /**\n * \uD83D\uDCE6 Get styles for a translation key from namespace cache (fallback)\n *\n * Used when styles are not available in the result (e.g., for fallback values).\n * Looks up the full ContentUnit from the namespace cache to get styles.\n *\n * @internal\n */\n private getStylesFromNamespace(\n request: TranslationRequest\n ): Record<string, string[]> {\n if (!request.namespace) {\n return {};\n }\n\n try {\n // Get namespace cache key: @locale:namespace\n const namespaceCacheKey = createNamespaceCacheKey(\n request.locale,\n request.namespace\n );\n\n // Get namespace data from handler chain\n const namespaceData = this.handlerChain.getNamespaceData(namespaceCacheKey);\n if (!namespaceData) {\n return {};\n }\n\n // Resolve the content unit for this key (server always returns ContentUnit format)\n const resolved = resolveNestedKey(namespaceData, request.cleanKey);\n\n if (resolved && typeof resolved === 'object' && 'styles' in resolved) {\n const contentUnit = resolved as ContentUnit;\n return contentUnit.styles;\n }\n\n return {};\n } catch (error) {\n logger.debug(`Error getting styles for key ${request.cleanKey}:`, error);\n return {};\n }\n }\n\n /**\n * \uD83D\uDCE6 Process HTML value - returns PLAIN TEXT\n *\n * Parses HTML to ContentUnit, processes ICU, strips indexed tags.\n * For HTML output, use tHtml() instead.\n *\n * @internal\n */\n private processHtmlValue(value: string, request: TranslationRequest): string {\n try {\n // 1. Parse HTML to ContentUnit (converts HTML tags to indexed format)\n const unit = this.markupParser.parse(value);\n\n // 2. Process ICU expressions in the text\n const processedText = this.processTranslationValue(unit.text, request);\n\n // 3. Strip indexed tags - t() returns plain text\n return processedText.replace(/<\\/?[0-9]+\\/?>/g, '');\n } catch (error) {\n logger.warn(`ContentUnit processing failed for \"${value}\":`, error);\n // Fallback to standard processing\n return this.processTranslationValue(value, request);\n }\n }\n\n /**\n * \u2705 Process translation value through embedded plugins\n *\n * Public overload for Trans component usage (simple API)\n */\n public processTranslationValue(\n value: string,\n params?: Record<string, unknown>,\n locale?: string,\n key?: string\n ): string;\n\n /**\n * Internal overload (with full TranslationRequest for t() method)\n */\n public processTranslationValue(\n value: string,\n request: TranslationRequest\n ): string;\n\n /**\n * Implementation (handles both overloads)\n */\n public processTranslationValue(\n value: string,\n paramsOrRequest?: Record<string, unknown> | TranslationRequest,\n locale?: string,\n key?: string\n ): string {\n // Determine which overload was called\n let params: Record<string, unknown> | undefined;\n let resolvedLocale: string;\n let resolvedKey: string | undefined;\n\n if (paramsOrRequest && 'cleanKey' in paramsOrRequest) {\n // Internal overload: TranslationRequest\n const request = paramsOrRequest as TranslationRequest;\n params = request.parsedParams;\n resolvedLocale = request.locale;\n resolvedKey = request.cleanKey;\n } else {\n // Public overload: simple parameters\n params = paramsOrRequest as Record<string, unknown> | undefined;\n resolvedLocale = locale || this.currentLocale;\n resolvedKey = key;\n }\n\n let processedValue = value;\n\n try {\n // \u2705 Step 1: Handle structured translation data (plurals, context variations)\n processedValue = this.applyStructuralFormatters(\n processedValue,\n params,\n resolvedKey\n );\n\n // \u2705 Step 2: Apply interpolation through embedded formatter plugin\n // ICU messages need processing even without params (for 'other' defaults)\n if (this.formatters.has('interpolate')) {\n const interpolateFormatter = this.formatters.get('interpolate')!;\n processedValue = interpolateFormatter(\n processedValue,\n params,\n resolvedLocale,\n resolvedKey\n );\n } else if (\n !this.warnedNoInterpolate &&\n params &&\n Object.keys(params).length > 0 &&\n processedValue.includes('{')\n ) {\n // Params against a {placeholder} string with nothing to interpolate:\n // without this, the miswiring is invisible and the SDK looks broken.\n this.warnedNoInterpolate = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[LionRapid] Translation params were passed but no interpolate ' +\n 'formatter is registered \u2014 {placeholders} render literally. ' +\n 'Install @lionrapid/formatters and add .use(coreFormattersPlugin) ' +\n 'to the builder.'\n );\n }\n\n // \u2705 Step 3: Apply value processors (escaping, sanitization, etc.)\n if (this.processors.size > 0) {\n for (const [name, processor] of this.processors.entries()) {\n try {\n processedValue = processor(processedValue, params, resolvedKey);\n } catch (error) {\n logger.warn(`Processor ${name} failed:`, error);\n }\n }\n }\n\n return processedValue;\n } catch (error) {\n logger.warn(`Translation processing failed for \"${value}\":`, error);\n return value;\n }\n }\n\n /**\n * \uD83D\uDCE6 CONTENT UNIT API\n * Returns translation as ContentUnit for JSX rendering (Trans component)\n *\n * This is the preferred method for components that need to render\n * styled content with JSX interpolation.\n *\n * @param key - Translation key\n * @param params - Optional interpolation parameters\n * @param defaultValue - Optional default value (can contain HTML)\n * @returns ContentUnit with indexed tags and styles\n *\n * @example\n * ```typescript\n * const unit = i18n.getContentUnit('terms', {}, 'Read our <b>Terms</b>.');\n * // \u2192 { text: \"Read our <1>Terms</1>.\", styles: {\"1\": [\"raw:<b>\"]} }\n * ```\n */\n getContentUnit(\n key: string,\n params?: Record<string, unknown>,\n defaultValue?: string\n ): ContentUnit {\n // Get translation value (ICU processing done separately per segment)\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n params,\n defaultValue,\n this.defaultNamespace\n );\n\n // Try memory cache\n const syncResult = this.handlerChain.handleSync(request);\n const rawValue =\n syncResult && syncResult.status === 200\n ? syncResult.value\n : request.parsedDefaultValue || request.cleanKey;\n\n // If no translation found, trigger background load\n if (!syncResult || syncResult.status !== 200) {\n this.triggerBackgroundLoad(request);\n }\n\n // Parse HTML to ContentUnit\n return this.markupParser.parse(rawValue);\n }\n\n /**\n * \uD83D\uDCE6 Process ContentUnit text through ICU formatters\n *\n * Used by JSX serializers to process individual text segments.\n *\n * @param text - Text segment (may contain ICU expressions like {name})\n * @param params - Interpolation parameters\n * @returns Processed text with ICU expressions resolved\n */\n processContentText(text: string, params?: Record<string, unknown>): string {\n return this.processTranslationValue(text, params, this.currentLocale);\n }\n\n /**\n * \uD83D\uDCE6 Check if a string contains HTML tags\n *\n * Used for auto-detection of HTML in default values.\n *\n * @param value - String to check\n * @returns true if HTML tags are detected\n */\n containsHtml(value: string): boolean {\n return HTML_TAG_REGEX.test(value);\n }\n\n /**\n * \u2705 Handle structured formatters (plural, context) - embedded in core\n */\n private applyStructuralFormatters(\n value: string,\n params?: Record<string, unknown>,\n translationKey?: string\n ): string {\n const translationData: string = value;\n\n // Type guard for params having a count property\n const hasCount = (\n p: Record<string, unknown> | undefined\n ): p is { count: number } => typeof p?.count === 'number';\n\n // Type guard for params having a context property\n const hasContext = (\n p: Record<string, unknown> | undefined\n ): p is { context: string } => typeof p?.context === 'string';\n\n // Apply plural formatter if available and applicable\n if (this.formatters.has('plural') && hasCount(params)) {\n const pluralFormatter = this.formatters.get('plural')!;\n try {\n const pluralResult = pluralFormatter(\n translationData,\n params,\n this.currentLocale,\n translationKey\n );\n if (pluralResult !== String(translationData)) {\n return pluralResult;\n }\n } catch (error) {\n logger.warn('Plural formatting failed:', error);\n }\n }\n\n // Apply context formatter if available and applicable\n if (this.formatters.has('context') && hasContext(params)) {\n const contextFormatter = this.formatters.get('context')!;\n try {\n const contextResult = contextFormatter(\n translationData,\n params,\n this.currentLocale,\n translationKey\n );\n if (contextResult !== String(translationData)) {\n return contextResult;\n }\n } catch (error) {\n logger.warn('Context formatting failed:', error);\n }\n }\n\n return String(translationData);\n }\n\n /**\n * Trigger background load via handler chain\n */\n private triggerBackgroundLoad(request: TranslationRequest): void {\n logger.debug(`Background load: ${request.cleanKey}`);\n const cacheKey = request.individualCacheKey;\n\n if (!this.pendingTranslations.has(cacheKey)) {\n const promise = this.handlerChain\n .handleAsync(request)\n .then(result => {\n if (result && result.value) {\n logger.debug(`Cached: ${request.cleanKey} = \"${result.value}\"`);\n } else {\n logger.debug(`Not found: ${request.cleanKey}`);\n }\n })\n .catch(error => {\n logger.warn(`Background load failed: ${request.cleanKey}`, error);\n });\n\n this.pendingTranslations.set(cacheKey, promise);\n promise.finally(() => this.pendingTranslations.delete(cacheKey));\n }\n }\n\n /**\n * Get the current locale\n */\n getCurrentLocale(): string {\n return this.currentLocale;\n }\n\n /**\n * Set default namespace (useful for scoped translations)\n */\n setDefaultNamespace(namespace?: string): void {\n this.defaultNamespace = namespace;\n }\n\n /**\n * Get current default namespace\n */\n getDefaultNamespace(): string | undefined {\n return this.defaultNamespace;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getEntries(): Record<string, any> {\n return this.handlerChain.getEntries();\n }\n\n isCached(key: string): boolean {\n const request = prepareTranslationRequest(\n key,\n this.currentLocale,\n undefined,\n undefined,\n this.defaultNamespace\n );\n\n return this.handlerChain.isCached(request);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getHandlerChainInfo(): any {\n return this.handlerChain.getChainInfo();\n }\n\n /**\n * \u2705 Smart language change with selective cache clearing\n */\n async changeLanguage(\n newLocale: string,\n options?: {\n clear?: boolean;\n preloadNamespaces?: string[];\n }\n ): Promise<void> {\n const oldLocale = this.currentLocale;\n\n if (oldLocale === newLocale) {\n logger.debug(`Language already set to ${newLocale}`);\n return;\n }\n\n const clear = options?.clear || false;\n const languageBus = this.bus.language(oldLocale, newLocale);\n\n try {\n logger.info(`Language change: ${oldLocale} \u2192 ${newLocale}`);\n logger.debug('Language change options', {\n clear,\n preloadNamespaces: options?.preloadNamespaces,\n });\n\n languageBus.start();\n\n this.currentLocale = newLocale;\n\n if (clear) {\n await this.clearCache();\n this.clearOldLocalePendingTranslations(oldLocale);\n }\n\n if (options?.preloadNamespaces?.length) {\n await this.loadNamespaces(newLocale, options.preloadNamespaces);\n }\n\n languageBus.complete();\n\n logger.info(`Language changed: ${newLocale}`);\n } catch (error) {\n logger.error('Language change failed:', error);\n languageBus.error(error as Error);\n throw error;\n }\n }\n\n private async clearCache(): Promise<void> {\n this.handlerChain.clearCache();\n logger.debug(`Cache cleared for locale: ${this.currentLocale}`);\n }\n\n private clearOldLocalePendingTranslations(oldLocale: string): void {\n let clearedCount = 0;\n\n for (const key of this.pendingTranslations.keys()) {\n if (key.includes(`${oldLocale}:`)) {\n this.pendingTranslations.delete(key);\n clearedCount++;\n }\n }\n\n if (clearedCount > 0) {\n logger.debug(\n `Cleared ${clearedCount} pending translations for ${oldLocale}`\n );\n }\n }\n\n private async loadNamespaces(\n locale: string,\n namespaces: string[]\n ): Promise<void> {\n logger.debug(`Preloading ${namespaces.length} namespaces for ${locale}`);\n\n const preloadPromises = namespaces.map(async namespace => {\n try {\n await this.handlerChain.loadNamespace?.(locale, namespace);\n logger.debug(`Preloaded: ${locale}:${namespace}`);\n } catch (error) {\n logger.warn(`Failed to preload ${locale}:${namespace}:`, error);\n }\n });\n\n await Promise.allSettled(preloadPromises);\n }\n\n /**\n * Reload a namespace by clearing cache and fetching fresh data from server\n * Useful after syncing new translations to ensure fresh data\n *\n * @param namespace - The namespace to reload\n * @param locale - Optional locale (defaults to current locale)\n * @deprecated Use cache.invalidate({ namespace, refetch: true }) instead\n */\n async reloadNamespace(namespace: string, locale?: string): Promise<void> {\n const targetLocale = locale || this.currentLocale;\n logger.debug(`Reloading namespace: ${targetLocale}:${namespace}`);\n\n // Delegate to cache manager\n await this.cache.invalidate({\n namespace,\n locale: targetLocale,\n refetch: true,\n });\n\n logger.info(`Namespace reloaded: ${targetLocale}:${namespace}`);\n }\n\n // Helper methods\n private isEmbeddedPlugin(plugin: IPlugin): boolean {\n return plugin.capabilities.some(cap =>\n ['formatters', 'processors', 'pluralization', 'context'].includes(cap)\n );\n }\n\n private isEventPlugin(plugin: IPlugin): boolean {\n return plugin.capabilities.some(cap =>\n [\n 'analytics',\n 'logging',\n 'react',\n 'validation',\n 'dev-tools',\n 'monitoring',\n ].includes(cap)\n );\n }\n}\n", "import { MemoryRepositoryConfig } from '../config/repository.config.js';\nimport type {\n IStatsProvider,\n ISyncRepository,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport { createNamespaceCacheKey } from '../utils/index.js';\n\nexport class MemoryRepository\n implements ISyncRepository<MemoryRepositoryConfig>, IStatsProvider\n{\n readonly name = 'MemoryRepository';\n readonly type = 'memory';\n readonly config: MemoryRepositoryConfig = {};\n private cache = new Map<string, string>();\n private accessOrder = new Map<string, number>();\n private maxSize: number = 1000;\n\n constructor(config: MemoryRepositoryConfig) {\n this.config = config;\n this.maxSize = this.config.options?.maxSize || 1000;\n }\n\n get(key: string): string | null {\n const value = this.cache.get(key);\n if (value !== undefined) {\n // Update access time for LRU\n this.accessOrder.set(key, Date.now());\n return value;\n }\n return null;\n }\n\n set(key: string, value: string): void {\n if (this.cache.size >= this.maxSize && !this.cache.has(key)) {\n this.evictOldest();\n }\n\n this.cache.set(key, value);\n this.accessOrder.set(key, Date.now());\n }\n\n remove(key: string): void {\n this.cache.delete(key);\n this.accessOrder.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n this.accessOrder.clear();\n }\n\n /**\n * Clear all entries for a specific namespace\n * Removes both the namespace cache entry and all individual translation keys\n */\n clearNamespace(locale: string, namespace: string): void {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n const keyPrefix = `${locale}:${namespace}:`;\n\n // Remove namespace cache entry\n this.cache.delete(namespaceCacheKey);\n this.accessOrder.delete(namespaceCacheKey);\n\n // Remove individual translation keys\n for (const key of this.cache.keys()) {\n if (key.startsWith(keyPrefix)) {\n this.cache.delete(key);\n this.accessOrder.delete(key);\n }\n }\n }\n\n getNamespace(locale: string, namespace: string): TranslationData | null {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n const namespaceData = this.cache.get(namespaceCacheKey);\n if (!namespaceData) return null;\n\n try {\n return JSON.parse(namespaceData);\n } catch (error) {\n this.cache.delete(namespaceCacheKey);\n return null;\n }\n }\n\n setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): void {\n const namespaceCacheKey = createNamespaceCacheKey(locale, namespace);\n this.cache.set(namespaceCacheKey, JSON.stringify(translations));\n }\n\n private evictOldest(): void {\n let oldestKey = '';\n let oldestTime = Date.now();\n\n for (const [key, time] of this.accessOrder.entries()) {\n if (time < oldestTime) {\n oldestTime = time;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.cache.delete(oldestKey);\n this.accessOrder.delete(oldestKey);\n }\n }\n /**\n * Get all cache entries for debugging\n */\n getEntries(): Record<string, string> {\n const entries: Record<string, string> = {};\n for (const [key, value] of this.cache.entries()) {\n entries[key] = value;\n }\n return entries;\n }\n\n getConfig(): MemoryRepositoryConfig {\n return this.config;\n }\n}\n", "import { MemoryRepositoryConfig } from '../config/repository.config.js';\nimport type {\n IStatsProvider,\n ISyncRepository,\n} from '../interfaces/repository.interface.js';\nimport type { TranslationData } from '../types/translation-data.types.js';\nimport { flattenTranslations } from '../utils/index.js';\nimport { MemoryRepository } from './memory-repository.js';\n\n/**\n * A bundle of translations to seed offline-first: locale \u2192 namespace \u2192 data,\n * where `data` is the raw `{ key: ContentUnit }` map the backend returns (and\n * the CLI `snapshot` command writes). Styles MUST be preserved (no flattening\n * to display strings), so inline markup renders offline.\n */\nexport type StaticBundle = Record<string, Record<string, TranslationData>>;\n\n/**\n * Read-only, pre-seeded sync repository for OFFLINE RESILIENCE. Bundle a\n * snapshot (or import the CLI's snapshot files) and feed it in; `t()` then\n * resolves synchronously from the bundle even with the server down and nothing\n * cached \u2014 the gap browser localStorage/Cache can't fill on a first load.\n *\n * It seeds an internal MemoryRepository exactly the way `SyncHandler.saveNamespace`\n * does (the namespace blob `@locale:namespace` + flattened `locale:namespace:key`\n * entries, each a JSON ContentUnit), so the standard SyncHandler resolves it with\n * zero special-casing. Writes are no-ops: when the network succeeds, the LIVE\n * MemoryRepository (priority 0) holds the fresh value and shadows this layer\n * (which sits at priority 0.5), so the bundle is never overwritten or corrupted.\n * TTL/size are effectively infinite so the bundle never expires or evicts.\n */\nexport class StaticRepository\n implements ISyncRepository<MemoryRepositoryConfig>, IStatsProvider\n{\n readonly name = 'StaticRepository';\n readonly type = 'memory' as const;\n readonly config: MemoryRepositoryConfig;\n private readonly mem: MemoryRepository;\n\n constructor(bundle: StaticBundle, config: MemoryRepositoryConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n priority: config.priority ?? 0.5, // after the live memory (0), before storage\n options: {\n ttl: Number.MAX_SAFE_INTEGER,\n maxSize: Number.MAX_SAFE_INTEGER,\n ...config.options,\n },\n };\n this.mem = new MemoryRepository({ options: { maxSize: Number.MAX_SAFE_INTEGER } });\n\n for (const [locale, namespaces] of Object.entries(bundle)) {\n for (const [namespace, translations] of Object.entries(namespaces)) {\n this.mem.setNamespace(locale, namespace, translations);\n const flat = flattenTranslations(\n translations as Record<string, unknown>,\n '',\n locale,\n namespace\n );\n for (const [key, value] of Object.entries(flat)) this.mem.set(key, value);\n }\n }\n }\n\n get(key: string): string | null {\n return this.mem.get(key);\n }\n\n getNamespace(locale: string, namespace: string): TranslationData | null {\n return this.mem.getNamespace(locale, namespace);\n }\n\n getEntries(): Record<string, string> {\n return this.mem.getEntries();\n }\n\n getConfig(): MemoryRepositoryConfig {\n return this.config;\n }\n\n // Read-only: the live memory layer owns fresh network data; this stays pristine.\n set(): void {}\n remove(): void {}\n clear(): void {}\n setNamespace(): void {}\n}\n", "/**\n * Queue for batching and syncing missing translations to the backend\n * Uses debouncing (500ms default) and batching (50 items default)\n */\n\nimport type { EventEmitter } from '../base/event-emitter.js';\nimport type { IAsyncRepository } from '../interfaces/repository.interface.js';\nimport { logger } from '../utils/logger.js';\n\nexport interface MissingTranslationItem {\n key: string;\n fallbackValue: string;\n styles?: Record<string, string[]>;\n locale: string;\n namespace: string;\n}\n\nexport interface MissingTranslationQueueConfig {\n enabled: boolean;\n debounceMs: number;\n batchSize: number;\n}\n\nconst COOLDOWN_MS = 60_000; // 60s cooldown before re-syncing same key\n\nexport class MissingTranslationQueue {\n private queue: Map<string, MissingTranslationItem> = new Map();\n private debounceTimer: NodeJS.Timeout | null = null;\n private repository: IAsyncRepository;\n private config: MissingTranslationQueueConfig;\n private eventEmitter: EventEmitter | null;\n private recentlySynced: Map<string, number> = new Map();\n\n constructor(\n repository: IAsyncRepository,\n config: MissingTranslationQueueConfig,\n eventEmitter?: EventEmitter\n ) {\n this.repository = repository;\n this.config = config;\n this.eventEmitter = eventEmitter ?? null;\n\n if (!config.enabled) {\n logger.debug('MissingTranslationQueue is disabled');\n } else {\n logger.debug(\n `MissingTranslationQueue: debounce=${config.debounceMs}ms, batchSize=${config.batchSize}`\n );\n }\n }\n\n /**\n * Add a missing translation to the queue\n * Triggers debounce timer or immediate flush if batch size reached\n */\n add(item: MissingTranslationItem): void {\n if (!this.config.enabled) return;\n\n // Use individual cache key format: locale:namespace:key\n const cacheKey = `${item.locale}:${item.namespace}:${item.key}`;\n\n // Skip keys synced within cooldown period (prevents re-sync loops)\n const syncedAt = this.recentlySynced.get(cacheKey);\n if (syncedAt && Date.now() - syncedAt < COOLDOWN_MS) {\n logger.debug(`Skipping recently synced key: ${cacheKey}`);\n return;\n }\n\n // Add to queue (overwrites if already exists)\n this.queue.set(cacheKey, item);\n\n logger.debug(\n `Missing translation queued: ${cacheKey} (queue size: ${this.queue.size})`\n );\n\n // Clear existing timer\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n // Check if batch size limit reached\n if (this.queue.size >= this.config.batchSize) {\n logger.debug(`Batch size reached (${this.config.batchSize}), flushing`);\n this.flush();\n return;\n }\n\n // Start new debounce timer\n this.debounceTimer = setTimeout(() => {\n this.flush();\n }, this.config.debounceMs);\n }\n\n /**\n * Flush the queue - send all queued items to the backend\n * Fire-and-forget pattern (async but not awaited)\n */\n flush(): void {\n if (this.queue.size === 0) return;\n\n // Clean up expired cooldown entries\n const now = Date.now();\n for (const [key, ts] of this.recentlySynced) {\n if (now - ts >= COOLDOWN_MS) this.recentlySynced.delete(key);\n }\n\n // Convert queue to array, preserving styles\n const batch = Array.from(this.queue.entries()).map(([cacheKey, item]) => ({\n key: cacheKey,\n value: item.fallbackValue,\n styles: item.styles,\n }));\n\n const batchSize = batch.length;\n\n // Clear queue\n this.queue.clear();\n\n // Clear timer\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n logger.debug(`Flushing ${batchSize} missing translations`);\n\n // Fire-and-forget sync (no await)\n this.syncBatch(batch).catch(error => {\n logger.warn(`Failed to sync ${batchSize} missing translations:`, error);\n });\n }\n\n /**\n * Send batch to backend via repository\n * Uses repository's retry logic from makeRequest()\n */\n private async syncBatch(\n batch: Array<{ key: string; value: string; styles?: Record<string, string[]> }>\n ): Promise<void> {\n try {\n // Use setBatchContentUnits when any item has styles\n const hasStyles = batch.some(item => item.styles && Object.keys(item.styles).length > 0);\n\n if (hasStyles && 'setBatchContentUnits' in this.repository) {\n const contentUnitBatch = batch.map(item => ({\n key: item.key,\n value: { text: item.value, styles: item.styles ?? {} },\n }));\n await (\n this.repository as IAsyncRepository & {\n setBatchContentUnits: (\n items: Array<{ key: string; value: { text: string; styles: Record<string, string[]> } }>\n ) => Promise<void>;\n }\n ).setBatchContentUnits(contentUnitBatch);\n logger.debug(`Synced ${batch.length} missing translations (ContentUnit)`);\n } else if ('setBatch' in this.repository) {\n // Plain string batch (no styles)\n const plainBatch = batch.map(item => ({ key: item.key, value: item.value }));\n await (\n this.repository as IAsyncRepository & {\n setBatch: (\n items: Array<{ key: string; value: string }>\n ) => Promise<void>;\n }\n ).setBatch(plainBatch);\n logger.debug(`Synced ${batch.length} missing translations`);\n } else {\n // Fallback: sync individually (parallel)\n logger.warn(\n 'Repository does not support setBatch, syncing individually'\n );\n await this.syncIndividually(batch);\n }\n // Record synced keys for cooldown\n const now = Date.now();\n const syncedKeys: string[] = [];\n for (const item of batch) {\n this.recentlySynced.set(item.key, now);\n syncedKeys.push(item.key);\n }\n\n // Emit sync:batch:complete event\n if (this.eventEmitter) {\n this.eventEmitter.emit('sync:batch:complete', {\n payload: { count: batch.length, keys: syncedKeys },\n });\n }\n } catch (error) {\n logger.error('Batch sync failed:', error);\n throw error;\n }\n }\n\n /**\n * Fallback: sync items individually in parallel\n */\n private async syncIndividually(\n batch: Array<{ key: string; value: string }>\n ): Promise<void> {\n const syncPromises = batch.map(async item => {\n try {\n await this.repository.set(item.key, item.value);\n logger.debug(`Synced: ${item.key}`);\n } catch (error) {\n logger.warn(`Failed to sync ${item.key}:`, error);\n }\n });\n\n await Promise.allSettled(syncPromises);\n }\n\n /**\n * Get current queue size (for debugging)\n */\n getQueueSize(): number {\n return this.queue.size;\n }\n\n /**\n * Get queue stats (for debugging)\n */\n getStats(): {\n queueSize: number;\n enabled: boolean;\n debounceMs: number;\n batchSize: number;\n } {\n return {\n queueSize: this.queue.size,\n enabled: this.config.enabled,\n debounceMs: this.config.debounceMs,\n batchSize: this.config.batchSize,\n };\n }\n\n /**\n * Cleanup - clear timer and queue\n */\n destroy(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n\n // Discard to avoid blocking during shutdown\n this.queue.clear();\n this.recentlySynced.clear();\n\n logger.debug('MissingTranslationQueue destroyed');\n }\n}\n", "/**\n * LionRapid Builder - Enhanced with explicit namespace preloading\n */\n\nimport { EventEmitter } from './base/event-emitter.js';\nimport type { LionRapidCoreConfig } from './config/lionrapid.config.js';\nimport type { NetworkRepositoryConfig } from './config/repository.config.js';\nimport { HandlerChain } from './handlers/handler-chain.js';\nimport { AsyncHandler, NetworkHandler, SyncHandler } from './handlers/index.js';\nimport type {\n IEmbeddedPlugin,\n IPlugin,\n} from './interfaces/plugin.interface.js';\nimport {\n IAsyncRepository,\n ISyncRepository,\n} from './interfaces/repository.interface.js';\nimport { LionRapidCore } from './lionRapid.js';\nimport {\n TranslationLockedError,\n TranslationNotFoundError,\n} from './errors/translation-errors.js';\nimport {\n StaticRepository,\n type StaticBundle,\n} from './repositories/static-repository.js';\nimport { MissingTranslationQueue } from './sync/missing-translation-queue.js';\nimport { logger } from './utils/logger.js';\n\n/**\n * True when a preload failure deserves a loud console diagnostic: network or\n * server trouble the integrator should hear about. 404 (empty project) and\n * 423 (content still being prepared) are routine states, not failures.\n * The internal logger is compiled out of production bundles, so genuine\n * failures must reach console.warn explicitly.\n */\nexport function isLoudPreloadFailure(error: unknown): boolean {\n return !(\n error instanceof TranslationNotFoundError ||\n error instanceof TranslationLockedError\n );\n}\n\nexport class LionRapidBuilder {\n private config: LionRapidCoreConfig;\n private plugins: IPlugin[] = [];\n private syncStorageRepos: ISyncRepository[] = [];\n private asyncStorageRepos: IAsyncRepository[] = [];\n private networkRepos: IAsyncRepository[] = [];\n private syncQueue: MissingTranslationQueue | null = null;\n\n constructor(config: LionRapidCoreConfig) {\n this.config = {\n defaultLocale: config.defaultLocale || 'en',\n namespace: config.namespace || 'app',\n };\n }\n\n static init(config: LionRapidCoreConfig = {}): LionRapidBuilder {\n return new LionRapidBuilder(config);\n }\n\n private useSyncStorage(memory: ISyncRepository): LionRapidBuilder {\n this.syncStorageRepos.push(memory);\n return this;\n }\n\n private useAsyncStorage(storage: IAsyncRepository): LionRapidBuilder {\n this.asyncStorageRepos.push(storage);\n return this;\n }\n\n private useNetwork(network: IAsyncRepository): LionRapidBuilder {\n this.networkRepos.push(network);\n return this;\n }\n\n use(\n instance: IPlugin | IEmbeddedPlugin | ISyncRepository | IAsyncRepository\n ): LionRapidBuilder {\n switch (instance.type) {\n case 'plugin':\n this.plugins.push(instance);\n break;\n case 'memory':\n this.useSyncStorage(instance);\n break;\n case 'storage':\n this.useAsyncStorage(instance);\n break;\n case 'network':\n this.useNetwork(instance);\n break;\n }\n return this;\n }\n\n /**\n * Offline resilience: seed a translation bundle (or the CLI's snapshot files)\n * as a read-only sync layer that resolves synchronously even with the server\n * down and nothing cached. Sits after the live memory layer (priority 0) at\n * `priority` (default 0.5), so fresh network data always shadows it.\n */\n useStaticBundle(bundle: StaticBundle, priority = 0.5): LionRapidBuilder {\n return this.use(new StaticRepository(bundle, { priority }));\n }\n\n async build(): Promise<LionRapidCore> {\n const eventEmitter = new EventEmitter();\n const buildBus = eventEmitter.builder();\n\n logger.info('Builder started');\n logger.debug('Builder config', this.config);\n buildBus.buildStart(this.config.defaultLocale!, this.config.namespace!);\n\n const handlerChain = new HandlerChain(eventEmitter);\n // Always add memory cache handler first\n for (const syncRepo of this.syncStorageRepos) {\n if (!syncRepo.getConfig().enabled) continue;\n const syncHandler = new SyncHandler(eventEmitter, syncRepo);\n buildBus.use('sync');\n handlerChain.addSyncHandler(syncHandler);\n }\n // Always add storage cache handler second\n for (const asyncRepo of this.asyncStorageRepos) {\n if (!asyncRepo.getConfig().enabled) continue;\n const asyncHandler = new AsyncHandler(eventEmitter, asyncRepo);\n buildBus.use('async');\n handlerChain.addAsyncHandler(asyncHandler);\n }\n\n // Always add network cache handler last\n let networkFirst: NetworkHandler | null = null;\n for (const networkRepo of this.networkRepos) {\n if (\n !networkRepo.getConfig().enabled ||\n !networkRepo.getConfig().options?.baseUrl\n )\n continue;\n const networkHandler = new NetworkHandler(eventEmitter, networkRepo);\n if (!networkFirst) {\n networkFirst = networkHandler;\n }\n buildBus.use('network');\n handlerChain.addAsyncHandler(networkHandler);\n\n // \u2705 Initialize missing translation sync queue if enabled\n const config = networkRepo.getConfig() as NetworkRepositoryConfig;\n if (config.options?.syncMissing?.enabled) {\n this.syncQueue = new MissingTranslationQueue(networkRepo, {\n enabled: config.options.syncMissing.enabled,\n debounceMs: config.options.syncMissing.debounceMs || 500,\n batchSize: config.options.syncMissing.batchSize || 50,\n }, eventEmitter);\n\n // Subscribe to translation:not-found events (404 only)\n // Note: translation:locked (423) is NOT synced since translation exists but is not ready\n eventEmitter.on('translation:not-found', envelope => {\n if (this.syncQueue) {\n this.syncQueue.add({\n key: envelope.payload.key,\n fallbackValue: envelope.payload.fallbackValue,\n styles: envelope.payload.styles,\n locale: envelope.payload.locale,\n namespace: envelope.payload.namespace,\n });\n }\n });\n\n logger.info('Missing translation sync enabled');\n logger.debug('Sync queue config', config.options.syncMissing);\n }\n }\n\n logger.debug('Handler chain constructed');\n\n // Create facade\n const facade = new LionRapidCore(\n eventEmitter,\n handlerChain,\n this.config.defaultLocale,\n this.config.namespace\n );\n\n // Initialize plugins and add their handlers\n for (const plugin of this.plugins) {\n buildBus.use('plugin');\n await plugin.initialize({ core: facade, bus: eventEmitter });\n facade.registerPlugin(plugin);\n logger.info(`Plugin initialized: ${plugin.name}`);\n logger.debug(`Plugin version: ${plugin.version}`, plugin.capabilities);\n }\n\n const chainInfo = handlerChain.getChainInfo();\n\n // \u2705 Explicit namespace preloading\n if (networkFirst) {\n await this.executePreloading(networkFirst, handlerChain);\n }\n logger.info('Builder completed');\n buildBus.buildDone(\n chainInfo.handlers.map(r => r.name),\n this.plugins.map(p => p.name)\n );\n\n return facade;\n }\n\n // \u2705 CLEAN: Preloading logic\n private async executePreloading(\n networkHandler: NetworkHandler,\n handlerChain: HandlerChain\n ): Promise<void> {\n const eagerPreloads = networkHandler\n .getPreload()\n .filter(config => config.eager !== false);\n\n if (!eagerPreloads || eagerPreloads.length === 0) {\n return;\n }\n\n logger.info(`Preloading ${eagerPreloads.length} namespaces`);\n logger.debug('Preload targets', {\n namespaces: eagerPreloads.map(c => `${c.locale}:${c.namespace}`),\n });\n\n let warnedLoudly = false;\n const warnLoudlyOnce = (namespaceKey: string, error: unknown) => {\n if (!isLoudPreloadFailure(error) || warnedLoudly) return;\n warnedLoudly = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[LionRapid] Could not load translations for ${namespaceKey} \u2014 the ` +\n 'page stays untranslated until the server is reachable.',\n error\n );\n };\n const promises = eagerPreloads.map(async preloadConfig => {\n const namespaceKey = `${preloadConfig.locale}:${preloadConfig.namespace}`;\n try {\n const result = await networkHandler.loadNamespace(\n preloadConfig.locale,\n preloadConfig.namespace\n );\n\n if (result && result.data && result.status === 200) {\n const context = {\n locale: preloadConfig.locale,\n namespace: preloadConfig.namespace,\n };\n\n await handlerChain.saveNamespaceToHandlers(result.data, context);\n logger.debug(`Preloaded: ${namespaceKey}`);\n return;\n }\n\n // loadNamespace never throws \u2014 failures come back as a fallback\n // result with the error attached (status 0 = network/transport).\n if (result?.error) {\n warnLoudlyOnce(namespaceKey, result.error);\n logger.warn(`Preload failed: ${namespaceKey}`, result.error);\n }\n } catch (error) {\n warnLoudlyOnce(namespaceKey, error);\n logger.warn(`Preload failed: ${namespaceKey}`, error);\n }\n });\n\n await Promise.allSettled(promises);\n logger.info('Preloading completed');\n }\n}\n", "/**\n * API repository - Simple HTTP data access layer\n * No business logic - just GET/POST operations\n *\n * Server always returns ContentUnit format: { text, styles }\n */\n\nimport type {\n NetworkRepositoryConfig,\n ProjectConfig,\n} from '../config/repository.config.js';\nimport type { ContentUnit } from '../content/types.js';\nimport {\n NetworkError,\n ServerError,\n TranslationLockedError,\n TranslationNotFoundError,\n} from '../errors/translation-errors.js';\nimport type { IAsyncRepository } from '../interfaces/repository.interface.js';\nimport type {\n ContentUnitData,\n TranslationData,\n} from '../types/translation-data.types.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Surface self-identification (hub Track B7). Snippet, WordPress and CLI all\n * share one project-wide (NULL-binding) pk_, so the server's surface registry\n * can't tell them apart from the key alone. Core is the snippet/SDK surface, so\n * every request advertises it via this header. Additive + inert: an older\n * server ignores the unknown header, so this ships safely in any order relative\n * to the server side. (Edge and webhook are out of scope \u2014 their bound keys\n * already identify them; a redundant tag would be a second source of truth.)\n */\nconst SURFACE_HEADER = 'X-LR-Surface';\nconst SURFACE_TAG = 'snippet';\n\n/** Server version + the exact payload it describes, stored atomically. */\ninterface NamespaceSnapshot {\n version: string;\n translations: Record<string, unknown>;\n}\n\n/**\n * API repository implementation\n * Pure data access - no caching, no business logic\n */\nexport class NetworkRepository\n implements IAsyncRepository<NetworkRepositoryConfig>\n{\n readonly name = 'NetworkRepository';\n readonly type = 'network';\n readonly config: NetworkRepositoryConfig = {};\n\n /**\n * Namespace snapshot per key \"locale:namespace\": the server version TOGETHER\n * with the payload it describes, persisted as ONE localStorage entry.\n *\n * Canonical 304 contract (same as edge KV bundle + WP transient cache):\n * never claim freshness you can't back. If-None-Match is only sent when the\n * snapshot is in hand; a 304 answers with that snapshot's payload; version\n * and payload can never desync because they live and die together.\n */\n private namespaceSnapshots = new Map<string, NamespaceSnapshot>();\n\n /** localStorage key prefix for persisted snapshots (version + payload) */\n private static readonly SNAPSHOT_PREFIX = 'lionrapid:ns:';\n\n /** Legacy bare-version prefix \u2014 a version WITHOUT its payload is exactly the\n * desync the snapshot store exists to prevent; entries are deleted on sight. */\n private static readonly LEGACY_VERSION_PREFIX = 'lionrapid:v:';\n\n /**\n * Miss-path flood protection (READINESS before-scale #1: one cold locale\n * switch measured ~380 requests in 10 s \u2014 every t() miss refired a key GET\n * and a namespace GET on every re-render, forever on animated pages).\n */\n\n /** GETs currently on the wire, keyed by `url|if-none-match` \u2014 identical\n * concurrent requests share one fetch; each awaiter gets a clone. The\n * If-None-Match value is part of the key so the 304-without-snapshot\n * unconditional refetch never coalesces onto a conditional flight. */\n private inflightGets = new Map<string, Promise<Response>>();\n\n /** URL \u2192 404/423 seen recently: repeats are answered locally (same typed\n * error, no network) until `until`. 423 honors the server's Retry-After.\n * Cleared entirely by any successful write \u2014 discovery sync keeps its\n * miss \u2192 batch \u2192 served-back round-trip. */\n private negativeCache = new Map<string, { status: number; until: number }>();\n\n /** One-way latch: a 401 anywhere (or a 403 on a READ) means the key is\n * wrong or unauthorized for this project, and retrying cannot heal it \u2014\n * after the first one nothing touches the network again for this\n * instance (a page reload starts fresh). Holds the status that tripped\n * it so short-circuits answer honestly. */\n private authFailedStatus: number | null = null;\n\n /** Write-only latch (auth-byok Phase 18): a 403 (scope) or 429 (quota) on\n * a WRITE degrades this instance to read-only \u2014 writes stop, silently\n * and without retries, while reads keep serving the page. */\n private writesFailedStatus: number | null = null;\n\n private static readonly DEFAULT_NEGATIVE_TTL_MS = 60_000;\n\n /**\n * Default endpoint templates with placeholder support\n * Placeholders: :key, :locale, :namespace\n */\n private readonly DEFAULT_ENDPOINTS = {\n getTranslation: '/api/integrations/translations/:key',\n getNamespace: '/api/integrations/translations/:locale/:namespace',\n getProjectConfig: '/api/integrations/project-config',\n setTranslation: '/api/integrations/sync/:key',\n setNamespace: '/api/integrations/sync/:locale/:namespace',\n setBatch: '/api/integrations/sync/batch',\n removeTranslation: '/api/integrations/sync/:key',\n clearTranslations: '/translations',\n } as const;\n\n constructor(config: NetworkRepositoryConfig = {}) {\n this.config = {\n options: {\n timeout: config.options?.timeout ?? 5000,\n baseUrl: config.options?.baseUrl ?? '',\n headers: config.options?.headers ?? {},\n },\n ...config,\n };\n }\n\n /**\n * Get single translation from API\n * Uses platform-specific integration endpoint\n * @throws {TranslationNotFoundError} When translation doesn't exist (404)\n * @throws {TranslationLockedError} When translation is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async get(key: string): Promise<string> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n const url = this.buildUrl('getTranslation', { key });\n logger.debug(`API GET: ${url}`);\n\n try {\n const response = await this.makeRequest(url, 'GET');\n\n if (!response.ok) {\n this.handleHttpError(response, key);\n }\n\n const data = await response.json();\n logger.debug('API response data:', data);\n\n // Try multiple key formats: meta.key, original key, or first translation\n const translation = data.translations[data.meta?.key]\n || data.translations[key]\n || Object.values(data.translations)[0];\n\n logger.debug(`Fetched translation for key \"${key}\":`, translation);\n if (!translation) {\n throw new TranslationNotFoundError(key);\n }\n\n // Handle both ContentUnit format and plain string\n if (typeof translation === 'object' && 'text' in translation) {\n logger.debug(`ContentUnit text: \"${translation.text}\"`);\n return translation.text;\n }\n\n return String(translation);\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Get single translation as full ContentUnit (with styles)\n * Used by NetworkHandler for individual key lookups that need styles\n * @throws {TranslationNotFoundError} When translation doesn't exist (404)\n * @throws {TranslationLockedError} When translation is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async getContentUnit(key: string): Promise<ContentUnit> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n const url = this.buildUrl('getTranslation', { key });\n logger.debug(`API GET ContentUnit: ${url}`);\n\n try {\n const response = await this.makeRequest(url, 'GET');\n\n if (!response.ok) {\n this.handleHttpError(response, key);\n }\n\n const data = await response.json();\n logger.debug('API response data:', data);\n\n // Try multiple key formats: meta.key, original key, or first translation\n const translation = data.translations[data.meta?.key]\n || data.translations[key]\n || Object.values(data.translations)[0];\n\n if (!translation) {\n throw new TranslationNotFoundError(key);\n }\n\n // Handle both ContentUnit format and plain string\n if (typeof translation === 'object' && 'text' in translation) {\n // Server returned ContentUnit format\n logger.debug(`ContentUnit for \"${key}\": text=\"${translation.text}\", styles=`, translation.styles);\n return {\n text: translation.text,\n styles: translation.styles || {},\n };\n }\n\n // Server returned plain string - wrap in ContentUnit\n logger.debug(`Plain string for \"${key}\": \"${translation}\" (no styles)`);\n return {\n text: String(translation),\n styles: {},\n };\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Get namespace with all translations\n * @throws {TranslationNotFoundError} When namespace doesn't exist (404)\n * @throws {TranslationLockedError} When namespace is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async getNamespace(\n locale: string,\n namespace: string\n ): Promise<TranslationData | null> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n try {\n return (await this.fetchNamespaceRaw(locale, namespace)) as TranslationData;\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Project-level config for this key \u2014 the dashboard's language list,\n * served under the same trust model as translation reads (docs/20,\n * companion track). Returns null when the server doesn't expose the\n * endpoint (404 \u2014 older server, feature not deployed) or the payload is\n * unusable: absence means \"keep your local fallback\", never an error.\n */\n async getProjectConfig(): Promise<ProjectConfig | null> {\n if (!this.config?.options?.baseUrl) {\n throw new NetworkError('API base URL is not set');\n }\n\n const url = this.buildUrl('getProjectConfig', {});\n logger.debug(`API GET ProjectConfig: ${url}`);\n\n try {\n const response = await this.makeRequest(url, 'GET');\n\n if (response.status === 404) {\n return null;\n }\n if (!response.ok) {\n this.handleHttpError(response, 'project-config');\n }\n\n const data = (await response.json()) as Partial<ProjectConfig> | null;\n if (\n !data ||\n typeof data.defaultLocale !== 'string' ||\n !Array.isArray(data.languages)\n ) {\n logger.warn('project-config payload unusable \u2014 keeping local fallback');\n return null;\n }\n\n return {\n defaultLocale: data.defaultLocale,\n languages: data.languages.map(String),\n };\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Shared namespace fetch with the canonical 304 contract:\n * - If-None-Match is sent ONLY when a snapshot (version + payload) is in hand.\n * - 304 answers with that snapshot's payload \u2014 never with \"nothing\".\n * - A 304 with no snapshot (server/proxy surprise) refetches unconditionally.\n * - A 200 stores version + payload atomically before either is trusted.\n */\n private async fetchNamespaceRaw(\n locale: string,\n namespace: string,\n allowConditional = true\n ): Promise<Record<string, unknown>> {\n const url = this.buildUrl('getNamespace', { locale, namespace });\n logger.debug(`API GET Namespace: ${url}`);\n\n const namespaceKey = `${locale}:${namespace}`;\n\n const snapshot = allowConditional ? this.getSnapshot(namespaceKey) : undefined;\n const extraHeaders: Record<string, string> = {};\n if (snapshot) {\n extraHeaders['If-None-Match'] = `W/\"${snapshot.version}\"`;\n }\n\n const response = await this.makeRequest(url, 'GET', undefined, extraHeaders);\n\n if (response.status === 304) {\n if (snapshot) {\n // Not modified \u2014 serve the exact payload the version vouches for, so\n // callers rehydrate the cache layers instead of assuming they're intact.\n logger.debug(`Namespace ${namespaceKey}: 304 Not Modified (snapshot served)`);\n return snapshot.translations;\n }\n // We never claimed freshness \u2014 refetch without the conditional header.\n logger.debug(`Namespace ${namespaceKey}: unexpected 304 with no snapshot \u2014 refetching`);\n return this.fetchNamespaceRaw(locale, namespace, false);\n }\n\n if (!response.ok) {\n this.handleHttpError(response, namespaceKey);\n }\n\n const data = await response.json();\n logger.debug('API response data:', data);\n\n if (!data.translations) {\n throw new TranslationNotFoundError(namespaceKey);\n }\n\n const version = data.meta?.version != null ? String(data.meta.version) : null;\n if (version) {\n this.setSnapshot(namespaceKey, { version, translations: data.translations });\n }\n\n return data.translations;\n }\n\n /**\n * Save translation to API (if supported)\n */\n async set(key: string, value: string): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('setTranslation', { key });\n const response = await this.makeRequest(url, 'PUT', {\n translation: value,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to save translation: ${response.status}`);\n }\n } catch (error) {\n logger.debug(`API set failed for key \"${key}\":`, error);\n throw error;\n }\n }\n\n async setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('setNamespace', { locale, namespace });\n const response = await this.makeRequest(url, 'PUT', {\n translations,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to save namespace: ${response.status}`);\n }\n } catch (error) {\n logger.debug(\n `API setNamespace failed for ${locale}:${namespace}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Batch sync multiple missing translations\n * Uses new batch endpoint for efficiency\n */\n async setBatch(items: Array<{ key: string; value: string }>): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n\n try {\n const url = this.buildUrl('setBatch');\n logger.debug(`API POST Batch: ${url} (${items.length} items)`);\n\n const response = await this.makeRequest(url, 'POST', {\n translations: items,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to sync batch: ${response.status}`);\n }\n\n logger.debug(`Batch sync successful: ${items.length} items`);\n } catch (error) {\n logger.debug(`API setBatch failed for ${items.length} items:`, error);\n throw error;\n }\n }\n\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n // ContentUnit API Methods\n // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n /**\n * Get namespace with all translations as ContentUnit data\n *\n * @returns ContentUnitData (Record<string, ContentUnit>)\n * @throws {TranslationNotFoundError} When namespace doesn't exist (404)\n * @throws {TranslationLockedError} When namespace is locked/not ready (423)\n * @throws {ServerError} When server returns 5xx error\n * @throws {NetworkError} When network request fails\n */\n async getNamespaceContentUnits(\n locale: string,\n namespace: string\n ): Promise<ContentUnitData | null> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n throw new NetworkError('API base URL is not set');\n }\n\n try {\n // Server always returns ContentUnit format\n return (await this.fetchNamespaceRaw(locale, namespace)) as ContentUnitData;\n } catch (error) {\n this.handleCaughtError(error);\n }\n }\n\n /**\n * Save ContentUnit to API\n *\n * Sends the ContentUnit format to server for storage.\n * Server should store in ContentUnit format for efficient retrieval.\n *\n * @param key - Translation key\n * @param unit - ContentUnit to save\n */\n async setContentUnit(key: string, unit: ContentUnit): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n\n try {\n const url = this.buildUrl('setTranslation', { key });\n const response = await this.makeRequest(url, 'PUT', {\n translation: unit,\n format: 'contentunit', // Signal to server that this is ContentUnit format\n });\n\n if (!response.ok) {\n throw new Error(`Failed to save ContentUnit: ${response.status}`);\n }\n\n logger.debug(`Saved ContentUnit for key \"${key}\"`);\n } catch (error) {\n logger.debug(`API setContentUnit failed for key \"${key}\":`, error);\n throw error;\n }\n }\n\n /**\n * Batch sync multiple ContentUnits\n *\n * Sends ContentUnit format to server for batch storage.\n *\n * @param items - Array of key-ContentUnit pairs\n */\n async setBatchContentUnits(\n items: Array<{ key: string; value: ContentUnit }>\n ): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n\n try {\n const url = this.buildUrl('setBatch');\n logger.debug(\n `API POST Batch ContentUnits: ${url} (${items.length} items)`\n );\n\n const response = await this.makeRequest(url, 'POST', {\n translations: items,\n format: 'contentunit', // Signal to server that this is ContentUnit format\n });\n\n if (!response.ok) {\n throw new Error(`Failed to sync batch ContentUnits: ${response.status}`);\n }\n\n logger.debug(`Batch ContentUnit sync successful: ${items.length} items`);\n } catch (error) {\n logger.debug(\n `API setBatchContentUnits failed for ${items.length} items:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Remove translation from API (if supported)\n */\n async remove(key: string): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('removeTranslation', { key });\n const response = await this.makeRequest(url, 'DELETE');\n\n if (!response.ok) {\n throw new Error(`Failed to remove translation: ${response.status}`);\n }\n } catch (error) {\n logger.debug(`API remove failed for key \"${key}\":`, error);\n throw error;\n }\n }\n\n /**\n * Clear all translations (if supported)\n */\n async clear(): Promise<void> {\n if (!this.config?.options?.baseUrl) {\n logger.debug('API base URL is not set');\n return Promise.reject(new Error('API base URL is not set'));\n }\n try {\n const url = this.buildUrl('clearTranslations');\n const response = await this.makeRequest(url, 'DELETE');\n\n if (!response.ok) {\n throw new Error(`Failed to clear translations: ${response.status}`);\n }\n } catch (error) {\n logger.debug('API clear failed:', error);\n throw error;\n }\n }\n\n getConfig(): NetworkRepositoryConfig {\n return this.config;\n }\n\n /** Read a persisted snapshot (version + payload), falling back to memory.\n * Legacy bare-version entries and corrupt snapshots are deleted on sight \u2014\n * a version without its payload must never drive a conditional request. */\n private getSnapshot(namespaceKey: string): NamespaceSnapshot | undefined {\n const mem = this.namespaceSnapshots.get(namespaceKey);\n if (mem) return mem;\n try {\n localStorage.removeItem(NetworkRepository.LEGACY_VERSION_PREFIX + namespaceKey);\n const raw = localStorage.getItem(NetworkRepository.SNAPSHOT_PREFIX + namespaceKey);\n if (raw) {\n const parsed = JSON.parse(raw) as NamespaceSnapshot;\n if (\n parsed &&\n typeof parsed.version === 'string' &&\n parsed.version.length > 0 &&\n parsed.translations &&\n typeof parsed.translations === 'object'\n ) {\n this.namespaceSnapshots.set(namespaceKey, parsed);\n return parsed;\n }\n localStorage.removeItem(NetworkRepository.SNAPSHOT_PREFIX + namespaceKey);\n }\n } catch {\n /* SSR, localStorage unavailable, or corrupt JSON */\n }\n return undefined;\n }\n\n /** Persist version + payload as ONE entry (memory + localStorage). On quota\n * failure the previous stored snapshot stays \u2014 still a consistent pair. */\n private setSnapshot(namespaceKey: string, snapshot: NamespaceSnapshot): void {\n this.namespaceSnapshots.set(namespaceKey, snapshot);\n try {\n localStorage.setItem(\n NetworkRepository.SNAPSHOT_PREFIX + namespaceKey,\n JSON.stringify(snapshot)\n );\n localStorage.removeItem(NetworkRepository.LEGACY_VERSION_PREFIX + namespaceKey);\n } catch {\n /* quota exceeded or unavailable \u2014 memory copy still serves this session */\n }\n }\n\n /**\n * Handle HTTP error responses by mapping to domain errors\n * @throws {TranslationNotFoundError} When status is 404\n * @throws {TranslationLockedError} When status is 423\n * @throws {ServerError} When status is 5xx\n * @throws {NetworkError} For other client errors\n */\n private handleHttpError(response: Response, key: string): never {\n logger.debug(`API response: ${response.status} ${response.statusText}`);\n\n if (response.status === 404) {\n throw new TranslationNotFoundError(key);\n }\n\n if (response.status === 423) {\n const retryAfter = response.headers.get('Retry-After');\n throw new TranslationLockedError(\n key,\n retryAfter ? parseInt(retryAfter, 10) * 1000 : undefined\n );\n }\n\n if (response.status >= 500 && response.status < 600) {\n throw new ServerError(key, response.status);\n }\n\n // Other client errors (400, 401, 403, etc.)\n throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n /**\n * Handle caught errors by wrapping non-domain errors\n * @throws {TranslationError} Always throws - propagates domain errors or wraps unexpected ones\n */\n private handleCaughtError(error: unknown): never {\n // Custom errors propagate automatically, wrap everything else\n if (\n error instanceof TranslationNotFoundError ||\n error instanceof TranslationLockedError ||\n error instanceof ServerError ||\n error instanceof NetworkError\n ) {\n throw error;\n }\n\n // Wrap unexpected errors (fetch abort, JSON parse, etc.)\n throw new NetworkError('Network request failed', error);\n }\n\n /**\n * Build URL from endpoint template and parameters\n * Supports placeholders: :key, :locale, :namespace\n * @param endpoint - Endpoint key from DEFAULT_ENDPOINTS\n * @param params - Parameters to replace placeholders with\n * @returns Complete URL with baseUrl + endpoint path\n */\n private buildUrl(\n endpoint: keyof typeof this.DEFAULT_ENDPOINTS,\n params: Record<string, string> = {}\n ): string {\n const baseUrl = this.config.options?.baseUrl || '';\n\n // Get endpoint template from config or use default\n let endpointTemplate =\n this.config.options?.endpoints?.[endpoint] ||\n this.DEFAULT_ENDPOINTS[endpoint];\n\n // Ensure endpoint starts with / for consistent URL building\n if (!endpointTemplate.startsWith('/')) {\n endpointTemplate = `/${endpointTemplate}`;\n }\n\n // Replace all placeholders with actual values (encoded)\n // Use global replace to handle multiple occurrences\n let path = endpointTemplate;\n for (const [key, value] of Object.entries(params)) {\n const placeholder = new RegExp(`:${key}`, 'g');\n path = path.replace(placeholder, encodeURIComponent(value));\n }\n\n return `${baseUrl}${path}`;\n }\n\n /**\n * Make HTTP request with timeout and headers\n */\n private makeRequest(\n url: string,\n method: string,\n body?: unknown,\n extraHeaders?: Record<string, string>\n ): Promise<Response> {\n if (this.authFailedStatus !== null) {\n return Promise.resolve(\n new Response(null, {\n status: this.authFailedStatus,\n statusText: `auth latched off after ${this.authFailedStatus}`,\n })\n );\n }\n\n if (method !== 'GET') {\n if (this.writesFailedStatus !== null) {\n return Promise.resolve(\n new Response(null, {\n status: this.writesFailedStatus,\n statusText: `writes latched off after ${this.writesFailedStatus}`,\n })\n );\n }\n return this.doFetch(url, method, body, extraHeaders).then(resp =>\n this.recordOutcome(url, method, resp)\n );\n }\n\n const negative = this.negativeCache.get(url);\n if (negative) {\n if (Date.now() < negative.until) {\n logger.debug(`Negative-cache hit (${negative.status}): ${url}`);\n const headers =\n negative.status === 423\n ? { 'Retry-After': String(Math.ceil((negative.until - Date.now()) / 1000)) }\n : undefined;\n return Promise.resolve(\n new Response(null, { status: negative.status, statusText: 'negative cache', headers })\n );\n }\n this.negativeCache.delete(url);\n }\n\n const flightKey = `${url}|${extraHeaders?.['If-None-Match'] ?? ''}`;\n const existing = this.inflightGets.get(flightKey);\n if (existing) {\n return existing.then(resp => this.cloneResponse(resp));\n }\n\n const flight = this.doFetch(url, method, body, extraHeaders)\n .then(resp => this.recordOutcome(url, method, resp))\n .finally(() => this.inflightGets.delete(flightKey));\n this.inflightGets.set(flightKey, flight);\n return flight.then(resp => this.cloneResponse(resp));\n }\n\n /** Bookkeeping on every real (non-synthesized) response \u2014 runs once per\n * physical fetch, never once per coalesced awaiter. */\n private recordOutcome(url: string, method: string, response: Response): Response {\n const status = response.status;\n\n if (status === 401 || (status === 403 && method === 'GET')) {\n if (this.authFailedStatus === null) {\n this.authFailedStatus = status;\n // eslint-disable-next-line no-console\n console.warn(\n `[LionRapid] API key rejected (${status}) \u2014 network translations ` +\n 'are disabled for this session. Fix the key and reload; ' +\n 'retrying cannot heal an auth failure.'\n );\n }\n return response;\n }\n\n // A 403 (scope) or 429 (quota) on a WRITE degrades to read-only,\n // silently: the key still reads fine \u2014 only the sync path is denied,\n // and retrying won't change the server's answer (Phase 18).\n if ((status === 403 || status === 429) && method !== 'GET') {\n if (this.writesFailedStatus === null) {\n this.writesFailedStatus = status;\n logger.warn(\n `Write path disabled after ${status} (scope/quota) \u2014 running read-only`\n );\n }\n return response;\n }\n\n if (method === 'GET' && (status === 404 || status === 423)) {\n const retryAfterSec =\n status === 423 ? Number(response.headers?.get?.('Retry-After')) : NaN;\n const ttl =\n Number.isFinite(retryAfterSec) && retryAfterSec > 0\n ? retryAfterSec * 1000\n : (this.config.options?.negativeCacheTtlMs ??\n NetworkRepository.DEFAULT_NEGATIVE_TTL_MS);\n this.negativeCache.set(url, { status, until: Date.now() + ttl });\n } else if (method !== 'GET' && response.ok) {\n // A write landed \u2014 server state changed, cached misses may now exist.\n this.negativeCache.clear();\n } else if (method === 'GET' && response.ok) {\n this.negativeCache.delete(url);\n }\n\n return response;\n }\n\n /** Test doubles (and exotic runtimes) hand us plain objects \u2014 only real\n * Responses need cloning so each coalesced awaiter can read the body. */\n private cloneResponse(response: Response): Response {\n return typeof response.clone === 'function' ? response.clone() : response;\n }\n\n private async doFetch(\n url: string,\n method: string,\n body?: unknown,\n extraHeaders?: Record<string, string>\n ): Promise<Response> {\n const controller = new AbortController();\n const timeout = this.config.options?.timeout ?? 10000;\n const timeoutId = setTimeout(\n () => controller.abort(),\n timeout\n );\n\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n [SURFACE_HEADER]: SURFACE_TAG,\n ...this.config.options?.headers,\n ...extraHeaders,\n };\n\n if (this.config.options?.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.options.apiKey}`;\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n}\n", "/**\n * Exclude Filter\n * Filters out text that should not be translated\n * Mirrors PHP's HtmlTranslator logic\n */\n\nexport interface ExcludePatterns {\n emails: boolean;\n urls: boolean;\n numbers: boolean;\n phones: boolean;\n}\n\nconst DEFAULT_PATTERNS: ExcludePatterns = {\n emails: true,\n urls: true,\n numbers: true,\n phones: true,\n};\n\n// Regex patterns matching PHP's HtmlTranslator\nconst PATTERNS = {\n email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n url: /^(https?:\\/\\/|www\\.)[^\\s]+$/i,\n number: /^[\\d\\s.,+-]+$/,\n phone: /^[+\\d][\\d\\s().-]{6,}$/,\n};\n\nexport class ExcludeFilter {\n private patterns: ExcludePatterns;\n private minTextLength: number;\n\n constructor(patterns: Partial<ExcludePatterns> = {}, minTextLength = 2) {\n this.patterns = { ...DEFAULT_PATTERNS, ...patterns };\n this.minTextLength = minTextLength;\n }\n\n /**\n * Check if text should be excluded from translation\n */\n shouldExclude(text: string): boolean {\n const trimmed = text.trim();\n\n // Too short\n if (trimmed.length < this.minTextLength) {\n return true;\n }\n\n // Check auto-exclude patterns\n if (this.patterns.emails && PATTERNS.email.test(trimmed)) {\n return true;\n }\n\n if (this.patterns.urls && PATTERNS.url.test(trimmed)) {\n return true;\n }\n\n if (this.patterns.numbers && PATTERNS.number.test(trimmed)) {\n return true;\n }\n\n if (this.patterns.phones && PATTERNS.phone.test(trimmed)) {\n return true;\n }\n\n return false;\n }\n}\n", "/**\n * DOM-based Markup Parser (raw-only)\n *\n * Converts a block element's childNodes into ContentUnit by walking the\n * DOM. Every inline element becomes an indexed tag whose style is the\n * verbatim opening tag in canonical form (see content/canonical-tag.ts).\n *\n * Mirrors the regex-based parser in `content/parser/MarkupParser.ts` and\n * the edge proxy parser, producing byte-identical text + styles for the\n * same source so translation keys match across boundaries.\n */\n\nimport type { ContentUnit } from '../content/types.js';\nimport { serializeOpeningTag, VOID_TAGS } from '../content/canonical-tag.js';\n\n/**\n * Parse a block element into ContentUnit using DOM walking.\n */\nexport function parseBlockElement(element: Element): ContentUnit {\n const styles: Record<string, string[]> = {};\n let tagIndex = 0;\n\n function walk(node: Node): string {\n if (node.nodeType === Node.TEXT_NODE) {\n return node.nodeValue ?? '';\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return '';\n }\n\n const el = node as Element;\n const tag = el.tagName.toLowerCase();\n\n // Collect attributes preserving source insertion order.\n const attrs: Record<string, string> = {};\n for (let i = 0; i < el.attributes.length; i++) {\n const attr = el.attributes[i];\n attrs[attr.name.toLowerCase()] = attr.value;\n }\n\n tagIndex++;\n const idx = tagIndex;\n styles[String(idx)] = [`raw:${serializeOpeningTag(tag, attrs)}`];\n\n if (VOID_TAGS.has(tag)) {\n return `<${idx}/>`;\n }\n\n let inner = '';\n for (let i = 0; i < node.childNodes.length; i++) {\n inner += walk(node.childNodes[i]);\n }\n return `<${idx}>${inner}</${idx}>`;\n }\n\n let text = '';\n for (let i = 0; i < element.childNodes.length; i++) {\n text += walk(element.childNodes[i]);\n }\n\n return { text, styles };\n}\n", "/**\n * MD5 Hash Implementation\n * Minimal implementation to match PHP's md5() function\n * Used for generating auto_* keys that match server-side\n */\n\n/* eslint-disable no-bitwise */\n\nfunction safeAdd(x: number, y: number): number {\n const lsw = (x & 0xffff) + (y & 0xffff);\n const msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xffff);\n}\n\nfunction bitRotateLeft(num: number, cnt: number): number {\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\nfunction md5cmn(\n q: number,\n a: number,\n b: number,\n x: number,\n s: number,\n t: number\n): number {\n return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);\n}\n\nfunction md5ff(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn((b & c) | (~b & d), a, b, x, s, t);\n}\n\nfunction md5gg(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\n\nfunction md5hh(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn(b ^ c ^ d, a, b, x, s, t);\n}\n\nfunction md5ii(\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n s: number,\n t: number\n): number {\n return md5cmn(c ^ (b | ~d), a, b, x, s, t);\n}\n\nfunction binlMD5(x: number[], len: number): number[] {\n x[len >> 5] |= 0x80 << len % 32;\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n let a = 1732584193;\n let b = -271733879;\n let c = -1732584194;\n let d = 271733878;\n\n for (let i = 0; i < x.length; i += 16) {\n const olda = a;\n const oldb = b;\n const oldc = c;\n const oldd = d;\n\n a = md5ff(a, b, c, d, x[i], 7, -680876936);\n d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\n c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\n a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\n d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\n b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\n a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\n c = md5ff(c, d, a, b, x[i + 10], 17, -42063);\n b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\n d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\n c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\n\n a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\n d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\n b = md5gg(b, c, d, a, x[i], 20, -373897302);\n a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\n c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\n b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\n d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\n c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\n a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\n d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\n b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\n\n a = md5hh(a, b, c, d, x[i + 5], 4, -378558);\n d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\n c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\n b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\n d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\n c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\n a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\n d = md5hh(d, a, b, c, x[i + 0], 11, -358537222);\n c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\n b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\n a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\n c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\n b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\n\n a = md5ii(a, b, c, d, x[i], 6, -198630844);\n d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\n c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\n a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\n d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\n b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\n a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\n c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\n b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\n d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\n c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\n\n a = safeAdd(a, olda);\n b = safeAdd(b, oldb);\n c = safeAdd(c, oldc);\n d = safeAdd(d, oldd);\n }\n\n return [a, b, c, d];\n}\n\nfunction binl2hex(binarray: number[]): string {\n const hexTab = '0123456789abcdef';\n let str = '';\n for (let i = 0; i < binarray.length * 4; i++) {\n str +=\n hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) +\n hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf);\n }\n return str;\n}\n\n/**\n * Encode a string to its UTF-8 bytes. PHP's md5() operates on bytes, so to\n * match its output we must hash the UTF-8 representation \u2014 not raw UTF-16\n * code units. The previous code did `charCodeAt & 0xff`, which truncated\n * any character above U+00FF to a single low byte: U+2019 (curly `'`) was\n * hashed as 0x19 instead of its real UTF-8 form `E2 80 99`. That silently\n * broke key parity with PHP for every non-ASCII character on the page.\n */\nfunction utf8Bytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str);\n }\n // Fallback (older Node/test envs without TextEncoder).\n const out: number[] = [];\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 0x80) {\n out.push(c);\n } else if (c < 0x800) {\n out.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f));\n } else if (c >= 0xd800 && c < 0xdc00 && i + 1 < str.length) {\n const c2 = str.charCodeAt(++i);\n const cp = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n out.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f),\n );\n } else {\n out.push(\n 0xe0 | (c >> 12),\n 0x80 | ((c >> 6) & 0x3f),\n 0x80 | (c & 0x3f),\n );\n }\n }\n return new Uint8Array(out);\n}\n\nfunction bytes2binl(bytes: Uint8Array): number[] {\n const bin: number[] = [];\n for (let i = 0; i < bytes.length; i++) {\n bin[i >> 2] |= bytes[i] << ((i % 4) * 8);\n }\n return bin;\n}\n\n/**\n * Generate MD5 hash of a string.\n * Hashes the UTF-8 bytes of `str` so output matches PHP's `md5()` for any\n * input \u2014 ASCII or not.\n */\nexport function md5(str: string): string {\n const bytes = utf8Bytes(str);\n return binl2hex(binlMD5(bytes2binl(bytes), bytes.length * 8));\n}\n\n/**\n * Generate auto key matching PHP's TranslationStateManager::generateKey()\n * Format: auto_ + first 12 chars of md5 hash\n */\nexport function generateAutoKey(text: string): string {\n const trimmed = text.trim();\n return 'auto_' + md5(trimmed).substring(0, 12);\n}\n", "/**\n * Block Extractor\n * Finds translatable block elements in DOM and parses them into ContentUnit.\n * Mirrors WordPress TS BlockExtractor and edge proxy block-level approach.\n */\n\nimport type { ContentUnit } from '../content/types.js';\nimport { ExcludeFilter, ExcludePatterns } from './exclude-filter.js';\nimport { parseBlockElement } from './markup-parser.js';\nimport { generateAutoKey } from './md5.js';\n\nconst BLOCK_SELECTOR =\n 'p,h1,h2,h3,h4,h5,h6,li,td,th,label,button,figcaption,dt,dd,summary,caption';\n\n// Inline elements eligible for \"orphan\" extraction when they have no block\n// ancestor. Without this, markup like `<div><a>Transfer</a></div>` produces\n// zero translatable units because <div>/<a> are absent from BLOCK_SELECTOR\n// and the link has no <p>/<li>/etc. parent to absorb it as an indexed style.\n// Conservative on purpose: only <a>. <span>/<button> can join later if real\n// usage demands it (button is already a block tag).\nconst INLINE_BLOCK_SELECTOR = 'a';\n\n// Tags to skip (same as PHP/edge)\nconst SKIP_TAGS = new Set([\n 'SCRIPT',\n 'STYLE',\n 'CODE',\n 'PRE',\n 'TEXTAREA',\n 'NOSCRIPT',\n 'SVG',\n]);\n\n// Attributes that mark elements to skip\nconst SKIP_ATTRIBUTES = [\n 'data-lionrapid-translated', // Server already translated\n 'data-lionrapid-client', // Client already translated\n 'data-no-translate', // Explicitly marked to skip\n // Edge proxy already rendered this block with the correct translation\n // and styles. Skip in normal extraction so the client-side auto-translator\n // can't overwrite the styled DOM with a stale (or plain-text) cache entry.\n // The editor passes includeTranslated=true to bypass this and re-extract\n // edge-rendered blocks for inspection.\n 'data-lr-block',\n];\n\nexport interface ExtractedBlock {\n element: Element;\n unit: ContentUnit;\n key: string;\n}\n\nexport class BlockExtractor {\n private excludeFilter: ExcludeFilter;\n private excludeSelectors: string[];\n\n constructor(\n excludePatterns: Partial<ExcludePatterns> = {},\n excludeSelectors: string[] = [],\n minTextLength = 2\n ) {\n this.excludeFilter = new ExcludeFilter(excludePatterns, minTextLength);\n this.excludeSelectors = excludeSelectors;\n }\n\n /**\n * Extract all translatable block elements from a root.\n * @param includeTranslated - If true, include elements already marked as translated (for editor mode)\n */\n extract(root: Element | Document, includeTranslated = false): ExtractedBlock[] {\n const results: ExtractedBlock[] = [];\n const descendants = root.querySelectorAll(BLOCK_SELECTOR);\n\n // Include the root itself if it matches the block selector\n const elements: Element[] = [];\n if (root instanceof Element && root.matches(BLOCK_SELECTOR)) {\n elements.push(root);\n }\n for (let i = 0; i < descendants.length; i++) {\n elements.push(descendants[i]);\n }\n\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n // Skip if inside a SKIP_TAG ancestor\n if (this.isInsideSkipTag(el)) {\n continue;\n }\n\n // Skip if has skip attributes (unless editor mode includes translated)\n if (!includeTranslated && this.hasSkipAttribute(el)) {\n continue;\n }\n\n // Skip if matches exclude selectors\n if (this.matchesExcludeSelector(el)) {\n continue;\n }\n\n // Skip if has translate=\"no\"\n if (el.getAttribute('translate') === 'no') {\n continue;\n }\n\n // Skip nested block elements (let the inner blocks be extracted)\n if (el.querySelector(BLOCK_SELECTOR)) {\n continue;\n }\n\n // For already-translated elements, use original HTML for key + unit\n const lrBlock = el.getAttribute('data-lr-block');\n const lrOriginal = el.getAttribute('data-lr-original');\n\n let unit: ContentUnit;\n if (lrOriginal) {\n // Parse original (source) HTML \u2192 correct ContentUnit for key generation\n const temp = document.createElement(el.tagName);\n temp.innerHTML = lrOriginal;\n unit = parseBlockElement(temp);\n } else {\n unit = parseBlockElement(el);\n }\n\n // Strip indexed tags for exclude filter\n const strippedText = unit.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n\n // Apply exclude filter\n if (this.excludeFilter.shouldExclude(strippedText)) {\n continue;\n }\n\n // Key priority: data-lr-block (translated) \u2192 data-i18n (named) \u2192 auto-generate\n let key: string;\n if (lrBlock) {\n key = lrBlock;\n } else {\n const dataI18n = el.getAttribute('data-i18n');\n if (dataI18n) {\n key = dataI18n.includes(':') ? dataI18n : `common:${dataI18n}`;\n } else {\n key = generateAutoKey(unit.text);\n }\n }\n\n results.push({ element: el, unit, key });\n }\n\n this.extractOrphanInline(root, results, includeTranslated);\n\n return results;\n }\n\n /**\n * Second pass: extract inline elements (currently <a>) that have no block\n * ancestor. These would otherwise slip through both the block pass (not in\n * BLOCK_SELECTOR) and the inline-style capture (no parent block to host\n * them as `<1>...</1>`). Common shape: a `<div>` action group containing\n * only links.\n */\n private extractOrphanInline(\n root: Element | Document,\n results: ExtractedBlock[],\n includeTranslated: boolean\n ): void {\n const candidates = root.querySelectorAll(INLINE_BLOCK_SELECTOR);\n const elements: Element[] = [];\n if (root instanceof Element && root.matches(INLINE_BLOCK_SELECTOR)) {\n elements.push(root);\n }\n for (let i = 0; i < candidates.length; i++) {\n elements.push(candidates[i]);\n }\n\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n\n if (this.isInsideSkipTag(el)) continue;\n if (!includeTranslated && this.hasSkipAttribute(el)) continue;\n if (this.matchesExcludeSelector(el)) continue;\n if (el.getAttribute('translate') === 'no') continue;\n\n // Has a block ancestor \u2014 already captured as `<N>...</N>` by the\n // block pass (or its parent block was skipped, in which case we leave\n // it alone to avoid double-counting from a partially-skipped block).\n if (el.parentElement?.closest(BLOCK_SELECTOR)) continue;\n\n // Outer orphan wins: `<a><span>X</span></a>` \u2192 only the outer <a>.\n // (Currently INLINE_BLOCK_SELECTOR is just <a>, so this guards\n // against nested links in malformed HTML.)\n if (el.parentElement?.closest(INLINE_BLOCK_SELECTOR)) continue;\n\n // Contains a nested block \u2014 let the inner block be extracted instead.\n if (el.querySelector(BLOCK_SELECTOR)) continue;\n\n const lrOriginal = el.getAttribute('data-lr-original');\n let unit: ContentUnit;\n if (lrOriginal) {\n const temp = document.createElement(el.tagName);\n temp.innerHTML = lrOriginal;\n unit = parseBlockElement(temp);\n } else {\n unit = parseBlockElement(el);\n }\n\n const strippedText = unit.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n if (this.excludeFilter.shouldExclude(strippedText)) continue;\n\n const lrBlock = el.getAttribute('data-lr-block');\n let key: string;\n if (lrBlock) {\n key = lrBlock;\n } else {\n const dataI18n = el.getAttribute('data-i18n');\n if (dataI18n) {\n key = dataI18n.includes(':') ? dataI18n : `common:${dataI18n}`;\n } else {\n key = generateAutoKey(unit.text);\n }\n }\n\n results.push({ element: el, unit, key });\n }\n }\n\n private isInsideSkipTag(element: Element): boolean {\n let current: Element | null = element.parentElement;\n while (current) {\n // Foreign elements (SVG/MathML) report a case-preserved tagName (\"svg\",\n // not \"SVG\"), so match case-insensitively or the SVG skip never fires.\n if (SKIP_TAGS.has(current.tagName.toUpperCase())) {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n }\n\n private hasSkipAttribute(element: Element): boolean {\n let current: Element | null = element;\n while (current) {\n for (const attr of SKIP_ATTRIBUTES) {\n if (current.hasAttribute(attr)) {\n return true;\n }\n }\n current = current.parentElement;\n }\n return false;\n }\n\n private matchesExcludeSelector(element: Element): boolean {\n for (const selector of this.excludeSelectors) {\n try {\n if (element.matches(selector) || element.closest(selector)) {\n return true;\n }\n } catch {\n // Invalid selector, skip\n }\n }\n return false;\n }\n}\n", "/**\n * Attribute Extractor\n *\n * Finds translatable HTML attribute values in the DOM and parses each\n * into an AttributeUnit. Pairs with BlockExtractor (text-content side)\n * to cover everything user-visible:\n *\n * - <img alt>, <area alt>, <input type=\"image\" alt>\n * - any element [title]\n * - <input placeholder>, <textarea placeholder>\n * - <meta name=\"description\" content=\"...\">\n * - <input type=\"submit|button|reset\" value>\n *\n * Cross-stack parity: produces the same auto_ key as BlockExtractor for\n * the same trimmed text \u2014 md5(text.trim()) prefix \u2014 so a button labelled\n * \"Submit\" and a paragraph \"Submit\" collide on key (intentional reuse).\n *\n * `<input type=\"text\" value=\"...\">` is deliberately excluded because\n * `value` on a plain text input is user data, not UI copy, and would\n * corrupt form state if treated as translatable.\n */\n\nimport type { AttributeKind, AttributeUnit } from '../content/types.js';\nimport { ExcludeFilter, type ExcludePatterns } from './exclude-filter.js';\nimport { generateAutoKey } from './md5.js';\n\ninterface AttributeTarget {\n /** CSS selector used to find candidate elements */\n selector: string;\n /** The actual HTML attribute name carrying the translatable value */\n attr: string;\n /** Semantic category exposed to the translation pipeline */\n type: AttributeKind;\n}\n\n// Each target has a unique `attr`, so a single element matching multiple\n// targets (e.g. `<input placeholder title>`) yields one ExtractedAttribute\n// per attribute \u2014 no cross-target dedup needed.\nconst TARGETS: AttributeTarget[] = [\n { selector: 'img[alt], area[alt], input[type=\"image\"][alt]', attr: 'alt', type: 'alt' },\n { selector: '[title]', attr: 'title', type: 'title' },\n { selector: 'input[placeholder], textarea[placeholder]', attr: 'placeholder', type: 'placeholder' },\n { selector: 'meta[name=\"description\"][content]', attr: 'content', type: 'meta-description' },\n {\n selector:\n 'input[type=\"submit\"][value], input[type=\"button\"][value], input[type=\"reset\"][value]',\n attr: 'value',\n type: 'input-value',\n },\n];\n\n// Skip the same containers as BlockExtractor \u2014 attribute values inside\n// <script>, <style>, etc. are never user-visible UI text.\nconst SKIP_TAGS = new Set([\n 'SCRIPT',\n 'STYLE',\n 'CODE',\n 'PRE',\n 'NOSCRIPT',\n 'SVG',\n]);\n\n// Ancestor attributes that opt the element out of translation. Matches\n// BlockExtractor's contract so authors get one consistent escape hatch.\nconst SKIP_ATTRIBUTES = [\n 'data-lionrapid-translated',\n 'data-lionrapid-client',\n 'data-no-translate',\n];\n\n/**\n * Server-stamped attribute marker \u2014 when the edge or PHP layer has already\n * keyed an attribute, the element carries `data-lr-attr-{name}=\"auto_xxx\"`.\n * Client extraction reads this instead of re-hashing, eliminating the same\n * class of cross-stack parity drift `data-lr-block` solves for body text.\n */\nfunction stampAttrName(attrName: string): string {\n return `data-lr-attr-${attrName.toLowerCase()}`;\n}\n\nexport interface ExtractedAttribute {\n /** Live element carrying the attribute */\n element: Element;\n /** HTML attribute name (e.g. `alt`, `content`) */\n attrName: string;\n /** Translatable payload */\n unit: AttributeUnit;\n /** auto_ key or server-stamped key */\n key: string;\n}\n\nexport class AttributeExtractor {\n private excludeFilter: ExcludeFilter;\n private excludeSelectors: string[];\n\n constructor(\n excludePatterns: Partial<ExcludePatterns> = {},\n excludeSelectors: string[] = [],\n minTextLength = 2\n ) {\n this.excludeFilter = new ExcludeFilter(excludePatterns, minTextLength);\n this.excludeSelectors = excludeSelectors;\n }\n\n /**\n * Walk the DOM under `root` and return every translatable attribute.\n *\n * @param root Element or Document to scan\n * @param includeStamped When true, elements already carrying\n * `data-lr-attr-{name}` are returned anyway \u2014\n * the editor uses this to surface server-handled\n * attributes for inspection. The runtime keeps\n * the default `false` so it doesn't re-extract\n * what the server already keyed.\n */\n extract(root: Element | Document, includeStamped = false): ExtractedAttribute[] {\n const results: ExtractedAttribute[] = [];\n\n for (const target of TARGETS) {\n const candidates = root.querySelectorAll(target.selector);\n const all: Element[] = [];\n if (root instanceof Element && root.matches(target.selector)) {\n all.push(root);\n }\n for (let i = 0; i < candidates.length; i++) {\n all.push(candidates[i]);\n }\n\n for (let i = 0; i < all.length; i++) {\n const el = all[i];\n\n if (this.isInsideSkipTag(el)) continue;\n if (this.hasSkipAncestor(el)) continue;\n if (this.matchesExcludeSelector(el)) continue;\n if (el.getAttribute('translate') === 'no') continue;\n\n const rawValue = el.getAttribute(target.attr);\n if (rawValue === null) continue;\n\n const trimmed = rawValue.trim();\n if (this.excludeFilter.shouldExclude(trimmed)) continue;\n\n const stampName = stampAttrName(target.attr);\n const stamped = el.getAttribute(stampName);\n if (!includeStamped && stamped) {\n continue;\n }\n\n const unit: AttributeUnit = { text: rawValue, type: target.type };\n const key = stamped ?? generateAutoKey(rawValue);\n\n results.push({ element: el, attrName: target.attr, unit, key });\n }\n }\n\n return results;\n }\n\n private isInsideSkipTag(element: Element): boolean {\n let current: Element | null = element.parentElement;\n while (current) {\n // Case-insensitive: foreign elements (SVG) keep a lowercase tagName.\n if (SKIP_TAGS.has(current.tagName.toUpperCase())) return true;\n current = current.parentElement;\n }\n return false;\n }\n\n private hasSkipAncestor(element: Element): boolean {\n let current: Element | null = element;\n while (current) {\n for (const attr of SKIP_ATTRIBUTES) {\n if (current.hasAttribute(attr)) return true;\n }\n current = current.parentElement;\n }\n return false;\n }\n\n private matchesExcludeSelector(element: Element): boolean {\n for (const selector of this.excludeSelectors) {\n try {\n if (element.matches(selector) || element.closest(selector)) {\n return true;\n }\n } catch {\n // Invalid selector \u2014 skip silently, same as BlockExtractor.\n }\n }\n return false;\n }\n}\n", "/**\n * DOM Observer\n * Watches for dynamically added content using MutationObserver\n * Triggers translation of new content (AJAX, SPA navigation, etc.)\n */\n\nexport interface DOMObserverCallbacks {\n onNewContent?: (element: Element) => void;\n onNewSwitchers?: () => void;\n}\n\nexport class DOMObserver {\n private observer: MutationObserver | null = null;\n private callbacks: DOMObserverCallbacks;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private pendingElements: Set<Element> = new Set();\n private debounceMs: number;\n\n constructor(callbacks: DOMObserverCallbacks, debounceMs = 50) {\n this.callbacks = callbacks;\n this.debounceMs = debounceMs;\n }\n\n /**\n * Start observing DOM changes\n */\n start(): void {\n if (this.observer) {\n return;\n }\n\n this.observer = new MutationObserver((mutations) => {\n this.handleMutations(mutations);\n });\n\n this.observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n /**\n * Stop observing\n */\n stop(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n this.pendingElements.clear();\n }\n\n /**\n * Handle DOM mutations\n */\n private handleMutations(mutations: MutationRecord[]): void {\n let hasNewSwitchers = false;\n\n for (const mutation of mutations) {\n for (const node of Array.from(mutation.addedNodes)) {\n if (node.nodeType !== Node.ELEMENT_NODE) continue;\n\n const element = node as Element;\n\n // Check for language switchers\n if (this.hasLanguageSwitcher(element)) {\n hasNewSwitchers = true;\n }\n\n // Queue for auto-translation\n if (this.callbacks.onNewContent) {\n this.pendingElements.add(element);\n }\n }\n }\n\n // Trigger switcher callback immediately\n if (hasNewSwitchers && this.callbacks.onNewSwitchers) {\n this.callbacks.onNewSwitchers();\n }\n\n // Debounce content translation\n if (this.pendingElements.size > 0) {\n this.scheduleFlush();\n }\n }\n\n /**\n * Schedule debounced processing of pending elements\n */\n private scheduleFlush(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n this.debounceTimer = setTimeout(() => {\n this.flushPendingElements();\n }, this.debounceMs);\n }\n\n /**\n * Process all pending elements\n */\n private flushPendingElements(): void {\n if (!this.callbacks.onNewContent || this.pendingElements.size === 0) {\n return;\n }\n\n for (const element of this.pendingElements) {\n // Skip if element was removed from DOM\n if (!document.body.contains(element)) {\n continue;\n }\n this.callbacks.onNewContent(element);\n }\n\n this.pendingElements.clear();\n }\n\n /**\n * Check if element or children are language switchers\n */\n private hasLanguageSwitcher(element: Element): boolean {\n return (\n element.hasAttribute('data-lionrapid-switcher') ||\n element.querySelector('[data-lionrapid-switcher]') !== null\n );\n }\n}\n", "/**\n * Auto Translator\n * Automatically translates block-level elements in DOM content.\n * Uses ContentUnit model for key parity with WordPress TS, PHP, and edge proxy.\n *\n * Missing translations are reported via the event bus (translation:not-found),\n * picked up by MissingTranslationQueue, and synced through NetworkRepository.\n */\n\nimport type { LionRapidCore } from '../lionRapid.js';\nimport type { ContentUnit } from '../content/types.js';\nimport { BlockExtractor, ExtractedBlock } from './block-extractor.js';\nimport { AttributeExtractor, ExtractedAttribute } from './attribute-extractor.js';\nimport { ExcludePatterns } from './exclude-filter.js';\nimport { DOMObserver } from './dom-observer.js';\nimport { HTMLSerializer } from '../content/serializer/HTMLSerializer.js';\nimport { generateAutoKey } from './md5.js';\n\nconst htmlSerializer = new HTMLSerializer();\n\nexport interface AutoTranslatorConfig {\n excludePatterns?: Partial<ExcludePatterns>;\n excludeSelectors?: string[];\n minTextLength?: number;\n debounceMs?: number;\n}\n\nexport class AutoTranslator {\n private core: LionRapidCore | null = null;\n private blockExtractor: BlockExtractor;\n private attributeExtractor: AttributeExtractor;\n private domObserver: DOMObserver | null = null;\n private locale = '';\n private sourceLocale = '';\n private namespace = '';\n private debounceMs: number;\n private pendingElements: Set<Element> = new Set();\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private translatedCount = 0;\n\n constructor(config: AutoTranslatorConfig = {}) {\n this.blockExtractor = new BlockExtractor(\n config.excludePatterns,\n config.excludeSelectors,\n config.minTextLength\n );\n this.attributeExtractor = new AttributeExtractor(\n config.excludePatterns,\n config.excludeSelectors,\n config.minTextLength\n );\n this.debounceMs = config.debounceMs ?? 100;\n }\n\n /**\n * Set the core instance\n */\n setCore(core: LionRapidCore): void {\n this.core = core;\n }\n\n /**\n * Initialize locale and namespace for cache key construction\n */\n init(config: { namespace: string; locale: string; sourceLocale: string }): void {\n this.locale = config.locale;\n this.sourceLocale = config.sourceLocale;\n this.namespace = config.namespace;\n }\n\n /**\n * Update locale (after language change)\n */\n updateLocale(locale: string): void {\n this.locale = locale;\n }\n\n /**\n * Check if ready\n */\n isReady(): boolean {\n return this.core !== null;\n }\n\n /**\n * Generate auto key for text (exposed for testing)\n */\n generateAutoKey(text: string): string {\n return generateAutoKey(text);\n }\n\n /**\n * Queue an element for translation (debounced)\n */\n queueElement(element: Element): void {\n this.pendingElements.add(element);\n this.scheduleProcessing();\n }\n\n /**\n * Translate an element immediately\n */\n translateElement(element: Element): number {\n if (!this.core) {\n return 0;\n }\n\n const blockCount = this.translateBlocks(this.blockExtractor.extract(element));\n const attrCount = this.translateAttributesIn(this.attributeExtractor.extract(element));\n return blockCount + attrCount;\n }\n\n /**\n * Translate the entire page\n */\n translatePage(): number {\n return this.translateElement(document.body);\n }\n\n /**\n * Start observing DOM for dynamic content\n */\n observe(): void {\n if (this.domObserver) {\n return;\n }\n\n this.domObserver = new DOMObserver({\n onNewContent: (element) => this.queueElement(element),\n });\n this.domObserver.start();\n }\n\n /**\n * Stop observing DOM\n */\n stopObserving(): void {\n if (this.domObserver) {\n this.domObserver.stop();\n this.domObserver = null;\n }\n }\n\n /**\n * Schedule debounced processing\n */\n private scheduleProcessing(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n this.debounceTimer = setTimeout(() => {\n this.processPendingElements();\n }, this.debounceMs);\n }\n\n /**\n * Process all pending elements\n */\n private processPendingElements(): void {\n if (!this.core || this.pendingElements.size === 0) {\n return;\n }\n\n let totalTranslated = 0;\n\n for (const element of this.pendingElements) {\n // Skip if element was removed from DOM\n if (!document.body.contains(element)) {\n continue;\n }\n\n const count = this.translateElement(element);\n totalTranslated += count;\n }\n\n this.pendingElements.clear();\n this.translatedCount += totalTranslated;\n }\n\n /**\n * Translate extracted blocks using ContentUnit model\n */\n private translateBlocks(extracted: ExtractedBlock[]): number {\n if (!this.core) return 0;\n\n let count = 0;\n\n for (const { element, unit, key } of extracted) {\n // Construct full cache key: locale:namespace:key\n const fullKey = `${this.locale}:${this.namespace}:${key}`;\n\n // Look up translation from cache\n const cached = this.core.cache.get(fullKey);\n\n if (cached && cached.value !== unit.text && cached.value !== key) {\n // Translation found \u2014 save original HTML before first translation\n if (!element.hasAttribute('data-lr-original')) {\n element.setAttribute('data-lr-original', element.innerHTML);\n }\n\n // Source styles win when the cached translation lacks them. Mirrors\n // the edge proxy's `{...translation.styles, ...source.styles}` merge\n // so a stale plain-text cache entry can't strip inline wrappers\n // (`<span class=\"...\">`, `<b>`, `<a>`) that the source has.\n const cacheHasStyles = cached.styles && Object.keys(cached.styles).length > 0;\n const sourceHasStyles = Object.keys(unit.styles).length > 0;\n const hasIndexedMarkers = /<\\/?[0-9]+\\/?>/.test(cached.value);\n\n if (sourceHasStyles && !hasIndexedMarkers) {\n // Cache value is missing the indexed-tag structure needed to\n // re-attach the source styles. Don't clobber the DOM \u2014 leave\n // whatever's currently rendered (e.g. edge-rendered styled HTML)\n // and just mark the element so we don't reprocess it.\n } else {\n const styles = cacheHasStyles ? cached.styles! : unit.styles;\n const translatedUnit: ContentUnit = { text: cached.value, styles };\n element.innerHTML = htmlSerializer.serialize(translatedUnit);\n }\n element.setAttribute('data-lr-block', key);\n element.setAttribute('data-lionrapid-client', '1');\n count++;\n } else {\n // No translation \u2014 report missing via event bus\n // MissingTranslationQueue picks this up and syncs through NetworkRepository\n this.core.bus.emit('translation:not-found', {\n payload: {\n key,\n fallbackValue: unit.text,\n locale: this.sourceLocale,\n namespace: this.namespace,\n status: 404 as const,\n styles: unit.styles,\n },\n });\n }\n }\n\n return count;\n }\n\n /**\n * Translate extracted attribute units against the cache.\n *\n * Mirrors translateBlocks but for attribute values. For each hit, the\n * original attribute value is preserved in `data-lr-orig-{name}` so\n * retranslate() can restore source. The element accumulates a comma-\n * separated `data-lionrapid-client-attrs` list naming every attr the\n * client touched \u2014 so we can find them all on retranslate without\n * iterating a fixed selector set.\n *\n * Cache misses emit `translation:not-found` with empty styles, so the\n * existing MissingTranslationQueue + NetworkRepository sync queue\n * picks them up unchanged.\n */\n private translateAttributesIn(extracted: ExtractedAttribute[]): number {\n if (!this.core) return 0;\n let count = 0;\n\n for (const { element, attrName, unit, key } of extracted) {\n const fullKey = `${this.locale}:${this.namespace}:${key}`;\n const cached = this.core.cache.get(fullKey);\n\n if (cached && cached.value !== unit.text && cached.value !== key) {\n const lower = attrName.toLowerCase();\n const origAttr = `data-lr-orig-${lower}`;\n // Preserve the source value the first time we touch this attr,\n // so retranslate() can restore it even after multiple in-page\n // language switches.\n if (!element.hasAttribute(origAttr)) {\n element.setAttribute(origAttr, unit.text);\n }\n element.setAttribute(attrName, cached.value);\n element.setAttribute(`data-lr-attr-${lower}`, key);\n\n // Append to the client-attrs list (dedup so multiple passes\n // don't grow it without bound).\n const existing = element.getAttribute('data-lionrapid-client-attrs') ?? '';\n const set = new Set(existing.split(',').filter(Boolean));\n set.add(lower);\n element.setAttribute('data-lionrapid-client-attrs', Array.from(set).join(','));\n\n count++;\n } else {\n this.core.bus.emit('translation:not-found', {\n payload: {\n key,\n fallbackValue: unit.text,\n locale: this.sourceLocale,\n namespace: this.namespace,\n status: 404 as const,\n styles: {},\n },\n });\n }\n }\n\n return count;\n }\n\n /**\n * Get translated count\n */\n getTranslatedCount(): number {\n return this.translatedCount;\n }\n\n /**\n * Restore every client-translated attribute on `el` from its\n * `data-lr-orig-*` backup, then strip the stamps. Mirrors the block-side\n * restoration in retranslate() so language switch / editor reset clears\n * attributes too.\n */\n private restoreClientAttributes(el: Element): void {\n const list = el.getAttribute('data-lionrapid-client-attrs');\n if (list === null) return;\n for (const name of list.split(',').filter(Boolean)) {\n const orig = el.getAttribute(`data-lr-orig-${name}`);\n if (orig !== null) {\n el.setAttribute(name, orig);\n el.removeAttribute(`data-lr-orig-${name}`);\n }\n el.removeAttribute(`data-lr-attr-${name}`);\n }\n el.removeAttribute('data-lionrapid-client-attrs');\n }\n\n /**\n * Re-translate a single element (for editor live preview reset)\n */\n retranslateElement(element: Element): void {\n const original = element.getAttribute('data-lr-original');\n if (original !== null) element.innerHTML = original;\n element.removeAttribute('data-lionrapid-client');\n element.removeAttribute('data-lr-block');\n this.restoreClientAttributes(element);\n this.translateElement(element);\n }\n\n /**\n * Re-translate the page (after language change)\n */\n retranslate(): void {\n // Restore original HTML for all previously translated blocks\n const translatedBlocks = document.querySelectorAll('[data-lionrapid-client]');\n translatedBlocks.forEach((el) => {\n const original = el.getAttribute('data-lr-original');\n if (original !== null) {\n el.innerHTML = original;\n }\n el.removeAttribute('data-lionrapid-client');\n el.removeAttribute('data-lr-block');\n });\n\n // Restore source values for client-translated attributes. Selector\n // matches the marker the attribute pass writes; per-name lists live\n // inside that attribute so we don't need a fixed selector per kind.\n const translatedAttrs = document.querySelectorAll('[data-lionrapid-client-attrs]');\n translatedAttrs.forEach((el) => this.restoreClientAttributes(el));\n\n // Re-translate (blocks are now back to source text, so auto_keys will be correct)\n this.translatedCount = 0;\n if (this.locale !== this.sourceLocale) {\n this.translatePage();\n }\n }\n}\n", "/**\n * Language Switcher\n * Auto-generates floating language switcher UI from data-lionrapid-switcher attributes.\n * All styles are fixed-position overlays \u2014 the style only changes the visual appearance.\n *\n * Styles:\n * - floating: button showing current language \u2192 click opens dropdown menu\n * - buttons: row of language code buttons (EN, ES, FR)\n * - flags: row of flag + name buttons\n */\n\nimport type { LionRapidCore } from '../lionRapid.js';\n\nexport type SwitcherStyle = 'flags' | 'buttons' | 'floating';\n\nexport interface Language {\n code: string;\n name: string;\n flag?: string;\n}\n\n// Default language data (expandable)\nconst DEFAULT_LANGUAGES: Record<string, Language> = {\n en: { code: 'en', name: 'English', flag: '\uD83C\uDDEC\uD83C\uDDE7' },\n es: { code: 'es', name: 'Espa\u00F1ol', flag: '\uD83C\uDDEA\uD83C\uDDF8' },\n fr: { code: 'fr', name: 'Fran\u00E7ais', flag: '\uD83C\uDDEB\uD83C\uDDF7' },\n de: { code: 'de', name: 'Deutsch', flag: '\uD83C\uDDE9\uD83C\uDDEA' },\n it: { code: 'it', name: 'Italiano', flag: '\uD83C\uDDEE\uD83C\uDDF9' },\n pt: { code: 'pt', name: 'Portugu\u00EAs', flag: '\uD83C\uDDF5\uD83C\uDDF9' },\n nl: { code: 'nl', name: 'Nederlands', flag: '\uD83C\uDDF3\uD83C\uDDF1' },\n pl: { code: 'pl', name: 'Polski', flag: '\uD83C\uDDF5\uD83C\uDDF1' },\n ru: { code: 'ru', name: '\u0420\u0443\u0441\u0441\u043A\u0438\u0439', flag: '\uD83C\uDDF7\uD83C\uDDFA' },\n ja: { code: 'ja', name: '\u65E5\u672C\u8A9E', flag: '\uD83C\uDDEF\uD83C\uDDF5' },\n ko: { code: 'ko', name: '\uD55C\uAD6D\uC5B4', flag: '\uD83C\uDDF0\uD83C\uDDF7' },\n zh: { code: 'zh', name: '\u4E2D\u6587', flag: '\uD83C\uDDE8\uD83C\uDDF3' },\n ar: { code: 'ar', name: '\u0627\u0644\u0639\u0631\u0628\u064A\u0629', flag: '\uD83C\uDDF8\uD83C\uDDE6' },\n hi: { code: 'hi', name: '\u0939\u093F\u0928\u094D\u0926\u0940', flag: '\uD83C\uDDEE\uD83C\uDDF3' },\n tr: { code: 'tr', name: 'T\u00FCrk\u00E7e', flag: '\uD83C\uDDF9\uD83C\uDDF7' },\n vi: { code: 'vi', name: 'Ti\u1EBFng Vi\u1EC7t', flag: '\uD83C\uDDFB\uD83C\uDDF3' },\n th: { code: 'th', name: '\u0E44\u0E17\u0E22', flag: '\uD83C\uDDF9\uD83C\uDDED' },\n sv: { code: 'sv', name: 'Svenska', flag: '\uD83C\uDDF8\uD83C\uDDEA' },\n da: { code: 'da', name: 'Dansk', flag: '\uD83C\uDDE9\uD83C\uDDF0' },\n fi: { code: 'fi', name: 'Suomi', flag: '\uD83C\uDDEB\uD83C\uDDEE' },\n no: { code: 'no', name: 'Norsk', flag: '\uD83C\uDDF3\uD83C\uDDF4' },\n cs: { code: 'cs', name: '\u010Ce\u0161tina', flag: '\uD83C\uDDE8\uD83C\uDDFF' },\n el: { code: 'el', name: '\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC', flag: '\uD83C\uDDEC\uD83C\uDDF7' },\n he: { code: 'he', name: '\u05E2\u05D1\u05E8\u05D9\u05EA', flag: '\uD83C\uDDEE\uD83C\uDDF1' },\n id: { code: 'id', name: 'Bahasa Indonesia', flag: '\uD83C\uDDEE\uD83C\uDDE9' },\n ms: { code: 'ms', name: 'Bahasa Melayu', flag: '\uD83C\uDDF2\uD83C\uDDFE' },\n uk: { code: 'uk', name: '\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430', flag: '\uD83C\uDDFA\uD83C\uDDE6' },\n ro: { code: 'ro', name: 'Rom\u00E2n\u0103', flag: '\uD83C\uDDF7\uD83C\uDDF4' },\n hu: { code: 'hu', name: 'Magyar', flag: '\uD83C\uDDED\uD83C\uDDFA' },\n sk: { code: 'sk', name: 'Sloven\u010Dina', flag: '\uD83C\uDDF8\uD83C\uDDF0' },\n bg: { code: 'bg', name: '\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438', flag: '\uD83C\uDDE7\uD83C\uDDEC' },\n hr: { code: 'hr', name: 'Hrvatski', flag: '\uD83C\uDDED\uD83C\uDDF7' },\n sr: { code: 'sr', name: '\u0421\u0440\u043F\u0441\u043A\u0438', flag: '\uD83C\uDDF7\uD83C\uDDF8' },\n sl: { code: 'sl', name: 'Sloven\u0161\u010Dina', flag: '\uD83C\uDDF8\uD83C\uDDEE' },\n lt: { code: 'lt', name: 'Lietuvi\u0173', flag: '\uD83C\uDDF1\uD83C\uDDF9' },\n lv: { code: 'lv', name: 'Latvie\u0161u', flag: '\uD83C\uDDF1\uD83C\uDDFB' },\n et: { code: 'et', name: 'Eesti', flag: '\uD83C\uDDEA\uD83C\uDDEA' },\n};\n\n// All switcher styles are floating overlays \u2014 position: fixed with configurable corner\nconst STYLES = `\n.lionrapid-switcher {\n position: fixed;\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n}\n.lionrapid-switcher[data-position=\"top-left\"] { top: 20px; left: 20px; }\n.lionrapid-switcher[data-position=\"top-right\"] { top: 20px; right: 20px; }\n.lionrapid-switcher[data-position=\"bottom-left\"] { bottom: 20px; left: 20px; }\n.lionrapid-switcher[data-position=\"bottom-right\"] { bottom: 20px; right: 20px; }\n\n/* Floating style: button + dropdown menu */\n.lionrapid-floating-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 16px;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n font-size: 14px;\n color: #333;\n}\n.lionrapid-floating-menu {\n display: none;\n position: absolute;\n margin: 4px 0;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n overflow: hidden;\n min-width: 150px;\n}\n.lionrapid-floating-menu.open { display: block; }\n.lionrapid-floating-menu button {\n display: block;\n width: 100%;\n padding: 8px 16px;\n text-align: left;\n background: none;\n border: none;\n cursor: pointer;\n color: #333;\n white-space: nowrap;\n font-size: 14px;\n}\n.lionrapid-floating-menu button:hover { background: #f5f5f5; }\n.lionrapid-floating-menu button.active { font-weight: 700; background: #f0f0f0; }\n\n/* Buttons + Flags styles: row of buttons */\n.lionrapid-btn-row {\n display: flex;\n gap: 0;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n overflow: hidden;\n}\n.lionrapid-btn-row button {\n padding: 8px 12px;\n font-size: 14px;\n border: none;\n border-right: 1px solid #eee;\n background: #fff;\n cursor: pointer;\n color: #333;\n white-space: nowrap;\n transition: background 0.15s;\n}\n.lionrapid-btn-row button:last-child { border-right: none; }\n.lionrapid-btn-row button:hover { background: #f5f5f5; }\n.lionrapid-btn-row button.active { background: #3b82f6; color: #fff; }\n`;\n\nexport class LanguageSwitcher {\n private core: LionRapidCore | null = null;\n private languages: Language[] = [];\n private initialLocale = 'en';\n private onLanguageChange: ((locale: string) => void) | null = null;\n private stylesInjected = false;\n\n constructor() {}\n\n /**\n * Set the core instance\n */\n setCore(core: LionRapidCore): void {\n this.core = core;\n }\n\n /**\n * Set initial locale (used before core is available)\n */\n setInitialLocale(locale: string): void {\n this.initialLocale = locale;\n }\n\n /**\n * Set available languages\n */\n setLanguages(languages: Language[] | string[]): void {\n this.languages = languages.map((lang) => {\n if (typeof lang === 'string') {\n return DEFAULT_LANGUAGES[lang] || { code: lang, name: lang };\n }\n return lang;\n });\n }\n\n /**\n * Set callback for language changes\n */\n setOnLanguageChange(callback: (locale: string) => void): void {\n this.onLanguageChange = callback;\n }\n\n /**\n * Initialize all switchers on the page\n */\n initAll(): void {\n this.injectStyles();\n const switchers = document.querySelectorAll('[data-lionrapid-switcher]');\n switchers.forEach((element) => this.initSwitcher(element as HTMLElement));\n }\n\n /**\n * Initialize a single switcher element\n */\n initSwitcher(element: HTMLElement): void {\n const style = (element.dataset.lionrapidSwitcher || 'floating') as SwitcherStyle;\n const currentLocale = this.core?.getCurrentLocale() || this.initialLocale;\n\n // Clear existing content\n element.innerHTML = '';\n element.classList.add('lionrapid-switcher');\n element.setAttribute('data-no-translate', '');\n element.setAttribute('translate', 'no');\n\n // Read config from data attributes\n const position = element.dataset.lionrapidSwitcherPosition || 'top-right';\n const showFlags = element.dataset.lionrapidSwitcherShowFlags !== 'false';\n const showNames = element.dataset.lionrapidSwitcherShowNames !== 'false';\n const customCss = element.dataset.lionrapidSwitcherCustomCss || null;\n\n // Set position for CSS\n element.dataset.position = position;\n\n // Inject custom CSS if provided\n if (customCss) {\n const styleEl = document.createElement('style');\n styleEl.textContent = customCss;\n document.head.appendChild(styleEl);\n }\n\n switch (style) {\n case 'flags':\n this.renderButtonRow(element, currentLocale, true, true);\n break;\n case 'buttons':\n this.renderButtonRow(element, currentLocale, showFlags, showNames);\n break;\n case 'floating':\n default:\n this.renderFloating(element, currentLocale, position, showFlags, showNames);\n break;\n }\n }\n\n /**\n * Render floating style (button showing current language \u2192 click opens dropdown menu)\n */\n private renderFloating(\n container: HTMLElement,\n currentLocale: string,\n position: string,\n showFlags: boolean,\n showNames: boolean,\n ): void {\n // Menu position: anchor above or below button, left or right aligned\n const menuStyle: Partial<CSSStyleDeclaration> = {};\n if (position.startsWith('bottom')) {\n menuStyle.bottom = '100%';\n } else {\n menuStyle.top = '100%';\n }\n if (position.endsWith('left')) {\n menuStyle.left = '0';\n } else {\n menuStyle.right = '0';\n }\n\n const formatLabel = (lang: Language): string => {\n const flag = showFlags ? (lang.flag || '') : '';\n const name = showNames ? lang.name : lang.code.toUpperCase();\n return `${flag}${flag && name ? ' ' : ''}${name}`;\n };\n\n // Current language display\n const currentLang = this.languages.find((l) => l.code === currentLocale) || this.languages[0];\n const currentLabel = currentLang ? formatLabel(currentLang) : currentLocale;\n\n // Button\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'lionrapid-floating-btn';\n btn.setAttribute('aria-expanded', 'false');\n btn.setAttribute('aria-haspopup', 'true');\n btn.textContent = `${currentLabel} \\u25BE`;\n\n // Menu\n const menu = document.createElement('div');\n menu.className = 'lionrapid-floating-menu';\n Object.assign(menu.style, menuStyle);\n\n for (const lang of this.languages) {\n const item = document.createElement('button');\n item.type = 'button';\n item.dataset.lang = lang.code;\n item.textContent = formatLabel(lang);\n if (lang.code === currentLocale) {\n item.classList.add('active');\n }\n item.addEventListener('click', () => {\n this.handleLanguageChange(lang.code);\n btn.textContent = formatLabel(lang) + ' \\u25BE';\n menu.querySelectorAll('button').forEach((b) => {\n b.classList.toggle('active', b.dataset.lang === lang.code);\n });\n menu.classList.remove('open');\n btn.setAttribute('aria-expanded', 'false');\n });\n menu.appendChild(item);\n }\n\n // Toggle menu on button click\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n const isOpen = menu.classList.contains('open');\n menu.classList.toggle('open', !isOpen);\n btn.setAttribute('aria-expanded', String(!isOpen));\n });\n\n // Close on outside click\n document.addEventListener('click', () => {\n menu.classList.remove('open');\n btn.setAttribute('aria-expanded', 'false');\n });\n\n container.appendChild(btn);\n container.appendChild(menu);\n }\n\n /**\n * Render button row style (used for both \"buttons\" and \"flags\")\n */\n private renderButtonRow(\n container: HTMLElement,\n currentLocale: string,\n showFlags: boolean,\n showNames: boolean,\n ): void {\n const row = document.createElement('div');\n row.className = 'lionrapid-btn-row';\n\n for (const lang of this.languages) {\n const button = document.createElement('button');\n button.type = 'button';\n button.dataset.lang = lang.code;\n\n const flag = showFlags ? (lang.flag || '') : '';\n const name = showNames ? lang.name : lang.code.toUpperCase();\n button.textContent = `${flag}${flag && name ? ' ' : ''}${name}`;\n\n if (lang.code === currentLocale) {\n button.classList.add('active');\n }\n\n button.addEventListener('click', () => {\n this.handleLanguageChange(lang.code);\n row.querySelectorAll('button').forEach((btn) => {\n btn.classList.toggle('active', btn.dataset.lang === lang.code);\n });\n });\n\n row.appendChild(button);\n }\n\n container.appendChild(row);\n }\n\n /**\n * Handle language change \u2014 update all switchers on page + fire callback\n */\n private handleLanguageChange(locale: string): void {\n if (this.onLanguageChange) {\n this.onLanguageChange(locale);\n }\n\n // Update all button row states\n document.querySelectorAll('.lionrapid-btn-row button').forEach((btn) => {\n const button = btn as HTMLButtonElement;\n button.classList.toggle('active', button.dataset.lang === locale);\n });\n }\n\n /**\n * Inject minimal styles\n */\n private injectStyles(): void {\n if (this.stylesInjected) return;\n\n const styleElement = document.createElement('style');\n styleElement.textContent = STYLES;\n document.head.appendChild(styleElement);\n this.stylesInjected = true;\n }\n\n /**\n * Get language info by code\n */\n static getLanguage(code: string): Language | undefined {\n return DEFAULT_LANGUAGES[code];\n }\n}\n", "/**\n * LocalStorage Repository for persistent cache (Browser Bundle Version)\n * Implements ISyncRepository for synchronous access to localStorage\n */\n\nimport type {\n ISyncRepository,\n IStatsProvider,\n} from '../../interfaces/repository.interface.js';\nimport type { MemoryRepositoryConfig } from '../../config/repository.config.js';\nimport type { TranslationData } from '../../types/translation-data.types.js';\n\nconst STORAGE_PREFIX = 'lionrapid:';\nconst VERSION_KEY = `${STORAGE_PREFIX}version`;\nconst CURRENT_VERSION = '1';\n\n/**\n * Stored item structure with TTL support\n */\ninterface StoredItem {\n value: string;\n expiry: number | null;\n timestamp: number;\n}\n\n/**\n * Configuration options for LocalStorageRepository\n */\nexport interface LocalStorageRepositoryConfig extends MemoryRepositoryConfig {\n options?: MemoryRepositoryConfig['options'] & {\n /** Storage key prefix (default: 'lionrapid:') */\n prefix?: string;\n /** TTL in milliseconds (default: 24 hours) */\n ttl?: number;\n /** Maximum number of entries before eviction (default: 500) */\n maxSize?: number;\n };\n}\n\n/**\n * LocalStorage-based repository for persistent translation caching\n *\n * Features:\n * - Synchronous access (localStorage is sync)\n * - TTL-based expiration\n * - Graceful fallback when localStorage unavailable (SSR, private mode)\n * - Automatic eviction when quota exceeded\n * - Version migration support\n */\nexport class LocalStorageRepository\n implements ISyncRepository<LocalStorageRepositoryConfig>, IStatsProvider\n{\n readonly name = 'LocalStorageRepository';\n readonly type = 'memory' as const;\n readonly config: LocalStorageRepositoryConfig;\n\n private available: boolean;\n private prefix: string;\n private defaultTTL: number;\n private maxSize: number;\n\n constructor(config: LocalStorageRepositoryConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n priority: config.priority ?? 0, // Use build sequence by default\n options: {\n prefix: config.options?.prefix ?? STORAGE_PREFIX,\n ttl: config.options?.ttl ?? 24 * 60 * 60 * 1000, // 24 hours default\n maxSize: config.options?.maxSize ?? 500,\n ...config.options,\n },\n };\n\n this.prefix = this.config.options?.prefix ?? STORAGE_PREFIX;\n this.defaultTTL = this.config.options?.ttl ?? 24 * 60 * 60 * 1000;\n this.maxSize = this.config.options?.maxSize ?? 500;\n this.available = this.checkAvailability();\n\n if (this.available) {\n this.migrateIfNeeded();\n }\n }\n\n /**\n * Check if localStorage is available\n * Returns false in SSR, private browsing, or when quota is 0\n */\n private checkAvailability(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n const testKey = `${this.prefix}__test__`;\n window.localStorage.setItem(testKey, 'test');\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Handle version migrations - clear cache when version changes\n */\n private migrateIfNeeded(): void {\n try {\n const storedVersion = window.localStorage.getItem(VERSION_KEY);\n if (storedVersion !== CURRENT_VERSION) {\n this.clear();\n window.localStorage.setItem(VERSION_KEY, CURRENT_VERSION);\n }\n } catch {\n // Ignore migration errors\n }\n }\n\n /**\n * Get a translation value by key\n * Returns null if not found or expired\n */\n get(key: string): string | null {\n if (!this.available) return null;\n\n try {\n const fullKey = this.prefix + key;\n const itemStr = window.localStorage.getItem(fullKey);\n if (!itemStr) return null;\n\n const item: StoredItem = JSON.parse(itemStr);\n\n // Check TTL expiry\n if (item.expiry !== null && Date.now() > item.expiry) {\n window.localStorage.removeItem(fullKey);\n return null;\n }\n\n return item.value;\n } catch {\n return null;\n }\n }\n\n /**\n * Set a translation value\n * Automatically handles quota exceeded by evicting oldest entries\n */\n set(key: string, value: string): void {\n if (!this.available) return;\n\n const fullKey = this.prefix + key;\n const item: StoredItem = {\n value,\n expiry: this.defaultTTL ? Date.now() + this.defaultTTL : null,\n timestamp: Date.now(),\n };\n\n try {\n // Check entry count and evict if needed\n const entryCount = this.getEntryCount();\n if (entryCount >= this.maxSize) {\n this.evictOldest();\n }\n\n window.localStorage.setItem(fullKey, JSON.stringify(item));\n } catch (error) {\n if (this.isQuotaError(error)) {\n this.evictOldest();\n // Retry once after eviction\n try {\n window.localStorage.setItem(fullKey, JSON.stringify(item));\n } catch {\n // Give up silently\n }\n }\n }\n }\n\n /**\n * Remove a translation by key\n */\n remove(key: string): void {\n if (!this.available) return;\n\n try {\n window.localStorage.removeItem(this.prefix + key);\n } catch {\n // Ignore removal errors\n }\n }\n\n /**\n * Clear all LionRapid entries from localStorage\n * Preserves entries from other applications\n */\n clear(): void {\n if (!this.available) return;\n\n try {\n const keysToRemove: string[] = [];\n for (let i = 0; i < window.localStorage.length; i++) {\n const key = window.localStorage.key(i);\n if (key?.startsWith(this.prefix) && key !== VERSION_KEY) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach(k => window.localStorage.removeItem(k));\n } catch {\n // Ignore clear errors\n }\n }\n\n /**\n * Clear all entries for a specific namespace\n */\n clearNamespace(locale: string, namespace: string): void {\n if (!this.available) return;\n\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const keyPrefix = `${locale}:${namespace}:`;\n\n try {\n const keysToRemove: string[] = [];\n for (let i = 0; i < window.localStorage.length; i++) {\n const key = window.localStorage.key(i);\n if (!key?.startsWith(this.prefix)) continue;\n\n const innerKey = key.slice(this.prefix.length);\n if (innerKey === namespaceCacheKey || innerKey.startsWith(keyPrefix)) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach(k => window.localStorage.removeItem(k));\n } catch {\n // Ignore errors\n }\n }\n\n /**\n * Get namespace translations\n */\n getNamespace(locale: string, namespace: string): TranslationData | null {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const value = this.get(namespaceCacheKey);\n if (!value) return null;\n\n try {\n return JSON.parse(value);\n } catch {\n this.remove(namespaceCacheKey);\n return null;\n }\n }\n\n /**\n * Set namespace translations\n */\n setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): void {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n this.set(namespaceCacheKey, JSON.stringify(translations));\n }\n\n /**\n * Get all cache entries for debugging\n */\n getEntries(): Record<string, string> {\n const entries: Record<string, string> = {};\n if (!this.available) return entries;\n\n try {\n for (let i = 0; i < window.localStorage.length; i++) {\n const fullKey = window.localStorage.key(i);\n if (!fullKey?.startsWith(this.prefix) || fullKey === VERSION_KEY) {\n continue;\n }\n\n const key = fullKey.slice(this.prefix.length);\n const value = this.get(key);\n if (value !== null) {\n entries[key] = value;\n }\n }\n } catch {\n // Ignore errors\n }\n\n return entries;\n }\n\n /**\n * Get repository configuration\n */\n getConfig(): LocalStorageRepositoryConfig {\n return this.config;\n }\n\n /**\n * Check if localStorage is available\n */\n isAvailable(): boolean {\n return this.available;\n }\n\n /**\n * Get the number of entries in the cache\n */\n private getEntryCount(): number {\n if (!this.available) return 0;\n\n let count = 0;\n try {\n for (let i = 0; i < window.localStorage.length; i++) {\n const key = window.localStorage.key(i);\n if (key?.startsWith(this.prefix) && key !== VERSION_KEY) {\n count++;\n }\n }\n } catch {\n // Ignore errors\n }\n\n return count;\n }\n\n /**\n * Check if error is a quota exceeded error\n */\n private isQuotaError(error: unknown): boolean {\n if (error instanceof DOMException) {\n // Most browsers\n return (\n error.name === 'QuotaExceededError' ||\n error.name === 'NS_ERROR_DOM_QUOTA_REACHED'\n );\n }\n return false;\n }\n\n /**\n * Evict oldest 25% of entries when quota is exceeded\n */\n private evictOldest(): void {\n if (!this.available) return;\n\n try {\n // Collect all entries with timestamps\n const entries: Array<{ key: string; timestamp: number }> = [];\n\n for (let i = 0; i < window.localStorage.length; i++) {\n const fullKey = window.localStorage.key(i);\n if (!fullKey?.startsWith(this.prefix) || fullKey === VERSION_KEY) {\n continue;\n }\n\n try {\n const itemStr = window.localStorage.getItem(fullKey);\n if (itemStr) {\n const item: StoredItem = JSON.parse(itemStr);\n entries.push({ key: fullKey, timestamp: item.timestamp });\n }\n } catch {\n // Remove corrupted entry\n window.localStorage.removeItem(fullKey);\n }\n }\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Remove oldest 25%\n const removeCount = Math.max(1, Math.floor(entries.length * 0.25));\n for (let i = 0; i < removeCount && i < entries.length; i++) {\n window.localStorage.removeItem(entries[i].key);\n }\n } catch {\n // Ignore eviction errors\n }\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; maxSize: number; usage: string } {\n const size = this.getEntryCount();\n const usage =\n this.maxSize > 0 ? `${Math.round((size / this.maxSize) * 100)}%` : '0%';\n\n return {\n size,\n maxSize: this.maxSize,\n usage,\n };\n }\n}\n", "/**\n * CacheStorageRepository - Cache API-based persistent storage (Browser Bundle Version)\n * Implements IAsyncRepository for asynchronous access to Cache API\n *\n * This provides Layer 3 caching in the handler chain:\n * 1. Memory (sync) \u2192 2. LocalStorage (sync) \u2192 3. CacheStorage (async) \u2192 4. Network (async)\n */\n\nimport type { IAsyncRepository } from '../../interfaces/repository.interface.js';\nimport type { StorageRepositoryConfig } from '../../config/repository.config.js';\nimport type { TranslationData } from '../../types/translation-data.types.js';\nimport { TranslationNotFoundError } from '../../errors/translation-errors.js';\n\nconst CACHE_NAME = 'lionrapid-v1';\n// The Cache API only accepts http/https request URLs as keys \u2014 `cache.put`\n// throws `TypeError: Request scheme '\u2026' is unsupported` for a bare string like\n// `lionrapid:\u2026`, which silently killed every write (caught by set()'s guard).\n// Use a synthetic https origin so keys are valid Requests. The host never\n// resolves; it only namespaces entries inside the named cache.\nconst CACHE_PREFIX = 'https://cache.lionrapid.internal/';\n\n/**\n * Stored item structure with TTL support\n */\ninterface StoredItem {\n value: string;\n expiry: number | null;\n timestamp: number;\n}\n\n/**\n * Configuration options for CacheStorageRepository\n */\nexport interface CacheStorageRepositoryConfig extends StorageRepositoryConfig {\n options?: StorageRepositoryConfig['options'] & {\n /** Cache name for the Cache API (default: 'lionrapid-v1') */\n cacheName?: string;\n /** TTL in milliseconds (default: 7 days) */\n ttl?: number;\n };\n}\n\n/**\n * Cache API-based repository for persistent translation caching\n *\n * Features:\n * - Asynchronous access (Cache API is async)\n * - TTL-based expiration\n * - Larger storage capacity than localStorage\n * - Graceful fallback when Cache API unavailable (SSR, old browsers)\n * - Works alongside Service Worker for offline support\n *\n * @example\n * ```typescript\n * import { CacheStorageRepository } from '@lionrapid/storage';\n *\n * const cacheRepo = new CacheStorageRepository({\n * enabled: true,\n * options: {\n * cacheName: 'my-app-translations',\n * ttl: 7 * 24 * 60 * 60 * 1000, // 7 days\n * },\n * });\n * ```\n */\nexport class CacheStorageRepository\n implements IAsyncRepository<CacheStorageRepositoryConfig>\n{\n readonly name = 'CacheStorageRepository';\n readonly type = 'storage' as const;\n readonly config: CacheStorageRepositoryConfig;\n\n private cacheName: string;\n private defaultTTL: number;\n private available: boolean;\n\n constructor(config: CacheStorageRepositoryConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n priority: config.priority ?? 0,\n options: {\n cacheName: config.options?.cacheName ?? CACHE_NAME,\n ttl: config.options?.ttl ?? 7 * 24 * 60 * 60 * 1000, // 7 days default\n ...config.options,\n },\n };\n\n this.cacheName = this.config.options?.cacheName ?? CACHE_NAME;\n this.defaultTTL = this.config.options?.ttl ?? 7 * 24 * 60 * 60 * 1000;\n this.available = this.checkAvailability();\n }\n\n /**\n * Check if Cache API is available\n * Returns false in SSR, old browsers, or insecure contexts\n */\n private checkAvailability(): boolean {\n return typeof caches !== 'undefined';\n }\n\n /**\n * Get a translation value by key\n * @throws {TranslationNotFoundError} When translation doesn't exist or is expired\n */\n async get(key: string): Promise<string> {\n if (!this.available) {\n throw new TranslationNotFoundError(key);\n }\n\n try {\n const cache = await caches.open(this.cacheName);\n const response = await cache.match(CACHE_PREFIX + key);\n\n if (!response) {\n throw new TranslationNotFoundError(key);\n }\n\n const data: StoredItem = await response.json();\n\n // Check TTL expiry\n if (data.expiry !== null && Date.now() > data.expiry) {\n await cache.delete(CACHE_PREFIX + key);\n throw new TranslationNotFoundError(key);\n }\n\n return data.value;\n } catch (error) {\n if (error instanceof TranslationNotFoundError) {\n throw error;\n }\n // Wrap any other error as not found\n throw new TranslationNotFoundError(key);\n }\n }\n\n /**\n * Set a translation value\n */\n async set(key: string, value: string): Promise<void> {\n if (!this.available) return;\n\n try {\n const cache = await caches.open(this.cacheName);\n const data: StoredItem = {\n value,\n expiry: this.defaultTTL ? Date.now() + this.defaultTTL : null,\n timestamp: Date.now(),\n };\n\n await cache.put(\n CACHE_PREFIX + key,\n new Response(JSON.stringify(data), {\n headers: { 'Content-Type': 'application/json' },\n })\n );\n } catch {\n // Silently fail - cache is non-critical\n }\n }\n\n /**\n * Remove a translation by key\n */\n async remove(key: string): Promise<void> {\n if (!this.available) return;\n\n try {\n const cache = await caches.open(this.cacheName);\n await cache.delete(CACHE_PREFIX + key);\n } catch {\n // Silently fail\n }\n }\n\n /**\n * Clear all LionRapid entries from the cache\n */\n async clear(): Promise<void> {\n if (!this.available) return;\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n\n await Promise.all(\n keys\n .filter(request => request.url.includes(CACHE_PREFIX))\n .map(request => cache.delete(request))\n );\n } catch {\n // Silently fail\n }\n }\n\n /**\n * Clear all entries for a specific namespace\n */\n async clearNamespace(locale: string, namespace: string): Promise<void> {\n if (!this.available) return;\n\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const keyPrefix = `${locale}:${namespace}:`;\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n\n await Promise.all(\n keys\n .filter(request => {\n const url = request.url;\n const key = url.includes(CACHE_PREFIX)\n ? url.substring(url.indexOf(CACHE_PREFIX) + CACHE_PREFIX.length)\n : '';\n return key === namespaceCacheKey || key.startsWith(keyPrefix);\n })\n .map(request => cache.delete(request))\n );\n } catch {\n // Silently fail\n }\n }\n\n /**\n * Get namespace translations\n * @throws {TranslationNotFoundError} When namespace doesn't exist\n */\n async getNamespace(\n locale: string,\n namespace: string\n ): Promise<TranslationData> {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n const value = await this.get(namespaceCacheKey);\n\n try {\n return JSON.parse(value);\n } catch {\n await this.remove(namespaceCacheKey);\n throw new TranslationNotFoundError(namespaceCacheKey);\n }\n }\n\n /**\n * Set namespace translations\n */\n async setNamespace(\n locale: string,\n namespace: string,\n translations: TranslationData\n ): Promise<void> {\n const namespaceCacheKey = `@${locale}:${namespace}`;\n await this.set(namespaceCacheKey, JSON.stringify(translations));\n }\n\n /**\n * Get repository configuration\n */\n getConfig(): CacheStorageRepositoryConfig {\n return this.config;\n }\n\n /**\n * Check if Cache API is available\n */\n isAvailable(): boolean {\n return this.available;\n }\n\n /**\n * Get all cached entries (for debugging)\n * Returns an object mapping keys to values\n */\n async getEntries(): Promise<Record<string, string>> {\n const entries: Record<string, string> = {};\n if (!this.available) return entries;\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n\n for (const request of keys) {\n const url = request.url;\n if (!url.includes(CACHE_PREFIX)) continue;\n\n const key = url.substring(\n url.indexOf(CACHE_PREFIX) + CACHE_PREFIX.length\n );\n try {\n const value = await this.get(key);\n entries[key] = value;\n } catch {\n // Skip expired or invalid entries\n }\n }\n } catch {\n // Silently fail\n }\n\n return entries;\n }\n\n /**\n * Get cache statistics\n */\n async getCacheStats(): Promise<{ size: number; cacheName: string }> {\n if (!this.available) {\n return { size: 0, cacheName: this.cacheName };\n }\n\n try {\n const cache = await caches.open(this.cacheName);\n const keys = await cache.keys();\n const size = keys.filter(r => r.url.includes(CACHE_PREFIX)).length;\n\n return { size, cacheName: this.cacheName };\n } catch {\n return { size: 0, cacheName: this.cacheName };\n }\n }\n}\n", "/**\n * Auto-Init for Browser Bundle\n * Reads script tag attributes and auto-configures LionRapid\n *\n * Usage:\n * <script\n * src=\"https://cdn.lionrapid.com/lionrapid.min.js\"\n * data-api-key=\"pk_live_xxx\"\n * data-default-locale=\"en\"\n * data-namespace=\"default\"\n * data-languages=\"en,es,fr,de\"\n * ></script>\n */\n\nimport { LionRapidBuilder } from '../builder.js';\nimport { MemoryRepository } from '../repositories/memory-repository.js';\nimport { NetworkRepository } from '../repositories/network-repository.js';\nimport { AutoTranslator } from './auto-translator.js';\nimport { LanguageSwitcher } from './language-switcher.js';\nimport { LocalStorageRepository } from './storage/localstorage-repository.js';\nimport { CacheStorageRepository } from './storage/cache-storage-repository.js';\nimport {\n matchLocale,\n normalizeLocale,\n localeDir,\n LOCALE_TAG_REGEX,\n} from '../utils/locale.js';\n\nexport interface AutoInitConfig {\n apiKey: string;\n baseUrl: string;\n defaultLocale: string;\n namespace: string;\n languages: string[];\n excludeSelectors: string[];\n autoDetect: boolean;\n mode: 'full' | 'dynamic-only';\n switcherStyle?: string;\n switcherPosition?: string;\n switcherShowFlags?: boolean;\n switcherShowNames?: boolean;\n switcherCustomCss?: string;\n /** Override for the visual editor bundle URL. Defaults to the public CDN.\n * Self-hosted hosts (e.g. the WordPress plugin) point this at their own\n * vendored copy so the editor is version-locked to the host, not the CDN. */\n editorCdnUrl?: string;\n /** Offline resilience: add a never-expiring \"last known good\" cache layer that\n * is hydrated by successful fetches, so the site keeps translating with the\n * server down even after the normal caches expire. Default on; disable with\n * `data-offline=\"false\"`. */\n offline?: boolean;\n}\n\ndeclare global {\n interface Window {\n LionRapid: LionRapidInstance | undefined;\n __lionrapidConfig?: AutoInitConfig;\n }\n}\n\n/**\n * Write policy for a browser-embedded key.\n *\n * A publishable `pk_` key gets the DISCOVERY path only: page views sync\n * missing source strings so rows appear in the dashboard (the server's\n * `_SYNC_KEYS` explicitly allows publishable keys on /sync). It can never\n * write translations \u2014 the server restricts those to master/editor-session\n * keys (`_WRITE_KEYS`), which is what actually blocks the stored-XSS loop.\n *\n * Anything that isn't a pk_ key is a secret shipped to the page (Phase 18):\n * the network layer refuses to boot at all \u2014 the key never goes on the\n * wire \u2014 and the refusal is flagged loudly so the integrator notices.\n */\nexport function resolveWritePolicy(apiKey: string): {\n /** Phase 18: pk_ is the ONLY key that boots the network layer \u2014 a non-pk_\n * value is a secret (or garbage) pasted into public HTML and must never\n * go on the wire. Cached/offline translations still apply. */\n bootNetwork: boolean;\n syncMissing: { enabled: boolean };\n warnRefused: boolean;\n} {\n const isPublishable = apiKey.startsWith('pk_');\n return {\n bootNetwork: isPublishable,\n syncMissing: { enabled: isPublishable },\n warnRefused: !isPublishable,\n };\n}\n\n/**\n * The config copy mirrored to `window.__lionrapidConfig` for the editor\n * bundle \u2014 with the API key stripped. The key must never sit on `window`\n * where any third-party script on the page could read it; the editor only\n * needs languages/namespace/locale from here.\n */\nexport function configForWindow(config: AutoInitConfig): AutoInitConfig {\n return { ...config, apiKey: '' };\n}\n\n/**\n * Switcher change-handling that survives the boot window. `build()` can take\n * seconds under a failing network (retry backoff); a click in that window\n * must not be silently dropped. The cookie is written and dynamic-only\n * navigation happens immediately (neither needs core); in full mode a click\n * before `attach` is remembered (last one wins) and replayed the moment the\n * core-bound apply function is attached.\n */\nexport function createDeferredLocaleHandler(effects: {\n setCookie: (locale: string) => void;\n /** non-null in dynamic-only mode \u2014 navigation replaces in-place apply */\n navigate: ((locale: string) => void) | null;\n}): {\n onChange: (locale: string) => Promise<void>;\n attach: (apply: (locale: string) => Promise<void>) => void;\n} {\n let applyLocale: ((locale: string) => Promise<void>) | null = null;\n let pendingLocale: string | null = null;\n return {\n onChange: async (locale) => {\n effects.setCookie(locale);\n if (effects.navigate) {\n effects.navigate(locale);\n return;\n }\n if (applyLocale) {\n await applyLocale(locale);\n return;\n }\n pendingLocale = locale;\n },\n attach: (apply) => {\n applyLocale = apply;\n if (pendingLocale !== null) {\n const replay = pendingLocale;\n pendingLocale = null;\n void apply(replay).catch(() => {});\n }\n },\n };\n}\n\n/**\n * Run `fn` once the DOM is parsed \u2014 immediately if it already is. Guards the\n * DOM-writing steps (switcher render, translatePage/observe) so a snippet\n * booted from `<head>` doesn't run them against a null `document.body`.\n * Network preload and `build()` are NOT gated \u2014 only DOM writes wait.\n */\nexport function onDomReady(fn: () => void): void {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', fn, { once: true });\n } else {\n fn();\n }\n}\n\nexport interface LionRapidInstance {\n t: (key: string, params?: Record<string, unknown>, defaultValue?: string) => string;\n tHtml: (key: string, params?: Record<string, unknown>, defaultValue?: string) => string;\n changeLanguage: (locale: string) => Promise<void>;\n getCurrentLocale: () => string;\n on: (event: string, callback: (payload: unknown) => void) => void;\n retranslate: () => void;\n reloadTranslations: () => Promise<void>;\n autoTranslator: AutoTranslator;\n languageSwitcher: LanguageSwitcher;\n}\n\n/**\n * Parse script tag attributes\n */\nfunction parseConfig(script: HTMLScriptElement): AutoInitConfig {\n const apiKey = script.dataset.apiKey || '';\n const baseUrl = script.dataset.baseUrl || 'https://api.lionrapid.com';\n const defaultLocale = script.dataset.defaultLocale || 'en';\n const namespace = script.dataset.namespace || 'default';\n const languages = (script.dataset.languages || defaultLocale)\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const excludeSelectors = (script.dataset.exclude || '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const autoDetect = script.dataset.autoDetect === 'true';\n const mode = (script.dataset.mode === 'dynamic-only' ? 'dynamic-only' : 'full') as AutoInitConfig['mode'];\n const switcherStyle = script.dataset.switcher && script.dataset.switcher !== 'false'\n ? script.dataset.switcher\n : undefined;\n const switcherPosition = script.dataset.switcherPosition || undefined;\n const switcherShowFlags = script.dataset.switcherShowFlags !== 'false';\n const switcherShowNames = script.dataset.switcherShowNames === 'true';\n const switcherCustomCss = script.dataset.switcherCustomCss || undefined;\n const editorCdnUrl = script.dataset.editorCdn || undefined;\n const offline = script.dataset.offline !== 'false';\n\n return {\n apiKey,\n baseUrl,\n defaultLocale,\n namespace,\n languages,\n excludeSelectors,\n autoDetect,\n mode,\n switcherStyle,\n switcherPosition,\n switcherShowFlags,\n switcherShowNames,\n switcherCustomCss,\n editorCdnUrl,\n offline,\n };\n}\n\n/**\n * Read the lionrapid_locale cookie and resolve it against the available\n * languages (full BCP-47 tags preserved \u2014 `pt-BR` is not chopped to `pt`).\n */\nfunction readLocaleCookie(availableLanguages: string[]): string | null {\n if (typeof document === 'undefined') return null;\n // Anchored to a cookie boundary \u2014 a foreign cookie merely containing the\n // name (e.g. `not_lionrapid_locale=de`) must not win.\n const match = document.cookie.match(\n /(?:^|;\\s*)lionrapid_locale=([a-z]{2,3}(?:-[a-z0-9]{2,4})*)/i,\n );\n if (!match) return null;\n return matchLocale([match[1]], availableLanguages, '') || null;\n}\n\n/**\n * Detect the browser's preferred language via BCP-47 negotiation.\n * `navigator.languages` is already preference-ordered; full tags survive.\n */\nfunction detectBrowserLanguage(availableLanguages: string[], defaultLocale: string): string {\n if (typeof navigator === 'undefined') return defaultLocale;\n\n const requested =\n navigator.languages && navigator.languages.length > 0\n ? [...navigator.languages]\n : [\n navigator.language ||\n (navigator as Navigator & { userLanguage?: string }).userLanguage ||\n '',\n ];\n\n return matchLocale(requested, availableLanguages, defaultLocale);\n}\n\n/**\n * Build a locale-prefixed URL (pure \u2014 no navigation). Strips an existing\n * locale prefix only when it's a known language, so a path like `/about-us/`\n * is never mistaken for a locale; full BCP-47 prefixes (`/pt-BR/\u2026`) are handled.\n * The default locale is served un-prefixed.\n */\nexport function buildLocaleUrl(\n pathname: string,\n search: string,\n locale: string,\n defaultLocale: string,\n availableLanguages: string[],\n): string {\n const segments = pathname.split('/'); // ['', 'pt-BR', 'about']\n const first = segments[1] ?? '';\n const hasLocalePrefix =\n LOCALE_TAG_REGEX.test(first) &&\n matchLocale([first], availableLanguages, '') !== '';\n const path = hasLocalePrefix ? '/' + segments.slice(2).join('/') : pathname;\n const prefix = locale === defaultLocale ? '' : '/' + locale;\n return prefix + (path || '/') + search;\n}\n\n/** Navigate to a locale-prefixed URL (dynamic-only mode). */\nfunction navigateToLocale(\n locale: string,\n defaultLocale: string,\n availableLanguages: string[],\n): void {\n window.location.href = buildLocaleUrl(\n window.location.pathname,\n window.location.search,\n locale,\n defaultLocale,\n availableLanguages,\n );\n}\n\n/**\n * Resolve the initial locale from the environment, preserving full BCP-47\n * tags. Dynamic-only trusts the server-set `<html lang>`; full mode uses\n * cookie \u2192 browser negotiation \u2192 default. Extracted so the precedence matrix\n * is testable without booting `autoInit`.\n */\nexport function resolveInitialLocale(config: AutoInitConfig): string {\n if (config.mode === 'dynamic-only') {\n const htmlLang =\n typeof document !== 'undefined' ? document.documentElement.lang : '';\n return htmlLang ? normalizeLocale(htmlLang) : config.defaultLocale;\n }\n const cookieLocale = readLocaleCookie(config.languages);\n if (cookieLocale) return cookieLocale;\n if (config.autoDetect) {\n return detectBrowserLanguage(config.languages, config.defaultLocale);\n }\n return config.defaultLocale;\n}\n\n/** Reflect the locale's text direction on `<html dir>` (RTL languages). */\nexport function applyLocaleDir(locale: string): void {\n if (typeof document !== 'undefined') {\n document.documentElement.dir = localeDir(locale);\n }\n}\n\n/**\n * The `<script data-api-key>` tag that configures this boot. Prefer the\n * script that is actually executing (valid here because autoInit runs at\n * script-eval time), so a page with several snippet tags configures from\n * the right one; fall back to the last matching tag when currentScript is\n * unavailable (module contexts, async boundaries) \u2014 flagged, since with two\n * or more candidates \"last wins\" is a silent guess.\n */\nexport function findConfigScript(): HTMLScriptElement | undefined {\n const current = document.currentScript;\n if (current instanceof HTMLScriptElement && current.dataset.apiKey) {\n return current;\n }\n const scripts = document.querySelectorAll('script[data-api-key]');\n if (scripts.length > 1) {\n console.warn(\n `[LionRapid] ${scripts.length} script tags with data-api-key found; using the last one`,\n );\n }\n return scripts[scripts.length - 1] as HTMLScriptElement | undefined;\n}\n\n/**\n * Initialize LionRapid from script tag\n */\nasync function autoInit(): Promise<void> {\n const script = findConfigScript();\n\n if (!script) {\n console.warn('[LionRapid] No script tag with data-api-key found');\n return;\n }\n\n const config = parseConfig(script);\n // Mirror config for the editor bundle, but never expose the key on window.\n window.__lionrapidConfig = configForWindow(config);\n\n if (!config.apiKey) {\n console.warn('[LionRapid] Missing data-api-key attribute');\n return;\n }\n\n // Hard gate (Phase 18): only a publishable pk_ key boots the network\n // layer. A non-pk_ key is a secret shipped to the page \u2014 refuse to put it\n // on the wire; cached/offline translations still apply.\n const writePolicy = resolveWritePolicy(config.apiKey);\n if (writePolicy.warnRefused) {\n console.error(\n '[LionRapid] data-api-key must be a publishable pk_ key \u2014 network ' +\n 'translations are disabled. Copy the snippet from the integration ' +\n 'hub to get the pk_ key for this project.',\n );\n }\n\n // Determine initial locale\n const initialLocale = resolveInitialLocale(config);\n\n // Reflect text direction for RTL locales on <html dir> before first paint.\n applyLocaleDir(initialLocale);\n\n // Create language switcher immediately (no core dependency for rendering)\n const languageSwitcher = new LanguageSwitcher();\n languageSwitcher.setLanguages(config.languages);\n languageSwitcher.setInitialLocale(initialLocale);\n\n // Render switcher as soon as DOM is ready (don't wait for network)\n const renderSwitcher = () => {\n // In full mode, auto-create floating container from script tag config\n // In dynamic-only mode, server (WP/edge) provides the container via HTML\n if (config.mode !== 'dynamic-only') {\n if (config.switcherStyle && !document.querySelector('[data-lionrapid-switcher]')) {\n const container = document.createElement('div');\n container.dataset.lionrapidSwitcher = config.switcherStyle;\n if (config.switcherPosition) {\n container.dataset.lionrapidSwitcherPosition = config.switcherPosition;\n }\n if (!config.switcherShowFlags) {\n container.dataset.lionrapidSwitcherShowFlags = 'false';\n }\n if (!config.switcherShowNames) {\n container.dataset.lionrapidSwitcherShowNames = 'false';\n }\n if (config.switcherCustomCss) {\n container.dataset.lionrapidSwitcherCustomCss = config.switcherCustomCss;\n }\n document.body.appendChild(container);\n }\n }\n // Always init: injects CSS, hydrates any [data-lionrapid-switcher] elements\n languageSwitcher.initAll();\n };\n\n onDomReady(renderSwitcher);\n\n // Language changes are accepted from the first paint: cookie + dynamic-only\n // navigation immediately, in-place retranslation replayed once core is up.\n const localeHandler = createDeferredLocaleHandler({\n setCookie: (locale) => {\n document.cookie = `lionrapid_locale=${locale}; path=/; max-age=31536000; SameSite=Lax`;\n },\n navigate:\n config.mode === 'dynamic-only'\n ? (locale) => navigateToLocale(locale, config.defaultLocale, config.languages)\n : null,\n });\n languageSwitcher.setOnLanguageChange(localeHandler.onChange);\n\n try {\n // Build LionRapid with all cache layers\n const builder = LionRapidBuilder.init({\n defaultLocale: initialLocale,\n namespace: config.namespace,\n })\n .use(new MemoryRepository({ enabled: true }))\n .use(new LocalStorageRepository({ enabled: true }))\n .use(new CacheStorageRepository({ enabled: true }));\n\n // Offline resilience floor: a never-expiring \"last known good\" cache layer,\n // hydrated by successful fetches. Checked AFTER the TTL'd caches and BEFORE\n // the network, so the site keeps translating with the server down even once\n // the normal caches expire.\n // - ttl must be huge \u2014 the handlers treat ttl=0 as \"expire immediately\".\n // - a DISTINCT cacheName is essential: CacheStorageRepository keys by\n // cacheName (it ignores `prefix`), so without this the floor would share\n // the default store and the 7d cache's expiry would delete its entries.\n if (config.offline !== false) {\n builder.use(\n new CacheStorageRepository({\n enabled: true,\n options: {\n ttl: Number.MAX_SAFE_INTEGER,\n cacheName: 'lionrapid-offline-v1',\n },\n })\n );\n }\n\n // Phase 18: the network layer exists only for pk_ keys \u2014 a refused key\n // boots caches/offline layers alone and never reaches the wire.\n if (writePolicy.bootNetwork) {\n builder.use(\n new NetworkRepository({\n enabled: true,\n options: {\n baseUrl: config.baseUrl,\n apiKey: config.apiKey,\n // pk_ keys sync missing source strings (discovery) \u2014 see\n // resolveWritePolicy.\n syncMissing: writePolicy.syncMissing,\n preloadNamespaces: [\n {\n locale: initialLocale,\n namespace: config.namespace,\n eager: true,\n },\n ],\n },\n })\n );\n }\n\n const core = await builder.build();\n\n // Create auto translator\n const autoTranslator = new AutoTranslator({\n excludeSelectors: config.excludeSelectors,\n });\n autoTranslator.setCore(core);\n autoTranslator.init({\n namespace: config.namespace,\n locale: initialLocale,\n sourceLocale: config.defaultLocale,\n });\n\n // Wire up core to switcher now that it's ready; a click that arrived\n // during build() replays here.\n languageSwitcher.setCore(core);\n localeHandler.attach(async (locale) => {\n await core.changeLanguage(locale, {\n preloadNamespaces: [config.namespace],\n });\n applyLocaleDir(locale);\n autoTranslator.updateLocale(locale);\n autoTranslator.retranslate();\n });\n\n // === Reactive translation reload ===\n const RETRY_DELAYS = [2000, 8000, 30000]; // backoff: 2s, 8s, 30s\n const REVALIDATE_STALE_MS = 60_000; // 60s before background revalidation\n let hasPendingTranslations = false;\n let retryTimers: ReturnType<typeof setTimeout>[] = [];\n let lastRevalidatedAt = Date.now();\n\n const reloadTranslations = async (): Promise<void> => {\n await core.reloadNamespace(config.namespace);\n autoTranslator.translatePage();\n lastRevalidatedAt = Date.now();\n };\n\n const cancelRetries = () => {\n retryTimers.forEach(t => clearTimeout(t));\n retryTimers = [];\n };\n\n // After sync: schedule backoff retries\n core.bus.on('sync:batch:complete', () => {\n hasPendingTranslations = true;\n cancelRetries();\n RETRY_DELAYS.forEach(delay => {\n retryTimers.push(\n setTimeout(() => reloadTranslations().catch(() => {}), delay)\n );\n });\n });\n\n // On tab focus: reload if pending, or background revalidate if stale (>60s)\n // The revalidation is cheap \u2014 server returns 304 if nothing changed\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState !== 'visible') return;\n\n if (hasPendingTranslations) {\n hasPendingTranslations = false;\n cancelRetries();\n reloadTranslations().catch(() => {});\n } else if (Date.now() - lastRevalidatedAt > REVALIDATE_STALE_MS) {\n reloadTranslations().catch(() => {});\n }\n });\n\n // Expose global API\n const instance: LionRapidInstance = {\n t: (key, params, defaultValue) => core.t(key, params || {}, defaultValue),\n tHtml: (key, params, defaultValue) => core.tHtml(key, params || {}, defaultValue),\n changeLanguage: async (locale) => {\n await core.changeLanguage(locale, {\n preloadNamespaces: [config.namespace],\n });\n applyLocaleDir(locale);\n autoTranslator.updateLocale(locale);\n autoTranslator.retranslate();\n languageSwitcher.initAll();\n },\n getCurrentLocale: () => core.getCurrentLocale(),\n on: (event, callback) => core.bus.on(event as keyof typeof core.bus, callback),\n retranslate: () => autoTranslator.retranslate(),\n reloadTranslations,\n autoTranslator,\n languageSwitcher,\n };\n\n window.LionRapid = instance;\n\n // Detect editor mode (snippet case). Edge proxy and WordPress inject the\n // editor server-side, so skip if either kind of editor script is already\n // present to avoid double-loading.\n const editorParam = new URLSearchParams(window.location.search).get('__lr_editor');\n if (editorParam && !document.querySelector('script[data-grant], script[data-lr-editor]')) {\n const editorScript = document.createElement('script');\n editorScript.src = config.editorCdnUrl\n || 'https://cdn.lionrapid.com/lionrapid.editor.min.js';\n editorScript.dataset.grant = editorParam;\n editorScript.dataset.locale = core.getCurrentLocale();\n editorScript.dataset.api = config.baseUrl;\n editorScript.async = true;\n document.body.appendChild(editorScript);\n }\n\n // Start auto-translation once the DOM is ready \u2014 a <head>-script boot\n // would otherwise run translatePage()/observe() against a null\n // document.body. Core build + network preload already ran above.\n onDomReady(() => {\n if (config.mode !== 'dynamic-only') {\n autoTranslator.translatePage();\n }\n autoTranslator.observe();\n });\n } catch (error) {\n console.error('[LionRapid] Initialization failed:', error);\n }\n}\n\n// Auto-run on script load\nautoInit();\n\nexport { autoInit, parseConfig };\n"],
5
+ "mappings": "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",
6
6
  "names": ["LogLevel", "locationInfo", "decodeEntities", "decodeEntities", "SKIP_TAGS", "SKIP_ATTRIBUTES"]
7
7
  }