@lionrapid/core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -11
- package/dist/browser/editor/editor-init.js +13 -0
- package/dist/browser/editor/editor-init.js.map +1 -1
- package/dist/browser/lionrapid.editor.js +10 -0
- package/dist/browser/lionrapid.editor.js.map +3 -3
- package/dist/browser/lionrapid.editor.min.js +2 -2
- package/dist/browser/lionrapid.editor.min.js.map +3 -3
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/browser/editor/editor-styles.ts", "../../src/content/style-mapper/DefaultStyleMapper.ts", "../../src/browser/markup-parser.ts", "../../src/browser/md5.ts", "../../src/browser/editor/key-resolver.ts", "../../src/browser/editor/inspector.ts", "../../src/browser/editor/toolbar.ts", "../../src/content/serializer/HTMLSerializer.ts", "../../src/browser/editor/live-preview.ts", "../../src/browser/exclude-filter.ts", "../../src/browser/block-extractor.ts", "../../src/browser/editor/sidebar.ts", "../../src/browser/editor/editor-api.ts", "../../src/browser/editor/editor-init.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Editor CSS Styles\n * All styles are injected into Shadow DOM \u2014 no leakage to host page.\n */\n\nexport const EDITOR_CSS = `\n/* Reset inside shadow DOM */\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #1a1a2e;\n line-height: 1.5;\n box-sizing: border-box;\n}\n\n*, *::before, *::after {\n box-sizing: border-box;\n}\n\n/* \u2500\u2500 FAB (replaces fixed toolbar) \u2500\u2500 */\n.lr-fab {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 0;\n user-select: none;\n}\n\n.lr-fab-btn {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #2d7f7f;\n color: #fff;\n border: none;\n font-weight: 700;\n font-size: 16px;\n cursor: grab;\n box-shadow: 0 4px 12px rgba(0,0,0,0.25);\n transition: box-shadow 0.15s;\n flex-shrink: 0;\n z-index: 1;\n}\n\n.lr-fab-btn:hover {\n box-shadow: 0 6px 20px rgba(0,0,0,0.3);\n}\n\n.lr-fab-btn:active {\n cursor: grabbing;\n}\n\n.lr-fab-panel {\n display: none;\n align-items: center;\n gap: 8px;\n background: #1a1a2e;\n color: #fff;\n padding: 8px 12px;\n border-radius: 8px;\n margin-right: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.25);\n white-space: nowrap;\n}\n\n.lr-fab.expanded .lr-fab-panel {\n display: flex;\n}\n\n.lr-lang-dropdown {\n position: relative;\n}\n\n.lr-lang-btn {\n background: rgba(255,255,255,0.1);\n color: #fff;\n border: 1px solid rgba(255,255,255,0.2);\n border-radius: 4px;\n padding: 4px 10px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n outline: none;\n}\n\n.lr-lang-btn:hover {\n background: rgba(255,255,255,0.2);\n}\n\n.lr-lang-menu {\n display: none;\n position: absolute;\n bottom: calc(100% + 6px);\n left: 0;\n background: #1a1a2e;\n border: 1px solid rgba(255,255,255,0.15);\n border-radius: 6px;\n padding: 4px;\n min-width: 60px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.4);\n}\n\n.lr-lang-menu.open {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.lr-lang-item {\n background: none;\n color: #ccc;\n border: none;\n padding: 6px 10px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: 4px;\n text-align: left;\n}\n\n.lr-lang-item:hover {\n background: rgba(255,255,255,0.1);\n color: #fff;\n}\n\n.lr-lang-item.active {\n background: #2d7f7f;\n color: #fff;\n}\n\n.lr-fab-progress {\n font-size: 13px;\n color: rgba(255,255,255,0.7);\n}\n\n.lr-fab-exit {\n background: none;\n border: 1px solid rgba(255,255,255,0.3);\n color: #fff;\n padding: 4px 10px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n}\n\n.lr-fab-exit:hover {\n background: rgba(255,255,255,0.1);\n}\n\n/* \u2500\u2500 Overlay \u2500\u2500 */\n.lr-overlay {\n position: fixed;\n pointer-events: none;\n border: 2px solid #2d7f7f;\n border-radius: 3px;\n background: rgba(45, 127, 127, 0.06);\n transition: all 0.1s ease;\n z-index: 2147483646;\n display: none;\n}\n\n.lr-overlay.active {\n display: block;\n}\n\n/* \u2500\u2500 Sidebar \u2500\u2500 */\n.lr-sidebar {\n position: fixed;\n top: 0;\n right: 0;\n width: 360px;\n min-width: 280px;\n max-width: 600px;\n bottom: 0;\n background: #fff;\n border-left: 1px solid #e0e0e0;\n z-index: 2147483647;\n overflow-y: auto;\n transform: translateX(100%);\n transition: transform 0.2s ease;\n}\n\n.lr-sidebar.open {\n transform: translateX(0);\n}\n\n/* Resize handle on left edge */\n.lr-sidebar-resize {\n position: absolute;\n top: 0;\n left: -4px;\n width: 8px;\n bottom: 0;\n cursor: col-resize;\n z-index: 1;\n}\n\n.lr-sidebar-resize:hover,\n.lr-sidebar-resize.active {\n background: rgba(45, 127, 127, 0.3);\n}\n\n.lr-sidebar-header {\n padding: 16px;\n border-bottom: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.lr-sidebar-title {\n font-weight: 600;\n font-size: 15px;\n}\n\n.lr-sidebar-close {\n background: none;\n border: none;\n font-size: 20px;\n cursor: pointer;\n color: #666;\n padding: 4px 8px;\n line-height: 1;\n}\n\n.lr-sidebar-close:hover {\n color: #1a1a2e;\n}\n\n.lr-sidebar-body {\n padding: 16px;\n}\n\n.lr-field {\n margin-bottom: 16px;\n}\n\n.lr-field-label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n}\n\n.lr-field-key {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n color: #2d7f7f;\n background: #f0f7f7;\n padding: 4px 8px;\n border-radius: 4px;\n word-break: break-all;\n}\n\n.lr-field-original {\n font-size: 13px;\n color: #333;\n background: #f8f8f8;\n padding: 10px 12px;\n border-radius: 6px;\n border: 1px solid #eee;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.lr-field-tag {\n display: inline;\n background: #d9eded;\n color: #2d7f7f;\n padding: 0 3px;\n border-radius: 2px;\n font-family: monospace;\n font-size: 12px;\n}\n\n.lr-textarea {\n width: 100%;\n min-height: 100px;\n padding: 10px 12px;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n resize: vertical;\n outline: none;\n transition: border-color 0.15s;\n}\n\n.lr-textarea:focus {\n border-color: #2d7f7f;\n box-shadow: 0 0 0 3px rgba(45, 127, 127, 0.1);\n}\n\n.lr-preview {\n padding: 10px 12px;\n background: #f8f8f8;\n border: 1px solid #eee;\n border-radius: 6px;\n font-size: 13px;\n min-height: 40px;\n}\n\n.lr-status {\n padding: 10px 16px;\n font-size: 12px;\n color: #666;\n text-align: center;\n border-top: 1px solid #eee;\n background: #fafafa;\n}\n\n.lr-status.saved {\n color: #22c55e;\n}\n\n.lr-status.error {\n color: #ef4444;\n}\n\n.lr-status.unsaved {\n color: #f59e0b;\n}\n\n/* \u2500\u2500 Page blocks list \u2500\u2500 */\n.lr-blocks-section {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n}\n\n.lr-blocks-title {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n\n.lr-block-item {\n padding: 8px 10px;\n border: 1px solid #eee;\n border-radius: 4px;\n margin-bottom: 4px;\n cursor: pointer;\n font-size: 13px;\n color: #333;\n overflow: hidden;\n transition: background 0.1s;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n\n.lr-block-item:hover {\n background: #f0f7f7;\n border-color: #2d7f7f;\n}\n\n.lr-block-item.active {\n background: #e5f2f2;\n border-color: #2d7f7f;\n}\n\n/* \u2500\u2500 Status dots \u2500\u2500 */\n.lr-status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n margin-top: 5px;\n background: #d1d5db;\n}\n\n.lr-status-dot.missing { background: #d1d5db; }\n.lr-status-dot.mt { background: #60a5fa; }\n.lr-status-dot.edited { background: #f97316; }\n.lr-status-dot.confirmed { background: #22c55e; }\n.lr-status-dot.ready { background: #22c55e; }\n.lr-status-dot.locked { background: #a855f7; }\n.lr-status-dot.unsaved { background: #f59e0b; }\n\n/* \u2500\u2500 Locked textarea \u2500\u2500 */\n.lr-textarea-locked {\n background: #f3f4f6;\n color: #6b7280;\n cursor: not-allowed;\n border-color: #e5e7eb;\n}\n\n/* \u2500\u2500 Block text layout \u2500\u2500 */\n.lr-block-text {\n overflow: hidden;\n min-width: 0;\n}\n\n.lr-block-source {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.lr-block-preview {\n font-size: 11px;\n color: #888;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-top: 2px;\n}\n`;\n", "/**\n * Default style mapper for bidirectional HTML element \u2194 style property mapping\n * @module content/style-mapper/DefaultStyleMapper\n */\n\nimport type { IStyleMapper, ElementMapping } from './IStyleMapper.js';\n\n/**\n * Default implementation of style mapping\n *\n * Provides bidirectional conversion between HTML elements and style properties:\n * - mapElementToStyles: `<b>` \u2192 `[\"bold\"]`\n * - mapStylesToElement: `[\"bold\"]` \u2192 `<b>`\n *\n * @example\n * ```typescript\n * const mapper = new DefaultStyleMapper();\n *\n * // Parsing: HTML \u2192 styles\n * mapper.mapElementToStyles('a', { href: '/terms' });\n * // \u2192 [\"hyperlink:/terms\"]\n *\n * // Serializing: styles \u2192 HTML\n * mapper.mapStylesToElement(['bold', 'hyperlink:/terms']);\n * // \u2192 { element: 'a', attrs: { href: '/terms' } }\n * ```\n */\nexport class DefaultStyleMapper implements IStyleMapper {\n /**\n * Element \u2192 Style mapping\n * Maps HTML element names to their style property\n */\n private readonly elementToStyles: Record<string, string> = {\n b: 'bold',\n strong: 'bold',\n i: 'italic',\n em: 'italic',\n u: 'underline',\n s: 'strikethrough',\n del: 'strikethrough',\n strike: 'strikethrough',\n code: 'code',\n mark: 'highlight',\n sub: 'subscript',\n sup: 'superscript',\n };\n\n /**\n * Style \u2192 Element mapping (reverse)\n * Uses simple, familiar elements for developer convenience\n * Also accepts element names directly (strong, em, etc.)\n */\n private readonly styleToElement: Record<string, string> = {\n // Semantic style names \u2192 simple elements\n bold: 'b',\n italic: 'i',\n underline: 'u',\n strikethrough: 's',\n code: 'code',\n highlight: 'mark',\n subscript: 'sub',\n superscript: 'sup',\n // Element names (for servers that store styles as element names)\n strong: 'b',\n b: 'b',\n em: 'i',\n i: 'i',\n u: 'u',\n s: 's',\n del: 's',\n strike: 's',\n mark: 'mark',\n sub: 'sub',\n sup: 'sup',\n };\n\n /**\n * Convert HTML element to style properties\n *\n * @param element - Tag name (e.g., \"b\", \"a\", \"strong\")\n * @param attrs - Element attributes (e.g., { href: \"/url\" })\n * @returns Array of style strings\n */\n mapElementToStyles(element: string, attrs: Record<string, string>): string[] {\n const styles: string[] = [];\n const tag = element.toLowerCase();\n\n // Basic element mapping\n const mappedStyle = this.elementToStyles[tag];\n if (mappedStyle) {\n styles.push(mappedStyle);\n }\n\n // Special: <a href=\"...\"> \u2192 hyperlink:url\n if (tag === 'a' && attrs.href) {\n styles.push(`hyperlink:${attrs.href}`);\n }\n\n return styles;\n }\n\n /**\n * Convert style properties to HTML element\n *\n * Priority order:\n * 1. Hyperlink (becomes wrapper element with href)\n * 2. First recognized style property\n * 3. Fallback to span\n *\n * @param styles - Array of style strings\n * @returns Element info for serialization\n */\n mapStylesToElement(styles: string[]): ElementMapping {\n // Check for hyperlink first (takes priority as wrapper element)\n for (const style of styles) {\n if (style.startsWith('hyperlink:')) {\n return {\n element: 'a',\n attrs: { href: style.slice('hyperlink:'.length) },\n };\n }\n }\n\n // Map first recognized style to element\n for (const style of styles) {\n const element = this.styleToElement[style];\n if (element) {\n return {\n element,\n attrs: {},\n };\n }\n }\n\n // Fallback: span with no special attributes\n return { element: 'span', attrs: {} };\n }\n}\n", "/**\n * DOM-based Markup Parser\n *\n * Converts a block element's childNodes into ContentUnit.\n * Uses the browser's DOM rather than regex (unlike edge/PHP which parse raw HTML strings).\n * Mirrors WordPress TS MarkupParser.\n */\n\nimport type { ContentUnit } from '../content/types.js';\nimport { DefaultStyleMapper } from '../content/style-mapper/DefaultStyleMapper.js';\n\nconst styleMapper = new DefaultStyleMapper();\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\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 const styleList = styleMapper.mapElementToStyles(tag, attrs);\n\n if (styleList.length > 0) {\n // Known styled element \u2014 assign indexed tag\n tagIndex++;\n const idx = tagIndex;\n styles[String(idx)] = styleList;\n\n let inner = '';\n for (let i = 0; i < node.childNodes.length; i++) {\n inner += walk(node.childNodes[i]);\n }\n\n return `<${idx}>${inner}</${idx}>`;\n }\n\n // Unknown element \u2014 strip tag, recurse children\n let result = '';\n for (let i = 0; i < node.childNodes.length; i++) {\n result += walk(node.childNodes[i]);\n }\n return result;\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\nfunction str2binl(str: string): number[] {\n const bin: number[] = [];\n for (let i = 0; i < str.length * 8; i += 8) {\n bin[i >> 5] |= (str.charCodeAt(i / 8) & 0xff) << i % 32;\n }\n return bin;\n}\n\n/**\n * Generate MD5 hash of a string\n * Matches PHP's md5() function output\n */\nexport function md5(str: string): string {\n return binl2hex(binlMD5(str2binl(str), str.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 * Key Resolver\n * Resolves a clicked element to its translation key and ContentUnit.\n */\n\nimport type { ContentUnit } from '../../content/types.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\nexport interface ResolvedKey {\n key: string;\n /** Source ContentUnit (original text with indexed tags) */\n unit: ContentUnit;\n /** Current translation as ContentUnit (if element is already translated) */\n translatedUnit: ContentUnit | null;\n element: Element;\n}\n\n/**\n * Resolve an element to its translation key.\n * Priority: data-lr-block attr \u2192 parseBlockElement \u2192 fallback textContent\n */\nexport function resolveKey(target: Element): ResolvedKey | null {\n // Priority 1: Already translated element with data-lr-block\n const blockEl = target.closest('[data-lr-block]');\n if (blockEl) {\n const key = blockEl.getAttribute('data-lr-block')!;\n const original = blockEl.getAttribute('data-lr-original');\n let unit: ContentUnit;\n let translatedUnit: ContentUnit | null = null;\n\n if (original) {\n // Parse original HTML \u2192 source ContentUnit\n const temp = document.createElement(blockEl.tagName);\n temp.innerHTML = original;\n unit = parseBlockElement(temp);\n // Parse current DOM \u2192 translated ContentUnit\n translatedUnit = parseBlockElement(blockEl);\n } else {\n unit = parseBlockElement(blockEl);\n }\n return { key, unit, translatedUnit, element: blockEl };\n }\n\n // Priority 2: Find nearest block element and parse it\n const nearest = target.closest(BLOCK_SELECTOR);\n if (nearest) {\n const unit = parseBlockElement(nearest);\n const key = generateAutoKey(unit.text);\n return { key, unit, translatedUnit: null, element: nearest };\n }\n\n // Priority 3: Fallback to element text\n const text = target.textContent?.trim();\n if (text && text.length >= 2) {\n const key = generateAutoKey(text);\n const unit: ContentUnit = { text, styles: {} };\n return { key, unit, translatedUnit: null, element: target };\n }\n\n return null;\n}\n", "/**\n * Inspector \u2014 Hover/click handling\n * Shows overlay on hover, resolves key on click, opens sidebar.\n */\n\nimport { resolveKey, ResolvedKey } from './key-resolver.js';\n\nconst SKIP_TAGS = new Set(['SCRIPT', 'STYLE', 'CODE', 'PRE', 'TEXTAREA', 'NOSCRIPT', 'SVG']);\n\nconst BLOCK_SELECTOR =\n 'p,h1,h2,h3,h4,h5,h6,li,td,th,label,button,figcaption,dt,dd,summary,caption';\n\nexport type OnSelectCallback = (resolved: ResolvedKey) => void;\n\nexport class Inspector {\n private overlay: HTMLDivElement;\n private currentTarget: Element | null = null;\n private onSelect: OnSelectCallback;\n private rafId: number | null = null;\n private active = true;\n\n constructor(shadowRoot: ShadowRoot, onSelect: OnSelectCallback) {\n this.onSelect = onSelect;\n\n // Create overlay inside shadow DOM\n this.overlay = document.createElement('div');\n this.overlay.className = 'lr-overlay';\n shadowRoot.appendChild(this.overlay);\n\n // Bind handlers\n this.handleMouseOver = this.handleMouseOver.bind(this);\n this.handleClick = this.handleClick.bind(this);\n this.handleScroll = this.handleScroll.bind(this);\n\n // Listen on document (capture phase to get events before page handlers)\n document.addEventListener('mouseover', this.handleMouseOver, true);\n document.addEventListener('click', this.handleClick, true);\n window.addEventListener('scroll', this.handleScroll, true);\n window.addEventListener('resize', this.handleScroll);\n }\n\n destroy(): void {\n this.active = false;\n document.removeEventListener('mouseover', this.handleMouseOver, true);\n document.removeEventListener('click', this.handleClick, true);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.overlay.remove();\n }\n\n clearHighlight(): void {\n this.currentTarget = null;\n this.overlay.classList.remove('active');\n }\n\n private handleMouseOver(e: Event): void {\n if (!this.active) return;\n const target = e.target as Element;\n if (!target || !target.closest) return;\n\n // Skip editor UI elements (inside shadow DOM won't trigger this, but be safe)\n if (target.closest('#__lionrapid-editor')) return;\n\n // Skip non-translatable elements\n if (this.shouldSkip(target)) {\n this.clearHighlight();\n return;\n }\n\n // Find nearest block element\n const block = target.closest(BLOCK_SELECTOR) || target.closest('[data-lr-block]');\n if (!block) {\n this.clearHighlight();\n return;\n }\n\n if (block === this.currentTarget) return;\n\n this.currentTarget = block;\n this.positionOverlay(block);\n }\n\n private handleClick(e: Event): void {\n if (!this.active) return;\n const target = e.target as Element;\n if (!target || !target.closest) return;\n\n // Skip editor UI\n if (target.closest('#__lionrapid-editor')) return;\n\n // Find the block to resolve\n const block = target.closest(BLOCK_SELECTOR) || target.closest('[data-lr-block]');\n if (!block) return;\n\n if (this.shouldSkip(block)) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const resolved = resolveKey(block);\n if (resolved) {\n this.onSelect(resolved);\n }\n }\n\n private handleScroll(): void {\n if (!this.currentTarget) return;\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(() => {\n if (this.currentTarget) {\n this.positionOverlay(this.currentTarget);\n }\n });\n }\n\n private positionOverlay(element: Element): void {\n const rect = element.getBoundingClientRect();\n this.overlay.style.top = `${rect.top}px`;\n this.overlay.style.left = `${rect.left}px`;\n this.overlay.style.width = `${rect.width}px`;\n this.overlay.style.height = `${rect.height}px`;\n this.overlay.classList.add('active');\n }\n\n private shouldSkip(element: Element): boolean {\n // Skip SKIP_TAGS\n let current: Element | null = element;\n while (current) {\n if (SKIP_TAGS.has(current.tagName)) return true;\n if (current.hasAttribute('data-no-translate')) return true;\n if (current.getAttribute('translate') === 'no') return true;\n current = current.parentElement;\n }\n return false;\n }\n}\n", "/**\n * Toolbar \u2014 Draggable FAB that expands to show controls\n * Collapsed: small circle with \"LR\" logo\n * Expanded: horizontal bar with language selector, progress, exit\n */\n\nexport type OnLanguageChange = (locale: string) => void;\nexport type OnExit = () => void;\n\nexport class Toolbar {\n private el: HTMLDivElement;\n private langBtnEl: HTMLButtonElement;\n private langMenuEl: HTMLDivElement;\n private progressEl: HTMLSpanElement;\n private expanded = false;\n private currentLocale: string;\n private onLanguageChange: OnLanguageChange;\n private onExit: OnExit;\n\n // Drag state\n private dragging = false;\n private dragOffsetX = 0;\n private dragOffsetY = 0;\n\n constructor(\n shadowRoot: ShadowRoot,\n languages: string[],\n currentLocale: string,\n onLanguageChange: OnLanguageChange,\n onExit: OnExit,\n ) {\n this.onLanguageChange = onLanguageChange;\n this.onExit = onExit;\n this.currentLocale = currentLocale;\n\n this.el = document.createElement('div');\n this.el.className = 'lr-fab';\n\n // FAB button (always visible)\n const fabBtn = document.createElement('button');\n fabBtn.className = 'lr-fab-btn';\n fabBtn.textContent = 'LR';\n fabBtn.addEventListener('click', (e) => {\n // Don't toggle if we just finished dragging\n if (this.dragging) return;\n e.stopPropagation();\n this.toggle();\n });\n this.el.appendChild(fabBtn);\n\n // Expanded panel\n const panel = document.createElement('div');\n panel.className = 'lr-fab-panel';\n\n // Custom language dropdown\n const langWrap = document.createElement('div');\n langWrap.className = 'lr-lang-dropdown';\n\n this.langBtnEl = document.createElement('button');\n this.langBtnEl.className = 'lr-lang-btn';\n this.langBtnEl.textContent = currentLocale.toUpperCase();\n this.langBtnEl.addEventListener('click', (e) => {\n e.stopPropagation();\n this.langMenuEl.classList.toggle('open');\n });\n langWrap.appendChild(this.langBtnEl);\n\n this.langMenuEl = document.createElement('div');\n this.langMenuEl.className = 'lr-lang-menu';\n for (const lang of languages) {\n const item = document.createElement('button');\n item.className = 'lr-lang-item';\n if (lang === currentLocale) item.classList.add('active');\n item.textContent = lang.toUpperCase();\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n this.currentLocale = lang;\n this.langBtnEl.textContent = lang.toUpperCase();\n this.langMenuEl.classList.remove('open');\n // Update active state\n this.langMenuEl.querySelectorAll('.lr-lang-item').forEach((el) => el.classList.remove('active'));\n item.classList.add('active');\n this.onLanguageChange(lang);\n });\n this.langMenuEl.appendChild(item);\n }\n langWrap.appendChild(this.langMenuEl);\n panel.appendChild(langWrap);\n\n // Progress\n this.progressEl = document.createElement('span');\n this.progressEl.className = 'lr-fab-progress';\n panel.appendChild(this.progressEl);\n\n // Exit button\n const exitBtn = document.createElement('button');\n exitBtn.className = 'lr-fab-exit';\n exitBtn.textContent = 'Exit';\n exitBtn.addEventListener('click', () => this.onExit());\n panel.appendChild(exitBtn);\n\n this.el.appendChild(panel);\n shadowRoot.appendChild(this.el);\n\n // Dragging\n this.handleMouseDown = this.handleMouseDown.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n fabBtn.addEventListener('mousedown', this.handleMouseDown);\n }\n\n toggle(): void {\n this.expanded = !this.expanded;\n this.el.classList.toggle('expanded', this.expanded);\n }\n\n updateProgress(translated: number, total: number): void {\n this.progressEl.textContent = `${translated}/${total}`;\n }\n\n getCurrentLocale(): string {\n return this.currentLocale;\n }\n\n destroy(): void {\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.el.remove();\n }\n\n private handleMouseDown(e: MouseEvent): void {\n this.dragging = false;\n this.dragOffsetX = e.clientX - this.el.getBoundingClientRect().left;\n this.dragOffsetY = e.clientY - this.el.getBoundingClientRect().top;\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n this.dragging = true;\n const x = Math.max(0, Math.min(e.clientX - this.dragOffsetX, window.innerWidth - this.el.offsetWidth));\n const y = Math.max(0, Math.min(e.clientY - this.dragOffsetY, window.innerHeight - this.el.offsetHeight));\n this.el.style.left = `${x}px`;\n this.el.style.top = `${y}px`;\n this.el.style.right = 'auto';\n this.el.style.bottom = 'auto';\n }\n\n private handleMouseUp(): void {\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n // Reset dragging flag after a tick so the click handler can check it\n if (this.dragging) {\n setTimeout(() => { this.dragging = false; }, 0);\n }\n }\n}\n", "/**\n * HTML serializer for converting ContentUnit to HTML strings\n * @module content/serializer/HTMLSerializer\n */\n\nimport type { ISerializer } from './ISerializer.js';\nimport type { ContentUnit } from '../types.js';\nimport type { IStyleMapper } from '../style-mapper/IStyleMapper.js';\nimport { DefaultStyleMapper } from '../style-mapper/DefaultStyleMapper.js';\n\n/**\n * Configuration options for HTMLSerializer\n */\nexport interface HTMLSerializerOptions {\n /**\n * Custom style mapper for styles \u2192 element conversion\n * Defaults to DefaultStyleMapper\n */\n styleMapper?: IStyleMapper;\n}\n\n/**\n * Serializer that converts ContentUnit format back to HTML strings\n *\n * Transforms indexed tags and style mappings into HTML:\n * - `<1>bold</1>` with styles `{\"1\": [\"bold\"]}` \u2192 `<b>bold</b>`\n * - `<1>link</1>` with styles `{\"1\": [\"hyperlink:/url\"]}` \u2192 `<a href=\"/url\">link</a>`\n *\n * @example\n * ```typescript\n * const serializer = new HTMLSerializer();\n *\n * const html = serializer.serialize({\n * text: 'Read our <1>Terms</1>.',\n * styles: { '1': ['bold'] }\n * });\n * // \u2192 \"Read our <b>Terms</b>.\"\n *\n * const link = serializer.serialize({\n * text: 'Click <1>here</1>.',\n * styles: { '1': ['hyperlink:/url'] }\n * });\n * // \u2192 \"Click <a href=\\\"/url\\\">here</a>.\"\n * ```\n */\nexport class HTMLSerializer implements ISerializer<string> {\n private readonly styleMapper: IStyleMapper;\n\n constructor(options: HTMLSerializerOptions = {}) {\n this.styleMapper = options.styleMapper ?? new DefaultStyleMapper();\n }\n\n /**\n * Serialize ContentUnit to HTML string\n *\n * @param unit - ContentUnit with indexed tags and styles\n * @returns HTML string with semantic elements\n */\n serialize(unit: ContentUnit): string {\n const { text, styles } = unit;\n\n // Pattern to match indexed tags: <1>, </1>, <1/>\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 // Append text before the tag\n result += text.slice(lastIndex, match.index);\n\n const [fullMatch, closingSlash, indexStr, selfClosingSlash] = match;\n const tagIndex = indexStr;\n const styleList = styles[tagIndex] || [];\n\n if (closingSlash) {\n // Closing tag: </1>\n const mapping = this.styleMapper.mapStylesToElement(styleList);\n result += `</${mapping.element}>`;\n } else if (selfClosingSlash) {\n // Self-closing tag: <1/>\n const mapping = this.styleMapper.mapStylesToElement(styleList);\n const attrs = this.formatAttributes(mapping.attrs);\n result += `<${mapping.element}${attrs} />`;\n } else {\n // Opening tag: <1>\n const mapping = this.styleMapper.mapStylesToElement(styleList);\n const attrs = this.formatAttributes(mapping.attrs);\n result += `<${mapping.element}${attrs}>`;\n }\n\n lastIndex = match.index + fullMatch.length;\n }\n\n // Append remaining text\n result += text.slice(lastIndex);\n\n return result;\n }\n\n /**\n * Format attributes object into HTML attribute string\n */\n private formatAttributes(attrs: Record<string, string>): string {\n const entries = Object.entries(attrs);\n if (entries.length === 0) return '';\n\n return (\n ' ' +\n entries\n .map(([key, value]) => `${key}=\"${this.escapeAttributeValue(value)}\"`)\n .join(' ')\n );\n }\n\n /**\n * Escape special characters in attribute values\n */\n private escapeAttributeValue(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n}\n", "/**\n * Live Preview\n * Optimistically updates DOM elements as the user types translations.\n */\n\nimport type { ContentUnit } from '../../content/types.js';\nimport { HTMLSerializer } from '../../content/serializer/HTMLSerializer.js';\n\nconst htmlSerializer = new HTMLSerializer();\n\n/**\n * Update a single element's content with a new translation.\n * Writes to core cache and updates the DOM without full page retranslate.\n */\nexport function applyLivePreview(\n element: Element,\n text: string,\n styles: Record<string, string[]>,\n key: string,\n locale: string,\n namespace: string,\n): void {\n // Save original HTML before first edit\n if (!element.hasAttribute('data-lr-original')) {\n element.setAttribute('data-lr-original', element.innerHTML);\n }\n\n // Update core cache if available\n const lr = (window as { LionRapid?: { autoTranslator?: { core?: { cache?: { set?: (k: string, v: string, s?: Record<string, string[]>) => void } } } } }).LionRapid;\n const cache = (lr as Record<string, unknown>)?.autoTranslator\n ? getCache()\n : null;\n if (cache) {\n const fullKey = `${locale}:${namespace}:${key}`;\n cache.set(fullKey, text, styles);\n }\n\n // Update DOM\n if (styles && Object.keys(styles).length > 0) {\n const unit: ContentUnit = { text, styles };\n element.innerHTML = htmlSerializer.serialize(unit);\n } else {\n element.textContent = text;\n }\n\n // Mark as translated\n element.setAttribute('data-lr-block', key);\n element.setAttribute('data-lionrapid-client', '1');\n}\n\nfunction getCache(): { set: (key: string, value: string, styles?: Record<string, string[]>) => void } | null {\n try {\n const lr = (window as unknown as { LionRapid?: Record<string, unknown> }).LionRapid;\n if (!lr) return null;\n const at = lr.autoTranslator as Record<string, unknown> | undefined;\n if (!at) return null;\n const core = at.core as Record<string, unknown> | undefined;\n if (!core) return null;\n const cache = core.cache as { set?: (key: string, value: string, styles?: Record<string, string[]>) => void } | undefined;\n if (!cache || typeof cache.set !== 'function') return null;\n return cache as { set: (key: string, value: string, styles?: Record<string, string[]>) => void };\n } catch {\n return null;\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 * 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// 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];\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 return results;\n }\n\n private isInsideSkipTag(element: Element): boolean {\n let current: Element | null = element.parentElement;\n while (current) {\n if (SKIP_TAGS.has(current.tagName)) {\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 * Sidebar \u2014 Translation editing panel\n * Shows original text, translation textarea, live preview, and page blocks list.\n */\n\nimport type { ContentUnit } from '../../content/types.js';\nimport type { ResolvedKey } from './key-resolver.js';\nimport { HTMLSerializer } from '../../content/serializer/HTMLSerializer.js';\nimport { applyLivePreview } from './live-preview.js';\nimport type { EditorAPI, TargetStatus } from './editor-api.js';\nimport { BlockExtractor } from '../block-extractor.js';\n\nconst htmlSerializer = new HTMLSerializer();\n\nexport class Sidebar {\n private el: HTMLDivElement;\n private bodyEl: HTMLDivElement;\n private statusEl: HTMLDivElement;\n private api: EditorAPI;\n private locale: string;\n private namespace: string;\n private defaultLocale: string;\n private current: ResolvedKey | null = null;\n private blockExtractor: BlockExtractor;\n private onBlockClick: (resolved: ResolvedKey) => void;\n private statusMap: Map<string, TargetStatus | null> = new Map();\n private unsavedKeys: Set<string> = new Set();\n private onProgressUpdate: ((translated: number, total: number) => void) | null = null;\n private lastFetchTime = 0;\n private lastFlushTime = 0;\n\n constructor(\n shadowRoot: ShadowRoot,\n api: EditorAPI,\n locale: string,\n namespace: string,\n defaultLocale: string,\n onBlockClick: (resolved: ResolvedKey) => void,\n ) {\n this.api = api;\n this.locale = locale;\n this.namespace = namespace;\n this.defaultLocale = defaultLocale;\n this.onBlockClick = onBlockClick;\n this.blockExtractor = new BlockExtractor();\n\n this.el = document.createElement('div');\n this.el.className = 'lr-sidebar';\n\n // Resize handle\n const resizeHandle = document.createElement('div');\n resizeHandle.className = 'lr-sidebar-resize';\n this.initResize(resizeHandle);\n this.el.appendChild(resizeHandle);\n\n // Header\n const header = document.createElement('div');\n header.className = 'lr-sidebar-header';\n const title = document.createElement('span');\n title.className = 'lr-sidebar-title';\n title.textContent = 'Edit Translation';\n header.appendChild(title);\n const closeBtn = document.createElement('button');\n closeBtn.className = 'lr-sidebar-close';\n closeBtn.innerHTML = '×';\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n // Body\n this.bodyEl = document.createElement('div');\n this.bodyEl.className = 'lr-sidebar-body';\n this.el.appendChild(this.bodyEl);\n\n // Status bar (rendered inline in renderContent, above preview)\n this.statusEl = document.createElement('div');\n this.statusEl.className = 'lr-status';\n\n // Wire up API status\n this.api.setStatusCallback((status, message) => {\n this.statusEl.textContent = message || status;\n this.statusEl.className = `lr-status ${status}`;\n });\n\n // After flush, re-fetch status for saved keys and refresh blocks list\n this.api.setFlushedCallback(async (keys) => {\n this.lastFlushTime = Date.now();\n const freshStatuses = await this.api.fetchStatus(keys, this.locale, this.namespace);\n for (const [key, status] of Object.entries(freshStatuses)) {\n this.statusMap.set(key, status);\n this.unsavedKeys.delete(key);\n }\n this.refreshBlocksList();\n this.emitProgress();\n });\n\n shadowRoot.appendChild(this.el);\n }\n\n open(resolved: ResolvedKey): void {\n this.current = resolved;\n this.el.classList.add('open');\n this.renderContent(resolved);\n }\n\n close(): void {\n this.current = null;\n this.el.classList.remove('open');\n }\n\n isOpen(): boolean {\n return this.el.classList.contains('open');\n }\n\n updateLocale(locale: string): void {\n this.locale = locale;\n // Clear status on locale change \u2014 will be re-fetched\n this.statusMap.clear();\n this.unsavedKeys.clear();\n }\n\n setProgressCallback(cb: (translated: number, total: number) => void): void {\n this.onProgressUpdate = cb;\n }\n\n /**\n * Hydrate the status map with server data for all page blocks.\n * Called once on editor init.\n */\n async hydrateStatus(): Promise<void> {\n const blocks = this.blockExtractor.extract(document.body, true);\n const keys = blocks.map((b) => b.key);\n if (keys.length === 0) return;\n\n const statuses = await this.api.fetchStatus(keys, this.locale, this.namespace);\n for (const [key, status] of Object.entries(statuses)) {\n this.statusMap.set(key, status);\n }\n\n // Apply draft translations to page blocks that the edge proxy didn't render\n // (edge proxy only shows is_ready_for_delivery; editor shows everything)\n for (const block of blocks) {\n const status = this.statusMap.get(block.key);\n if (status && status.text && !status.isReady) {\n applyLivePreview(block.element, status.text, block.unit.styles, block.key, this.locale, this.namespace);\n }\n }\n\n this.emitProgress();\n }\n\n getTranslatedCount(): number {\n let count = 0;\n for (const status of this.statusMap.values()) {\n if (status && status.rowState !== 'empty') count++;\n }\n return count;\n }\n\n getTotalCount(): number {\n return this.blockExtractor.extract(document.body, true).length;\n }\n\n private emitProgress(): void {\n if (this.onProgressUpdate) {\n this.onProgressUpdate(this.getTranslatedCount(), this.getTotalCount());\n }\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n private async renderContent(resolved: ResolvedKey): Promise<void> {\n const { key, unit, element } = resolved;\n this.bodyEl.innerHTML = '';\n\n // Smart fetch: if no flush since last full fetch, only fetch the clicked key.\n // Otherwise re-fetch all blocks to pick up server-side changes from our saves.\n const isStale = this.lastFlushTime > this.lastFetchTime || this.lastFetchTime === 0;\n\n if (isStale) {\n const blocks = this.blockExtractor.extract(document.body, true);\n const allKeys = blocks.map((b) => b.key);\n if (!allKeys.includes(key)) allKeys.push(key);\n const freshStatuses = await this.api.fetchStatus(allKeys, this.locale, this.namespace);\n for (const [k, s] of Object.entries(freshStatuses)) {\n this.statusMap.set(k, s);\n }\n this.lastFetchTime = Date.now();\n } else {\n // Fresh \u2014 only fetch the clicked key\n const freshStatus = await this.api.fetchStatus([key], this.locale, this.namespace);\n if (freshStatus[key] !== undefined) {\n this.statusMap.set(key, freshStatus[key]);\n }\n }\n const status = this.statusMap.get(key) ?? null;\n\n // Key field\n this.addField('Key', () => {\n const keyEl = document.createElement('div');\n keyEl.className = 'lr-field-key';\n keyEl.textContent = key;\n return keyEl;\n });\n\n // Original text\n this.addField('Original', () => {\n const origEl = document.createElement('div');\n origEl.className = 'lr-field-original';\n origEl.innerHTML = this.renderTextWithTags(unit.text);\n return origEl;\n });\n\n const isSourceLocale = this.locale === this.defaultLocale;\n const isLocked = isSourceLocale || status?.isLocked || status?.isReady || false;\n\n // Translation textarea\n const textarea = document.createElement('textarea');\n this.addField('Translation', () => {\n textarea.className = 'lr-textarea';\n // Pre-fill: server status > in-DOM translation > empty\n textarea.value = status?.text || resolved.translatedUnit?.text || '';\n textarea.placeholder = unit.text; // Show source as placeholder\n if (isLocked) {\n textarea.readOnly = true;\n textarea.classList.add('lr-textarea-locked');\n textarea.title = isSourceLocale\n ? 'Source language \u2014 switch to a target language to edit'\n : status?.isReady ? 'Approved for delivery \u2014 read only' : 'Locked \u2014 read only';\n }\n return textarea;\n });\n\n // Status bar (above preview)\n this.bodyEl.appendChild(this.statusEl);\n\n // Preview\n const previewEl = document.createElement('div');\n this.addField('Preview', () => {\n previewEl.className = 'lr-preview';\n if (textarea.value) {\n previewEl.innerHTML = this.renderPreview(textarea.value, unit.styles);\n }\n return previewEl;\n });\n\n // Live preview on input (only if not locked)\n if (!isLocked) {\n textarea.addEventListener('input', () => {\n const text = textarea.value;\n previewEl.innerHTML = this.renderPreview(text, unit.styles);\n if (text) {\n applyLivePreview(element, text, unit.styles, key, this.locale, this.namespace);\n }\n this.unsavedKeys.add(key);\n this.api.queueSave({\n key,\n locale: this.locale,\n namespace: this.namespace,\n text,\n styles: unit.styles,\n });\n });\n }\n\n // Page blocks list\n this.renderBlocksList();\n\n // Focus textarea (only if editable)\n if (!isLocked) {\n setTimeout(() => textarea.focus(), 100);\n }\n }\n\n private addField(label: string, contentFn: () => HTMLElement): void {\n const field = document.createElement('div');\n field.className = 'lr-field';\n const labelEl = document.createElement('span');\n labelEl.className = 'lr-field-label';\n labelEl.textContent = label;\n field.appendChild(labelEl);\n field.appendChild(contentFn());\n this.bodyEl.appendChild(field);\n }\n\n /**\n * Get CSS class for the status dot based on actual row state.\n */\n private getDotClass(key: string): string {\n if (this.unsavedKeys.has(key)) return 'unsaved';\n const s = this.statusMap.get(key);\n if (!s) return 'missing';\n if (s.isLocked) return 'locked';\n if (s.isReady) return 'ready';\n if (s.isConfirmed) return 'confirmed';\n if (s.rowState === 'edited') return 'edited';\n if (s.rowState === 'machine_translated') return 'mt';\n return 'missing';\n }\n\n private renderTextWithTags(text: string): string {\n // Highlight indexed tags like <1>, </1>\n return text.replace(\n /<(\\/?)?(\\d+)(\\/)?>/g,\n (match) => `<span class=\"lr-field-tag\">${match}</span>`\n );\n }\n\n private renderPreview(text: string, styles: Record<string, string[]>): string {\n if (!text) return '';\n if (Object.keys(styles).length > 0) {\n const unit: ContentUnit = { text, styles };\n return htmlSerializer.serialize(unit);\n }\n return text;\n }\n\n private initResize(handle: HTMLDivElement): void {\n let startX = 0;\n let startWidth = 0;\n\n const onMouseMove = (e: MouseEvent) => {\n const newWidth = startWidth + (startX - e.clientX);\n const clamped = Math.max(280, Math.min(600, newWidth));\n this.el.style.width = `${clamped}px`;\n };\n\n const onMouseUp = () => {\n handle.classList.remove('active');\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n };\n\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n startX = e.clientX;\n startWidth = this.el.offsetWidth;\n handle.classList.add('active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n }\n\n private refreshBlocksList(): void {\n const existing = this.bodyEl.querySelector('.lr-blocks-section');\n if (existing) existing.remove();\n this.renderBlocksList();\n }\n\n private renderBlocksList(): void {\n const section = document.createElement('div');\n section.className = 'lr-blocks-section';\n\n const blocks = this.blockExtractor.extract(document.body, true);\n const translatedCount = this.getTranslatedCount();\n\n const title = document.createElement('div');\n title.className = 'lr-blocks-title';\n title.textContent = `Blocks on this page (${translatedCount}/${blocks.length} translated)`;\n section.appendChild(title);\n\n for (const block of blocks) {\n const item = document.createElement('div');\n item.className = 'lr-block-item';\n\n const isActive = this.current && block.element === this.current.element;\n if (isActive) item.classList.add('active');\n\n // Status dot\n const dot = document.createElement('span');\n dot.className = 'lr-status-dot';\n dot.classList.add(this.getDotClass(block.key));\n item.appendChild(dot);\n\n // Source text\n const textWrap = document.createElement('div');\n textWrap.className = 'lr-block-text';\n const displayText = block.unit.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n const sourceSpan = document.createElement('div');\n sourceSpan.className = 'lr-block-source';\n sourceSpan.textContent = displayText.length > 60 ? displayText.slice(0, 60) + '...' : displayText;\n sourceSpan.title = displayText;\n textWrap.appendChild(sourceSpan);\n\n // Translation preview (if exists)\n const blockStatus = this.statusMap.get(block.key);\n if (blockStatus && blockStatus.text) {\n const previewSpan = document.createElement('div');\n previewSpan.className = 'lr-block-preview';\n const previewText = blockStatus.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n previewSpan.textContent = previewText.length > 50 ? previewText.slice(0, 50) + '...' : previewText;\n textWrap.appendChild(previewSpan);\n }\n\n item.appendChild(textWrap);\n\n item.addEventListener('click', () => {\n block.element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n this.onBlockClick({ key: block.key, unit: block.unit, translatedUnit: null, element: block.element });\n });\n\n section.appendChild(item);\n }\n\n this.bodyEl.appendChild(section);\n }\n}\n", "/**\n * Editor API \u2014 Batch save queue + session auth\n * Queues translation edits and flushes them in a single batch API call.\n * Uses editor session JWTs (es_ prefixed) for authentication with auto-renewal.\n */\n\nexport interface QueuedTranslation {\n key: string;\n locale: string;\n namespace: string;\n text: string;\n styles: Record<string, string[]>;\n}\n\nexport interface TargetStatus {\n text: string;\n rowState: string; // \"empty\" | \"machine_translated\" | \"edited\"\n isConfirmed: boolean;\n isReady: boolean; // approved for delivery\n isLocked: boolean; // workflow locked OR delivery locked\n}\n\nexport type StatusCallback = (status: 'unsaved' | 'saving' | 'saved' | 'error', message?: string) => void;\n\nexport class EditorAPI {\n private queue: QueuedTranslation[] = [];\n private apiBase: string;\n private sessionToken: string;\n private projectId: string;\n private flushInterval: ReturnType<typeof setInterval> | null = null;\n private renewalInterval: ReturnType<typeof setInterval> | null = null;\n private onStatus: StatusCallback = () => {};\n private onFlushed: (keys: string[]) => void = () => {};\n private onSessionExpired: (() => void) | null = null;\n\n constructor(apiBase: string, sessionToken: string, projectId: string) {\n this.apiBase = apiBase.replace(/\\/$/, '');\n this.sessionToken = sessionToken;\n this.projectId = projectId;\n }\n\n setStatusCallback(cb: StatusCallback): void {\n this.onStatus = cb;\n }\n\n setFlushedCallback(cb: (keys: string[]) => void): void {\n this.onFlushed = cb;\n }\n\n setSessionExpiredCallback(cb: () => void): void {\n this.onSessionExpired = cb;\n }\n\n /**\n * Start auto-flush (30s interval + visibilitychange) and session renewal (60s check)\n */\n startAutoFlush(): void {\n this.flushInterval = setInterval(() => this.flush(), 30_000);\n document.addEventListener('visibilitychange', this.handleVisibility);\n\n // Check session renewal every 60s\n this.renewalInterval = setInterval(() => this.maybeRenewSession(), 60_000);\n }\n\n /**\n * Stop auto-flush and flush remaining items\n */\n async stopAndFlush(): Promise<void> {\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n this.flushInterval = null;\n }\n if (this.renewalInterval) {\n clearInterval(this.renewalInterval);\n this.renewalInterval = null;\n }\n document.removeEventListener('visibilitychange', this.handleVisibility);\n await this.flush();\n }\n\n /**\n * Queue a translation for saving\n */\n queueSave(item: QueuedTranslation): void {\n // Replace existing entry for same key+locale\n const idx = this.queue.findIndex(\n (q) => q.key === item.key && q.locale === item.locale && q.namespace === item.namespace\n );\n if (idx >= 0) {\n this.queue[idx] = item;\n } else {\n this.queue.push(item);\n }\n this.onStatus('unsaved', `${this.queue.length} unsaved`);\n\n // Auto-flush if queue is large\n if (this.queue.length > 50) {\n this.flush();\n }\n }\n\n /**\n * Flush all queued translations to the server\n */\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n\n const items = [...this.queue];\n this.onStatus('saving');\n\n try {\n const response = await fetch(\n `${this.apiBase}/api/integrations/targets/batch`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.sessionToken}`,\n },\n body: JSON.stringify({\n translations: items.map((t) => ({\n key: `${t.locale}:${t.namespace}:${t.key}`,\n value: { text: t.text, styles: t.styles },\n })),\n }),\n }\n );\n\n if (response.status === 401) {\n this.handleSessionExpired();\n return;\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n // Remove flushed items from queue (new items may have been added during fetch)\n const flushedKeys = items.map((i) => i.key);\n for (const item of items) {\n const idx = this.queue.indexOf(item);\n if (idx >= 0) this.queue.splice(idx, 1);\n }\n\n // Notify sidebar to re-fetch status for flushed keys\n this.onFlushed(flushedKeys);\n\n if (this.queue.length === 0) {\n this.onStatus('saved', 'All changes saved');\n } else {\n this.onStatus('unsaved', `${this.queue.length} unsaved`);\n }\n } catch (err) {\n this.onStatus('error', `Save failed: ${(err as Error).message}`);\n }\n }\n\n private statusAbort: AbortController | null = null;\n\n /**\n * Fetch translation status for a batch of keys (includes unconfirmed rows).\n * Cancels any in-flight status request. Caps at 200 keys per request.\n */\n async fetchStatus(\n keys: string[],\n locale: string,\n namespace: string\n ): Promise<Record<string, TargetStatus | null>> {\n if (keys.length === 0) return {};\n\n // Cancel previous in-flight request\n if (this.statusAbort) this.statusAbort.abort();\n this.statusAbort = new AbortController();\n\n // Cap keys to avoid exceeding URL length limits\n const batch = keys.slice(0, 200);\n\n const params = new URLSearchParams({ locale, namespace, keys: batch.join(',') });\n try {\n const response = await fetch(\n `${this.apiBase}/api/integrations/targets/status?${params}`,\n {\n headers: { 'Authorization': `Bearer ${this.sessionToken}` },\n signal: this.statusAbort.signal,\n }\n );\n if (response.status === 401) {\n this.handleSessionExpired();\n return {};\n }\n if (!response.ok) return {};\n const data = await response.json();\n return data.translations;\n } catch (err) {\n if ((err as Error).name === 'AbortError') return {};\n return {};\n }\n }\n\n get pendingCount(): number {\n return this.queue.length;\n }\n\n // ============================================\n // Session renewal\n // ============================================\n\n /**\n * Check if session is within 2min of expiry, and renew if so.\n */\n private async maybeRenewSession(): Promise<void> {\n const exp = this.getSessionExp();\n if (!exp) return;\n\n const timeLeft = exp * 1000 - Date.now();\n if (timeLeft > 120_000) return; // More than 2 min left, skip\n\n await this.renewSession();\n }\n\n private async renewSession(): Promise<void> {\n try {\n const response = await fetch(`${this.apiBase}/api/editor/renew`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.sessionToken}`,\n },\n });\n\n if (response.status === 401) {\n this.handleSessionExpired();\n return;\n }\n\n if (!response.ok) return;\n\n const data = await response.json();\n this.sessionToken = data.session_token;\n\n // Update sessionStorage\n try {\n const raw = this.sessionToken.startsWith('es_') ? this.sessionToken.slice(3) : this.sessionToken;\n const parts = raw.split('.');\n if (parts.length === 3) {\n const payload = JSON.parse(atob(parts[1]));\n sessionStorage.setItem('__lr_editor_session', JSON.stringify({\n token: this.sessionToken,\n exp: payload.exp || 0,\n }));\n }\n } catch { /* non-critical */ }\n } catch {\n // Network error \u2014 will retry on next interval\n }\n }\n\n private getSessionExp(): number | null {\n try {\n const raw = this.sessionToken.startsWith('es_') ? this.sessionToken.slice(3) : this.sessionToken;\n const parts = raw.split('.');\n if (parts.length !== 3) return null;\n const payload = JSON.parse(atob(parts[1]));\n return payload.exp || null;\n } catch {\n return null;\n }\n }\n\n private handleSessionExpired(): void {\n this.onStatus('error', 'Session expired. Please reopen the editor from the dashboard.');\n if (this.onSessionExpired) {\n this.onSessionExpired();\n }\n }\n\n private handleVisibility = (): void => {\n if (document.visibilityState === 'hidden') {\n this.flush();\n }\n };\n}\n", "/**\n * Visual Translation Editor \u2014 Entry Point\n * Self-executing IIFE bundle loaded by edge proxy or auto-init when ?__lr_editor is detected.\n *\n * Reads script tag attributes, polls for window.LionRapid, creates Shadow DOM,\n * and instantiates Inspector, Sidebar, and Toolbar.\n *\n * Auth flow: grant token \u2192 exchange for scoped session JWT \u2192 use JWT for API calls.\n */\n\nimport { EDITOR_CSS } from './editor-styles.js';\nimport { Inspector } from './inspector.js';\nimport { Toolbar } from './toolbar.js';\nimport { Sidebar } from './sidebar.js';\nimport { EditorAPI } from './editor-api.js';\nimport type { ResolvedKey } from './key-resolver.js';\n\n// ============================================\n// Session helpers\n// ============================================\n\nconst SESSION_KEY = '__lr_editor_session';\n\ninterface StoredSession {\n token: string;\n exp: number;\n}\n\nfunction getStoredSession(): string | null {\n try {\n const raw = sessionStorage.getItem(SESSION_KEY);\n if (!raw) return null;\n const parsed: StoredSession = JSON.parse(raw);\n // Check if expired (with 30s buffer)\n if (parsed.exp * 1000 < Date.now() + 30_000) {\n sessionStorage.removeItem(SESSION_KEY);\n return null;\n }\n return parsed.token;\n } catch {\n return null;\n }\n}\n\nfunction storeSession(token: string): void {\n try {\n // Parse exp from JWT payload (es_<header>.<payload>.<sig>)\n const raw = token.startsWith('es_') ? token.slice(3) : token;\n const parts = raw.split('.');\n if (parts.length !== 3) return;\n const payload = JSON.parse(atob(parts[1]));\n const session: StoredSession = { token, exp: payload.exp || 0 };\n sessionStorage.setItem(SESSION_KEY, JSON.stringify(session));\n } catch {\n // Non-critical \u2014 session just won't persist across navigations\n }\n}\n\nfunction clearSession(): void {\n sessionStorage.removeItem(SESSION_KEY);\n}\n\n// ============================================\n// Init\n// ============================================\n\nfunction initEditor(): void {\n // Read attributes from own script tag\n const scriptEl = document.querySelector('script[data-grant]') as HTMLScriptElement | null;\n if (!scriptEl) {\n console.warn('[LionRapid Editor] No script tag with data-grant found');\n return;\n }\n\n const grant = scriptEl.dataset.grant || '';\n const locale = scriptEl.dataset.locale || '';\n const apiBase = scriptEl.dataset.api || 'https://api.lionrapid.com';\n const projectId = scriptEl.dataset.project || '';\n\n // Poll for window.LionRapid (auto-init loads first)\n let attempts = 0;\n const maxAttempts = 100; // 10s at 100ms intervals\n\n const poll = setInterval(() => {\n attempts++;\n const lr = window.LionRapid;\n\n if (lr) {\n clearInterval(poll);\n activate(lr, grant, locale, apiBase, projectId);\n } else if (attempts >= maxAttempts) {\n clearInterval(poll);\n console.warn('[LionRapid Editor] Timed out waiting for window.LionRapid');\n }\n }, 100);\n}\n\nasync function activate(\n lr: NonNullable<typeof window.LionRapid>,\n grant: string,\n locale: string,\n apiBase: string,\n projectId: string,\n): Promise<void> {\n const config = window.__lionrapidConfig;\n const languages = config?.languages || [locale];\n const namespace = config?.namespace || 'default';\n const defaultLocale = config?.defaultLocale || 'en';\n const currentLocale = locale || lr.getCurrentLocale();\n const normalizedApiBase = apiBase.replace(/\\/$/, '');\n\n // --- Session acquisition ---\n let sessionToken = getStoredSession();\n\n if (!sessionToken && grant) {\n // Exchange grant for session JWT\n try {\n const res = await fetch(`${normalizedApiBase}/api/editor/exchange`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ grant, domain: window.location.host }),\n });\n if (!res.ok) {\n console.error('[LionRapid Editor] Grant exchange failed:', res.status);\n return;\n }\n const data = await res.json();\n sessionToken = data.session_token;\n if (sessionToken) {\n storeSession(sessionToken);\n }\n } catch (err) {\n console.error('[LionRapid Editor] Grant exchange error:', err);\n return;\n }\n }\n\n if (!sessionToken) {\n console.error('[LionRapid Editor] No valid session. Please reopen the editor from the dashboard.');\n return;\n }\n\n // Create Shadow DOM host\n const host = document.createElement('div');\n host.id = '__lionrapid-editor';\n host.setAttribute('data-no-translate', '');\n document.body.appendChild(host);\n const shadow = host.attachShadow({ mode: 'closed' });\n\n // Inject styles\n const styleEl = document.createElement('style');\n styleEl.textContent = EDITOR_CSS;\n shadow.appendChild(styleEl);\n\n // Hide the proxy/auto-init language switcher while editor is active\n const switcherEl = document.querySelector('[data-lionrapid-switcher]') as HTMLElement | null;\n if (switcherEl) switcherEl.style.display = 'none';\n\n // Create API client with session token\n const api = new EditorAPI(normalizedApiBase, sessionToken, projectId);\n api.startAutoFlush();\n\n // Create sidebar (needs api + locale)\n const handleBlockSelect = (resolved: ResolvedKey) => {\n sidebar.open(resolved);\n inspector.clearHighlight();\n };\n\n const sidebar = new Sidebar(shadow, api, currentLocale, namespace, defaultLocale, handleBlockSelect);\n\n // Create inspector (hover/click \u2192 sidebar)\n const inspector = new Inspector(shadow, handleBlockSelect);\n\n // Create toolbar\n const toolbar = new Toolbar(\n shadow,\n languages,\n currentLocale,\n // Language change\n async (newLocale) => {\n sidebar.updateLocale(newLocale);\n sidebar.close();\n inspector.clearHighlight();\n await lr.changeLanguage(newLocale);\n await sidebar.hydrateStatus();\n },\n // Exit\n async () => {\n await api.stopAndFlush();\n inspector.destroy();\n toolbar.destroy();\n sidebar.destroy();\n host.remove();\n clearSession();\n },\n );\n\n // Wire progress counter to sidebar status\n sidebar.setProgressCallback((translated, total) => {\n toolbar.updateProgress(translated, total);\n });\n\n // Hydrate status from server and update progress\n sidebar.hydrateStatus().then(() => {\n toolbar.updateProgress(sidebar.getTranslatedCount(), sidebar.getTotalCount());\n });\n\n // Clean editor param from URL\n const url = new URL(window.location.href);\n if (url.searchParams.has('__lr_editor')) {\n url.searchParams.delete('__lr_editor');\n history.replaceState(null, '', url.toString());\n }\n}\n\n// Self-execute\ninitEditor();\n"],
|
|
5
|
-
"mappings": ";;;;;;;AAKO,MAAM,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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
|
|
6
|
-
"names": ["BLOCK_SELECTOR", "BLOCK_SELECTOR", "SKIP_TAGS", "htmlSerializer"]
|
|
4
|
+
"sourcesContent": ["/**\n * Editor CSS Styles\n * All styles are injected into Shadow DOM \u2014 no leakage to host page.\n */\n\nexport const EDITOR_CSS = `\n/* Reset inside shadow DOM */\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #1a1a2e;\n line-height: 1.5;\n box-sizing: border-box;\n}\n\n*, *::before, *::after {\n box-sizing: border-box;\n}\n\n/* \u2500\u2500 FAB (replaces fixed toolbar) \u2500\u2500 */\n.lr-fab {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 0;\n user-select: none;\n}\n\n.lr-fab-btn {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #2d7f7f;\n color: #fff;\n border: none;\n font-weight: 700;\n font-size: 16px;\n cursor: grab;\n box-shadow: 0 4px 12px rgba(0,0,0,0.25);\n transition: box-shadow 0.15s;\n flex-shrink: 0;\n z-index: 1;\n}\n\n.lr-fab-btn:hover {\n box-shadow: 0 6px 20px rgba(0,0,0,0.3);\n}\n\n.lr-fab-btn:active {\n cursor: grabbing;\n}\n\n.lr-fab-panel {\n display: none;\n align-items: center;\n gap: 8px;\n background: #1a1a2e;\n color: #fff;\n padding: 8px 12px;\n border-radius: 8px;\n margin-right: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.25);\n white-space: nowrap;\n}\n\n.lr-fab.expanded .lr-fab-panel {\n display: flex;\n}\n\n.lr-lang-dropdown {\n position: relative;\n}\n\n.lr-lang-btn {\n background: rgba(255,255,255,0.1);\n color: #fff;\n border: 1px solid rgba(255,255,255,0.2);\n border-radius: 4px;\n padding: 4px 10px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n outline: none;\n}\n\n.lr-lang-btn:hover {\n background: rgba(255,255,255,0.2);\n}\n\n.lr-lang-menu {\n display: none;\n position: absolute;\n bottom: calc(100% + 6px);\n left: 0;\n background: #1a1a2e;\n border: 1px solid rgba(255,255,255,0.15);\n border-radius: 6px;\n padding: 4px;\n min-width: 60px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.4);\n}\n\n.lr-lang-menu.open {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.lr-lang-item {\n background: none;\n color: #ccc;\n border: none;\n padding: 6px 10px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: 4px;\n text-align: left;\n}\n\n.lr-lang-item:hover {\n background: rgba(255,255,255,0.1);\n color: #fff;\n}\n\n.lr-lang-item.active {\n background: #2d7f7f;\n color: #fff;\n}\n\n.lr-fab-progress {\n font-size: 13px;\n color: rgba(255,255,255,0.7);\n}\n\n.lr-fab-exit {\n background: none;\n border: 1px solid rgba(255,255,255,0.3);\n color: #fff;\n padding: 4px 10px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n}\n\n.lr-fab-exit:hover {\n background: rgba(255,255,255,0.1);\n}\n\n/* \u2500\u2500 Overlay \u2500\u2500 */\n.lr-overlay {\n position: fixed;\n pointer-events: none;\n border: 2px solid #2d7f7f;\n border-radius: 3px;\n background: rgba(45, 127, 127, 0.06);\n transition: all 0.1s ease;\n z-index: 2147483646;\n display: none;\n}\n\n.lr-overlay.active {\n display: block;\n}\n\n/* \u2500\u2500 Sidebar \u2500\u2500 */\n.lr-sidebar {\n position: fixed;\n top: 0;\n right: 0;\n width: 360px;\n min-width: 280px;\n max-width: 600px;\n bottom: 0;\n background: #fff;\n border-left: 1px solid #e0e0e0;\n z-index: 2147483647;\n overflow-y: auto;\n transform: translateX(100%);\n transition: transform 0.2s ease;\n}\n\n.lr-sidebar.open {\n transform: translateX(0);\n}\n\n/* Resize handle on left edge */\n.lr-sidebar-resize {\n position: absolute;\n top: 0;\n left: -4px;\n width: 8px;\n bottom: 0;\n cursor: col-resize;\n z-index: 1;\n}\n\n.lr-sidebar-resize:hover,\n.lr-sidebar-resize.active {\n background: rgba(45, 127, 127, 0.3);\n}\n\n.lr-sidebar-header {\n padding: 16px;\n border-bottom: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.lr-sidebar-title {\n font-weight: 600;\n font-size: 15px;\n}\n\n.lr-sidebar-close {\n background: none;\n border: none;\n font-size: 20px;\n cursor: pointer;\n color: #666;\n padding: 4px 8px;\n line-height: 1;\n}\n\n.lr-sidebar-close:hover {\n color: #1a1a2e;\n}\n\n.lr-sidebar-body {\n padding: 16px;\n}\n\n.lr-field {\n margin-bottom: 16px;\n}\n\n.lr-field-label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n}\n\n.lr-field-key {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n color: #2d7f7f;\n background: #f0f7f7;\n padding: 4px 8px;\n border-radius: 4px;\n word-break: break-all;\n}\n\n.lr-field-original {\n font-size: 13px;\n color: #333;\n background: #f8f8f8;\n padding: 10px 12px;\n border-radius: 6px;\n border: 1px solid #eee;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.lr-field-tag {\n display: inline;\n background: #d9eded;\n color: #2d7f7f;\n padding: 0 3px;\n border-radius: 2px;\n font-family: monospace;\n font-size: 12px;\n}\n\n.lr-textarea {\n width: 100%;\n min-height: 100px;\n padding: 10px 12px;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n resize: vertical;\n outline: none;\n transition: border-color 0.15s;\n}\n\n.lr-textarea:focus {\n border-color: #2d7f7f;\n box-shadow: 0 0 0 3px rgba(45, 127, 127, 0.1);\n}\n\n.lr-preview {\n padding: 10px 12px;\n background: #f8f8f8;\n border: 1px solid #eee;\n border-radius: 6px;\n font-size: 13px;\n min-height: 40px;\n}\n\n.lr-status {\n padding: 10px 16px;\n font-size: 12px;\n color: #666;\n text-align: center;\n border-top: 1px solid #eee;\n background: #fafafa;\n}\n\n.lr-status.saved {\n color: #22c55e;\n}\n\n.lr-status.error {\n color: #ef4444;\n}\n\n.lr-status.unsaved {\n color: #f59e0b;\n}\n\n/* \u2500\u2500 Page blocks list \u2500\u2500 */\n.lr-blocks-section {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n}\n\n.lr-blocks-title {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n\n.lr-block-item {\n padding: 8px 10px;\n border: 1px solid #eee;\n border-radius: 4px;\n margin-bottom: 4px;\n cursor: pointer;\n font-size: 13px;\n color: #333;\n overflow: hidden;\n transition: background 0.1s;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n\n.lr-block-item:hover {\n background: #f0f7f7;\n border-color: #2d7f7f;\n}\n\n.lr-block-item.active {\n background: #e5f2f2;\n border-color: #2d7f7f;\n}\n\n/* \u2500\u2500 Status dots \u2500\u2500 */\n.lr-status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n margin-top: 5px;\n background: #d1d5db;\n}\n\n.lr-status-dot.missing { background: #d1d5db; }\n.lr-status-dot.mt { background: #60a5fa; }\n.lr-status-dot.edited { background: #f97316; }\n.lr-status-dot.confirmed { background: #22c55e; }\n.lr-status-dot.ready { background: #22c55e; }\n.lr-status-dot.locked { background: #a855f7; }\n.lr-status-dot.unsaved { background: #f59e0b; }\n\n/* \u2500\u2500 Locked textarea \u2500\u2500 */\n.lr-textarea-locked {\n background: #f3f4f6;\n color: #6b7280;\n cursor: not-allowed;\n border-color: #e5e7eb;\n}\n\n/* \u2500\u2500 Block text layout \u2500\u2500 */\n.lr-block-text {\n overflow: hidden;\n min-width: 0;\n}\n\n.lr-block-source {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.lr-block-preview {\n font-size: 11px;\n color: #888;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-top: 2px;\n}\n`;\n", "/**\n * Default style mapper for bidirectional HTML element \u2194 style property mapping\n * @module content/style-mapper/DefaultStyleMapper\n */\n\nimport type { IStyleMapper, ElementMapping } from './IStyleMapper.js';\n\n/**\n * Default implementation of style mapping\n *\n * Provides bidirectional conversion between HTML elements and style properties:\n * - mapElementToStyles: `<b>` \u2192 `[\"bold\"]`\n * - mapStylesToElement: `[\"bold\"]` \u2192 `<b>`\n *\n * @example\n * ```typescript\n * const mapper = new DefaultStyleMapper();\n *\n * // Parsing: HTML \u2192 styles\n * mapper.mapElementToStyles('a', { href: '/terms' });\n * // \u2192 [\"hyperlink:/terms\"]\n *\n * // Serializing: styles \u2192 HTML\n * mapper.mapStylesToElement(['bold', 'hyperlink:/terms']);\n * // \u2192 { element: 'a', attrs: { href: '/terms' } }\n * ```\n */\nexport class DefaultStyleMapper implements IStyleMapper {\n /**\n * Element \u2192 Style mapping\n * Maps HTML element names to their style property\n */\n private readonly elementToStyles: Record<string, string> = {\n b: 'bold',\n strong: 'bold',\n i: 'italic',\n em: 'italic',\n u: 'underline',\n s: 'strikethrough',\n del: 'strikethrough',\n strike: 'strikethrough',\n code: 'code',\n mark: 'highlight',\n sub: 'subscript',\n sup: 'superscript',\n };\n\n /**\n * Style \u2192 Element mapping (reverse)\n * Uses simple, familiar elements for developer convenience\n * Also accepts element names directly (strong, em, etc.)\n */\n private readonly styleToElement: Record<string, string> = {\n // Semantic style names \u2192 simple elements\n bold: 'b',\n italic: 'i',\n underline: 'u',\n strikethrough: 's',\n code: 'code',\n highlight: 'mark',\n subscript: 'sub',\n superscript: 'sup',\n // Element names (for servers that store styles as element names)\n strong: 'b',\n b: 'b',\n em: 'i',\n i: 'i',\n u: 'u',\n s: 's',\n del: 's',\n strike: 's',\n mark: 'mark',\n sub: 'sub',\n sup: 'sup',\n };\n\n /**\n * Convert HTML element to style properties\n *\n * @param element - Tag name (e.g., \"b\", \"a\", \"strong\")\n * @param attrs - Element attributes (e.g., { href: \"/url\" })\n * @returns Array of style strings\n */\n mapElementToStyles(element: string, attrs: Record<string, string>): string[] {\n const styles: string[] = [];\n const tag = element.toLowerCase();\n\n // Basic element mapping\n const mappedStyle = this.elementToStyles[tag];\n if (mappedStyle) {\n styles.push(mappedStyle);\n }\n\n // Special: <a href=\"...\"> \u2192 hyperlink:url\n if (tag === 'a' && attrs.href) {\n styles.push(`hyperlink:${attrs.href}`);\n }\n\n return styles;\n }\n\n /**\n * Convert style properties to HTML element\n *\n * Priority order:\n * 1. Hyperlink (becomes wrapper element with href)\n * 2. First recognized style property\n * 3. Fallback to span\n *\n * @param styles - Array of style strings\n * @returns Element info for serialization\n */\n mapStylesToElement(styles: string[]): ElementMapping {\n // Check for hyperlink first (takes priority as wrapper element)\n for (const style of styles) {\n if (style.startsWith('hyperlink:')) {\n return {\n element: 'a',\n attrs: { href: style.slice('hyperlink:'.length) },\n };\n }\n }\n\n // Map first recognized style to element\n for (const style of styles) {\n const element = this.styleToElement[style];\n if (element) {\n return {\n element,\n attrs: {},\n };\n }\n }\n\n // Fallback: span with no special attributes\n return { element: 'span', attrs: {} };\n }\n}\n", "/**\n * DOM-based Markup Parser\n *\n * Converts a block element's childNodes into ContentUnit.\n * Uses the browser's DOM rather than regex (unlike edge/PHP which parse raw HTML strings).\n * Mirrors WordPress TS MarkupParser.\n */\n\nimport type { ContentUnit } from '../content/types.js';\nimport { DefaultStyleMapper } from '../content/style-mapper/DefaultStyleMapper.js';\n\nconst styleMapper = new DefaultStyleMapper();\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\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 const styleList = styleMapper.mapElementToStyles(tag, attrs);\n\n if (styleList.length > 0) {\n // Known styled element \u2014 assign indexed tag\n tagIndex++;\n const idx = tagIndex;\n styles[String(idx)] = styleList;\n\n let inner = '';\n for (let i = 0; i < node.childNodes.length; i++) {\n inner += walk(node.childNodes[i]);\n }\n\n return `<${idx}>${inner}</${idx}>`;\n }\n\n // Unknown element \u2014 strip tag, recurse children\n let result = '';\n for (let i = 0; i < node.childNodes.length; i++) {\n result += walk(node.childNodes[i]);\n }\n return result;\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\nfunction str2binl(str: string): number[] {\n const bin: number[] = [];\n for (let i = 0; i < str.length * 8; i += 8) {\n bin[i >> 5] |= (str.charCodeAt(i / 8) & 0xff) << i % 32;\n }\n return bin;\n}\n\n/**\n * Generate MD5 hash of a string\n * Matches PHP's md5() function output\n */\nexport function md5(str: string): string {\n return binl2hex(binlMD5(str2binl(str), str.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 * Key Resolver\n * Resolves a clicked element to its translation key and ContentUnit.\n */\n\nimport type { ContentUnit } from '../../content/types.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\nexport interface ResolvedKey {\n key: string;\n /** Source ContentUnit (original text with indexed tags) */\n unit: ContentUnit;\n /** Current translation as ContentUnit (if element is already translated) */\n translatedUnit: ContentUnit | null;\n element: Element;\n}\n\n/**\n * Resolve an element to its translation key.\n * Priority: data-lr-block attr \u2192 parseBlockElement \u2192 fallback textContent\n */\nexport function resolveKey(target: Element): ResolvedKey | null {\n // Priority 1: Already translated element with data-lr-block\n const blockEl = target.closest('[data-lr-block]');\n if (blockEl) {\n const key = blockEl.getAttribute('data-lr-block')!;\n const original = blockEl.getAttribute('data-lr-original');\n let unit: ContentUnit;\n let translatedUnit: ContentUnit | null = null;\n\n if (original) {\n // Parse original HTML \u2192 source ContentUnit\n const temp = document.createElement(blockEl.tagName);\n temp.innerHTML = original;\n unit = parseBlockElement(temp);\n // Parse current DOM \u2192 translated ContentUnit\n translatedUnit = parseBlockElement(blockEl);\n } else {\n unit = parseBlockElement(blockEl);\n }\n return { key, unit, translatedUnit, element: blockEl };\n }\n\n // Priority 2: Find nearest block element and parse it\n const nearest = target.closest(BLOCK_SELECTOR);\n if (nearest) {\n const unit = parseBlockElement(nearest);\n const key = generateAutoKey(unit.text);\n return { key, unit, translatedUnit: null, element: nearest };\n }\n\n // Priority 3: Fallback to element text\n const text = target.textContent?.trim();\n if (text && text.length >= 2) {\n const key = generateAutoKey(text);\n const unit: ContentUnit = { text, styles: {} };\n return { key, unit, translatedUnit: null, element: target };\n }\n\n return null;\n}\n", "/**\n * Inspector \u2014 Hover/click handling\n * Shows overlay on hover, resolves key on click, opens sidebar.\n */\n\nimport { resolveKey, ResolvedKey } from './key-resolver.js';\n\nconst SKIP_TAGS = new Set(['SCRIPT', 'STYLE', 'CODE', 'PRE', 'TEXTAREA', 'NOSCRIPT', 'SVG']);\n\nconst BLOCK_SELECTOR =\n 'p,h1,h2,h3,h4,h5,h6,li,td,th,label,button,figcaption,dt,dd,summary,caption';\n\nexport type OnSelectCallback = (resolved: ResolvedKey) => void;\n\nexport class Inspector {\n private overlay: HTMLDivElement;\n private currentTarget: Element | null = null;\n private onSelect: OnSelectCallback;\n private rafId: number | null = null;\n private active = true;\n\n constructor(shadowRoot: ShadowRoot, onSelect: OnSelectCallback) {\n this.onSelect = onSelect;\n\n // Create overlay inside shadow DOM\n this.overlay = document.createElement('div');\n this.overlay.className = 'lr-overlay';\n shadowRoot.appendChild(this.overlay);\n\n // Bind handlers\n this.handleMouseOver = this.handleMouseOver.bind(this);\n this.handleClick = this.handleClick.bind(this);\n this.handleScroll = this.handleScroll.bind(this);\n\n // Listen on document (capture phase to get events before page handlers)\n document.addEventListener('mouseover', this.handleMouseOver, true);\n document.addEventListener('click', this.handleClick, true);\n window.addEventListener('scroll', this.handleScroll, true);\n window.addEventListener('resize', this.handleScroll);\n }\n\n destroy(): void {\n this.active = false;\n document.removeEventListener('mouseover', this.handleMouseOver, true);\n document.removeEventListener('click', this.handleClick, true);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.overlay.remove();\n }\n\n clearHighlight(): void {\n this.currentTarget = null;\n this.overlay.classList.remove('active');\n }\n\n private handleMouseOver(e: Event): void {\n if (!this.active) return;\n const target = e.target as Element;\n if (!target || !target.closest) return;\n\n // Skip editor UI elements (inside shadow DOM won't trigger this, but be safe)\n if (target.closest('#__lionrapid-editor')) return;\n\n // Skip non-translatable elements\n if (this.shouldSkip(target)) {\n this.clearHighlight();\n return;\n }\n\n // Find nearest block element\n const block = target.closest(BLOCK_SELECTOR) || target.closest('[data-lr-block]');\n if (!block) {\n this.clearHighlight();\n return;\n }\n\n if (block === this.currentTarget) return;\n\n this.currentTarget = block;\n this.positionOverlay(block);\n }\n\n private handleClick(e: Event): void {\n if (!this.active) return;\n const target = e.target as Element;\n if (!target || !target.closest) return;\n\n // Skip editor UI\n if (target.closest('#__lionrapid-editor')) return;\n\n // Find the block to resolve\n const block = target.closest(BLOCK_SELECTOR) || target.closest('[data-lr-block]');\n if (!block) return;\n\n if (this.shouldSkip(block)) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const resolved = resolveKey(block);\n if (resolved) {\n this.onSelect(resolved);\n }\n }\n\n private handleScroll(): void {\n if (!this.currentTarget) return;\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(() => {\n if (this.currentTarget) {\n this.positionOverlay(this.currentTarget);\n }\n });\n }\n\n private positionOverlay(element: Element): void {\n const rect = element.getBoundingClientRect();\n this.overlay.style.top = `${rect.top}px`;\n this.overlay.style.left = `${rect.left}px`;\n this.overlay.style.width = `${rect.width}px`;\n this.overlay.style.height = `${rect.height}px`;\n this.overlay.classList.add('active');\n }\n\n private shouldSkip(element: Element): boolean {\n // Skip SKIP_TAGS\n let current: Element | null = element;\n while (current) {\n if (SKIP_TAGS.has(current.tagName)) return true;\n if (current.hasAttribute('data-no-translate')) return true;\n if (current.getAttribute('translate') === 'no') return true;\n current = current.parentElement;\n }\n return false;\n }\n}\n", "/**\n * Toolbar \u2014 Draggable FAB that expands to show controls\n * Collapsed: small circle with \"LR\" logo\n * Expanded: horizontal bar with language selector, progress, exit\n */\n\nexport type OnLanguageChange = (locale: string) => void;\nexport type OnExit = () => void;\n\nexport class Toolbar {\n private el: HTMLDivElement;\n private langBtnEl: HTMLButtonElement;\n private langMenuEl: HTMLDivElement;\n private progressEl: HTMLSpanElement;\n private expanded = false;\n private currentLocale: string;\n private onLanguageChange: OnLanguageChange;\n private onExit: OnExit;\n\n // Drag state\n private dragging = false;\n private dragOffsetX = 0;\n private dragOffsetY = 0;\n\n constructor(\n shadowRoot: ShadowRoot,\n languages: string[],\n currentLocale: string,\n onLanguageChange: OnLanguageChange,\n onExit: OnExit,\n ) {\n this.onLanguageChange = onLanguageChange;\n this.onExit = onExit;\n this.currentLocale = currentLocale;\n\n this.el = document.createElement('div');\n this.el.className = 'lr-fab';\n\n // FAB button (always visible)\n const fabBtn = document.createElement('button');\n fabBtn.className = 'lr-fab-btn';\n fabBtn.textContent = 'LR';\n fabBtn.addEventListener('click', (e) => {\n // Don't toggle if we just finished dragging\n if (this.dragging) return;\n e.stopPropagation();\n this.toggle();\n });\n this.el.appendChild(fabBtn);\n\n // Expanded panel\n const panel = document.createElement('div');\n panel.className = 'lr-fab-panel';\n\n // Custom language dropdown\n const langWrap = document.createElement('div');\n langWrap.className = 'lr-lang-dropdown';\n\n this.langBtnEl = document.createElement('button');\n this.langBtnEl.className = 'lr-lang-btn';\n this.langBtnEl.textContent = currentLocale.toUpperCase();\n this.langBtnEl.addEventListener('click', (e) => {\n e.stopPropagation();\n this.langMenuEl.classList.toggle('open');\n });\n langWrap.appendChild(this.langBtnEl);\n\n this.langMenuEl = document.createElement('div');\n this.langMenuEl.className = 'lr-lang-menu';\n for (const lang of languages) {\n const item = document.createElement('button');\n item.className = 'lr-lang-item';\n if (lang === currentLocale) item.classList.add('active');\n item.textContent = lang.toUpperCase();\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n this.currentLocale = lang;\n this.langBtnEl.textContent = lang.toUpperCase();\n this.langMenuEl.classList.remove('open');\n // Update active state\n this.langMenuEl.querySelectorAll('.lr-lang-item').forEach((el) => el.classList.remove('active'));\n item.classList.add('active');\n this.onLanguageChange(lang);\n });\n this.langMenuEl.appendChild(item);\n }\n langWrap.appendChild(this.langMenuEl);\n panel.appendChild(langWrap);\n\n // Progress\n this.progressEl = document.createElement('span');\n this.progressEl.className = 'lr-fab-progress';\n panel.appendChild(this.progressEl);\n\n // Exit button\n const exitBtn = document.createElement('button');\n exitBtn.className = 'lr-fab-exit';\n exitBtn.textContent = 'Exit';\n exitBtn.addEventListener('click', () => this.onExit());\n panel.appendChild(exitBtn);\n\n this.el.appendChild(panel);\n shadowRoot.appendChild(this.el);\n\n // Dragging\n this.handleMouseDown = this.handleMouseDown.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n fabBtn.addEventListener('mousedown', this.handleMouseDown);\n }\n\n toggle(): void {\n this.expanded = !this.expanded;\n this.el.classList.toggle('expanded', this.expanded);\n }\n\n updateProgress(translated: number, total: number): void {\n this.progressEl.textContent = `${translated}/${total}`;\n }\n\n getCurrentLocale(): string {\n return this.currentLocale;\n }\n\n destroy(): void {\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.el.remove();\n }\n\n private handleMouseDown(e: MouseEvent): void {\n this.dragging = false;\n this.dragOffsetX = e.clientX - this.el.getBoundingClientRect().left;\n this.dragOffsetY = e.clientY - this.el.getBoundingClientRect().top;\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n this.dragging = true;\n const x = Math.max(0, Math.min(e.clientX - this.dragOffsetX, window.innerWidth - this.el.offsetWidth));\n const y = Math.max(0, Math.min(e.clientY - this.dragOffsetY, window.innerHeight - this.el.offsetHeight));\n this.el.style.left = `${x}px`;\n this.el.style.top = `${y}px`;\n this.el.style.right = 'auto';\n this.el.style.bottom = 'auto';\n }\n\n private handleMouseUp(): void {\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n // Reset dragging flag after a tick so the click handler can check it\n if (this.dragging) {\n setTimeout(() => { this.dragging = false; }, 0);\n }\n }\n}\n", "/**\n * HTML serializer for converting ContentUnit to HTML strings\n * @module content/serializer/HTMLSerializer\n */\n\nimport type { ISerializer } from './ISerializer.js';\nimport type { ContentUnit } from '../types.js';\nimport type { IStyleMapper } from '../style-mapper/IStyleMapper.js';\nimport { DefaultStyleMapper } from '../style-mapper/DefaultStyleMapper.js';\n\n/**\n * Configuration options for HTMLSerializer\n */\nexport interface HTMLSerializerOptions {\n /**\n * Custom style mapper for styles \u2192 element conversion\n * Defaults to DefaultStyleMapper\n */\n styleMapper?: IStyleMapper;\n}\n\n/**\n * Serializer that converts ContentUnit format back to HTML strings\n *\n * Transforms indexed tags and style mappings into HTML:\n * - `<1>bold</1>` with styles `{\"1\": [\"bold\"]}` \u2192 `<b>bold</b>`\n * - `<1>link</1>` with styles `{\"1\": [\"hyperlink:/url\"]}` \u2192 `<a href=\"/url\">link</a>`\n *\n * @example\n * ```typescript\n * const serializer = new HTMLSerializer();\n *\n * const html = serializer.serialize({\n * text: 'Read our <1>Terms</1>.',\n * styles: { '1': ['bold'] }\n * });\n * // \u2192 \"Read our <b>Terms</b>.\"\n *\n * const link = serializer.serialize({\n * text: 'Click <1>here</1>.',\n * styles: { '1': ['hyperlink:/url'] }\n * });\n * // \u2192 \"Click <a href=\\\"/url\\\">here</a>.\"\n * ```\n */\nexport class HTMLSerializer implements ISerializer<string> {\n private readonly styleMapper: IStyleMapper;\n\n constructor(options: HTMLSerializerOptions = {}) {\n this.styleMapper = options.styleMapper ?? new DefaultStyleMapper();\n }\n\n /**\n * Serialize ContentUnit to HTML string\n *\n * @param unit - ContentUnit with indexed tags and styles\n * @returns HTML string with semantic elements\n */\n serialize(unit: ContentUnit): string {\n const { text, styles } = unit;\n\n // Pattern to match indexed tags: <1>, </1>, <1/>\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 // Append text before the tag\n result += text.slice(lastIndex, match.index);\n\n const [fullMatch, closingSlash, indexStr, selfClosingSlash] = match;\n const tagIndex = indexStr;\n const styleList = styles[tagIndex] || [];\n\n if (closingSlash) {\n // Closing tag: </1>\n const mapping = this.styleMapper.mapStylesToElement(styleList);\n result += `</${mapping.element}>`;\n } else if (selfClosingSlash) {\n // Self-closing tag: <1/>\n const mapping = this.styleMapper.mapStylesToElement(styleList);\n const attrs = this.formatAttributes(mapping.attrs);\n result += `<${mapping.element}${attrs} />`;\n } else {\n // Opening tag: <1>\n const mapping = this.styleMapper.mapStylesToElement(styleList);\n const attrs = this.formatAttributes(mapping.attrs);\n result += `<${mapping.element}${attrs}>`;\n }\n\n lastIndex = match.index + fullMatch.length;\n }\n\n // Append remaining text\n result += text.slice(lastIndex);\n\n return result;\n }\n\n /**\n * Format attributes object into HTML attribute string\n */\n private formatAttributes(attrs: Record<string, string>): string {\n const entries = Object.entries(attrs);\n if (entries.length === 0) return '';\n\n return (\n ' ' +\n entries\n .map(([key, value]) => `${key}=\"${this.escapeAttributeValue(value)}\"`)\n .join(' ')\n );\n }\n\n /**\n * Escape special characters in attribute values\n */\n private escapeAttributeValue(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n}\n", "/**\n * Live Preview\n * Optimistically updates DOM elements as the user types translations.\n */\n\nimport type { ContentUnit } from '../../content/types.js';\nimport { HTMLSerializer } from '../../content/serializer/HTMLSerializer.js';\n\nconst htmlSerializer = new HTMLSerializer();\n\n/**\n * Update a single element's content with a new translation.\n * Writes to core cache and updates the DOM without full page retranslate.\n */\nexport function applyLivePreview(\n element: Element,\n text: string,\n styles: Record<string, string[]>,\n key: string,\n locale: string,\n namespace: string,\n): void {\n // Save original HTML before first edit\n if (!element.hasAttribute('data-lr-original')) {\n element.setAttribute('data-lr-original', element.innerHTML);\n }\n\n // Update core cache if available\n const lr = (window as { LionRapid?: { autoTranslator?: { core?: { cache?: { set?: (k: string, v: string, s?: Record<string, string[]>) => void } } } } }).LionRapid;\n const cache = (lr as Record<string, unknown>)?.autoTranslator\n ? getCache()\n : null;\n if (cache) {\n const fullKey = `${locale}:${namespace}:${key}`;\n cache.set(fullKey, text, styles);\n }\n\n // Update DOM\n if (styles && Object.keys(styles).length > 0) {\n const unit: ContentUnit = { text, styles };\n element.innerHTML = htmlSerializer.serialize(unit);\n } else {\n element.textContent = text;\n }\n\n // Mark as translated\n element.setAttribute('data-lr-block', key);\n element.setAttribute('data-lionrapid-client', '1');\n}\n\nfunction getCache(): { set: (key: string, value: string, styles?: Record<string, string[]>) => void } | null {\n try {\n const lr = (window as unknown as { LionRapid?: Record<string, unknown> }).LionRapid;\n if (!lr) return null;\n const at = lr.autoTranslator as Record<string, unknown> | undefined;\n if (!at) return null;\n const core = at.core as Record<string, unknown> | undefined;\n if (!core) return null;\n const cache = core.cache as { set?: (key: string, value: string, styles?: Record<string, string[]>) => void } | undefined;\n if (!cache || typeof cache.set !== 'function') return null;\n return cache as { set: (key: string, value: string, styles?: Record<string, string[]>) => void };\n } catch {\n return null;\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 * 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// 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];\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 return results;\n }\n\n private isInsideSkipTag(element: Element): boolean {\n let current: Element | null = element.parentElement;\n while (current) {\n if (SKIP_TAGS.has(current.tagName)) {\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 * Sidebar \u2014 Translation editing panel\n * Shows original text, translation textarea, live preview, and page blocks list.\n */\n\nimport type { ContentUnit } from '../../content/types.js';\nimport type { ResolvedKey } from './key-resolver.js';\nimport { HTMLSerializer } from '../../content/serializer/HTMLSerializer.js';\nimport { applyLivePreview } from './live-preview.js';\nimport type { EditorAPI, TargetStatus } from './editor-api.js';\nimport { BlockExtractor } from '../block-extractor.js';\n\nconst htmlSerializer = new HTMLSerializer();\n\nexport class Sidebar {\n private el: HTMLDivElement;\n private bodyEl: HTMLDivElement;\n private statusEl: HTMLDivElement;\n private api: EditorAPI;\n private locale: string;\n private namespace: string;\n private defaultLocale: string;\n private current: ResolvedKey | null = null;\n private blockExtractor: BlockExtractor;\n private onBlockClick: (resolved: ResolvedKey) => void;\n private statusMap: Map<string, TargetStatus | null> = new Map();\n private unsavedKeys: Set<string> = new Set();\n private onProgressUpdate: ((translated: number, total: number) => void) | null = null;\n private lastFetchTime = 0;\n private lastFlushTime = 0;\n\n constructor(\n shadowRoot: ShadowRoot,\n api: EditorAPI,\n locale: string,\n namespace: string,\n defaultLocale: string,\n onBlockClick: (resolved: ResolvedKey) => void,\n ) {\n this.api = api;\n this.locale = locale;\n this.namespace = namespace;\n this.defaultLocale = defaultLocale;\n this.onBlockClick = onBlockClick;\n this.blockExtractor = new BlockExtractor();\n\n this.el = document.createElement('div');\n this.el.className = 'lr-sidebar';\n\n // Resize handle\n const resizeHandle = document.createElement('div');\n resizeHandle.className = 'lr-sidebar-resize';\n this.initResize(resizeHandle);\n this.el.appendChild(resizeHandle);\n\n // Header\n const header = document.createElement('div');\n header.className = 'lr-sidebar-header';\n const title = document.createElement('span');\n title.className = 'lr-sidebar-title';\n title.textContent = 'Edit Translation';\n header.appendChild(title);\n const closeBtn = document.createElement('button');\n closeBtn.className = 'lr-sidebar-close';\n closeBtn.innerHTML = '×';\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n // Body\n this.bodyEl = document.createElement('div');\n this.bodyEl.className = 'lr-sidebar-body';\n this.el.appendChild(this.bodyEl);\n\n // Status bar (rendered inline in renderContent, above preview)\n this.statusEl = document.createElement('div');\n this.statusEl.className = 'lr-status';\n\n // Wire up API status\n this.api.setStatusCallback((status, message) => {\n this.statusEl.textContent = message || status;\n this.statusEl.className = `lr-status ${status}`;\n });\n\n // After flush, re-fetch status for saved keys and refresh blocks list\n this.api.setFlushedCallback(async (keys) => {\n this.lastFlushTime = Date.now();\n const freshStatuses = await this.api.fetchStatus(keys, this.locale, this.namespace);\n for (const [key, status] of Object.entries(freshStatuses)) {\n this.statusMap.set(key, status);\n this.unsavedKeys.delete(key);\n }\n this.refreshBlocksList();\n this.emitProgress();\n });\n\n shadowRoot.appendChild(this.el);\n }\n\n open(resolved: ResolvedKey): void {\n this.current = resolved;\n this.el.classList.add('open');\n this.renderContent(resolved);\n }\n\n close(): void {\n this.current = null;\n this.el.classList.remove('open');\n }\n\n isOpen(): boolean {\n return this.el.classList.contains('open');\n }\n\n updateLocale(locale: string): void {\n this.locale = locale;\n // Clear status on locale change \u2014 will be re-fetched\n this.statusMap.clear();\n this.unsavedKeys.clear();\n }\n\n setProgressCallback(cb: (translated: number, total: number) => void): void {\n this.onProgressUpdate = cb;\n }\n\n /**\n * Hydrate the status map with server data for all page blocks.\n * Called once on editor init.\n */\n async hydrateStatus(): Promise<void> {\n const blocks = this.blockExtractor.extract(document.body, true);\n const keys = blocks.map((b) => b.key);\n if (keys.length === 0) return;\n\n const statuses = await this.api.fetchStatus(keys, this.locale, this.namespace);\n for (const [key, status] of Object.entries(statuses)) {\n this.statusMap.set(key, status);\n }\n\n // Apply draft translations to page blocks that the edge proxy didn't render\n // (edge proxy only shows is_ready_for_delivery; editor shows everything)\n for (const block of blocks) {\n const status = this.statusMap.get(block.key);\n if (status && status.text && !status.isReady) {\n applyLivePreview(block.element, status.text, block.unit.styles, block.key, this.locale, this.namespace);\n }\n }\n\n this.emitProgress();\n }\n\n getTranslatedCount(): number {\n let count = 0;\n for (const status of this.statusMap.values()) {\n if (status && status.rowState !== 'empty') count++;\n }\n return count;\n }\n\n getTotalCount(): number {\n return this.blockExtractor.extract(document.body, true).length;\n }\n\n private emitProgress(): void {\n if (this.onProgressUpdate) {\n this.onProgressUpdate(this.getTranslatedCount(), this.getTotalCount());\n }\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n private async renderContent(resolved: ResolvedKey): Promise<void> {\n const { key, unit, element } = resolved;\n this.bodyEl.innerHTML = '';\n\n // Smart fetch: if no flush since last full fetch, only fetch the clicked key.\n // Otherwise re-fetch all blocks to pick up server-side changes from our saves.\n const isStale = this.lastFlushTime > this.lastFetchTime || this.lastFetchTime === 0;\n\n if (isStale) {\n const blocks = this.blockExtractor.extract(document.body, true);\n const allKeys = blocks.map((b) => b.key);\n if (!allKeys.includes(key)) allKeys.push(key);\n const freshStatuses = await this.api.fetchStatus(allKeys, this.locale, this.namespace);\n for (const [k, s] of Object.entries(freshStatuses)) {\n this.statusMap.set(k, s);\n }\n this.lastFetchTime = Date.now();\n } else {\n // Fresh \u2014 only fetch the clicked key\n const freshStatus = await this.api.fetchStatus([key], this.locale, this.namespace);\n if (freshStatus[key] !== undefined) {\n this.statusMap.set(key, freshStatus[key]);\n }\n }\n const status = this.statusMap.get(key) ?? null;\n\n // Key field\n this.addField('Key', () => {\n const keyEl = document.createElement('div');\n keyEl.className = 'lr-field-key';\n keyEl.textContent = key;\n return keyEl;\n });\n\n // Original text\n this.addField('Original', () => {\n const origEl = document.createElement('div');\n origEl.className = 'lr-field-original';\n origEl.innerHTML = this.renderTextWithTags(unit.text);\n return origEl;\n });\n\n const isSourceLocale = this.locale === this.defaultLocale;\n const isLocked = isSourceLocale || status?.isLocked || status?.isReady || false;\n\n // Translation textarea\n const textarea = document.createElement('textarea');\n this.addField('Translation', () => {\n textarea.className = 'lr-textarea';\n // Pre-fill: server status > in-DOM translation > empty\n textarea.value = status?.text || resolved.translatedUnit?.text || '';\n textarea.placeholder = unit.text; // Show source as placeholder\n if (isLocked) {\n textarea.readOnly = true;\n textarea.classList.add('lr-textarea-locked');\n textarea.title = isSourceLocale\n ? 'Source language \u2014 switch to a target language to edit'\n : status?.isReady ? 'Approved for delivery \u2014 read only' : 'Locked \u2014 read only';\n }\n return textarea;\n });\n\n // Status bar (above preview)\n this.bodyEl.appendChild(this.statusEl);\n\n // Preview\n const previewEl = document.createElement('div');\n this.addField('Preview', () => {\n previewEl.className = 'lr-preview';\n if (textarea.value) {\n previewEl.innerHTML = this.renderPreview(textarea.value, unit.styles);\n }\n return previewEl;\n });\n\n // Live preview on input (only if not locked)\n if (!isLocked) {\n textarea.addEventListener('input', () => {\n const text = textarea.value;\n previewEl.innerHTML = this.renderPreview(text, unit.styles);\n if (text) {\n applyLivePreview(element, text, unit.styles, key, this.locale, this.namespace);\n }\n this.unsavedKeys.add(key);\n this.api.queueSave({\n key,\n locale: this.locale,\n namespace: this.namespace,\n text,\n styles: unit.styles,\n });\n });\n }\n\n // Page blocks list\n this.renderBlocksList();\n\n // Focus textarea (only if editable)\n if (!isLocked) {\n setTimeout(() => textarea.focus(), 100);\n }\n }\n\n private addField(label: string, contentFn: () => HTMLElement): void {\n const field = document.createElement('div');\n field.className = 'lr-field';\n const labelEl = document.createElement('span');\n labelEl.className = 'lr-field-label';\n labelEl.textContent = label;\n field.appendChild(labelEl);\n field.appendChild(contentFn());\n this.bodyEl.appendChild(field);\n }\n\n /**\n * Get CSS class for the status dot based on actual row state.\n */\n private getDotClass(key: string): string {\n if (this.unsavedKeys.has(key)) return 'unsaved';\n const s = this.statusMap.get(key);\n if (!s) return 'missing';\n if (s.isLocked) return 'locked';\n if (s.isReady) return 'ready';\n if (s.isConfirmed) return 'confirmed';\n if (s.rowState === 'edited') return 'edited';\n if (s.rowState === 'machine_translated') return 'mt';\n return 'missing';\n }\n\n private renderTextWithTags(text: string): string {\n // Highlight indexed tags like <1>, </1>\n return text.replace(\n /<(\\/?)?(\\d+)(\\/)?>/g,\n (match) => `<span class=\"lr-field-tag\">${match}</span>`\n );\n }\n\n private renderPreview(text: string, styles: Record<string, string[]>): string {\n if (!text) return '';\n if (Object.keys(styles).length > 0) {\n const unit: ContentUnit = { text, styles };\n return htmlSerializer.serialize(unit);\n }\n return text;\n }\n\n private initResize(handle: HTMLDivElement): void {\n let startX = 0;\n let startWidth = 0;\n\n const onMouseMove = (e: MouseEvent) => {\n const newWidth = startWidth + (startX - e.clientX);\n const clamped = Math.max(280, Math.min(600, newWidth));\n this.el.style.width = `${clamped}px`;\n };\n\n const onMouseUp = () => {\n handle.classList.remove('active');\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n };\n\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n startX = e.clientX;\n startWidth = this.el.offsetWidth;\n handle.classList.add('active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n }\n\n private refreshBlocksList(): void {\n const existing = this.bodyEl.querySelector('.lr-blocks-section');\n if (existing) existing.remove();\n this.renderBlocksList();\n }\n\n private renderBlocksList(): void {\n const section = document.createElement('div');\n section.className = 'lr-blocks-section';\n\n const blocks = this.blockExtractor.extract(document.body, true);\n const translatedCount = this.getTranslatedCount();\n\n const title = document.createElement('div');\n title.className = 'lr-blocks-title';\n title.textContent = `Blocks on this page (${translatedCount}/${blocks.length} translated)`;\n section.appendChild(title);\n\n for (const block of blocks) {\n const item = document.createElement('div');\n item.className = 'lr-block-item';\n\n const isActive = this.current && block.element === this.current.element;\n if (isActive) item.classList.add('active');\n\n // Status dot\n const dot = document.createElement('span');\n dot.className = 'lr-status-dot';\n dot.classList.add(this.getDotClass(block.key));\n item.appendChild(dot);\n\n // Source text\n const textWrap = document.createElement('div');\n textWrap.className = 'lr-block-text';\n const displayText = block.unit.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n const sourceSpan = document.createElement('div');\n sourceSpan.className = 'lr-block-source';\n sourceSpan.textContent = displayText.length > 60 ? displayText.slice(0, 60) + '...' : displayText;\n sourceSpan.title = displayText;\n textWrap.appendChild(sourceSpan);\n\n // Translation preview (if exists)\n const blockStatus = this.statusMap.get(block.key);\n if (blockStatus && blockStatus.text) {\n const previewSpan = document.createElement('div');\n previewSpan.className = 'lr-block-preview';\n const previewText = blockStatus.text.replace(/<\\/?[0-9]+\\/?>/g, '');\n previewSpan.textContent = previewText.length > 50 ? previewText.slice(0, 50) + '...' : previewText;\n textWrap.appendChild(previewSpan);\n }\n\n item.appendChild(textWrap);\n\n item.addEventListener('click', () => {\n block.element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n this.onBlockClick({ key: block.key, unit: block.unit, translatedUnit: null, element: block.element });\n });\n\n section.appendChild(item);\n }\n\n this.bodyEl.appendChild(section);\n }\n}\n", "/**\n * Editor API \u2014 Batch save queue + session auth\n * Queues translation edits and flushes them in a single batch API call.\n * Uses editor session JWTs (es_ prefixed) for authentication with auto-renewal.\n */\n\nexport interface QueuedTranslation {\n key: string;\n locale: string;\n namespace: string;\n text: string;\n styles: Record<string, string[]>;\n}\n\nexport interface TargetStatus {\n text: string;\n rowState: string; // \"empty\" | \"machine_translated\" | \"edited\"\n isConfirmed: boolean;\n isReady: boolean; // approved for delivery\n isLocked: boolean; // workflow locked OR delivery locked\n}\n\nexport type StatusCallback = (status: 'unsaved' | 'saving' | 'saved' | 'error', message?: string) => void;\n\nexport class EditorAPI {\n private queue: QueuedTranslation[] = [];\n private apiBase: string;\n private sessionToken: string;\n private projectId: string;\n private flushInterval: ReturnType<typeof setInterval> | null = null;\n private renewalInterval: ReturnType<typeof setInterval> | null = null;\n private onStatus: StatusCallback = () => {};\n private onFlushed: (keys: string[]) => void = () => {};\n private onSessionExpired: (() => void) | null = null;\n\n constructor(apiBase: string, sessionToken: string, projectId: string) {\n this.apiBase = apiBase.replace(/\\/$/, '');\n this.sessionToken = sessionToken;\n this.projectId = projectId;\n }\n\n setStatusCallback(cb: StatusCallback): void {\n this.onStatus = cb;\n }\n\n setFlushedCallback(cb: (keys: string[]) => void): void {\n this.onFlushed = cb;\n }\n\n setSessionExpiredCallback(cb: () => void): void {\n this.onSessionExpired = cb;\n }\n\n /**\n * Start auto-flush (30s interval + visibilitychange) and session renewal (60s check)\n */\n startAutoFlush(): void {\n this.flushInterval = setInterval(() => this.flush(), 30_000);\n document.addEventListener('visibilitychange', this.handleVisibility);\n\n // Check session renewal every 60s\n this.renewalInterval = setInterval(() => this.maybeRenewSession(), 60_000);\n }\n\n /**\n * Stop auto-flush and flush remaining items\n */\n async stopAndFlush(): Promise<void> {\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n this.flushInterval = null;\n }\n if (this.renewalInterval) {\n clearInterval(this.renewalInterval);\n this.renewalInterval = null;\n }\n document.removeEventListener('visibilitychange', this.handleVisibility);\n await this.flush();\n }\n\n /**\n * Queue a translation for saving\n */\n queueSave(item: QueuedTranslation): void {\n // Replace existing entry for same key+locale\n const idx = this.queue.findIndex(\n (q) => q.key === item.key && q.locale === item.locale && q.namespace === item.namespace\n );\n if (idx >= 0) {\n this.queue[idx] = item;\n } else {\n this.queue.push(item);\n }\n this.onStatus('unsaved', `${this.queue.length} unsaved`);\n\n // Auto-flush if queue is large\n if (this.queue.length > 50) {\n this.flush();\n }\n }\n\n /**\n * Flush all queued translations to the server\n */\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n\n const items = [...this.queue];\n this.onStatus('saving');\n\n try {\n const response = await fetch(\n `${this.apiBase}/api/integrations/targets/batch`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.sessionToken}`,\n },\n body: JSON.stringify({\n translations: items.map((t) => ({\n key: `${t.locale}:${t.namespace}:${t.key}`,\n value: { text: t.text, styles: t.styles },\n })),\n }),\n }\n );\n\n if (response.status === 401) {\n this.handleSessionExpired();\n return;\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n // Remove flushed items from queue (new items may have been added during fetch)\n const flushedKeys = items.map((i) => i.key);\n for (const item of items) {\n const idx = this.queue.indexOf(item);\n if (idx >= 0) this.queue.splice(idx, 1);\n }\n\n // Notify sidebar to re-fetch status for flushed keys\n this.onFlushed(flushedKeys);\n\n if (this.queue.length === 0) {\n this.onStatus('saved', 'All changes saved');\n } else {\n this.onStatus('unsaved', `${this.queue.length} unsaved`);\n }\n } catch (err) {\n this.onStatus('error', `Save failed: ${(err as Error).message}`);\n }\n }\n\n private statusAbort: AbortController | null = null;\n\n /**\n * Fetch translation status for a batch of keys (includes unconfirmed rows).\n * Cancels any in-flight status request. Caps at 200 keys per request.\n */\n async fetchStatus(\n keys: string[],\n locale: string,\n namespace: string\n ): Promise<Record<string, TargetStatus | null>> {\n if (keys.length === 0) return {};\n\n // Cancel previous in-flight request\n if (this.statusAbort) this.statusAbort.abort();\n this.statusAbort = new AbortController();\n\n // Cap keys to avoid exceeding URL length limits\n const batch = keys.slice(0, 200);\n\n const params = new URLSearchParams({ locale, namespace, keys: batch.join(',') });\n try {\n const response = await fetch(\n `${this.apiBase}/api/integrations/targets/status?${params}`,\n {\n headers: { 'Authorization': `Bearer ${this.sessionToken}` },\n signal: this.statusAbort.signal,\n }\n );\n if (response.status === 401) {\n this.handleSessionExpired();\n return {};\n }\n if (!response.ok) return {};\n const data = await response.json();\n return data.translations;\n } catch (err) {\n if ((err as Error).name === 'AbortError') return {};\n return {};\n }\n }\n\n get pendingCount(): number {\n return this.queue.length;\n }\n\n // ============================================\n // Session renewal\n // ============================================\n\n /**\n * Check if session is within 2min of expiry, and renew if so.\n */\n private async maybeRenewSession(): Promise<void> {\n const exp = this.getSessionExp();\n if (!exp) return;\n\n const timeLeft = exp * 1000 - Date.now();\n if (timeLeft > 120_000) return; // More than 2 min left, skip\n\n await this.renewSession();\n }\n\n private async renewSession(): Promise<void> {\n try {\n const response = await fetch(`${this.apiBase}/api/editor/renew`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.sessionToken}`,\n },\n });\n\n if (response.status === 401) {\n this.handleSessionExpired();\n return;\n }\n\n if (!response.ok) return;\n\n const data = await response.json();\n this.sessionToken = data.session_token;\n\n // Update sessionStorage\n try {\n const raw = this.sessionToken.startsWith('es_') ? this.sessionToken.slice(3) : this.sessionToken;\n const parts = raw.split('.');\n if (parts.length === 3) {\n const payload = JSON.parse(atob(parts[1]));\n sessionStorage.setItem('__lr_editor_session', JSON.stringify({\n token: this.sessionToken,\n exp: payload.exp || 0,\n }));\n }\n } catch { /* non-critical */ }\n } catch {\n // Network error \u2014 will retry on next interval\n }\n }\n\n private getSessionExp(): number | null {\n try {\n const raw = this.sessionToken.startsWith('es_') ? this.sessionToken.slice(3) : this.sessionToken;\n const parts = raw.split('.');\n if (parts.length !== 3) return null;\n const payload = JSON.parse(atob(parts[1]));\n return payload.exp || null;\n } catch {\n return null;\n }\n }\n\n private handleSessionExpired(): void {\n this.onStatus('error', 'Session expired. Please reopen the editor from the dashboard.');\n if (this.onSessionExpired) {\n this.onSessionExpired();\n }\n }\n\n private handleVisibility = (): void => {\n if (document.visibilityState === 'hidden') {\n this.flush();\n }\n };\n}\n", "/**\n * Visual Translation Editor \u2014 Entry Point\n * Self-executing IIFE bundle loaded by edge proxy or auto-init when ?__lr_editor is detected.\n *\n * Reads script tag attributes, polls for window.LionRapid, creates Shadow DOM,\n * and instantiates Inspector, Sidebar, and Toolbar.\n *\n * Auth flow: grant token \u2192 exchange for scoped session JWT \u2192 use JWT for API calls.\n */\n\nimport { EDITOR_CSS } from './editor-styles.js';\nimport { Inspector } from './inspector.js';\nimport { Toolbar } from './toolbar.js';\nimport { Sidebar } from './sidebar.js';\nimport { EditorAPI } from './editor-api.js';\nimport type { ResolvedKey } from './key-resolver.js';\n\n// ============================================\n// Session helpers\n// ============================================\n\nconst SESSION_KEY = '__lr_editor_session';\n\ninterface StoredSession {\n token: string;\n exp: number;\n}\n\nfunction getStoredSession(): string | null {\n try {\n const raw = sessionStorage.getItem(SESSION_KEY);\n if (!raw) return null;\n const parsed: StoredSession = JSON.parse(raw);\n // Check if expired (with 30s buffer)\n if (parsed.exp * 1000 < Date.now() + 30_000) {\n sessionStorage.removeItem(SESSION_KEY);\n return null;\n }\n return parsed.token;\n } catch {\n return null;\n }\n}\n\nfunction storeSession(token: string): void {\n try {\n // Parse exp from JWT payload (es_<header>.<payload>.<sig>)\n const raw = token.startsWith('es_') ? token.slice(3) : token;\n const parts = raw.split('.');\n if (parts.length !== 3) return;\n const payload = JSON.parse(atob(parts[1]));\n const session: StoredSession = { token, exp: payload.exp || 0 };\n sessionStorage.setItem(SESSION_KEY, JSON.stringify(session));\n } catch {\n // Non-critical \u2014 session just won't persist across navigations\n }\n}\n\nfunction clearSession(): void {\n sessionStorage.removeItem(SESSION_KEY);\n}\n\n// ============================================\n// Init\n// ============================================\n\nfunction initEditor(): void {\n // Read attributes from own script tag\n const scriptEl = document.querySelector('script[data-grant]') as HTMLScriptElement | null;\n if (!scriptEl) {\n console.warn('[LionRapid Editor] No script tag with data-grant found');\n return;\n }\n\n const grant = scriptEl.dataset.grant || '';\n const locale = scriptEl.dataset.locale || '';\n const apiBase = scriptEl.dataset.api || 'https://api.lionrapid.com';\n const projectId = scriptEl.dataset.project || '';\n\n // Poll for window.LionRapid (auto-init loads first)\n let attempts = 0;\n const maxAttempts = 100; // 10s at 100ms intervals\n\n const poll = setInterval(() => {\n attempts++;\n const lr = window.LionRapid;\n\n if (lr) {\n clearInterval(poll);\n activate(lr, grant, locale, apiBase, projectId);\n } else if (attempts >= maxAttempts) {\n clearInterval(poll);\n console.warn('[LionRapid Editor] Timed out waiting for window.LionRapid');\n }\n }, 100);\n}\n\nasync function activate(\n lr: NonNullable<typeof window.LionRapid>,\n grant: string,\n locale: string,\n apiBase: string,\n projectId: string,\n): Promise<void> {\n const config = window.__lionrapidConfig;\n const languages = config?.languages || [locale];\n const namespace = config?.namespace || 'default';\n const defaultLocale = config?.defaultLocale || 'en';\n const currentLocale = locale || lr.getCurrentLocale();\n const normalizedApiBase = apiBase.replace(/\\/$/, '');\n\n // --- Session acquisition ---\n let sessionToken = getStoredSession();\n\n if (!sessionToken && grant) {\n // Exchange grant for session JWT\n try {\n const res = await fetch(`${normalizedApiBase}/api/editor/exchange`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ grant, domain: window.location.host }),\n });\n if (!res.ok) {\n console.error('[LionRapid Editor] Grant exchange failed:', res.status);\n return;\n }\n const data = await res.json();\n sessionToken = data.session_token;\n if (sessionToken) {\n storeSession(sessionToken);\n }\n } catch (err) {\n console.error('[LionRapid Editor] Grant exchange error:', err);\n return;\n }\n }\n\n if (!sessionToken) {\n console.error('[LionRapid Editor] No valid session. Please reopen the editor from the dashboard.');\n return;\n }\n\n // Create Shadow DOM host\n const host = document.createElement('div');\n host.id = '__lionrapid-editor';\n host.setAttribute('data-no-translate', '');\n document.body.appendChild(host);\n const shadow = host.attachShadow({ mode: 'closed' });\n\n // Inject styles\n const styleEl = document.createElement('style');\n styleEl.textContent = EDITOR_CSS;\n shadow.appendChild(styleEl);\n\n // Hide the proxy/auto-init language switcher while editor is active\n const switcherEl = document.querySelector('[data-lionrapid-switcher]') as HTMLElement | null;\n if (switcherEl) switcherEl.style.display = 'none';\n\n // Create API client with session token\n const api = new EditorAPI(normalizedApiBase, sessionToken, projectId);\n api.startAutoFlush();\n\n // Create sidebar (needs api + locale)\n const handleBlockSelect = (resolved: ResolvedKey) => {\n sidebar.open(resolved);\n inspector.clearHighlight();\n };\n\n const sidebar = new Sidebar(shadow, api, currentLocale, namespace, defaultLocale, handleBlockSelect);\n\n // Create inspector (hover/click \u2192 sidebar)\n const inspector = new Inspector(shadow, handleBlockSelect);\n\n // Create toolbar\n const toolbar = new Toolbar(\n shadow,\n languages,\n currentLocale,\n // Language change\n async (newLocale) => {\n // Edge proxy context: navigate to locale URL instead of client-side translation\n const isEdgeProxy = document.querySelector('script[data-mode=\"dynamic-only\"]') !== null;\n if (isEdgeProxy) {\n const url = new URL(window.location.href);\n // Strip existing locale prefix if present\n const stripped = url.pathname.replace(/^\\/[a-z]{2}(\\/|$)/, '/');\n // Build new URL: /es/path?__lr_editor=grant\n const prefix = newLocale === defaultLocale ? '' : `/${newLocale}`;\n url.pathname = prefix + (stripped === '/' && prefix ? '' : stripped);\n url.searchParams.set('__lr_editor', grant);\n window.location.href = url.toString();\n return;\n }\n sidebar.updateLocale(newLocale);\n sidebar.close();\n inspector.clearHighlight();\n await lr.changeLanguage(newLocale);\n await sidebar.hydrateStatus();\n },\n // Exit\n async () => {\n await api.stopAndFlush();\n inspector.destroy();\n toolbar.destroy();\n sidebar.destroy();\n host.remove();\n clearSession();\n },\n );\n\n // Wire progress counter to sidebar status\n sidebar.setProgressCallback((translated, total) => {\n toolbar.updateProgress(translated, total);\n });\n\n // Hydrate status from server and update progress\n sidebar.hydrateStatus().then(() => {\n toolbar.updateProgress(sidebar.getTranslatedCount(), sidebar.getTotalCount());\n });\n\n // Clean editor param from URL\n const url = new URL(window.location.href);\n if (url.searchParams.has('__lr_editor')) {\n url.searchParams.delete('__lr_editor');\n history.replaceState(null, '', url.toString());\n }\n}\n\n// Self-execute\ninitEditor();\n"],
|
|
5
|
+
"mappings": ";;;;;;;AAKO,MAAM,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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
|
|
6
|
+
"names": ["BLOCK_SELECTOR", "BLOCK_SELECTOR", "SKIP_TAGS", "htmlSerializer", "url"]
|
|
7
7
|
}
|