mail-editor-pancake 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/registry/registry.ts","../src/utils/dynamicVariantKey.ts","../src/utils/dynamicVariantHtml.ts","../src/utils/inlineListEditing.ts","../src/utils/emailListStyles.ts","../src/utils/contentWidth.ts","../src/utils/dom.ts","../src/utils/fontWeightSteps.ts","../src/utils/lockedMjml.ts","../src/renderer/mjml.ts","../src/renderer/index.ts","../src/utils/id.ts","../src/store/store.ts","../src/variables/index.ts","../src/utils/richHtmlInsert.ts","../src/utils/dynamicVariantSection.ts","../src/utils/sectionLayout.ts","../src/utils/html.ts","../src/utils/modalSize.ts","../src/editor/Modal.ts","../src/editor/BlockCodeModal.ts","../src/utils/richTextCommand.ts","../src/utils/richHtmlEmpty.ts","../src/utils/accentColor.ts","../src/i18n/index.ts","../src/editor/ColorPickerPopover.ts","../src/editor/InlineEditor.ts","../src/editor/Canvas.ts","../src/editor/ExportModal.ts","../src/editor/LeftPanel.ts","../src/editor/PreviewModal.ts","../src/editor/RichTextToolbar.ts","../src/socialDefaults.ts","../src/editor/imageAssets.ts","../src/editor/FocusBreadcrumb.ts","../src/editor/ImageGalleryModal.ts","../src/editor/VariablePickerPanel.ts","../src/editor/RightPanel.ts","../src/editor/SourceView.ts","../src/editor/Topbar.ts","../src/utils/docClipboard.ts","../src/editor/ImportDocModal.ts","../src/editor/Editor.ts"],"sourcesContent":["import type { Block, BlockDefinition } from '../types';\n\n/**\n * 组件注册表。所有内置/自定义组件都通过 `defineBlock` 注册进来;\n * 渲染、属性面板、左栏拖拽源、组件级代码模式四方都从这里读取。\n */\nexport class Registry {\n private map = new Map<string, BlockDefinition<any>>();\n\n register<P extends object>(def: BlockDefinition<P>) {\n if (this.map.has(def.type)) {\n console.warn(`[simple-mail] block type 重复注册: ${def.type},后注册的会覆盖前者`);\n }\n this.map.set(def.type, def as BlockDefinition<any>);\n return this;\n }\n\n get(type: string): BlockDefinition | undefined {\n return this.map.get(type);\n }\n\n /** 必须能找到,否则抛出。渲染/属性面板都用它,未注册即 bug。 */\n require(type: string): BlockDefinition {\n const def = this.map.get(type);\n if (!def) throw new Error(`[simple-mail] 未注册的 block type: ${type}`);\n return def;\n }\n\n list(): BlockDefinition[] {\n return [...this.map.values()];\n }\n\n byCategory(category: BlockDefinition['category']): BlockDefinition[] {\n return this.list().filter((d) => d.category === category);\n }\n\n /** 用注册表里的默认 props 创建一个新 block 实例。 */\n createBlock(type: string): Block {\n const def = this.require(type);\n return {\n id: cryptoRandomId(),\n type,\n props: structuredClone(def.defaultProps),\n };\n }\n}\n\nfunction cryptoRandomId() {\n const ts = Date.now().toString(36).slice(-4);\n const rand = Math.floor(Math.random() * 36 ** 4)\n .toString(36)\n .padStart(4, '0');\n return `blk_${ts}${rand}`;\n}\n\n/** 工厂函数,便于外部以函数式风格定义组件。 */\nexport function defineBlock<P extends object>(def: BlockDefinition<P>): BlockDefinition<P> {\n return def;\n}\n","import type { Section } from '../types';\n\n/**\n * 导出 HTML 上标记动态变量组合的宿主约定属性名(值为 `Section.attrs.dynamicVariantKey`)。\n */\nexport const DYNAMIC_VARIANT_HTML_ATTR = 'data-dv';\n\n/** 本节导出后替换为 `{{dynamicVariantKey}}`,内容由宿主写入 dynamicVariant */\nexport function getSectionDynamicVariantKey(section: Section): string | undefined {\n const key = String(section.attrs.dynamicVariantKey ?? '').trim();\n return key || undefined;\n}\n\nexport function isDynamicVariantSection(section: Section): boolean {\n return !!getSectionDynamicVariantKey(section);\n}\n\nexport function dynamicVariantPlaceholder(key: string): string {\n return `{{${String(key).trim()}}}`;\n}\n\nexport function sectionMjClassName(sectionId: string): string {\n return `sm-sec-${sectionId.replace(/[^a-zA-Z0-9_-]/g, '_')}`;\n}\n","import type { EmailDoc } from '../types';\nimport {\n DYNAMIC_VARIANT_HTML_ATTR,\n getSectionDynamicVariantKey,\n isDynamicVariantSection,\n sectionMjClassName,\n} from './dynamicVariantKey';\n\nfunction serializeParsedHtml(doc: Document): string {\n const head = doc.head?.innerHTML || '';\n const body = doc.body?.innerHTML || '';\n return `${head}${body}`;\n}\n\n/**\n * 编译后为带 `dynamicVariantKey` 的 Section 根节点写入 `data-dv=\"{key}\"`,供宿主 DOM 抽取。\n */\nexport function annotateDynamicVariantHtmlAttributes(html: string, doc: EmailDoc): string {\n const slots = doc.sections.filter(isDynamicVariantSection);\n if (!slots.length) return html;\n try {\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n for (const section of slots) {\n const key = getSectionDynamicVariantKey(section);\n if (!key) continue;\n const cls = sectionMjClassName(section.id);\n const marked = parsed.querySelector(`[${DYNAMIC_VARIANT_HTML_ATTR}=\"${key}\"]`);\n if (marked) continue;\n const candidates = parsed.querySelectorAll(`[class~=\"${cls}\"], [class*=\"${cls}\"]`);\n let target: Element | null = null;\n for (const el of candidates) {\n const cn = el.getAttribute('class') || '';\n if (cn.split(/\\s+/).includes(cls)) {\n target = el;\n break;\n }\n }\n if (!target && candidates.length) target = candidates[0];\n if (target) target.setAttribute(DYNAMIC_VARIANT_HTML_ATTR, key);\n }\n return serializeParsedHtml(parsed);\n } catch {\n return html;\n }\n}\n","/** contenteditable 内 ul/ol 的 Enter / Backspace / 退出列表等 DOM 操作 */\n\n/** 空列表项 Enter 退出后插入的正文段,勿当作可合并的分隔块 */\nexport const LIST_GAP_ATTR = 'data-sm-list-gap';\n\nexport function findListItem(node: Node | null, root: HTMLElement): HTMLLIElement | null {\n while (node && node !== root) {\n if (node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).tagName === 'LI') {\n return node as HTMLLIElement;\n }\n node = node.parentNode;\n }\n return null;\n}\n\nexport function findListRoot(\n li: HTMLLIElement,\n): HTMLUListElement | HTMLOListElement | null {\n const parent = li.parentElement;\n if (!parent) return null;\n if (parent.tagName === 'UL' || parent.tagName === 'OL') {\n return parent as HTMLUListElement | HTMLOListElement;\n }\n return null;\n}\n\ntype ListElement = HTMLUListElement | HTMLOListElement;\n\n/** 两个列表之间可忽略的分隔块(空段落、仅含 br 的 div 等) */\nexport function isIgnorableListSeparator(el: Element): boolean {\n if (el.hasAttribute(LIST_GAP_ATTR)) return false;\n if (el.tagName !== 'P' && el.tagName !== 'DIV') return false;\n const clone = el.cloneNode(true) as HTMLElement;\n clone.querySelectorAll('br').forEach((br) => br.remove());\n return (clone.textContent ?? '').replace(/\\u200b/g, '').trim() === '';\n}\n\nfunction findPreviousListOfSameType(list: ListElement): ListElement | null {\n let node: Element | null = list.previousElementSibling;\n while (node) {\n if (node.tagName === list.tagName) return node as ListElement;\n if (!isIgnorableListSeparator(node)) return null;\n node = node.previousElementSibling;\n }\n return null;\n}\n\nfunction findNextListOfSameType(list: ListElement): ListElement | null {\n let node: Element | null = list.nextElementSibling;\n while (node) {\n if (node.tagName === list.tagName) return node as ListElement;\n if (!isIgnorableListSeparator(node)) return null;\n node = node.nextElementSibling;\n }\n return null;\n}\n\n/** 将 source 的全部 li 并入 target,并移除中间分隔块与空的 source */\nfunction mergeListInto(target: ListElement, source: ListElement): void {\n let node: Element | null = target.nextElementSibling;\n while (node && node !== source) {\n const next = node.nextElementSibling;\n if (isIgnorableListSeparator(node)) node.remove();\n else break;\n node = next;\n }\n while (source.firstChild) target.appendChild(source.firstChild);\n source.remove();\n}\n\n/** 删除中间内容后,合并仅由空行分隔的同类型相邻列表 */\nexport function mergeAdjacentSameTypeLists(root: HTMLElement): boolean {\n let merged = false;\n for (const list of Array.from(root.querySelectorAll('ol, ul'))) {\n if (!root.contains(list)) continue;\n const prev = findPreviousListOfSameType(list as ListElement);\n if (prev && root.contains(prev)) {\n mergeListInto(prev, list as ListElement);\n merged = true;\n }\n }\n return merged;\n}\n\nexport function isLiEffectivelyEmpty(li: HTMLLIElement): boolean {\n const clone = li.cloneNode(true) as HTMLLIElement;\n clone.querySelectorAll('br').forEach((br) => br.remove());\n return (clone.textContent ?? '').replace(/\\u200b/g, '').trim() === '';\n}\n\nexport function isCaretAtLiStart(li: HTMLLIElement, range: Range): boolean {\n const probe = document.createRange();\n probe.selectNodeContents(li);\n probe.setEnd(range.startContainer, range.startOffset);\n return probe.toString().replace(/\\u200b/g, '').length === 0;\n}\n\nfunction fragmentHasSubstantiveText(frag: DocumentFragment): boolean {\n const box = document.createElement('div');\n box.appendChild(frag);\n box.querySelectorAll('br').forEach((br) => br.remove());\n return (box.textContent ?? '').replace(/\\u200b/g, '').trim().length > 0;\n}\n\n/** 光标后是否仅剩 br / 空块等可忽略内容(视为处于列表项末尾) */\nexport function isCaretAtLiEnd(li: HTMLLIElement, range: Range): boolean {\n const after = document.createRange();\n try {\n after.setStart(range.endContainer, range.endOffset);\n if (li.lastChild) after.setEndAfter(li.lastChild);\n else after.setEnd(li, 0);\n } catch {\n return false;\n }\n return !fragmentHasSubstantiveText(after.cloneContents());\n}\n\nexport function placeCaretInElement(el: HTMLElement, atStart: boolean): void {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(atStart);\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nexport function placeCaretAtEndOfElement(el: HTMLElement): void {\n placeCaretInElement(el, false);\n}\n\nfunction visibleTextLength(text: string): number {\n return text.replace(/\\u200b/g, '').length;\n}\n\n/** 容器内光标前的可见文本长度(忽略零宽空格) */\nexport function getCaretTextOffset(container: HTMLElement, range: Range): number {\n const probe = document.createRange();\n probe.selectNodeContents(container);\n probe.setEnd(range.startContainer, range.startOffset);\n return visibleTextLength(probe.toString());\n}\n\n/** 元素内可见文本偏移处放置光标;偏移超出则落在末尾 */\nexport function setCaretByTextOffset(container: HTMLElement, offset: number): void {\n const target = Math.max(0, offset);\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);\n let remaining = target;\n let textNode: Text | null = null;\n\n while ((textNode = walker.nextNode() as Text | null)) {\n const data = textNode.data ?? '';\n const len = visibleTextLength(data);\n if (remaining <= len) {\n let count = 0;\n let nodeOffset = data.length;\n for (let i = 0; i < data.length; i++) {\n if (data[i] === '\\u200b') continue;\n if (count === remaining) {\n nodeOffset = i;\n break;\n }\n count++;\n }\n const range = document.createRange();\n range.setStart(textNode, nodeOffset);\n range.collapse(true);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n return;\n }\n remaining -= len;\n }\n\n placeCaretAtEndOfElement(container);\n}\n\nexport function getElementVisibleTextLength(el: HTMLElement): number {\n return visibleTextLength(el.textContent ?? '');\n}\n\nconst CARET_MARKER_ATTR = 'data-sm-caret';\nconst RANGE_START_MARKER_ATTR = 'data-sm-sel-start';\n\nfunction insertBoundaryMarker(range: Range, attr: string): HTMLSpanElement | null {\n if (!range.collapsed) return null;\n const marker = document.createElement('span');\n marker.setAttribute(attr, '1');\n marker.appendChild(document.createTextNode('\\u200b'));\n try {\n range.insertNode(marker);\n return marker;\n } catch {\n marker.remove();\n return null;\n }\n}\n\n/** 在折叠光标处插入临时标记(空行/空列表项时比文本偏移更准) */\nexport function insertCaretMarker(range: Range): HTMLSpanElement | null {\n return insertBoundaryMarker(range, CARET_MARKER_ATTR);\n}\n\n/** 在选区起止处插入边界标记(用于列表命令后定位新建列表) */\nexport function insertSelectionBoundaryMarkers(range: Range): {\n start: HTMLSpanElement | null;\n end: HTMLSpanElement | null;\n} {\n const startRange = range.cloneRange();\n startRange.collapse(true);\n const endRange = range.cloneRange();\n endRange.collapse(false);\n return {\n start: insertBoundaryMarker(startRange, RANGE_START_MARKER_ATTR),\n end: insertBoundaryMarker(endRange, CARET_MARKER_ATTR),\n };\n}\n\n/** 在选区末尾插入光标标记(列表等命令后应落在选区末端) */\nexport function insertCaretMarkerAtRangeEnd(range: Range): HTMLSpanElement | null {\n const atEnd = range.cloneRange();\n atEnd.collapse(false);\n return insertCaretMarker(atEnd);\n}\n\nexport function removeSelectionBoundaryMarkers(root: HTMLElement): void {\n root\n .querySelectorAll(\n `span[${RANGE_START_MARKER_ATTR}=\"1\"], span[${CARET_MARKER_ATTR}=\"1\"]`,\n )\n .forEach((m) => m.remove());\n}\n\n/** 选区末尾在容器内的可见文本偏移 */\nexport function getCaretTextOffsetAtRangeEnd(\n container: HTMLElement,\n range: Range,\n): number {\n const atEnd = range.cloneRange();\n atEnd.collapse(false);\n return getCaretTextOffset(container, atEnd);\n}\n\n/** 将光标恢复到标记处并移除标记 */\nexport function restoreCaretMarker(root: HTMLElement): boolean {\n const marker = root.querySelector(`span[${CARET_MARKER_ATTR}=\"1\"]`);\n if (!(marker instanceof HTMLSpanElement) || !root.contains(marker)) return false;\n\n const range = document.createRange();\n range.setStartBefore(marker);\n range.collapse(true);\n marker.remove();\n\n const sel = window.getSelection();\n if (!sel) return false;\n sel.removeAllRanges();\n sel.addRange(range);\n return true;\n}\n\nfunction normalizeSelectionSpan(start: Node, end: Node): { anchor: Node; far: Node } {\n if (start.compareDocumentPosition(end) & Node.DOCUMENT_POSITION_FOLLOWING) {\n return { anchor: start, far: end };\n }\n return { anchor: end, far: start };\n}\n\nfunction listInSelectionSpan(list: Element, start: Node, end: Node): boolean {\n if (list.contains(start) || list.contains(end)) return true;\n\n const { anchor, far } = normalizeSelectionSpan(start, end);\n const afterAnchor =\n (list.compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;\n const beforeFar =\n (list.compareDocumentPosition(far) & Node.DOCUMENT_POSITION_PRECEDING) !== 0;\n return afterAnchor && beforeFar;\n}\n\nfunction lastListInDocumentOrder(lists: ListElement[]): ListElement | null {\n let best: ListElement | null = null;\n for (const list of lists) {\n if (\n !best ||\n (best.compareDocumentPosition(list) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0\n ) {\n best = list;\n }\n }\n return best;\n}\n\nfunction placeCaretAtEndOfList(list: ListElement): boolean {\n const items = Array.from(list.children).filter(\n (c): c is HTMLLIElement => c.tagName === 'LI',\n );\n const lastLi = items[items.length - 1];\n if (!lastLi) return false;\n placeCaretAtEndOfElement(lastLi);\n return true;\n}\n\n/**\n * 新建列表后:光标落在选区范围内(起止标记之间)文档顺序最靠后的列表末项。\n * 空行选中时末端标记常落在上方已有列表内,不能只看「标记所在列表」。\n */\nexport function restoreCaretToEndOfListInSelectionBounds(root: HTMLElement): boolean {\n const start = root.querySelector(`span[${RANGE_START_MARKER_ATTR}=\"1\"]`);\n const end = root.querySelector(`span[${CARET_MARKER_ATTR}=\"1\"]`);\n if (\n !(start instanceof HTMLSpanElement) ||\n !(end instanceof HTMLSpanElement) ||\n !root.contains(start) ||\n !root.contains(end)\n ) {\n return false;\n }\n\n const matched: ListElement[] = [];\n for (const node of root.querySelectorAll('ul, ol')) {\n if (!(node instanceof HTMLElement) || !root.contains(node)) continue;\n const list = node as ListElement;\n if (listInSelectionSpan(list, start, end)) matched.push(list);\n }\n\n start.remove();\n end.remove();\n\n const target = lastListInDocumentOrder(matched);\n if (!target) return false;\n return placeCaretAtEndOfList(target);\n}\n\n/** 列表操作后恢复光标:优先标记点,否则文本偏移 */\nexport function restoreCaretAfterListMutation(\n root: HTMLElement,\n marker: HTMLSpanElement | null,\n fallbackOffset: number,\n): void {\n if (restoreCaretMarker(root)) return;\n setCaretByTextOffset(root, fallbackOffset);\n}\n\nfunction ensureLiHasPlaceholder(li: HTMLLIElement): void {\n if (isLiEffectivelyEmpty(li)) {\n li.textContent = '';\n li.appendChild(document.createElement('br'));\n }\n}\n\n/** 空列表项 + Enter:退出列表(必要时拆成两段列表) */\nexport function exitListFromEmptyItem(li: HTMLLIElement): void {\n const list = findListRoot(li);\n if (!list) return;\n\n const items = Array.from(list.children).filter(\n (c): c is HTMLLIElement => c.tagName === 'LI',\n );\n const index = items.indexOf(li);\n if (index === -1) return;\n\n const afterItems = items.slice(index + 1);\n li.remove();\n\n const p = document.createElement('p');\n p.setAttribute(LIST_GAP_ATTR, '1');\n p.appendChild(document.createElement('br'));\n\n if (list.children.length === 0) {\n list.replaceWith(p);\n } else if (afterItems.length === 0) {\n list.after(p);\n } else if (index === 0) {\n list.before(p);\n } else {\n const newList = document.createElement(list.tagName.toLowerCase()) as\n | HTMLUListElement\n | HTMLOListElement;\n afterItems.forEach((item) => newList.appendChild(item));\n list.after(p);\n p.after(newList);\n }\n\n placeCaretInElement(p, true);\n}\n\n/** Enter:新列表项或拆分当前项 */\nexport function splitListItemOnEnter(li: HTMLLIElement, range: Range): void {\n const list = findListRoot(li);\n if (!list) return;\n\n if (isLiEffectivelyEmpty(li)) {\n exitListFromEmptyItem(li);\n return;\n }\n\n if (isCaretAtLiStart(li, range)) {\n const newLi = document.createElement('li');\n newLi.appendChild(document.createElement('br'));\n list.insertBefore(newLi, li);\n placeCaretInElement(newLi, true);\n return;\n }\n\n if (isCaretAtLiEnd(li, range)) {\n const newLi = document.createElement('li');\n newLi.appendChild(document.createElement('br'));\n if (li.nextSibling) list.insertBefore(newLi, li.nextSibling);\n else list.appendChild(newLi);\n placeCaretInElement(newLi, true);\n return;\n }\n\n const tailRange = document.createRange();\n tailRange.setStart(range.startContainer, range.startOffset);\n if (li.lastChild) tailRange.setEndAfter(li.lastChild);\n else tailRange.setEnd(li, 0);\n\n const tailProbe = document.createRange();\n tailProbe.setStart(range.startContainer, range.startOffset);\n if (li.lastChild) tailProbe.setEndAfter(li.lastChild);\n else tailProbe.setEnd(li, 0);\n if (!fragmentHasSubstantiveText(tailProbe.cloneContents())) {\n const newLi = document.createElement('li');\n newLi.appendChild(document.createElement('br'));\n if (li.nextSibling) list.insertBefore(newLi, li.nextSibling);\n else list.appendChild(newLi);\n placeCaretInElement(newLi, true);\n return;\n }\n\n const newLi = document.createElement('li');\n const fragment = tailRange.extractContents();\n newLi.appendChild(fragment);\n ensureLiHasPlaceholder(li);\n\n if (li.nextSibling) list.insertBefore(newLi, li.nextSibling);\n else list.appendChild(newLi);\n\n placeCaretInElement(newLi, true);\n}\n\n/** Backspace 在列表项行首:合并上一项、跨列表合并或退出列表 */\nexport function mergeListItemOnBackspace(li: HTMLLIElement, range: Range): boolean {\n if (!range.collapsed || !isCaretAtLiStart(li, range)) return false;\n\n const list = findListRoot(li);\n if (!list) return false;\n\n if (isLiEffectivelyEmpty(li)) {\n const prevInList = li.previousElementSibling;\n if (!prevInList || prevInList.tagName !== 'LI') {\n const prevList = findPreviousListOfSameType(list);\n if (prevList) {\n li.remove();\n mergeListInto(prevList, list);\n const lastLi = prevList.lastElementChild;\n if (lastLi instanceof HTMLLIElement) placeCaretAtEndOfElement(lastLi);\n return true;\n }\n }\n exitListFromEmptyItem(li);\n return true;\n }\n\n const prevInList = li.previousElementSibling;\n if (prevInList && prevInList.tagName === 'LI') {\n const prevLi = prevInList as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(prevLi);\n while (li.firstChild) prevLi.appendChild(li.firstChild);\n li.remove();\n setCaretByTextOffset(prevLi, junctionOffset);\n return true;\n }\n\n const prevList = findPreviousListOfSameType(list);\n if (prevList) {\n const prevLi = prevList.lastElementChild;\n if (prevLi && prevLi.tagName === 'LI') {\n const prevLiEl = prevLi as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(prevLiEl);\n while (li.firstChild) prevLiEl.appendChild(li.firstChild);\n li.remove();\n if (list.children.length === 0) mergeListInto(prevList, list);\n setCaretByTextOffset(prevLiEl, junctionOffset);\n return true;\n }\n }\n\n const p = document.createElement('p');\n while (li.firstChild) p.appendChild(li.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n li.remove();\n\n if (list.children.length === 0) {\n list.replaceWith(p);\n } else {\n list.before(p);\n }\n placeCaretAtEndOfElement(p);\n return true;\n}\n\n/** Delete 在列表项行末:整项合并下一项,或跨列表合并(含 Shift+Enter 软换行) */\nexport function mergeNextListItemOnDelete(li: HTMLLIElement, range: Range): boolean {\n if (!range.collapsed || !isCaretAtLiEnd(li, range)) return false;\n\n const list = findListRoot(li);\n if (!list) return false;\n\n const nextInList = li.nextElementSibling;\n if (nextInList && nextInList.tagName === 'LI') {\n const nextLi = nextInList as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(li);\n\n if (isLiEffectivelyEmpty(nextLi)) {\n nextLi.remove();\n setCaretByTextOffset(li, junctionOffset);\n return true;\n }\n\n while (nextLi.firstChild) li.appendChild(nextLi.firstChild);\n nextLi.remove();\n setCaretByTextOffset(li, junctionOffset);\n return true;\n }\n\n const nextList = findNextListOfSameType(list);\n if (!nextList) return false;\n\n const nextLi = nextList.firstElementChild;\n if (!nextLi || nextLi.tagName !== 'LI') return false;\n\n const nextLiEl = nextLi as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(li);\n\n if (isLiEffectivelyEmpty(nextLiEl)) {\n nextLiEl.remove();\n if (nextList.children.length === 0) mergeListInto(list, nextList);\n setCaretByTextOffset(li, junctionOffset);\n return true;\n }\n\n while (nextLiEl.firstChild) li.appendChild(nextLiEl.firstChild);\n nextLiEl.remove();\n if (nextList.children.length === 0) mergeListInto(list, nextList);\n setCaretByTextOffset(li, junctionOffset);\n return true;\n}\n\nfunction rangeIntersectsNode(range: Range, node: Node): boolean {\n try {\n const nodeRange = document.createRange();\n nodeRange.selectNodeContents(node);\n return (\n range.compareBoundaryPoints(Range.END_TO_START, nodeRange) > -1 &&\n range.compareBoundaryPoints(Range.START_TO_END, nodeRange) < 1\n );\n } catch {\n return false;\n }\n}\n\nfunction sortByDocumentOrder<T extends Node>(nodes: T[]): T[] {\n return [...nodes].sort((a, b) => {\n const pos = a.compareDocumentPosition(b);\n if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;\n if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;\n return 0;\n });\n}\n\n/** 选区触及的列表项(块级,按文档顺序) */\nexport function getListItemsInRange(\n range: Range,\n root: HTMLElement,\n): HTMLLIElement[] {\n const items: HTMLLIElement[] = [];\n for (const node of root.querySelectorAll('li')) {\n if (!(node instanceof HTMLLIElement)) continue;\n if (!findListRoot(node)) continue;\n if (!rangeIntersectsNode(range, node)) continue;\n items.push(node);\n }\n return sortByDocumentOrder(items);\n}\n\nfunction copyListElementAttributes(from: ListElement, to: ListElement): void {\n const indentAttr = from.getAttribute('data-sm-list-indent');\n if (indentAttr != null) to.setAttribute('data-sm-list-indent', indentAttr);\n const style = from.getAttribute('style');\n if (style) to.setAttribute('style', style);\n}\n\nfunction appendListWithItems(\n frag: DocumentFragment,\n tag: 'ul' | 'ol',\n source: ListElement,\n items: HTMLLIElement[],\n): void {\n if (!items.length) return;\n const el = document.createElement(tag) as ListElement;\n copyListElementAttributes(source, el);\n items.forEach((li) => el.appendChild(li));\n frag.appendChild(el);\n}\n\nfunction appendUnwrappedItems(frag: DocumentFragment, items: HTMLLIElement[]): void {\n for (const li of items) {\n const p = document.createElement('p');\n while (li.firstChild) p.appendChild(li.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n frag.appendChild(p);\n }\n}\n\ntype ListSegmentMiddle =\n | 'unwrap'\n | { tag: 'ul' | 'ol' };\n\n/** 将列表拆成前/中/后三段:中段改类型或取消列表 */\nfunction replaceListWithSegments(\n list: ListElement,\n before: HTMLLIElement[],\n middle: HTMLLIElement[],\n after: HTMLLIElement[],\n middleMode: ListSegmentMiddle,\n): void {\n const parent = list.parentNode;\n if (!parent) return;\n\n const origTag = list.tagName.toLowerCase() as 'ul' | 'ol';\n const frag = document.createDocumentFragment();\n\n appendListWithItems(frag, origTag, list, before);\n\n if (middleMode === 'unwrap') {\n appendUnwrappedItems(frag, middle);\n } else {\n appendListWithItems(frag, middleMode.tag, list, middle);\n }\n\n appendListWithItems(frag, origTag, list, after);\n\n parent.insertBefore(frag, list);\n list.remove();\n}\n\nfunction applyListTypeToWholeList(list: ListElement, wantUl: boolean): void {\n const inUl = list.tagName === 'UL';\n const toggleOff = wantUl === inUl;\n if (toggleOff) unwrapList(list);\n else convertListTag(list, wantUl ? 'ul' : 'ol');\n}\n\n/**\n * 切换列表类型。\n * - 折叠光标在列表内:整表转换/取消。\n * - 有选区:仅影响选区触及的 li;选满整表时仍整表处理。\n * wantUl=true 为无序;与当前类型相同时为取消列表。\n */\nexport function applyListCommandForSelection(\n root: HTMLElement,\n range: Range,\n wantUl: boolean,\n /** 非折叠选区在 DOM 变更前算好的 li;折叠时忽略 */\n affectedItems?: HTMLLIElement[],\n): boolean {\n if (range.collapsed) {\n const li = findListItem(range.startContainer, root);\n const list = li ? findListRoot(li) : null;\n if (!list) return false;\n applyListTypeToWholeList(list, wantUl);\n return true;\n }\n\n const items = affectedItems ?? getListItemsInRange(range, root);\n if (!items.length) return false;\n\n const byList = new Map<ListElement, HTMLLIElement[]>();\n for (const li of items) {\n const list = findListRoot(li);\n if (!list) continue;\n const group = byList.get(list) ?? [];\n group.push(li);\n byList.set(list, group);\n }\n\n const lists = sortByDocumentOrder([...byList.keys()]).reverse();\n\n for (const list of lists) {\n const selected = sortByDocumentOrder(byList.get(list) ?? []);\n const allItems = Array.from(list.children).filter(\n (c): c is HTMLLIElement => c.tagName === 'LI',\n );\n const selectedSet = new Set(selected);\n const allSelected =\n selected.length === allItems.length &&\n allItems.every((li) => selectedSet.has(li));\n\n if (allSelected) {\n applyListTypeToWholeList(list, wantUl);\n continue;\n }\n\n const inUl = list.tagName === 'UL';\n const toggleOff = wantUl === inUl;\n\n const indices = selected\n .map((li) => allItems.indexOf(li))\n .filter((i) => i >= 0)\n .sort((a, b) => a - b);\n if (!indices.length) continue;\n\n const firstIdx = indices[0]!;\n const lastIdx = indices[indices.length - 1]!;\n const before = allItems.slice(0, firstIdx);\n const middle = allItems.slice(firstIdx, lastIdx + 1);\n const after = allItems.slice(lastIdx + 1);\n\n if (toggleOff) {\n replaceListWithSegments(list, before, middle, after, 'unwrap');\n } else {\n replaceListWithSegments(list, before, middle, after, {\n tag: wantUl ? 'ul' : 'ol',\n });\n }\n }\n return true;\n}\n\n/** 取消列表:每个 li 拆成段落 */\nexport function unwrapList(list: HTMLUListElement | HTMLOListElement): void {\n const parent = list.parentNode;\n if (!parent) return;\n const fragment = document.createDocumentFragment();\n for (const child of Array.from(list.children)) {\n if (child.tagName !== 'LI') continue;\n const p = document.createElement('p');\n while (child.firstChild) p.appendChild(child.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n fragment.appendChild(p);\n }\n parent.insertBefore(fragment, list);\n list.remove();\n}\n\n/** 有序 ↔ 无序 */\nexport function convertListTag(\n list: HTMLUListElement | HTMLOListElement,\n tag: 'ul' | 'ol',\n): HTMLUListElement | HTMLOListElement {\n if (list.tagName.toLowerCase() === tag) return list;\n const next = document.createElement(tag) as HTMLUListElement | HTMLOListElement;\n while (list.firstChild) next.appendChild(list.firstChild);\n const indentAttr = list.getAttribute('data-sm-list-indent');\n if (indentAttr != null) next.setAttribute('data-sm-list-indent', indentAttr);\n const style = list.getAttribute('style');\n if (style) next.setAttribute('style', style);\n list.replaceWith(next);\n return next;\n}\n\nexport function detectListFormats(node: Node | null, root: HTMLElement): {\n unorderedList: boolean;\n orderedList: boolean;\n} {\n const li = findListItem(node, root);\n const list = li ? findListRoot(li) : null;\n return {\n unorderedList: list?.tagName === 'UL',\n orderedList: list?.tagName === 'OL',\n };\n}\n","import type { GlobalStyles } from '../types';\nimport { findListItem, findListRoot } from './inlineListEditing';\n\n/** 标记显式列表缩进;无此属性表示「默认」(画布 CSS + 导出时注入标准内联样式) */\nexport const LIST_INDENT_ATTR = 'data-sm-list-indent';\n\n/** 导出/邮件客户端默认缩进(与画布 1.5em @16px 对齐) */\nexport const LIST_INDENT_DEFAULT_PX = 24;\n\nexport const LIST_INDENT_SLIDER_MAX = 48;\n\nexport const LIST_INDENT_PRESETS_PX = [0, 16, 24, 32, 40] as const;\n\n/** 全局配置存库:内置默认 24 时不写入 listIndentDefaultPx */\nexport function normalizeGlobalListIndentStorage(px: number): number | undefined {\n const n = clampListIndent(px);\n return n === LIST_INDENT_DEFAULT_PX ? undefined : n;\n}\n\n/** null = 不设值(默认);number = 显式左缩进 px,0 为与正文左缘对齐 */\nexport type ListIndentValue = number | null;\n\nconst LIST_STYLE_KEYS = [\n 'padding-left',\n 'margin',\n 'margin-top',\n 'margin-bottom',\n 'margin-left',\n 'margin-right',\n 'list-style-position',\n 'list-style-type',\n] as const;\n\nconst LI_STYLE_KEYS = ['margin', 'padding'] as const;\n\nfunction parsePaddingLeftPx(raw: string | null | undefined): number | null {\n const s = (raw ?? '').trim();\n if (!s) return null;\n const m = s.match(/^(-?\\d+(?:\\.\\d+)?)(px)?$/i);\n if (!m) return null;\n const n = Number(m[1]);\n return Number.isFinite(n) ? Math.max(0, Math.round(n)) : null;\n}\n\nfunction readStyleProp(styleAttr: string | null, prop: string): string {\n if (!styleAttr) return '';\n const re = new RegExp(`(?:^|;)\\\\s*${prop}\\\\s*:\\\\s*([^;]+)`, 'i');\n const m = styleAttr.match(re);\n return m?.[1]?.trim() ?? '';\n}\n\nfunction mergeInlineStyle(\n el: HTMLElement,\n patch: Record<string, string | null>,\n managedKeys: readonly string[],\n): void {\n const map = new Map<string, string>();\n const prev = el.getAttribute('style') ?? '';\n for (const part of prev.split(';')) {\n const idx = part.indexOf(':');\n if (idx < 0) continue;\n const key = part.slice(0, idx).trim().toLowerCase();\n const val = part.slice(idx + 1).trim();\n if (key && val) map.set(key, val);\n }\n for (const key of managedKeys) map.delete(key);\n for (const [key, val] of Object.entries(patch)) {\n if (val == null || val === '') map.delete(key);\n else map.set(key, val);\n }\n const next = [...map.entries()].map(([k, v]) => `${k}:${v}`).join(';');\n if (next) el.setAttribute('style', next);\n else el.removeAttribute('style');\n}\n\nfunction stripManagedListStyles(list: HTMLUListElement | HTMLOListElement): void {\n mergeInlineStyle(list, {}, LIST_STYLE_KEYS);\n}\n\nfunction listMarkerType(list: HTMLUListElement | HTMLOListElement): string {\n return list.tagName === 'OL' ? 'decimal' : 'disc';\n}\n\nfunction applyExplicitListInline(\n list: HTMLUListElement | HTMLOListElement,\n paddingLeftPx: number,\n): void {\n mergeInlineStyle(\n list,\n {\n 'padding-left': `${paddingLeftPx}px`,\n margin: '0.5em 0',\n 'list-style-position': 'outside',\n 'list-style-type': listMarkerType(list),\n },\n LIST_STYLE_KEYS,\n );\n for (const li of Array.from(list.children)) {\n if (li.tagName !== 'LI') continue;\n mergeInlineStyle(li as HTMLLIElement, { margin: '0', padding: '0' }, LI_STYLE_KEYS);\n }\n}\n\n/** 读取当前列表缩进:无属性且无 padding-left 视为默认 null */\nexport function getListIndent(list: HTMLUListElement | HTMLOListElement): ListIndentValue {\n if (list.hasAttribute(LIST_INDENT_ATTR)) {\n const raw = list.getAttribute(LIST_INDENT_ATTR);\n if (raw == null || raw === 'default') return null;\n const n = parseInt(raw, 10);\n return Number.isFinite(n) ? clampListIndent(n) : null;\n }\n const fromStyle =\n parsePaddingLeftPx(list.style.paddingLeft) ??\n parsePaddingLeftPx(readStyleProp(list.getAttribute('style'), 'padding-left'));\n return fromStyle;\n}\n\nexport function clampListIndent(px: number): number {\n return Math.max(0, Math.min(LIST_INDENT_SLIDER_MAX, Math.round(px)));\n}\n\n/** 设置列表缩进;null 恢复为默认(移除显式标记与内联缩进) */\nexport function setListIndent(\n list: HTMLUListElement | HTMLOListElement,\n value: ListIndentValue,\n): void {\n if (value === null) {\n list.removeAttribute(LIST_INDENT_ATTR);\n stripManagedListStyles(list);\n return;\n }\n const px = clampListIndent(value);\n list.setAttribute(LIST_INDENT_ATTR, String(px));\n applyExplicitListInline(list, px);\n}\n\nexport function findListAtSelection(\n node: Node | null,\n root: HTMLElement,\n): HTMLUListElement | HTMLOListElement | null {\n const li = findListItem(node, root);\n return li ? findListRoot(li) : null;\n}\n\nfunction resolveExportPaddingPx(\n list: HTMLUListElement | HTMLOListElement,\n globalDefaultPx: number,\n): number {\n const explicit = getListIndent(list);\n if (explicit != null) return explicit;\n return globalDefaultPx;\n}\n\n/** 邮件设置中的列表默认缩进;未配置时返回内置 24px */\nexport function resolveGlobalListIndentPx(styles: GlobalStyles): number {\n const v = styles.listIndentDefaultPx;\n if (v === undefined) return LIST_INDENT_DEFAULT_PX;\n return clampListIndent(v);\n}\n\n/** 画布 CSS 变量值(px) */\nexport function globalListIndentCssVarValue(styles: GlobalStyles): string {\n return `${resolveGlobalListIndentPx(styles)}px`;\n}\n\n/** 编译后 HTML:统一 ul/ol 内联样式,剥离编辑态 data 属性 */\nexport function normalizeEmailListsInHtml(\n html: string,\n globalDefaultPx: number = LIST_INDENT_DEFAULT_PX,\n): string {\n const src = (html ?? '').trim();\n if (!src || typeof DOMParser === 'undefined') return html;\n\n const doc = new DOMParser().parseFromString(src, 'text/html');\n const lists = doc.querySelectorAll('ul, ol');\n if (!lists.length) return html;\n\n lists.forEach((node) => {\n const list = node as HTMLUListElement | HTMLOListElement;\n const px = resolveExportPaddingPx(list, globalDefaultPx);\n applyExplicitListInline(list, px);\n list.removeAttribute(LIST_INDENT_ATTR);\n });\n\n const serialized = doc.documentElement.outerHTML;\n const doctype = src.match(/<!DOCTYPE[^>]*>/i)?.[0];\n return doctype ? `${doctype}\\n${serialized}` : serialized;\n}\n","/**\n * 内容区 / 按钮等「布局宽度」解析:数字与无单位数字按 px;支持显式 `px` 与 `%`。\n */\n\nfunction coerceCssWidth(raw: unknown): string | undefined {\n if (raw == null || raw === '') return undefined;\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n const n = Math.round(raw);\n return n > 0 ? `${n}px` : undefined;\n }\n const s = String(raw).trim();\n if (!s) return undefined;\n if (/^\\d+(\\.\\d+)?%$/.test(s)) return s;\n if (/^\\d+(\\.\\d+)?px$/i.test(s)) return s.replace(/px$/i, 'px');\n if (/^\\d+(\\.\\d+)?$/.test(s)) return `${s}px`;\n return undefined;\n}\n\n/** 邮件 `meta.width` → CSS / mj-body 可用的宽度(非法则 600px) */\nexport function docContentWidthCss(raw: unknown): string {\n return coerceCssWidth(raw) ?? '600px';\n}\n\n/** 右栏输入解析存库:纯整数可存 number,其它存 string */\nexport function parseMetaWidthFromUserInput(input: string): number | string {\n const t = input.trim();\n if (!t) return 600;\n if (/^\\d+(\\.\\d+)?%$/.test(t)) return t;\n if (/^\\d+(\\.\\d+)?px$/i.test(t)) return t.replace(/PX$/i, 'px');\n if (/^\\d+$/.test(t)) return Number(t);\n if (/^\\d+\\.\\d+$/.test(t)) return `${t}px`;\n return t;\n}\n\nexport function metaWidthInputString(raw: unknown): string {\n if (raw == null) return '600';\n if (typeof raw === 'number' && Number.isFinite(raw)) return String(raw);\n return String(raw);\n}\n\n/** 按钮 / Section 等:可选宽度,空或 auto 表示不限制 */\nexport function blockButtonWidthCss(raw: unknown): string | undefined {\n if (raw == null) return undefined;\n const s = String(raw).trim();\n if (!s || s.toLowerCase() === 'auto') return undefined;\n return coerceCssWidth(s);\n}\n\n/** Section 右栏输入;空字符串表示清除宽度 */\nexport function parseSectionWidthFromUserInput(input: string): string | number | undefined {\n const t = input.trim();\n if (!t) return undefined;\n if (/^\\d+(\\.\\d+)?%$/.test(t)) return t;\n if (/^\\d+(\\.\\d+)?px$/i.test(t)) return t.replace(/PX$/i, 'px');\n if (/^\\d+$/.test(t)) return Number(t);\n if (/^\\d+\\.\\d+$/.test(t)) return `${t}px`;\n return t;\n}\n\nexport function sectionWidthInputString(raw: unknown): string {\n if (raw == null || raw === '') return '';\n if (typeof raw === 'number' && Number.isFinite(raw)) return String(raw);\n return String(raw);\n}\n","/** 极简 DOM 创建工具,避免引入 hyperscript 等额外依赖。 */\n\ntype Attrs = Record<string, string | number | boolean | EventListener | undefined | null>;\n\nexport function h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: (Node | string | null | undefined | false)[] = [],\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (v == null || v === false) continue;\n if (k === 'class') el.className = String(v);\n else if (k === 'style') el.setAttribute('style', String(v));\n else if (k === 'html') el.innerHTML = String(v);\n else if (k.startsWith('on') && typeof v === 'function') {\n el.addEventListener(k.slice(2).toLowerCase(), v as EventListener);\n } else if (typeof v === 'boolean') {\n if (v) el.setAttribute(k, '');\n } else {\n el.setAttribute(k, String(v));\n }\n }\n for (const child of children) {\n if (child == null || child === false) continue;\n el.appendChild(typeof child === 'string' ? document.createTextNode(child) : child);\n }\n return el;\n}\n\nexport function clear(el: HTMLElement) {\n while (el.firstChild) el.removeChild(el.firstChild);\n}\n\nexport function escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nexport function escapeAttr(s: string): string {\n return escapeHtml(s);\n}\n","/** 全局与各组件字重:固定五档,便于右栏平铺或步进滑块 */\nexport const FONT_WEIGHT_STEP_VALUES = ['300', '400', '500', '600', '700'] as const;\nexport type FontWeightStep = (typeof FONT_WEIGHT_STEP_VALUES)[number];\n\nexport const FONT_WEIGHT_STEP_OPTIONS: { label: string; value: string }[] = FONT_WEIGHT_STEP_VALUES.map(\n (v) => ({ label: v, value: v }),\n);\n\n/** 将任意历史写法映射到最近一档(normal→400,bold→700 等) */\nexport function normalizeFontWeightStep(raw: string | undefined | null): FontWeightStep {\n const s = String(raw ?? '400').trim().toLowerCase();\n if (s === '' || s === 'normal' || s === 'regular') return '400';\n if (s === 'bold' || s === 'bolder') return '700';\n if (s === 'lighter') return '300';\n const match = /^(\\d+)(\\.\\d+)?$/.exec(s);\n if (match) {\n const n = parseInt(match[1], 10);\n const steps = [300, 400, 500, 600, 700];\n let best: FontWeightStep = '400';\n let bestD = Infinity;\n for (const st of steps) {\n const d = Math.abs(n - st);\n if (d < bestD) {\n bestD = d;\n best = String(st) as FontWeightStep;\n }\n }\n return best;\n }\n return '400';\n}\n","import type { GlobalStyles } from '../types';\nimport { normalizeFontWeightStep } from './fontWeightSteps';\n\n/**\n * mj-column 编译结果外层会有 `font-size:0`(多列 inline-block 间距技巧),\n * mj-raw 内若未在祖先上重置字号,li/p 等会继承 0 导致「看不见」。\n * 在包裹 td 上对齐邮件全局正文样式即可规避。\n */\nexport interface MjRawCellTypography {\n fontSize: string;\n lineHeight: string;\n color: string;\n fontFamily: string;\n fontWeight: string;\n}\n\nexport function mjRawCellTypographyFromStyles(s: GlobalStyles): MjRawCellTypography {\n return {\n fontSize: (s.fontSize || '16px').trim(),\n lineHeight: (s.lineHeight || '1.25').trim(),\n color: (s.color || '#433f3f').trim(),\n fontFamily: (s.fontFamily || 'sans-serif').trim(),\n fontWeight: normalizeFontWeightStep(s.fontWeight),\n };\n}\n\n/** style=\"...\" 为双引号属性,避免值内双引号破坏解析 */\nfunction cssForDoubleQuotedAttr(value: string): string {\n return value.replace(/\"/g, \"'\").replace(/\\s+/g, ' ').trim();\n}\n\nfunction buildMjRawTdStyle(paddingCss: string, typo: MjRawCellTypography): string {\n const fontSize = cssForDoubleQuotedAttr(typo.fontSize);\n const lineHeight = cssForDoubleQuotedAttr(typo.lineHeight);\n const color = cssForDoubleQuotedAttr(typo.color);\n const fontFamily = cssForDoubleQuotedAttr(typo.fontFamily);\n const fontWeight = cssForDoubleQuotedAttr(typo.fontWeight);\n return `padding:${paddingCss};font-size:${fontSize};line-height:${lineHeight};color:${color};font-family:${fontFamily};font-weight:${fontWeight}`;\n}\n\n/**\n * mj-column 编译结果是表格布局,列内若用 mj-raw 直接输出 div/ul 等块级 HTML,\n * 会变成非法 table 子节点,浏览器/邮件里常表现为整块空白。\n * 用 presentation table + 单格 td 包住用户 HTML,与 mj-text 等组件结构一致。\n */\nexport function mjRawEmailTableWrap(\n paddingCss: string,\n cellInnerHtml: string,\n typo: MjRawCellTypography,\n): string {\n const tdStyle = buildMjRawTdStyle(paddingCss, typo);\n return `<mj-raw>\n<table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\">\n <tbody>\n <tr>\n <td style=\"${tdStyle}\">\n ${cellInnerHtml}\n </td>\n </tr>\n </tbody>\n</table>\n</mj-raw>`;\n}\n\n/**\n * 锁定片段插入 mj-column 时的规范化。\n *\n * mj-column 内只允许 mj-* 节点(或 mj-raw 包一层 HTML)。\n * 用户若在「编辑组件代码」里只保存了 `<ul>...</ul>` 等裸 HTML,直接下发会导致 MJML 编译失败、预览空白。\n */\nexport function wrapLockedMjmlForMjColumn(fragment: string, typo: MjRawCellTypography): string {\n const lead = fragment.trimStart();\n if (!lead) return '<mj-raw><!-- empty --></mj-raw>';\n if (/^<mj-/i.test(lead)) return fragment;\n const t = fragment.trim();\n // 无 props 上下文,内边距交给 0;用户可在片段内自行写 padding\n return mjRawEmailTableWrap('0', t, typo);\n}\n\n/** 旧版 HTML 块/锁定片段只有 mj-raw 包 div 或裸标签,编译进列后表格结构非法;统一包一层 presentation table。 */\nexport function normalizeHtmlBlockLockedMjmlForCompile(\n fragment: string,\n paddingCss: string,\n typo: MjRawCellTypography,\n): string {\n const raw = fragment.trim();\n const mj = raw.match(/^<mj-raw\\b[^>]*>([\\s\\S]*)<\\/mj-raw\\s*>$/i);\n if (!mj) return fragment;\n let inner = mj[1].trim();\n const divStrip = inner.match(/^\\s*<div\\b[^>]*style=\"[^\"]*\"[^>]*>([\\s\\S]*)<\\/div>\\s*$/i);\n if (divStrip) inner = divStrip[1].trim();\n if (/^\\s*<table\\b/i.test(inner)) return raw;\n return mjRawEmailTableWrap(paddingCss, inner, typo);\n}\n\n/** HTML 块内容是否误含 MJML 标签(应只写 HTML,MJML 标签在 mj-raw 内不会被编译)。 */\nexport function htmlContainsMjmlTags(html: string): boolean {\n return /<mj-[a-z]/i.test(String(html ?? ''));\n}\n\n/** 从 `<tag...>` 之后起,提取到与之配对的 `</tag>` 之前的完整内容(支持同名标签嵌套)。 */\nfunction extractHtmlUntilMatchingCloseTag(\n html: string,\n contentStart: number,\n tagName: string,\n): string | null {\n const openRe = new RegExp(`<${tagName}\\\\b`, 'gi');\n const closeRe = new RegExp(`</${tagName}\\\\s*>`, 'gi');\n let depth = 1;\n let i = contentStart;\n\n while (i < html.length) {\n openRe.lastIndex = i;\n closeRe.lastIndex = i;\n const nextOpen = openRe.exec(html);\n const nextClose = closeRe.exec(html);\n if (!nextClose) return null;\n\n if (nextOpen && nextOpen.index < nextClose.index) {\n depth++;\n i = nextOpen.index + nextOpen[0].length;\n continue;\n }\n\n depth--;\n if (depth === 0) return html.slice(contentStart, nextClose.index);\n i = nextClose.index + nextClose[0].length;\n }\n\n return null;\n}\n\n/** 提取最外层 `<table>...</table>` 内的 HTML(不含 table 标签本身)。 */\nfunction extractOutermostTableInner(html: string): string | null {\n const open = html.match(/^(\\s*)<table\\b[^>]*>/i);\n if (!open) return null;\n const contentStart = open[0].length;\n return extractHtmlUntilMatchingCloseTag(html, contentStart, 'table');\n}\n\n/** 从 presentation table 中提取最外层包裹 td 的完整内层 HTML(支持嵌套 table/td)。 */\nfunction innerFromPresentationTable(html: string): string | null {\n const trimmed = html.trim();\n if (!/^\\s*<table\\b/i.test(trimmed)) return null;\n\n const tableInner = extractOutermostTableInner(trimmed);\n if (tableInner == null) return null;\n\n const tdOpen = tableInner.match(/<td\\b[^>]*>/i);\n if (!tdOpen || tdOpen.index === undefined) return null;\n\n const contentStart = tdOpen.index + tdOpen[0].length;\n return extractHtmlUntilMatchingCloseTag(tableInner, contentStart, 'td');\n}\n\n/**\n * 从锁定 MJML 片段提取可在画布内渲染的 HTML;无法识别时返回 null(回退源码视图)。\n */\nexport function extractPreviewHtmlFromLockedMjml(lockedMjml: string): string | null {\n const raw = String(lockedMjml ?? '').trim();\n if (!raw) return '';\n\n const mjText = raw.match(/^<mj-text\\b[^>]*>([\\s\\S]*)<\\/mj-text\\s*>$/i);\n if (mjText) return mjText[1].trim();\n\n const mjButton = raw.match(/^<mj-button\\b[^>]*>([\\s\\S]*)<\\/mj-button\\s*>$/i);\n if (mjButton) {\n const label = mjButton[1].trim();\n if (!label) return '';\n return `<span style=\"display:inline-block;padding:12px 24px;background:#ff5a00;color:#fff;border-radius:4px;font-size:14px;\">${label}</span>`;\n }\n\n const mjRaw = raw.match(/^<mj-raw\\b[^>]*>([\\s\\S]*)<\\/mj-raw\\s*>$/i);\n if (mjRaw) {\n let body = mjRaw[1].trim();\n if (/^\\s*<table\\b/i.test(body)) {\n const tdInner = innerFromPresentationTable(body);\n if (tdInner != null) return tdInner;\n }\n return body;\n }\n\n if (!/^<mj-/i.test(raw)) return raw;\n\n return null;\n}\n\nexport interface BlockPaddingBox {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/** 锁定块画布预览用的默认内边距(与文本块一致:水平 0,由 section 承担版心 gutter)。 */\nexport function defaultPaddingForLockedBlock(\n _blockType: string,\n _lockedMjml: string,\n props: {\n paddingTop?: number;\n paddingRight?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n },\n): BlockPaddingBox {\n return {\n top: Number(props.paddingTop ?? 8),\n right: Number(props.paddingRight ?? 0),\n bottom: Number(props.paddingBottom ?? 8),\n left: Number(props.paddingLeft ?? 0),\n };\n}\n\n/** 锁定块在画布上的渲染结果:preview 为 WYSIWYG HTML,source 为无法解析时的源码回退。 */\nexport function resolveLockedMjmlCanvasContent(\n lockedMjml: string,\n padding: BlockPaddingBox,\n): { mode: 'preview'; html: string } | { mode: 'source'; source: string } {\n const previewInner = extractPreviewHtmlFromLockedMjml(lockedMjml);\n const pad = `${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px`;\n\n if (previewInner !== null) {\n if (!previewInner) {\n return {\n mode: 'preview',\n html: `<div style=\"padding:${pad};color:#9ca3af;font-size:13px;\">(无内容)</div>`,\n };\n }\n return {\n mode: 'preview',\n html: `<div style=\"padding:${pad};min-height:1em;\">${previewInner}</div>`,\n };\n }\n\n return { mode: 'source', source: lockedMjml };\n}\n\n/** @deprecated 使用 resolveLockedMjmlCanvasContent */\nexport function htmlFragmentForLockedHtmlBlockCanvas(\n lockedMjml: string,\n padding: BlockPaddingBox,\n): string {\n const resolved = resolveLockedMjmlCanvasContent(lockedMjml, padding);\n return resolved.mode === 'preview' ? resolved.html : resolved.source;\n}\n","import type { Registry } from '../registry/registry';\nimport type { Column, EmailDoc, RenderContext, Section, SectionLayout } from '../types';\nimport { getSectionDynamicVariantKey, sectionMjClassName } from '../utils/dynamicVariantKey';\nimport { blockButtonWidthCss, docContentWidthCss } from '../utils/contentWidth';\nimport { escapeAttr } from '../utils/dom';\nimport { normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport {\n mjRawCellTypographyFromStyles,\n normalizeHtmlBlockLockedMjmlForCompile,\n wrapLockedMjmlForMjColumn,\n} from '../utils/lockedMjml';\n\n/**\n * Schema → MJML 字符串。\n *\n * 不直接编译成 HTML——HTML 编译交给 `mjml-browser`,\n * 这一层只负责把数据模型翻译成 MJML 语义化标签。\n */\nexport function docToMjml(doc: EmailDoc, registry: Registry): string {\n const ctx: RenderContext = { doc, engine: 'mjml' };\n const attrs = doc.styles;\n\n const sections = doc.sections.map((s) => sectionToMjml(s, registry, ctx)).join('\\n');\n\n return `<mjml>\n <mj-head>\n <mj-title>${escapeAttr(doc.meta.subject || '')}</mj-title>\n ${doc.meta.preheader ? `<mj-preview>${escapeAttr(doc.meta.preheader)}</mj-preview>` : ''}\n <mj-attributes>\n <mj-all font-family=\"${escapeAttr(attrs.fontFamily)}\" />\n <mj-text font-size=\"${escapeAttr(attrs.fontSize)}\" font-weight=\"${escapeAttr(normalizeFontWeightStep(attrs.fontWeight))}\" color=\"${escapeAttr(attrs.color)}\" line-height=\"${escapeAttr(attrs.lineHeight ?? '1.25')}\" />\n <mj-class name=\"link\" color=\"${escapeAttr(attrs.linkColor)}\" />\n </mj-attributes>\n <mj-style>\n a { color: ${escapeAttr(attrs.linkColor)}; }\n${sectionWidthConstraintCss(doc)}\n </mj-style>\n </mj-head>\n <mj-body background-color=\"${escapeAttr(attrs.backgroundColor)}\" width=\"${escapeAttr(docContentWidthCss(doc.meta.width))}\">\n${sections}\n </mj-body>\n</mjml>`;\n}\n\n/** 为设置了宽度的 Section 生成 max-width 规则(css-class 挂在 mj-section 上) */\nfunction sectionWidthConstraintCss(doc: EmailDoc): string {\n return doc.sections\n .map((s) => {\n const w = blockButtonWidthCss(s.attrs.width);\n if (!w) return '';\n const cls = sectionMjClassName(s.id);\n return ` .${cls} { max-width: ${w} !important; width: 100% !important; margin-left: auto !important; margin-right: auto !important; }`;\n })\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction sectionToMjml(section: Section, registry: Registry, ctx: RenderContext): string {\n const a = section.attrs;\n const padding = [a.paddingTop, a.paddingRight, a.paddingBottom, a.paddingLeft]\n .map((v) => `${v ?? 0}px`)\n .join(' ');\n const bg = a.backgroundColor ? ` background-color=\"${escapeAttr(a.backgroundColor)}\"` : '';\n const secW = blockButtonWidthCss(a.width);\n const dvKey = getSectionDynamicVariantKey(section);\n const secCls =\n secW || dvKey ? ` css-class=\"${escapeAttr(sectionMjClassName(section.id))}\"` : '';\n const widths = layoutWidths(section.layout);\n const gapPx = Math.max(0, section.attrs.columnGap ?? 0);\n\n const columns = section.columns\n .map((col, i) =>\n columnToMjml(col, widths[i], i, section.columns.length, gapPx, registry, ctx),\n )\n .join('\\n');\n\n /** 多列 + 显式开启时包 mj-group,阻止小屏列堆叠(MJML 官方语义) */\n const multiCol = section.columns.length > 1;\n const grouped =\n multiCol && section.attrs.preserveColumnsOnMobile === true\n ? ` <mj-group>\\n${indent(columns, 2)}\\n </mj-group>`\n : columns;\n\n return ` <mj-section padding=\"${padding}\"${bg}${secCls}>\n${grouped}\n </mj-section>`;\n}\n\nfunction columnToMjml(\n column: Column,\n width: string,\n columnIndex: number,\n columnCount: number,\n columnGapPx: number,\n registry: Registry,\n ctx: RenderContext,\n): string {\n const a = column.attrs;\n const va = a.verticalAlign ? ` vertical-align=\"${a.verticalAlign}\"` : '';\n const bg = a.backgroundColor ? ` background-color=\"${escapeAttr(a.backgroundColor)}\"` : '';\n\n let gapPad = '';\n if (columnCount > 1 && columnGapPx > 0) {\n const half = columnGapPx / 2;\n const pl = columnIndex > 0 ? `${half}px` : '0px';\n const pr = columnIndex < columnCount - 1 ? `${half}px` : '0px';\n gapPad = ` padding=\"0px ${pr} 0px ${pl}\"`;\n }\n\n const rawTypo = mjRawCellTypographyFromStyles(ctx.doc.styles);\n const blocks = column.blocks\n .map((b) => {\n if (b.lockedMjml) {\n let frag = wrapLockedMjmlForMjColumn(b.lockedMjml, rawTypo);\n if (b.type === 'html') {\n const p = b.props as {\n paddingTop?: number;\n paddingRight?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n };\n const pad = `${Number(p.paddingTop ?? 8)}px ${Number(p.paddingRight ?? 0)}px ${Number(p.paddingBottom ?? 8)}px ${Number(p.paddingLeft ?? 0)}px`;\n frag = normalizeHtmlBlockLockedMjmlForCompile(frag, pad, rawTypo);\n }\n return indent(frag, 8);\n }\n const def = registry.require(b.type);\n return indent(def.toMjml(b.props, ctx), 8);\n })\n .join('\\n');\n\n return ` <mj-column width=\"${width}\"${va}${bg}${gapPad}>\n${blocks || ' <!-- empty column -->'}\n </mj-column>`;\n}\n\nfunction layoutWidths(layout: SectionLayout): string[] {\n // 内容宽度 600,给到百分比即可,让 MJML 自己处理像素分配\n const parts = layout.split('-').map(Number);\n const total = parts.reduce((s, x) => s + x, 0);\n return parts.map((p) => `${((p / total) * 100).toFixed(2)}%`);\n}\n\nfunction indent(text: string, n: number): string {\n const pad = ' '.repeat(n);\n return text\n .split('\\n')\n .map((l) => (l ? pad + l : l))\n .join('\\n');\n}\n","import mjmlCompile from 'mjml-browser';\nimport type { EmailDoc, RenderEngine, Variable } from '../types';\nimport type { Registry } from '../registry/registry';\nimport { annotateDynamicVariantHtmlAttributes } from '../utils/dynamicVariantHtml';\nimport {\n normalizeEmailListsInHtml,\n resolveGlobalListIndentPx,\n} from '../utils/emailListStyles';\nimport { docToMjml } from './mjml';\n\nexport interface RenderResult {\n mjml: string;\n html: string;\n errors: { message: string }[];\n}\n\nexport interface RenderOptions {\n /** 渲染引擎,目前仅 'mjml';'table' 预留作将来直输 table HTML。 */\n engine?: RenderEngine;\n /**\n * 是否把 {{var}} 替换为变量的 sample 值。\n * 设计态预览默认不替换,保持占位符;仅当变量显式配置了 sample 且调用方传 true 时才替换。\n */\n withSampleVariables?: boolean;\n}\n\nexport function renderDoc(\n doc: EmailDoc,\n registry: Registry,\n opts: RenderOptions = {},\n): RenderResult {\n const engine: RenderEngine = opts.engine ?? 'mjml';\n\n if (engine !== 'mjml') {\n // 预留:将来可在此分支实现纯 table 输出。\n throw new Error(`渲染引擎暂未实现: ${engine}`);\n }\n\n const mjml = docToMjml(doc, registry);\n\n const compiled = mjmlCompile(mjml, {\n validationLevel: 'soft',\n keepComments: false,\n });\n\n let html = compiled.html;\n html = annotateDynamicVariantHtmlAttributes(html, doc);\n html = normalizeEmailListsInHtml(html, resolveGlobalListIndentPx(doc.styles));\n if (opts.withSampleVariables) {\n html = replaceVariables(html, doc.variables);\n }\n\n return {\n mjml,\n html,\n errors: (compiled.errors || []).map((e: any) => ({\n message: e.formattedMessage ?? e.message ?? String(e),\n })),\n };\n}\n\n/**\n * 用 sample 值替换 `{{var.name}}` 占位符。仅做最简单的字符串替换,\n * 不做任何沙箱式表达式求值(邮件场景里下游模板引擎会再处理一次)。\n */\nexport function replaceVariables(text: string, vars: Variable[]): string {\n if (!vars.length) return text;\n return text.replace(/\\{\\{\\s*([^}\\s]+)\\s*\\}\\}/g, (raw, key) => {\n const v = vars.find((x) => x.key === key);\n if (v && v.sample != null) return v.sample;\n return raw;\n });\n}\n","let _counter = 0;\n\n/**\n * 生成短 ID。无需密码学强度——仅用于文档内引用。\n * 使用 base36 + 自增计数,保证同 doc 内单调,便于 diff 调试。\n */\nexport function uid(prefix = 'id'): string {\n _counter += 1;\n const ts = Date.now().toString(36).slice(-4);\n const rand = Math.floor(Math.random() * 36 ** 3)\n .toString(36)\n .padStart(3, '0');\n return `${prefix}_${ts}${rand}${_counter.toString(36)}`;\n}\n","import type { Block, Column, EmailDoc, Section, SectionLayout, Selection } from '../types';\nimport { uid } from '../utils/id';\n\n/** 文档变更通知来源(右栏等可按来源决定是否保留焦点) */\nexport type DocChangedDetail = { source: 'mutate' | 'history' | 'replace' };\n\ntype Listener = (detail?: DocChangedDetail) => void;\ntype SelectionListener = () => void;\n\n/**\n * 极小的不可变 store + 发布订阅 + history。\n * 所有变更都通过 `update(fn)` 走结构化克隆,保证:\n * - 引用不可变(外部 memo/diff 友好)\n * - 变更原子(一个 update 一条 history)\n */\nexport class Store {\n private _doc: EmailDoc;\n private _selection: Selection | null = null;\n private _listeners: Set<Listener> = new Set();\n private _selectionListeners: Set<SelectionListener> = new Set();\n private _past: EmailDoc[] = [];\n private _future: EmailDoc[] = [];\n private _historyLimit = 100;\n\n constructor(initial: EmailDoc) {\n this._doc = initial;\n }\n\n get doc(): EmailDoc {\n return this._doc;\n }\n\n get selection(): Selection | null {\n return this._selection;\n }\n\n subscribe(fn: Listener): () => void {\n this._listeners.add(fn);\n return () => this._listeners.delete(fn);\n }\n\n subscribeSelection(fn: SelectionListener): () => void {\n this._selectionListeners.add(fn);\n return () => this._selectionListeners.delete(fn);\n }\n\n setSelection(sel: Selection | null) {\n this._selection = sel;\n this._selectionListeners.forEach((l) => l());\n }\n\n /**\n * 应用一次变更。`mutator` 收到一份可直接修改的 draft(结构化克隆得来)。\n * 修改完毕后用新对象替换当前 doc,并把旧 doc 入历史。\n */\n update(mutator: (draft: EmailDoc) => void, opts: { silent?: boolean } = {}) {\n const draft = structuredClone(this._doc);\n mutator(draft);\n this._past.push(this._doc);\n if (this._past.length > this._historyLimit) this._past.shift();\n this._future = [];\n this._doc = draft;\n if (!opts.silent) this._notify('mutate');\n }\n\n /** 替换整个文档(如外部 setValue),会清空 history。 */\n replace(doc: EmailDoc) {\n this._past = [];\n this._future = [];\n this._doc = doc;\n this._notify('replace');\n }\n\n undo(): boolean {\n const prev = this._past.pop();\n if (!prev) return false;\n this._future.push(this._doc);\n this._doc = prev;\n this._notify('history');\n return true;\n }\n\n redo(): boolean {\n const next = this._future.pop();\n if (!next) return false;\n this._past.push(this._doc);\n this._doc = next;\n this._notify('history');\n return true;\n }\n\n canUndo() {\n return this._past.length > 0;\n }\n\n canRedo() {\n return this._future.length > 0;\n }\n\n private _notify(source: DocChangedDetail['source']) {\n const detail: DocChangedDetail = { source };\n this._listeners.forEach((l) => l(detail));\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* 便捷的查询/变更助手 */\n/* -------------------------------------------------------------------------- */\n\nexport function findSection(doc: EmailDoc, sectionId: string): Section | undefined {\n return doc.sections.find((s) => s.id === sectionId);\n}\n\nexport function findBlockLocation(\n doc: EmailDoc,\n blockId: string,\n): { section: Section; columnIndex: number; block: Block } | undefined {\n for (const section of doc.sections) {\n for (let i = 0; i < section.columns.length; i += 1) {\n const col = section.columns[i];\n const blk = col.blocks.find((b) => b.id === blockId);\n if (blk) return { section, columnIndex: i, block: blk };\n }\n }\n return undefined;\n}\n\n/**\n * 若指定 Section 的每一列都没有 Block,则从文档中移除该 Section。\n * 在内容块被删除或拖走后调用,可与 `autoWrapSection` 搭配,避免单列 Section 在唯一块离场后仍残留空壳;\n * 多列 Section 始终保留,便于继续向各列拖入内容。\n * 仅处理刚变空的 Section,不会误删用户事先添加、尚未拖入内容的空布局。\n */\nexport function pruneSectionIfEmpty(draft: EmailDoc, sectionId: string) {\n const sec = draft.sections.find((s) => s.id === sectionId);\n if (!sec) return;\n if (sec.columns.length > 1) return;\n const isEmpty = sec.columns.every((col) => col.blocks.length === 0);\n if (!isEmpty) return;\n draft.sections = draft.sections.filter((s) => s.id !== sectionId);\n}\n\n/** @deprecated 请改用 {@link pruneSectionIfEmpty},避免误删多个空 Section */\nexport function pruneEmptySections(draft: EmailDoc) {\n draft.sections = draft.sections.filter((sec) =>\n sec.columns.some((col) => col.blocks.length > 0),\n );\n}\n\n/** 多列 Section 的列布局(左栏拖入默认 `1-1`,右栏可切换列数/比例) */\nexport const MULTI_COLUMN_LAYOUTS = ['1-1', '1-2', '2-1', '1-1-1'] as const;\nexport type MultiColumnLayout = (typeof MULTI_COLUMN_LAYOUTS)[number];\n\n/** @deprecated 使用 MULTI_COLUMN_LAYOUTS */\nexport const TWO_COLUMN_LAYOUTS = ['1-1', '1-2', '2-1'] as const;\nexport type TwoColumnLayout = (typeof TWO_COLUMN_LAYOUTS)[number];\n\nexport function isMultiColumnLayout(layout: SectionLayout): layout is MultiColumnLayout {\n return (\n layout === '1-1' || layout === '1-2' || layout === '2-1' || layout === '1-1-1'\n );\n}\n\n/** @deprecated 使用 isMultiColumnLayout */\nexport function isTwoColumnLayout(layout: SectionLayout): layout is TwoColumnLayout {\n return layout === '1-1' || layout === '1-2' || layout === '2-1';\n}\n\n/** 更新 layout;列数变化时增删列,被删列内块并入最后一列 */\nexport function setSectionLayout(section: Section, layout: SectionLayout): void {\n const nextCols = layout.split('-').length;\n const curCols = section.columns.length;\n if (nextCols === curCols) {\n section.layout = layout;\n return;\n }\n if (nextCols > curCols) {\n for (let i = curCols; i < nextCols; i++) {\n section.columns.push({ id: uid('col'), attrs: {}, blocks: [] });\n }\n } else {\n const removed = section.columns.splice(nextCols);\n const last = section.columns[nextCols - 1];\n if (last) {\n for (const col of removed) last.blocks.push(...col.blocks);\n }\n }\n section.layout = layout;\n}\n\nexport function createSection(layout: SectionLayout): Section {\n const colCount = layout.split('-').length;\n const columns: Column[] = Array.from({ length: colCount }, () => ({\n id: uid('col'),\n attrs: {},\n blocks: [],\n }));\n return {\n id: uid('sec'),\n type: 'section',\n layout,\n attrs: {\n /** 默认左右 16:版心内边距由节承担;上下 0 由内容块堆叠节奏(常见 8)控制 */\n paddingTop: 0,\n paddingRight: 16,\n paddingBottom: 0,\n paddingLeft: 16,\n },\n columns,\n };\n}\n","import type { Variable } from '../types';\n\nexport type VariableKind = 'text' | 'link' | 'image';\n\n/** 从 Mustache token 提取 key,如 `{{username}}` → `username` */\nexport function tokenToVariableKey(token: string): string {\n const t = String(token || '').trim();\n const m = t.match(/^\\{\\{\\s*([^}]+?)\\s*\\}\\}$/);\n return (m?.[1] || t.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '')).trim();\n}\n\nexport function variablePlaceholder(key: string): string {\n return `{{${key}}}`;\n}\n\n/** 无显式 sample 时保留 Mustache 占位符;仅当宿主传入 sample 才用于可选的示例替换。 */\nexport function defaultVariableSample(v: Pick<Variable, 'key' | 'label' | 'kind' | 'sample'>): string {\n if (v.sample != null && String(v.sample).trim() !== '') return String(v.sample);\n const key = v.key?.trim() || tokenToVariableKey(String(v.key));\n return variablePlaceholder(key);\n}\n\n/** 规范化 Variable(补 kind、sample) */\nexport function normalizeVariable(v: Variable): Variable {\n const key = v.key?.trim() || tokenToVariableKey(String(v.key));\n const kind = v.kind ?? 'text';\n return {\n ...v,\n key,\n kind,\n sample: defaultVariableSample({ ...v, key, kind }),\n };\n}\n\nexport function buildLinkVariableHtml(token: string, linkColor: string): string {\n const safeHref = token.replace(/\"/g, '&quot;');\n const safeText = token\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n return `<a href=\"${safeHref}\" style=\"color:${linkColor} !important;text-decoration:underline;\">${safeText}</a>`;\n}\n\nexport interface BodyVariableInsert {\n content: string;\n asHtml: boolean;\n}\n\n/** 插入变量 key(`{{key}}`) */\nexport function buildBodyVariableKeyInsert(v: Variable): BodyVariableInsert {\n const normalized = normalizeVariable(v);\n return { content: variablePlaceholder(normalized.key), asHtml: false };\n}\n\n/** 插入链接 / 图片等元素片段 */\nexport function buildBodyVariableElementInsert(\n v: Variable,\n options?: { linkColor?: string; token?: string },\n): BodyVariableInsert {\n const normalized = normalizeVariable(v);\n const token = options?.token?.trim() || variablePlaceholder(normalized.key);\n const linkColor = options?.linkColor?.trim() || '#ff5a00';\n\n if (normalized.kind === 'link') {\n return {\n content: buildLinkVariableHtml(token, linkColor),\n asHtml: true,\n };\n }\n if (normalized.kind === 'image') {\n const alt = tokenToVariableKey(token);\n return {\n content: `<img src=\"${token.replace(/\"/g, '&quot;')}\" alt=\"${alt.replace(/\"/g, '&quot;')}\" width=\"100\" style=\"max-width:100%;height:auto;display:block;border:0;\" />`,\n asHtml: true,\n };\n }\n return buildBodyVariableKeyInsert(normalized);\n}\n\n/** @deprecated 使用 buildBodyVariableKeyInsert / buildBodyVariableElementInsert */\nexport function buildBodyVariableInsert(\n v: Variable,\n options?: { linkColor?: string; token?: string },\n): BodyVariableInsert {\n const normalized = normalizeVariable(v);\n if (normalized.kind === 'link' || normalized.kind === 'image') {\n return buildBodyVariableElementInsert(normalized, options);\n }\n return buildBodyVariableKeyInsert(normalized);\n}\n","/**\n * 向富文本 HTML 末尾「行内」追加内容,避免落在 `</p>` 外产生换行。\n * 无块级标签时包一层 `<p style=\"margin:0;\">`。\n */\nexport function appendInlineToRichHtml(html: string, insert: string): string {\n const trimmed = String(html ?? '').trim();\n if (!insert) return trimmed;\n if (!trimmed) return `<p style=\"margin:0;\">${insert}</p>`;\n\n const blockClose = trimmed.match(/<\\/(p|div|h[1-6]|li)>\\s*$/i);\n if (blockClose && blockClose.index != null) {\n const idx = blockClose.index;\n return trimmed.slice(0, idx) + insert + trimmed.slice(idx);\n }\n return trimmed + insert;\n}\n","import type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { EmailDoc } from '../types';\nimport { DYNAMIC_VARIANT_HTML_ATTR } from './dynamicVariantKey';\nimport {\n dynamicVariantPlaceholder,\n getSectionDynamicVariantKey,\n isDynamicVariantSection,\n} from './dynamicVariantKey';\n\nexport {\n DYNAMIC_VARIANT_HTML_ATTR,\n dynamicVariantPlaceholder,\n getSectionDynamicVariantKey,\n isDynamicVariantSection,\n sectionMjClassName,\n} from './dynamicVariantKey';\n\n/** 仅编译某一 Section,返回邮件 body 内 HTML 片段 */\nexport function renderSectionBodyHtml(\n doc: EmailDoc,\n sectionId: string,\n registry: Registry,\n): string {\n const section = doc.sections.find((s) => s.id === sectionId);\n if (!section) return '';\n const mini: EmailDoc = { ...doc, sections: [section] };\n const { html } = renderDoc(mini, registry, { withSampleVariables: false });\n try {\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n return (parsed.body?.innerHTML || '').trim();\n } catch {\n return '';\n }\n}\n\nexport interface ExtractDynamicVariantSlotsResult {\n html: string;\n variants: Record<string, string>;\n}\n\nfunction replaceVariantMarkerInHtml(\n html: string,\n key: string,\n): { html: string; variantHtml: string } | null {\n try {\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n const el = parsed.querySelector(`[${DYNAMIC_VARIANT_HTML_ATTR}=\"${key}\"]`);\n if (!el) return null;\n const variantHtml = el.outerHTML || '';\n const token = dynamicVariantPlaceholder(key);\n el.replaceWith(parsed.createTextNode(token));\n const head = parsed.head?.innerHTML || '';\n const body = parsed.body?.innerHTML || '';\n return { html: `${head}${body}`, variantHtml };\n } catch {\n return null;\n }\n}\n\n/**\n * 将带 `dynamicVariantKey` 的 Section 从全文 HTML 中替换为占位符,并返回各 key 的编译 HTML。\n * 优先使用导出 HTML 上的 `data-dv=\"{key}\"` 标记。\n */\nexport function extractDynamicVariantSlots(\n html: string,\n doc: EmailDoc,\n registry: Registry,\n): ExtractDynamicVariantSlotsResult {\n const slots = doc.sections.filter(isDynamicVariantSection);\n if (!slots.length) return { html, variants: {} };\n\n let resultHtml = html;\n const variants: Record<string, string> = {};\n\n for (const section of slots) {\n const key = getSectionDynamicVariantKey(section);\n if (!key) continue;\n\n const fromMarker = replaceVariantMarkerInHtml(resultHtml, key);\n if (fromMarker) {\n variants[key] = fromMarker.variantHtml;\n resultHtml = fromMarker.html;\n continue;\n }\n\n const snippet = renderSectionBodyHtml(doc, section.id, registry);\n if (!snippet) continue;\n variants[key] = snippet;\n const token = dynamicVariantPlaceholder(key);\n const idx = resultHtml.indexOf(snippet);\n if (idx >= 0) {\n resultHtml = resultHtml.slice(0, idx) + token + resultHtml.slice(idx + snippet.length);\n }\n }\n\n return { html: resultHtml, variants };\n}\n","import type { SectionLayout } from '../types';\n\nconst LAYOUT_LABELS: Record<SectionLayout, string> = {\n '1': '一列',\n '1-1': '1:1',\n '1-2': '1:2',\n '2-1': '2:1',\n '1-1-1': '1:1:1',\n};\n\nexport function layoutHumanLabel(layout: SectionLayout): string {\n return LAYOUT_LABELS[layout] ?? layout;\n}\n","/**\n * 极轻量 HTML 格式化器(约 50 行)。\n *\n * 不追求 100% 通用,但对邮件 HTML(table 嵌套、inline style、无脚本)非常稳定:\n * - 按 `<` 切 token,识别开标签 / 闭标签 / 自闭合 / 注释 / DOCTYPE\n * - 维护 depth 控制缩进\n * - void 元素与 self-closing 不增加 depth\n * - <pre> / <textarea> 内的换行不二次处理(保留原样)\n */\nexport function prettyHtml(html: string, indent = ' '): string {\n if (!html) return '';\n const VOID = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n ]);\n const PRESERVE = new Set(['pre', 'textarea', 'script', 'style']);\n\n const tokens = html.match(/<!--[\\s\\S]*?-->|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|<![^>]*>|<\\/?[^<>]+>|[^<]+/g) ?? [];\n let depth = 0;\n let preserveStack: string[] = [];\n const out: string[] = [];\n const pad = (n: number) => indent.repeat(Math.max(0, n));\n\n for (const raw of tokens) {\n const tok = raw;\n const inPreserve = preserveStack.length > 0;\n\n if (tok.startsWith('<!--') || tok.startsWith('<![')) {\n if (inPreserve) out.push(tok);\n else out.push(pad(depth) + tok.trim());\n continue;\n }\n if (tok.startsWith('<!')) {\n out.push(tok.trim());\n continue;\n }\n\n if (tok.startsWith('</')) {\n const tag = (tok.match(/^<\\/([\\w-]+)/) ?? [])[1]?.toLowerCase();\n if (preserveStack[preserveStack.length - 1] === tag) {\n preserveStack.pop();\n out.push(tok);\n continue;\n }\n depth = Math.max(0, depth - 1);\n out.push(pad(depth) + tok.trim());\n continue;\n }\n\n if (tok.startsWith('<')) {\n const tag = (tok.match(/^<([\\w-]+)/) ?? [])[1]?.toLowerCase();\n const selfClosing = tok.endsWith('/>') || (tag && VOID.has(tag));\n if (inPreserve) {\n out.push(tok);\n if (tag && PRESERVE.has(tag) && !selfClosing) preserveStack.push(tag);\n continue;\n }\n out.push(pad(depth) + tok.trim());\n if (tag && !selfClosing) {\n if (PRESERVE.has(tag)) preserveStack.push(tag);\n else depth += 1;\n }\n continue;\n }\n\n // 文本\n if (inPreserve) {\n out.push(tok);\n } else {\n const txt = tok.replace(/\\s+/g, ' ').trim();\n if (txt) out.push(pad(depth) + txt);\n }\n }\n\n return out.join('\\n');\n}\n","export interface CodeEditorModalSize {\n width: string;\n height: string;\n}\n\nconst DEFAULT_MAX_WIDTH_RATIO = 0.96;\nconst DEFAULT_MAX_HEIGHT_RATIO = 0.88;\n\n/** 组件代码弹框默认固定尺寸 */\nexport function getCodeEditorModalDefaultSize(): CodeEditorModalSize {\n return {\n width: 'min(720px, 92vw)',\n height: 'min(560px, 85vh)',\n };\n}\n\n/** 代码编辑弹框最大化时的视口占比 */\nexport function getCodeEditorModalMaximizedSize(\n opts?: { maxWidthRatio?: number; maxHeightRatio?: number },\n): CodeEditorModalSize {\n const maxWidthRatio = opts?.maxWidthRatio ?? DEFAULT_MAX_WIDTH_RATIO;\n const maxHeightRatio = opts?.maxHeightRatio ?? DEFAULT_MAX_HEIGHT_RATIO;\n return {\n width: `${Math.floor(window.innerWidth * maxWidthRatio)}px`,\n height: `${Math.floor(window.innerHeight * maxHeightRatio)}px`,\n };\n}\n","import { h } from '../utils/dom';\nimport type { SimpleMailT } from '../i18n';\n\n/**\n * 极简 Modal:遮罩 + 居中卡片 + header/body/footer 三段。\n * - 自带 Esc / 点遮罩 关闭\n * - 不锁 body scroll(邮件编辑器场景内通常已经接管了高度)\n * - 不依赖框架,保持 vanilla\n */\nexport interface ModalOptions {\n title: string;\n /** 卡片宽度 / 高度。可传 'auto' / px / % */\n width?: string;\n height?: string;\n /** 自定义类名,便于覆盖样式(如 sm-modal--preview) */\n className?: string;\n /** 关闭回调;用户取消、Esc、点遮罩时触发 */\n onClose?: () => void;\n t?: SimpleMailT;\n}\n\nexport class Modal {\n el: HTMLElement;\n private mask: HTMLElement;\n private card: HTMLElement;\n private headerEl: HTMLElement;\n private bodyEl: HTMLElement;\n private footerEl: HTMLElement;\n private opts: ModalOptions;\n private headerToolNodes: HTMLElement[] = [];\n private keydownHandler?: (e: KeyboardEvent) => void;\n\n constructor(opts: ModalOptions) {\n this.opts = opts;\n\n this.mask = h('div', {\n class: 'sm-modal__mask',\n onclick: (e: Event) => {\n if (e.target === this.mask) this._handleClose();\n },\n });\n\n this.headerEl = h('header', { class: 'sm-modal__header' });\n this.bodyEl = h('div', { class: 'sm-modal__body' });\n this.footerEl = h('footer', { class: 'sm-modal__footer' });\n\n this.card = h(\n 'div',\n {\n class: `sm-modal__card ${opts.className ?? ''}`,\n style: [\n opts.width ? `width:${opts.width};` : '',\n opts.height ? `height:${opts.height};` : '',\n ].join(''),\n },\n [this.headerEl, this.bodyEl, this.footerEl],\n );\n\n this.mask.append(this.card);\n this.el = this.mask;\n\n this._renderHeader();\n }\n\n open(parent: HTMLElement = document.body) {\n parent.append(this.el);\n this.keydownHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this._handleClose();\n };\n document.addEventListener('keydown', this.keydownHandler);\n requestAnimationFrame(() => this.el.classList.add('is-open'));\n }\n\n close() {\n this._handleClose();\n }\n\n setTitle(title: string) {\n this.opts.title = title;\n this._renderHeader();\n }\n\n /** 动态调整卡片宽高(如 CodeMirror 弹框按内容适配) */\n setSize(width?: string, height?: string) {\n if (width !== undefined) {\n this.opts.width = width;\n this.card.style.width = width;\n }\n if (height !== undefined) {\n this.opts.height = height;\n this.card.style.height = height;\n }\n }\n\n /** body 容器直接给外部填充 */\n get body(): HTMLElement {\n return this.bodyEl;\n }\n\n /** footer 容器直接给外部填充按钮等 */\n get footer(): HTMLElement {\n return this.footerEl;\n }\n\n /** 在 header 右侧追加自定义工具按钮(setTitle 重绘 header 时保留) */\n appendHeaderTool(el: HTMLElement) {\n this.headerToolNodes.push(el);\n const tools = this.headerEl.querySelector('.sm-modal__header-tools');\n tools?.append(el);\n }\n\n get cardElement(): HTMLElement {\n return this.card;\n }\n\n private _renderHeader() {\n this.headerEl.innerHTML = '';\n const title = h('div', { class: 'sm-modal__title' }, [this.opts.title]);\n const tools = h('div', { class: 'sm-modal__header-tools' });\n for (const el of this.headerToolNodes) tools.append(el);\n const closeBtn = h(\n 'button',\n {\n class: 'sm-modal__close',\n type: 'button',\n title: this.opts.t?.('common.closeEsc') ?? '关闭 Esc',\n 'aria-label': this.opts.t?.('common.close') ?? '关闭',\n onclick: () => this._handleClose(),\n },\n [iconClose()],\n );\n this.headerEl.append(title, tools, closeBtn);\n }\n\n private _handleClose() {\n if (this.keydownHandler) document.removeEventListener('keydown', this.keydownHandler);\n this.el.classList.remove('is-open');\n setTimeout(() => this.el.remove(), 180);\n this.opts.onClose?.();\n }\n}\n\nfunction iconClose(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M5 5l10 10M15 5L5 15\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>';\n return el;\n}\n","import { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport { EditorState } from '@codemirror/state';\nimport type { Registry } from '../registry/registry';\nimport { findBlockLocation } from '../store/store';\nimport type { Store } from '../store/store';\nimport { h } from '../utils/dom';\nimport { prettyHtml } from '../utils/html';\nimport {\n getCodeEditorModalDefaultSize,\n getCodeEditorModalMaximizedSize,\n} from '../utils/modalSize';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface BlockCodeModalOptions {\n store: Store;\n registry: Registry;\n /** 须落在 MailEditor `.sm-root` 子树内,才能继承 `--sm-code-bg` 等变量 */\n mountParent: HTMLElement;\n t: SimpleMailT;\n}\n\nconst MAXIMIZED_PREF_KEY = 'sm-block-code-modal-maximized';\n\n/**\n * 画布内快速编辑单个 Block 的 MJML:与右栏「代码」Tab 行为一致(写入 lockedMjml)。\n */\nexport class BlockCodeModal {\n private opts: BlockCodeModalOptions;\n private modal: Modal;\n private editorHost: HTMLElement;\n private cm: EditorView | null = null;\n private blockId: string | null = null;\n private maximizeBtn: HTMLButtonElement;\n private maximized = false;\n\n constructor(opts: BlockCodeModalOptions) {\n this.opts = opts;\n const defaultSize = getCodeEditorModalDefaultSize();\n this.modal = new Modal({\n title: opts.t('blockCode.title'),\n className: 'sm-modal--block-code',\n width: defaultSize.width,\n height: defaultSize.height,\n onClose: () => this._destroyCm(),\n t: opts.t,\n });\n this.editorHost = h('div', { class: 'sm-export__editor' });\n this.modal.body.append(this.editorHost);\n\n this.maximizeBtn = h(\n 'button',\n {\n class: 'sm-modal__close',\n type: 'button',\n onclick: () => this._toggleMaximize(),\n },\n [iconMaximize()],\n ) as HTMLButtonElement;\n this.modal.appendHeaderTool(this.maximizeBtn);\n this._syncMaximizeButton();\n\n const beautifyBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this._beautify() },\n [opts.t('common.beautify')],\n );\n const saveBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => this._saveAndClose(),\n },\n [opts.t('common.save')],\n );\n this.modal.footer.append(beautifyBtn, saveBtn);\n }\n\n open(blockId: string, componentLabel: string) {\n const doc = this.opts.store.doc;\n const loc = findBlockLocation(doc, blockId);\n if (!loc) return;\n\n this._destroyCm();\n this.blockId = blockId;\n const block = loc.block;\n const def = this.opts.registry.get(block.type);\n const initial =\n block.lockedMjml ??\n (def ? def.toMjml(block.props as Record<string, unknown>, { doc, engine: 'mjml' }) : '');\n\n this.maximized = readMaximizedPref();\n this.modal.setTitle(this.opts.t('blockCode.titleWithName', { name: componentLabel }));\n this._applyModalSize();\n this.cm = new EditorView({\n parent: this.editorHost,\n state: EditorState.create({\n doc: initial,\n extensions: [basicSetup, cmHtml()],\n }),\n });\n this.modal.open(this.opts.mountParent);\n }\n\n destroy() {\n this._destroyCm();\n if (this.modal.el.parentElement) this.modal.close();\n }\n\n private _beautify() {\n if (!this.cm) return;\n const text = prettyHtml(this.cm.state.doc.toString());\n this.cm.dispatch({\n changes: { from: 0, to: this.cm.state.doc.length, insert: text },\n });\n }\n\n private _applyModalSize() {\n const size = this.maximized\n ? getCodeEditorModalMaximizedSize()\n : getCodeEditorModalDefaultSize();\n this.modal.setSize(size.width, size.height);\n this.modal.cardElement.classList.toggle('is-maximized', this.maximized);\n this._syncMaximizeButton();\n }\n\n private _toggleMaximize() {\n this.maximized = !this.maximized;\n writeMaximizedPref(this.maximized);\n this._applyModalSize();\n requestAnimationFrame(() => this.cm?.requestMeasure());\n }\n\n private _syncMaximizeButton() {\n this.maximizeBtn.title = this.maximized ? this.opts.t('common.restore') : this.opts.t('common.maximize');\n this.maximizeBtn.setAttribute('aria-pressed', this.maximized ? 'true' : 'false');\n this.maximizeBtn.replaceChildren(this.maximized ? iconRestore() : iconMaximize());\n }\n\n private _saveAndClose() {\n if (!this.cm || !this.blockId) return;\n const text = this.cm.state.doc.toString();\n const id = this.blockId;\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, id);\n if (l) l.block.lockedMjml = text;\n });\n this.modal.close();\n }\n\n private _destroyCm() {\n if (this.cm) {\n this.cm.destroy();\n this.cm = null;\n }\n this.blockId = null;\n this.modal.cardElement.classList.remove('is-maximized');\n }\n}\n\nfunction readMaximizedPref(): boolean {\n try {\n return localStorage.getItem(MAXIMIZED_PREF_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nfunction writeMaximizedPref(maximized: boolean) {\n try {\n localStorage.setItem(MAXIMIZED_PREF_KEY, maximized ? '1' : '0');\n } catch {\n /* ignore quota / private mode */\n }\n}\n\nfunction iconMaximize(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M4 10V4h6M10 10h6v6M10 4h6v6M4 10v6h6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>';\n return el;\n}\n\nfunction iconRestore(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M7 4H4v3M13 4h3v3M7 16H4v-3M13 16h3v-3\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>';\n return el;\n}\n","/**\n * contenteditable 富文本仍依赖 Document.execCommand / queryCommand* 系列 API。\n * 浏览器与 TypeScript lib.dom 虽已标记 deprecated,但目前无等价替代;集中封装便于 IDE 消警与日后迁移。\n */\nexport interface RichTextDocument extends Document {\n execCommand(commandId: string, showUI?: boolean, value?: string): boolean;\n queryCommandState(commandId: string): boolean;\n queryCommandValue(commandId: string): string;\n}\n\nfunction asRichTextDoc(doc: Document = document): RichTextDocument {\n return doc as RichTextDocument;\n}\n\nexport function richTextExecCommand(\n commandId: string,\n showUI = false,\n value?: string,\n doc: Document = document,\n): boolean {\n return asRichTextDoc(doc).execCommand(commandId, showUI, value);\n}\n\nexport function richTextQueryCommandState(commandId: string, doc: Document = document): boolean {\n return asRichTextDoc(doc).queryCommandState(commandId);\n}\n\nexport function richTextQueryCommandValue(commandId: string, doc: Document = document): string {\n return asRichTextDoc(doc).queryCommandValue(commandId);\n}\n","/** 是否仅为进入编辑时注入的占位 <br>(用户未改动) */\nexport function isRichHtmlEditorSeedOnly(html: string): boolean {\n const s = String(html ?? '').trim().toLowerCase();\n return s === '<br>' || s === '<br/>' || s === '<br />';\n}\n\n/** 是否包含换行(<br>) */\nexport function hasRichHtmlLineBreak(html: string): boolean {\n const tpl = document.createElement('template');\n tpl.innerHTML = String(html ?? '');\n return tpl.content.querySelector('br') != null;\n}\n\n/** 富文本纯文本(不 trim,保留空格;去掉零宽字符) */\nexport function getRichHtmlPlainText(html: string): string {\n const tpl = document.createElement('template');\n tpl.innerHTML = String(html ?? '');\n return (tpl.content.textContent ?? '').replace(/\\u200b/g, '');\n}\n\n/**\n * 富文本是否「完全无内容」。\n * 空格、&nbsp;、换行(<br>)均视为有效内容;仅空串或空标签壳子算空。\n */\nexport function isRichHtmlEffectivelyEmpty(html: string): boolean {\n const raw = String(html ?? '');\n if (!raw.trim()) return true;\n\n const tpl = document.createElement('template');\n tpl.innerHTML = raw;\n const root = tpl.content;\n\n if (root.querySelector('img')) return false;\n if (root.querySelector('br')) return false;\n\n const text = (root.textContent ?? '').replace(/\\u200b/g, '');\n return text.length === 0;\n}\n\n/** 提交前:完全无内容时统一为 '' */\nexport function normalizeRichHtmlForCommit(html: string): string {\n return isRichHtmlEffectivelyEmpty(html) ? '' : html;\n}\n","/**\n * 邮件编辑器品牌/主题色:写入 .sm-root 的 --sm-primary / --sm-primary-soft。\n */\n\n/** 合法则规范为 #RRGGBB(大写),否则 null */\nexport function normalizeAccentHex(input: string): string | null {\n const t = input.trim();\n if (!t) return null;\n const h = t.replace(/^#/, '');\n if (/^[0-9a-fA-F]{3}$/.test(h)) {\n return `#${(h[0] + h[0] + h[1] + h[1] + h[2] + h[2]).toUpperCase()}`;\n }\n if (/^[0-9a-fA-F]{6}$/.test(h)) {\n return `#${h.toUpperCase()}`;\n }\n return null;\n}\n\n/** 由 getComputedStyle 得到的 rgb(...) / rgba(...) 转 #rrggbb */\nexport function rgbCssToHex(rgb: string): string | null {\n const m = rgb.trim().match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (!m) return null;\n const h = (n: string) => Number(n).toString(16).padStart(2, '0');\n return `#${h(m[1])}${h(m[2])}${h(m[3])}`;\n}\n\n/**\n * 与浅色/深色界面配套的浅底强调色(选区、滑块 accent 等)。\n */\nexport function accentPrimarySoftRgba(primaryHex: string, isDarkChrome: boolean): string {\n const hex = normalizeAccentHex(primaryHex);\n if (!hex) return isDarkChrome ? 'rgba(129, 140, 248, 0.18)' : 'rgba(79, 70, 229, 0.12)';\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n const a = isDarkChrome ? 0.22 : 0.14;\n return `rgba(${r},${g},${b},${a})`;\n}\n","export type SimpleMailLocale = 'zh-CN' | 'en-US';\n\nexport type SimpleMailMessages = Record<string, string>;\n\nexport type SimpleMailMessagesInput = Partial<SimpleMailMessages>;\n\nexport type SimpleMailT = (key: string, params?: Record<string, string | number>) => string;\n\nexport interface SimpleMailI18nOptions {\n locale?: SimpleMailLocale;\n messages?: SimpleMailMessagesInput;\n}\n\nexport interface SimpleMailI18nContext {\n locale: SimpleMailLocale;\n messages: SimpleMailMessages;\n t: SimpleMailT;\n}\n\nexport const zhCNMessages: SimpleMailMessages = {\n 'common.cancel': '取消',\n 'common.close': '关闭',\n 'common.closeEsc': '关闭 Esc',\n 'common.save': '保存',\n 'common.beautify': '美化',\n 'common.maximize': '最大化',\n 'common.restore': '还原',\n 'common.delete': '删除',\n 'common.upload': '上传',\n 'common.add': '添加',\n 'common.insert': '插入',\n 'common.copy': '复制',\n 'common.image': '图片',\n 'common.noPermission': '无权限',\n 'common.noPermissionUpload': '无上传权限',\n 'common.noPermissionAdd': '无添加权限',\n 'common.noPermissionDelete': '无删除权限',\n 'common.left': '左',\n 'common.center': '居中',\n 'common.right': '右',\n 'common.inheritGlobal': '继承全局',\n 'common.dragSort': '拖拽排序',\n 'common.editText': '编辑文本',\n 'common.editCode': '编辑组件代码',\n 'common.clear': '清除',\n 'doc.defaultSubject': '一封新邮件',\n 'topbar.mode': '编辑模式',\n 'topbar.design': '设计',\n 'topbar.source': '源码',\n 'topbar.theme': '界面主题',\n 'topbar.light': '浅色',\n 'topbar.dark': '深色',\n 'topbar.system': '跟随系统',\n 'topbar.accentColor': '主题色',\n 'topbar.undoTitle': '撤销 ⌘Z',\n 'topbar.undo': '撤销',\n 'topbar.redoTitle': '重做 ⌘⇧Z',\n 'topbar.redo': '重做',\n 'topbar.clearCanvasTitle': '清空画布:移除画布上所有 Section 与组件',\n 'topbar.clearCanvas': '清空画布',\n 'topbar.resetContentTitle': '重置内容:恢复为预置邮件结构',\n 'topbar.resetContent': '重置内容',\n 'topbar.copyDesignTitle': '复制设计稿:将画布 JSON 写入剪贴板,可在另一封邮件中导入',\n 'topbar.copyDesign': '复制设计稿',\n 'topbar.importDesignTitle': '导入设计稿:从剪贴板或粘贴 JSON 覆盖当前画布',\n 'topbar.importDesign': '导入设计稿',\n 'topbar.preview': '预览',\n 'topbar.exportHtml': '导出 HTML',\n 'topbar.mailSettingsTitle': '邮件设置:主题、宽度与全局样式',\n 'topbar.mailSettings': '邮件设置',\n 'topbar.insertVariable': '插入变量',\n 'topbar.showLayoutBorders': '显示 Section / Block 边框',\n 'topbar.hideLayoutBorders': '隐藏 Section / Block 边框',\n 'topbar.fullscreen': '全屏',\n 'topbar.exitFullscreen': '退出全屏',\n 'leftPanel.layout': '布局',\n 'leftPanel.components': '组件',\n 'leftPanel.customTooltipSuffix': 'Navimow 定制组件,拖入列内使用',\n 'leftPanel.oneColumn': '一列',\n 'leftPanel.multiColumn': '多列',\n 'leftPanel.multiColumnTitle': '多列(右栏可调 2/3 列比例)',\n 'canvas.emptyHint': '从左侧拖入布局开始,或直接双击开始 ✦',\n 'canvas.addSection': '+ 添加 Section:',\n 'canvas.dynamicSectionLabel': '动态变量 {index} · {token}',\n 'canvas.sectionLabel': '区块 {index} · {layout}',\n 'canvas.sectionTitle': '{chip}。子组件铺满列内时:按 Esc 或 Alt+点击块可选中本节。',\n 'canvas.unknownBlock': '未知组件: {type}',\n 'canvas.emptyColumnHint': '拖入组件 · 双击插入文本',\n 'canvas.lockedCode': '已锁定为代码',\n 'rightPanel.docRoot.mail': '邮件',\n 'rightPanel.docRoot.layout': '版式',\n 'rightPanel.breadcrumb.selected': '当前选中',\n 'rightPanel.breadcrumb.selectTitle': '选中:{label}',\n 'rightPanel.layout.oneColumn': '一列',\n 'rightPanel.layout.columns': '多列',\n 'rightPanel.tabs.props': '属性',\n 'rightPanel.tabs.code': '代码',\n 'rightPanel.block.deleted': '该组件可能已被删除,请重新选中画布中的块。',\n 'rightPanel.block.locked': '该组件已被代码模式锁定。',\n 'rightPanel.block.restoreProps': '恢复为属性模式',\n 'rightPanel.block.unregistered': '未注册的组件: {type}',\n 'rightPanel.block.mjmlWarning': '检测到 MJML 标签(如 <mj-text>)。此处应只写 HTML,否则预览会显示源码。简单链接请用「文本」块。',\n 'rightPanel.doc.title': '邮件设置',\n 'rightPanel.doc.layoutTitle': '版式',\n 'rightPanel.doc.subject': '主题',\n 'rightPanel.doc.preheader': 'Preheader',\n 'rightPanel.doc.contentWidth': '内容宽度',\n 'rightPanel.doc.contentWidthPlaceholder': '如 600、600px、100%',\n 'rightPanel.doc.globalStyles': '全局样式',\n 'rightPanel.doc.pageBackground': '页面背景',\n 'rightPanel.doc.contentBackground': '内容背景',\n 'rightPanel.doc.fontFamily': '字体',\n 'rightPanel.doc.lineHeight': '行高',\n 'rightPanel.doc.lineHeightPlaceholder': '如 1.25 或 24px',\n 'rightPanel.doc.textColor': '正文颜色',\n 'rightPanel.doc.linkColor': '链接颜色',\n 'rightPanel.doc.fontSize': '字号',\n 'rightPanel.doc.fontSizeHelp': '滑块与数字均以 px 写入(如 16px)',\n 'rightPanel.doc.fontWeight': '字重',\n 'rightPanel.doc.listIndent': '列表默认缩进',\n 'rightPanel.doc.listIndentHelp': '未单独设置缩进的列表使用此值。',\n 'rightPanel.width.auto': '自适应',\n 'rightPanel.width.customHelp': '当前值为自定义写法,请直接编辑;清空后可选「自适应」再用滑块。',\n 'rightPanel.width.customPlaceholder': '如 480px、90%',\n 'rightPanel.inheritGlobal': '继承全局',\n 'rightPanel.spacing.suffix': '(上/右/下/左)',\n 'rightPanel.spacing.reset': '恢复默认',\n 'rightPanel.spacing.top': '上',\n 'rightPanel.spacing.right': '右',\n 'rightPanel.spacing.bottom': '下',\n 'rightPanel.spacing.left': '左',\n 'rightPanel.section.title': 'Section 设置',\n 'rightPanel.section.dynamicTitle': '动态变量 Section',\n 'rightPanel.section.dynamicKey': '动态变量名',\n 'rightPanel.section.dynamicKeyPlaceholder': '谨慎填写,需确认业务场景是否支持',\n 'rightPanel.section.dynamicKeyHelp': '本段内容将整体替换成该动态变量名',\n 'rightPanel.section.backgroundColor': '背景色',\n 'rightPanel.section.transparentPlaceholder': '留空=透明',\n 'rightPanel.section.width': '区域宽度',\n 'rightPanel.section.widthHelp': '留空=与邮件同宽;自适应等价于清空宽度',\n 'rightPanel.section.padding': '内边距',\n 'rightPanel.section.columnGap': '列间距 (px)',\n 'rightPanel.section.preserveMobile': '小屏仍并排显示多列(可能字很窄)',\n 'rightPanel.section.preserveMobileHelp': '开启后 MJML 会生成 mj-group,移动端预览/导出与默认「小屏堆叠列」行为不同。',\n 'rightPanel.section.columnLayout': '列布局',\n 'rightPanel.social.labelPlaceholder': '标签文字(可选)',\n 'rightPanel.social.iconUrlPlaceholder': '图标 URL(可选)',\n 'rightPanel.social.add': '+ 添加社交链接',\n 'rightPanel.image.uploadTitle': '上传本地图片',\n 'rightPanel.image.upload': '上传',\n 'rightPanel.image.galleryTitle': '从图库选择',\n 'rightPanel.image.gallery': '图库',\n 'rightPanel.image.helpManual': '可手输 URL',\n 'rightPanel.image.helpUpload': '或使用「上传」',\n 'rightPanel.image.helpGallery': '或使用「图库」',\n 'rightPanel.image.helpSeparator': ';',\n 'rightPanel.image.helpEnd': '。',\n 'rightPanel.image.helpAssetsConfigured': '已传入 imageAssets:上传默认显示(提供 uploadImage 且未设 showUpload:false);图库需 showGallery:true,可使用内置 imageGallery 或自管 pickImageFromGallery。仍可手输 URL。',\n 'rightPanel.image.helpNoAssets': '在 MailEditor 的 imageAssets 中配置 uploadImage、内置 imageGallery 或 pickImageFromGallery 等;未配置时仅支持手输 URL。',\n 'rightPanel.color.unset': '未设置',\n 'rightPanel.fontSize.placeholder': '如 16px',\n 'rightPanel.code.title': '编辑组件 MJML 源码',\n 'rightPanel.code.restoreDefault': '恢复默认',\n 'rightPanel.code.saveLocked': '保存为锁定 MJML',\n 'rightPanel.code.help': '保存后该组件将以这段 MJML 直接输出,属性面板会被禁用,可点\"恢复默认\"取消锁定。',\n 'toolbar.fontDefault': '默认',\n 'toolbar.fontPingFang': '苹方/PingFang',\n 'toolbar.fontMicrosoftYaHei': '微软雅黑',\n 'toolbar.fontSimSun': '宋体',\n 'toolbar.bold': '加粗 ⌘B',\n 'toolbar.italic': '斜体 ⌘I',\n 'toolbar.underline': '下划线 ⌘U',\n 'toolbar.strikethrough': '删除线',\n 'toolbar.alignLeft': '左对齐',\n 'toolbar.alignCenter': '居中',\n 'toolbar.alignRight': '右对齐',\n 'toolbar.unorderedList': '无序列表',\n 'toolbar.orderedList': '有序列表',\n 'toolbar.listIndent': '列表缩进',\n 'toolbar.indent': '缩进',\n 'toolbar.fontFamily': '字体',\n 'toolbar.fontSize': '字号',\n 'toolbar.fontWeight': '字重',\n 'toolbar.textColor': '文字颜色',\n 'toolbar.textBackground': '文字背景色',\n 'toolbar.insertLink': '插入或编辑链接',\n 'toolbar.unlink': '取消链接',\n 'toolbar.clearFormat': '清除格式',\n 'toolbar.apply': '确定',\n 'variablePicker.title': '插入变量',\n 'variablePicker.pin': '固定面板',\n 'variablePicker.pinTitle': '固定面板,连续插入',\n 'variablePicker.unpinTitle': '取消固定',\n 'variablePicker.closeTitle': '关闭变量列表',\n 'variablePicker.empty': '暂无可用变量,请由宿主通过 setVariables 注入。',\n 'variablePicker.insertElement': '插入元素',\n 'variablePicker.copyTitle': '复制 {token}',\n 'gallery.title': '图库',\n 'gallery.searchPlaceholder': '搜索…',\n 'gallery.searchAria': '搜索图片',\n 'gallery.loadMore': '加载更多',\n 'gallery.empty': '暂无图片,可上传、添加链接或更换搜索条件',\n 'gallery.deleteTitle': '从图库删除',\n 'gallery.deleteConfirm': '确定从图库中删除这张图片?',\n 'gallery.deleteFailed': '删除失败',\n 'gallery.loadFailed': '加载失败',\n 'gallery.addUrlPlaceholder': '图片链接 https://…',\n 'gallery.addFailed': '添加失败',\n 'gallery.uploadFailed': '上传失败',\n 'source.compiledHtml': 'HTML(编译产物)',\n 'export.title': '导出 HTML',\n 'export.copyHtml': '复制 HTML',\n 'export.downloadHtml': '下载 .html',\n 'preview.title': '预览邮件',\n 'colorPicker.title': '选择颜色',\n 'colorPicker.custom': '自定义颜色',\n 'colorPicker.doubleClickConfirm': '{hex}(双击确认)',\n 'colorPicker.openTitle': '点击打开色板;预设色块可双击快速确认',\n 'importDoc.title': '导入设计稿',\n 'importDoc.hint1': '将覆盖当前画布上的所有 Section 与组件(全局样式会一并替换)。',\n 'importDoc.hint2': '若宿主管理邮件主题/宽度,这些字段可能保持不变。',\n 'importDoc.hint3': '粘贴由「复制设计稿」生成的 JSON,或裸 EmailDoc(version: \"1\")。',\n 'importDoc.placeholder': '在此粘贴设计稿 JSON…',\n 'importDoc.pasteFromClipboard': '从剪贴板填入',\n 'importDoc.apply': '应用并覆盖画布',\n 'importDoc.clipboardEmpty': '剪贴板为空或无法读取,请手动粘贴 JSON。',\n 'importDoc.clipboardFilled': '已从剪贴板填入,请确认后点击「应用并覆盖画布」。',\n 'importDoc.empty': '请先粘贴设计稿 JSON。',\n 'importDoc.invalid': 'JSON 无效或不是 simple-mail 设计稿格式。',\n 'blockCode.title': '编辑组件代码',\n 'blockCode.titleWithName': '编辑组件代码 · {name}',\n 'toast.copyDesignOk': '设计稿已复制到剪贴板',\n 'toast.copyDesignFailed': '复制失败,请检查浏览器剪贴板权限',\n 'toast.importDesignOk': '设计稿已导入',\n 'toast.noVariables': '暂无可用变量',\n 'toast.variableCopied': '已复制变量',\n 'toast.copiedToClipboard': '已复制到剪贴板',\n 'toast.copied': '已复制',\n 'blocks.text.name': '文本',\n 'blocks.html.name': 'HTML',\n 'blocks.image.name': '图片',\n 'blocks.social-group.name': '社交图标',\n 'blocks.hero.name': 'Hero 大图',\n 'blocks.button.name': '按钮',\n 'blocks.divider.name': '分隔线',\n 'blocks.spacer.name': '间距',\n 'blocks.logo.name': '公司 Logo',\n 'blocks.social.name': '社交链接',\n 'blocks.footer.name': '页脚',\n 'blocks.button.defaultText': '立即查看',\n 'blocks.text.defaultContent': '<p style=\"margin:0;\">在此处输入文本。<strong>双击</strong>进入编辑模式,<em>选中文字</em>会出现工具条;支持变量 {{user.name}}</p>',\n 'blocks.html.defaultHtml': '<p style=\"margin:0;\">在此写入任意 HTML,将经 <strong>mj-raw</strong> 原样输出到邮件。支持变量 {{user.name}}</p>',\n 'blocks.hero.defaultContent': '<p style=\"margin:0;font-size:28px;font-weight:700;line-height:1.25;\">主标题落在大图上</p><p style=\"margin:12px 0 0;font-size:16px;font-weight:400;opacity:0.95;line-height:1.5;\">支援变量与 <strong>双击编辑</strong>,与正文组件一致。</p>',\n 'blocks.footer.defaultCompanyName': '你的公司',\n 'blocks.footer.defaultAddress': '上海市某区某路某号',\n 'blocks.footer.defaultUnsubscribeText': '退订邮件',\n 'blocks.field.align': '对齐',\n 'blocks.field.textAlign': '文字水平对齐',\n 'blocks.field.verticalAlign': '文字垂直位置',\n 'blocks.field.color': '颜色',\n 'blocks.field.textColor': '文字颜色',\n 'blocks.field.backgroundColor': '背景色',\n 'blocks.field.backgroundUrl': '背景图',\n 'blocks.field.backgroundPlaceholderColor': '背景占位色',\n 'blocks.field.heightPx': '高度 (px)',\n 'blocks.field.areaHeightPx': '区域高度 (px)',\n 'blocks.field.width': '宽度',\n 'blocks.field.widthPx': '宽度 (px)',\n 'blocks.field.widthPercentOrPx': '宽度 (% 或 px)',\n 'blocks.field.thicknessPx': '粗细 (px)',\n 'blocks.field.padding': '内边距',\n 'blocks.field.margin': '外边距',\n 'blocks.field.topMargin': '上边距',\n 'blocks.field.bottomMargin': '下边距',\n 'blocks.field.text': '文字',\n 'blocks.field.link': '链接',\n 'blocks.field.href': '点击跳转',\n 'blocks.field.imageUrl': '图片地址',\n 'blocks.field.alt': '替代文本',\n 'blocks.field.fontSize': '字号',\n 'blocks.field.fontFamily': '字体',\n 'blocks.field.fontWeight': '字重',\n 'blocks.field.lineHeight': '行高',\n 'blocks.field.contentHtml': '内容(HTML,备用)',\n 'blocks.field.bodyHtml': '正文(HTML)',\n 'blocks.field.html': 'HTML',\n 'blocks.field.borderRadius': '圆角 (px)',\n 'blocks.field.buttonInnerPaddingV': '按钮内上下边距',\n 'blocks.field.buttonInnerPaddingH': '按钮内左右边距',\n 'blocks.field.logoImage': 'Logo 图片',\n 'blocks.field.websiteLink': '官网链接',\n 'blocks.field.socialLinks': '社交链接',\n 'blocks.field.labelFontSize': '标签字号 (px)',\n 'blocks.field.labelFontWeight': '标签字重',\n 'blocks.field.labelColor': '标签颜色',\n 'blocks.field.iconSize': '图标尺寸 (px)',\n 'blocks.field.iconRadius': '图标圆角 (px)',\n 'blocks.field.iconSpacing': '图标间距 (px)',\n 'blocks.field.companyName': '公司名称',\n 'blocks.field.address': '地址',\n 'blocks.field.unsubscribeText': '退订文案',\n 'blocks.field.unsubscribeLink': '退订链接',\n 'blocks.field.imageDescription': '图片描述',\n 'blocks.field.inheritGlobalPlaceholder': '继承全局',\n 'blocks.field.buttonTextPlaceholder': '按钮文字',\n 'blocks.field.textPlaceholder': '输入文本…',\n 'blocks.field.htmlPlaceholder': '输入 HTML…',\n 'blocks.field.heroPlaceholder': '编写覆盖在图片上的文案…',\n 'blocks.help.globalLineHeight': '留空则使用邮件设置里的全局行距',\n 'blocks.help.canvasEditRecommended': '建议直接在画布双击编辑;这里保留为高级编辑入口。',\n 'blocks.help.canvasEditRecommendedShort': '建议在画布内双击编辑;此处供高级修改。',\n 'blocks.help.htmlOnly': '只写 HTML(如 <a>、<table>),不要写 <mj-text> 等 MJML 标签;MJML 标签在 mj-raw 内不会被编译。简单链接建议用「文本」块。',\n 'blocks.help.imageFallbackColor': '图片加载失败时的底色',\n 'blocks.help.imageAutoHeight': '0 为自适应高度;填写固定值时画布与 MJML 会限制显示高度(预览可用 object-fit: cover)',\n 'blocks.help.buttonWidth': '支持纯数字(按 px)、带 px 或百分比',\n 'blocks.help.socialLinks': '每行:平台、链接、可选标签文字、自定义图标 URL、图标背景色。标签的字号/字重/颜色在下方统一设置。',\n 'blocks.help.bizSocialLinks': '平台:X、Rabbit、Facebook、TikTok、Instagram (ig)。可填标签、自定义图标 URL。MJML 侧 Rabbit/TikTok 使用 web 占位图标,需要品牌图时请填「图标 URL」。',\n 'blocks.help.iconRadius': '0 为方形直角;填较大值(如 999)或与尺寸一半相当时为圆形(默认圆形)。',\n 'blocks.help.iconSpacing': '每个图标周围的留白,横向即图标之间的间隔(MJML inner-padding)。',\n 'blocks.help.bizIconSpacing': '图标之间的间隔(MJML inner-padding)。',\n 'blocks.placeholder.buttonWidth': '留空=自适应,如 280px、100%',\n 'blocks.option.top': '靠上',\n 'blocks.option.middle': '居中',\n 'blocks.option.bottom': '靠下',\n};\n\nexport const enUSMessages: SimpleMailMessages = {\n 'common.cancel': 'Cancel',\n 'common.close': 'Close',\n 'common.closeEsc': 'Close Esc',\n 'common.save': 'Save',\n 'common.beautify': 'Format',\n 'common.maximize': 'Maximize',\n 'common.restore': 'Restore',\n 'common.delete': 'Delete',\n 'common.upload': 'Upload',\n 'common.add': 'Add',\n 'common.insert': 'Insert',\n 'common.copy': 'Copy',\n 'common.image': 'Image',\n 'common.noPermission': 'No permission',\n 'common.noPermissionUpload': 'No upload permission',\n 'common.noPermissionAdd': 'No add permission',\n 'common.noPermissionDelete': 'No delete permission',\n 'common.left': 'Left',\n 'common.center': 'Center',\n 'common.right': 'Right',\n 'common.inheritGlobal': 'Inherit global',\n 'common.dragSort': 'Drag to reorder',\n 'common.editText': 'Edit text',\n 'common.editCode': 'Edit block code',\n 'common.clear': 'Clear',\n 'doc.defaultSubject': 'New email',\n 'topbar.mode': 'Editor mode',\n 'topbar.design': 'Design',\n 'topbar.source': 'Source',\n 'topbar.theme': 'Interface theme',\n 'topbar.light': 'Light',\n 'topbar.dark': 'Dark',\n 'topbar.system': 'System',\n 'topbar.accentColor': 'Accent color',\n 'topbar.undoTitle': 'Undo ⌘Z',\n 'topbar.undo': 'Undo',\n 'topbar.redoTitle': 'Redo ⌘⇧Z',\n 'topbar.redo': 'Redo',\n 'topbar.clearCanvasTitle': 'Clear canvas: remove all sections and blocks',\n 'topbar.clearCanvas': 'Clear canvas',\n 'topbar.resetContentTitle': 'Reset content: restore the preset email layout',\n 'topbar.resetContent': 'Reset content',\n 'topbar.copyDesignTitle': 'Copy design: write the canvas JSON to the clipboard for reuse',\n 'topbar.copyDesign': 'Copy design',\n 'topbar.importDesignTitle': 'Import design: paste JSON or read from the clipboard to replace the canvas',\n 'topbar.importDesign': 'Import design',\n 'topbar.preview': 'Preview',\n 'topbar.exportHtml': 'Export HTML',\n 'topbar.mailSettingsTitle': 'Email settings: subject, width, and global styles',\n 'topbar.mailSettings': 'Email settings',\n 'topbar.insertVariable': 'Insert variable',\n 'topbar.showLayoutBorders': 'Show section/block borders',\n 'topbar.hideLayoutBorders': 'Hide section/block borders',\n 'topbar.fullscreen': 'Fullscreen',\n 'topbar.exitFullscreen': 'Exit fullscreen',\n 'leftPanel.layout': 'Layout',\n 'leftPanel.components': 'Components',\n 'leftPanel.customTooltipSuffix': 'Custom Navimow block. Drag it into a column.',\n 'leftPanel.oneColumn': 'One column',\n 'leftPanel.multiColumn': 'Columns',\n 'leftPanel.multiColumnTitle': 'Columns (adjust 2/3-column ratios in the right panel)',\n 'canvas.emptyHint': 'Drag a layout from the left, or double-click to start ✦',\n 'canvas.addSection': '+ Add section:',\n 'canvas.dynamicSectionLabel': 'Dynamic variable {index} · {token}',\n 'canvas.sectionLabel': 'Section {index} · {layout}',\n 'canvas.sectionTitle': '{chip}. When child blocks fill the column, press Esc or Alt-click a block to select this section.',\n 'canvas.unknownBlock': 'Unknown block: {type}',\n 'canvas.emptyColumnHint': 'Drag in a block · Double-click to insert text',\n 'canvas.lockedCode': 'Locked as code',\n 'rightPanel.docRoot.mail': 'Email',\n 'rightPanel.docRoot.layout': 'Layout',\n 'rightPanel.breadcrumb.selected': 'Current selection',\n 'rightPanel.breadcrumb.selectTitle': 'Select: {label}',\n 'rightPanel.layout.oneColumn': 'One column',\n 'rightPanel.layout.columns': 'Columns',\n 'rightPanel.tabs.props': 'Properties',\n 'rightPanel.tabs.code': 'Code',\n 'rightPanel.block.deleted': 'This block may have been deleted. Select a block on the canvas again.',\n 'rightPanel.block.locked': 'This block is locked in code mode.',\n 'rightPanel.block.restoreProps': 'Restore property mode',\n 'rightPanel.block.unregistered': 'Unregistered block: {type}',\n 'rightPanel.block.mjmlWarning': 'MJML tags were detected, such as <mj-text>. Write HTML only here, otherwise the preview will show source code. Use a Text block for simple links.',\n 'rightPanel.doc.title': 'Email settings',\n 'rightPanel.doc.layoutTitle': 'Layout',\n 'rightPanel.doc.subject': 'Subject',\n 'rightPanel.doc.preheader': 'Preheader',\n 'rightPanel.doc.contentWidth': 'Content width',\n 'rightPanel.doc.contentWidthPlaceholder': 'e.g. 600, 600px, or 100%',\n 'rightPanel.doc.globalStyles': 'Global styles',\n 'rightPanel.doc.pageBackground': 'Page background',\n 'rightPanel.doc.contentBackground': 'Content background',\n 'rightPanel.doc.fontFamily': 'Font family',\n 'rightPanel.doc.lineHeight': 'Line height',\n 'rightPanel.doc.lineHeightPlaceholder': 'e.g. 1.25 or 24px',\n 'rightPanel.doc.textColor': 'Body color',\n 'rightPanel.doc.linkColor': 'Link color',\n 'rightPanel.doc.fontSize': 'Font size',\n 'rightPanel.doc.fontSizeHelp': 'The slider and number input both write px values, such as 16px.',\n 'rightPanel.doc.fontWeight': 'Font weight',\n 'rightPanel.doc.listIndent': 'Default list indent',\n 'rightPanel.doc.listIndentHelp': 'Lists without their own indent use this value.',\n 'rightPanel.width.auto': 'Auto',\n 'rightPanel.width.customHelp': 'This value uses custom syntax. Edit it directly, or clear it to choose Auto and use the slider.',\n 'rightPanel.width.customPlaceholder': 'e.g. 480px or 90%',\n 'rightPanel.inheritGlobal': 'Inherit global',\n 'rightPanel.spacing.suffix': ' (top/right/bottom/left)',\n 'rightPanel.spacing.reset': 'Reset',\n 'rightPanel.spacing.top': 'Top',\n 'rightPanel.spacing.right': 'Right',\n 'rightPanel.spacing.bottom': 'Bottom',\n 'rightPanel.spacing.left': 'Left',\n 'rightPanel.section.title': 'Section settings',\n 'rightPanel.section.dynamicTitle': 'Dynamic variable section',\n 'rightPanel.section.dynamicKey': 'Dynamic variable name',\n 'rightPanel.section.dynamicKeyPlaceholder': 'Use with care. Confirm the business flow supports it.',\n 'rightPanel.section.dynamicKeyHelp': 'This whole section will be replaced by the dynamic variable name.',\n 'rightPanel.section.backgroundColor': 'Background color',\n 'rightPanel.section.transparentPlaceholder': 'Empty = transparent',\n 'rightPanel.section.width': 'Section width',\n 'rightPanel.section.widthHelp': 'Empty = email width. Auto is equivalent to clearing the width.',\n 'rightPanel.section.padding': 'Padding',\n 'rightPanel.section.columnGap': 'Column gap (px)',\n 'rightPanel.section.preserveMobile': 'Keep columns side by side on small screens',\n 'rightPanel.section.preserveMobileHelp': 'When enabled, MJML outputs mj-group. Mobile preview/export differs from the default stacked-column behavior.',\n 'rightPanel.section.columnLayout': 'Column layout',\n 'rightPanel.social.labelPlaceholder': 'Label text (optional)',\n 'rightPanel.social.iconUrlPlaceholder': 'Icon URL (optional)',\n 'rightPanel.social.add': '+ Add social link',\n 'rightPanel.image.uploadTitle': 'Upload local image',\n 'rightPanel.image.upload': 'Upload',\n 'rightPanel.image.galleryTitle': 'Choose from gallery',\n 'rightPanel.image.gallery': 'Gallery',\n 'rightPanel.image.helpManual': 'Enter a URL manually',\n 'rightPanel.image.helpUpload': 'or use Upload',\n 'rightPanel.image.helpGallery': 'or use Gallery',\n 'rightPanel.image.helpSeparator': '; ',\n 'rightPanel.image.helpEnd': '.',\n 'rightPanel.image.helpAssetsConfigured': 'imageAssets is configured: upload is shown by default when uploadImage exists and showUpload is not false; gallery requires showGallery:true and either imageGallery or pickImageFromGallery. Manual URLs are still supported.',\n 'rightPanel.image.helpNoAssets': 'Configure uploadImage, imageGallery, or pickImageFromGallery in MailEditor imageAssets. Without them, only manual URLs are supported.',\n 'rightPanel.color.unset': 'Not set',\n 'rightPanel.fontSize.placeholder': 'e.g. 16px',\n 'rightPanel.code.title': 'Edit block MJML source',\n 'rightPanel.code.restoreDefault': 'Restore default',\n 'rightPanel.code.saveLocked': 'Save as locked MJML',\n 'rightPanel.code.help': 'After saving, this block will output this MJML directly, and the properties panel will be disabled. Use \"Restore default\" to unlock it.',\n 'toolbar.fontDefault': 'Default',\n 'toolbar.fontPingFang': 'PingFang SC',\n 'toolbar.fontMicrosoftYaHei': 'Microsoft YaHei',\n 'toolbar.fontSimSun': 'SimSun',\n 'toolbar.bold': 'Bold ⌘B',\n 'toolbar.italic': 'Italic ⌘I',\n 'toolbar.underline': 'Underline ⌘U',\n 'toolbar.strikethrough': 'Strikethrough',\n 'toolbar.alignLeft': 'Align left',\n 'toolbar.alignCenter': 'Align center',\n 'toolbar.alignRight': 'Align right',\n 'toolbar.unorderedList': 'Bulleted list',\n 'toolbar.orderedList': 'Numbered list',\n 'toolbar.listIndent': 'List indent',\n 'toolbar.indent': 'Indent',\n 'toolbar.fontFamily': 'Font family',\n 'toolbar.fontSize': 'Font size',\n 'toolbar.fontWeight': 'Font weight',\n 'toolbar.textColor': 'Text color',\n 'toolbar.textBackground': 'Text background',\n 'toolbar.insertLink': 'Insert or edit link',\n 'toolbar.unlink': 'Remove link',\n 'toolbar.clearFormat': 'Clear formatting',\n 'toolbar.apply': 'Apply',\n 'variablePicker.title': 'Insert variable',\n 'variablePicker.pin': 'Pin panel',\n 'variablePicker.pinTitle': 'Pin panel for repeated inserts',\n 'variablePicker.unpinTitle': 'Unpin panel',\n 'variablePicker.closeTitle': 'Close variable list',\n 'variablePicker.empty': 'No variables available. Inject them from the host with setVariables.',\n 'variablePicker.insertElement': 'Insert element',\n 'variablePicker.copyTitle': 'Copy {token}',\n 'gallery.title': 'Gallery',\n 'gallery.searchPlaceholder': 'Search...',\n 'gallery.searchAria': 'Search images',\n 'gallery.loadMore': 'Load more',\n 'gallery.empty': 'No images. Upload one, add a link, or try another search.',\n 'gallery.deleteTitle': 'Delete from gallery',\n 'gallery.deleteConfirm': 'Delete this image from the gallery?',\n 'gallery.deleteFailed': 'Delete failed',\n 'gallery.loadFailed': 'Load failed',\n 'gallery.addUrlPlaceholder': 'Image URL https://...',\n 'gallery.addFailed': 'Add failed',\n 'gallery.uploadFailed': 'Upload failed',\n 'source.compiledHtml': 'HTML (compiled output)',\n 'export.title': 'Export HTML',\n 'export.copyHtml': 'Copy HTML',\n 'export.downloadHtml': 'Download .html',\n 'preview.title': 'Preview email',\n 'colorPicker.title': 'Choose color',\n 'colorPicker.custom': 'Custom color',\n 'colorPicker.doubleClickConfirm': '{hex} (double-click to confirm)',\n 'colorPicker.openTitle': 'Click to open the palette. Double-click a swatch to confirm.',\n 'importDoc.title': 'Import design',\n 'importDoc.hint1': 'This will replace all sections and blocks on the current canvas, including global styles.',\n 'importDoc.hint2': 'If the host manages subject or width, those fields may remain unchanged.',\n 'importDoc.hint3': 'Paste JSON generated by \"Copy design\", or a raw EmailDoc with version: \"1\".',\n 'importDoc.placeholder': 'Paste design JSON here...',\n 'importDoc.pasteFromClipboard': 'Paste from clipboard',\n 'importDoc.apply': 'Apply and replace canvas',\n 'importDoc.clipboardEmpty': 'Clipboard is empty or unreadable. Paste JSON manually.',\n 'importDoc.clipboardFilled': 'Filled from clipboard. Review it, then apply and replace the canvas.',\n 'importDoc.empty': 'Paste design JSON first.',\n 'importDoc.invalid': 'Invalid JSON or not a simple-mail design.',\n 'blockCode.title': 'Edit block code',\n 'blockCode.titleWithName': 'Edit block code · {name}',\n 'toast.copyDesignOk': 'Design copied to clipboard',\n 'toast.copyDesignFailed': 'Copy failed. Check browser clipboard permissions.',\n 'toast.importDesignOk': 'Design imported',\n 'toast.noVariables': 'No variables available',\n 'toast.variableCopied': 'Variable copied',\n 'toast.copiedToClipboard': 'Copied to clipboard',\n 'toast.copied': 'Copied',\n 'blocks.text.name': 'Text',\n 'blocks.html.name': 'HTML',\n 'blocks.image.name': 'Image',\n 'blocks.social-group.name': 'Social icons',\n 'blocks.hero.name': 'Hero image',\n 'blocks.button.name': 'Button',\n 'blocks.divider.name': 'Divider',\n 'blocks.spacer.name': 'Spacer',\n 'blocks.logo.name': 'Logo',\n 'blocks.social.name': 'Social card',\n 'blocks.footer.name': 'Footer',\n 'blocks.button.defaultText': 'View now',\n 'blocks.text.defaultContent': '<p style=\"margin:0;\">Enter text here. <strong>Double-click</strong> to edit, select text to show the toolbar, and use variables like {{user.name}}.</p>',\n 'blocks.html.defaultHtml': '<p style=\"margin:0;\">Write any HTML here. It will be output through <strong>mj-raw</strong>. Variables like {{user.name}} are supported.</p>',\n 'blocks.hero.defaultContent': '<p style=\"margin:0;font-size:28px;font-weight:700;line-height:1.25;\">Main headline on the hero image</p><p style=\"margin:12px 0 0;font-size:16px;font-weight:400;opacity:0.95;line-height:1.5;\">Supports variables and <strong>double-click editing</strong>, just like text blocks.</p>',\n 'blocks.footer.defaultCompanyName': 'Your company',\n 'blocks.footer.defaultAddress': '123 Example Street, Shanghai',\n 'blocks.footer.defaultUnsubscribeText': 'Unsubscribe',\n 'blocks.field.align': 'Alignment',\n 'blocks.field.textAlign': 'Text alignment',\n 'blocks.field.verticalAlign': 'Vertical text position',\n 'blocks.field.color': 'Color',\n 'blocks.field.textColor': 'Text color',\n 'blocks.field.backgroundColor': 'Background color',\n 'blocks.field.backgroundUrl': 'Background image',\n 'blocks.field.backgroundPlaceholderColor': 'Fallback background',\n 'blocks.field.heightPx': 'Height (px)',\n 'blocks.field.areaHeightPx': 'Area height (px)',\n 'blocks.field.width': 'Width',\n 'blocks.field.widthPx': 'Width (px)',\n 'blocks.field.widthPercentOrPx': 'Width (% or px)',\n 'blocks.field.thicknessPx': 'Thickness (px)',\n 'blocks.field.padding': 'Padding',\n 'blocks.field.margin': 'Margin',\n 'blocks.field.topMargin': 'Top margin',\n 'blocks.field.bottomMargin': 'Bottom margin',\n 'blocks.field.text': 'Text',\n 'blocks.field.link': 'Link',\n 'blocks.field.href': 'Click target',\n 'blocks.field.imageUrl': 'Image URL',\n 'blocks.field.alt': 'Alt text',\n 'blocks.field.fontSize': 'Font size',\n 'blocks.field.fontFamily': 'Font family',\n 'blocks.field.fontWeight': 'Font weight',\n 'blocks.field.lineHeight': 'Line height',\n 'blocks.field.contentHtml': 'Content (HTML, fallback)',\n 'blocks.field.bodyHtml': 'Body (HTML)',\n 'blocks.field.html': 'HTML',\n 'blocks.field.borderRadius': 'Radius (px)',\n 'blocks.field.buttonInnerPaddingV': 'Button vertical padding',\n 'blocks.field.buttonInnerPaddingH': 'Button horizontal padding',\n 'blocks.field.logoImage': 'Logo image',\n 'blocks.field.websiteLink': 'Website link',\n 'blocks.field.socialLinks': 'Social links',\n 'blocks.field.labelFontSize': 'Label font size (px)',\n 'blocks.field.labelFontWeight': 'Label font weight',\n 'blocks.field.labelColor': 'Label color',\n 'blocks.field.iconSize': 'Icon size (px)',\n 'blocks.field.iconRadius': 'Icon radius (px)',\n 'blocks.field.iconSpacing': 'Icon spacing (px)',\n 'blocks.field.companyName': 'Company name',\n 'blocks.field.address': 'Address',\n 'blocks.field.unsubscribeText': 'Unsubscribe text',\n 'blocks.field.unsubscribeLink': 'Unsubscribe link',\n 'blocks.field.imageDescription': 'Image description',\n 'blocks.field.inheritGlobalPlaceholder': 'Inherit global',\n 'blocks.field.buttonTextPlaceholder': 'Button text',\n 'blocks.field.textPlaceholder': 'Enter text...',\n 'blocks.field.htmlPlaceholder': 'Enter HTML...',\n 'blocks.field.heroPlaceholder': 'Write copy over the image...',\n 'blocks.help.globalLineHeight': 'Leave empty to use the global line height from email settings.',\n 'blocks.help.canvasEditRecommended': 'Double-click on the canvas to edit directly. This field remains as an advanced fallback.',\n 'blocks.help.canvasEditRecommendedShort': 'Double-click on the canvas to edit. Use this field for advanced edits.',\n 'blocks.help.htmlOnly': 'Write HTML only, such as <a> or <table>. Do not use MJML tags like <mj-text>; MJML tags inside mj-raw will not compile. Use a Text block for simple links.',\n 'blocks.help.imageFallbackColor': 'Background color used if the image fails to load.',\n 'blocks.help.imageAutoHeight': '0 means automatic height. Fixed values limit both canvas and MJML display height; preview uses object-fit: cover.',\n 'blocks.help.buttonWidth': 'Supports plain numbers as px, px values, or percentages.',\n 'blocks.help.socialLinks': 'Each row contains a network, link, optional label text, custom icon URL, and icon background color. Label font size, weight, and color are configured below.',\n 'blocks.help.bizSocialLinks': 'Networks: X, Rabbit, Facebook, TikTok, and Instagram (ig). Labels and custom icon URLs are optional. Rabbit/TikTok use the web placeholder icon in MJML unless you provide an icon URL.',\n 'blocks.help.iconRadius': '0 gives square corners. Large values such as 999, or about half the icon size, make it circular.',\n 'blocks.help.iconSpacing': 'Space around each icon; horizontally this is the gap between icons (MJML inner-padding).',\n 'blocks.help.bizIconSpacing': 'Gap between icons (MJML inner-padding).',\n 'blocks.placeholder.buttonWidth': 'Empty = auto, e.g. 280px or 100%',\n 'blocks.option.top': 'Top',\n 'blocks.option.middle': 'Middle',\n 'blocks.option.bottom': 'Bottom',\n};\n\nconst FALLBACK_LOCALE: SimpleMailLocale = 'zh-CN';\n\nexport function createI18nContext(options: SimpleMailI18nOptions = {}): SimpleMailI18nContext {\n const locale = options.locale ?? FALLBACK_LOCALE;\n const base = locale === 'en-US' ? enUSMessages : zhCNMessages;\n const messages: SimpleMailMessages = { ...zhCNMessages, ...base };\n for (const [key, value] of Object.entries(options.messages ?? {})) {\n if (typeof value === 'string') messages[key] = value;\n }\n const t: SimpleMailT = (key, params) => {\n let text = messages[key] ?? zhCNMessages[key] ?? key;\n if (params) {\n for (const [name, value] of Object.entries(params)) {\n text = text.replaceAll(`{${name}}`, String(value));\n }\n }\n return text;\n };\n return { locale, messages, t };\n}\n","import { normalizeAccentHex } from '../utils/accentColor';\nimport { h } from '../utils/dom';\nimport { createI18nContext, type SimpleMailT } from '../i18n';\n\n/** 邮件常用预设色 */\nexport const COLOR_PICKER_PALETTE = [\n '#FFFFFF',\n '#F5F6F8',\n '#E6E8EC',\n '#9AA0A6',\n '#6B7280',\n '#433F3F',\n '#1F2328',\n '#000000',\n '#DC2626',\n '#EA580C',\n '#FF5A00',\n '#CA8A04',\n '#16A34A',\n '#059669',\n '#2563EB',\n '#4F46E5',\n '#7C3AED',\n '#DB2777',\n '#FEE2E2',\n '#FFEDD5',\n '#FEF3C7',\n '#D1FAE5',\n '#EEF2FF',\n '#F3E8FF',\n] as const;\n\nexport interface ColorPickerPopoverOptions {\n anchor: HTMLElement;\n layerRoot: HTMLElement;\n value: string;\n placeholder?: string;\n /** 显示「清除」并允许提交空值 */\n allowClear?: boolean;\n t?: SimpleMailT;\n /** 每次改色立即 onCommit(富文本/顶栏) */\n liveCommit?: boolean;\n onPreview?: (hex: string) => void;\n onCommit: (hex: string) => void;\n onClear?: () => void;\n /** 打开前调用(富文本:在失焦前保存选区) */\n onBeforeOpen?: () => void;\n /** 为 false 时不自动 focus 十六进制输入,避免抢编辑区选区 */\n autoFocusHex?: boolean;\n onClosed?: () => void;\n}\n\nlet activeTeardown: (() => void) | null = null;\n\nexport function isColorPickerOpen(): boolean {\n return activeTeardown !== null;\n}\n\nexport function closeActiveColorPicker(): void {\n activeTeardown?.();\n activeTeardown = null;\n}\n\nfunction positionLayer(layer: HTMLElement, anchor: HTMLElement, layerRoot: HTMLElement) {\n const rect = anchor.getBoundingClientRect();\n const rootRect = layerRoot.getBoundingClientRect();\n layer.style.top = `${rect.bottom - rootRect.top + 4}px`;\n layer.style.left = `${Math.max(4, rect.left - rootRect.left)}px`;\n\n requestAnimationFrame(() => {\n const popRect = layer.getBoundingClientRect();\n if (popRect.right > rootRect.right - 8) {\n layer.style.left = `${Math.max(4, parseFloat(layer.style.left) - (popRect.right - rootRect.right + 8))}px`;\n }\n if (popRect.bottom > window.innerHeight - 8) {\n layer.style.top = `${rect.top - rootRect.top - popRect.height - 4}px`;\n }\n });\n}\n\n/** 点击色块网格缝隙等无焦点区域时,避免编辑区 blur 导致误提交 */\nfunction guardInlineEditFocus(layer: HTMLElement) {\n layer.addEventListener(\n 'mousedown',\n (e) => {\n const t = e.target as Element;\n if (t.closest('input, button, select, textarea, a, [contenteditable]')) return;\n e.preventDefault();\n },\n true,\n );\n}\n\nfunction syncNativeInput(native: HTMLInputElement, hex: string) {\n const n = normalizeAccentHex(hex);\n if (n) native.value = n;\n}\n\n/** 打开自定义色板(含关闭按钮);点击色卡触发,不再使用系统色板。 */\nexport function openColorPickerPopover(opts: ColorPickerPopoverOptions): void {\n closeActiveColorPicker();\n opts.onBeforeOpen?.();\n const t = opts.t ?? createI18nContext().t;\n\n const initialHex = normalizeAccentHex(opts.value);\n let draft = initialHex ?? '#4F46E5';\n let closed = false;\n\n const layer = h('div', {\n class: 'sm-color-picker-layer',\n 'data-sm-color-picker-layer': '',\n });\n const panel = h('div', {\n class: 'sm-color-picker',\n role: 'dialog',\n 'aria-label': t('colorPicker.title'),\n });\n\n const closeBtn = h(\n 'button',\n {\n class: 'sm-color-picker__close',\n type: 'button',\n title: t('common.close'),\n 'aria-label': t('common.close'),\n },\n ['×'],\n );\n\n const head = h('div', { class: 'sm-color-picker__head' }, [\n h('span', { class: 'sm-color-picker__title' }, [t('colorPicker.title')]),\n closeBtn,\n ]);\n\n const native = h('input', {\n class: 'sm-color-picker__native',\n type: 'color',\n 'aria-label': t('colorPicker.custom'),\n }) as HTMLInputElement;\n\n const hexInput = h('input', {\n class: 'sm-input sm-color-picker__hex',\n type: 'text',\n placeholder: opts.placeholder ?? '#RRGGBB',\n }) as HTMLInputElement;\n\n const applyDraft = (hex: string, commit: boolean) => {\n const n = normalizeAccentHex(hex);\n if (!n) return;\n draft = n;\n syncNativeInput(native, n);\n hexInput.value = n;\n opts.onPreview?.(n);\n if (commit || opts.liveCommit) opts.onCommit(n);\n };\n\n syncNativeInput(native, draft);\n hexInput.value = initialHex ?? '';\n\n const teardown = (commit: boolean) => {\n if (closed) return;\n closed = true;\n activeTeardown = null;\n document.removeEventListener('keydown', onKey, true);\n document.removeEventListener('mousedown', onDoc, true);\n layer.remove();\n if (commit && !opts.liveCommit) {\n const n = normalizeAccentHex(draft);\n if (n) opts.onCommit(n);\n }\n opts.onClosed?.();\n };\n\n const swatchGrid = h('div', { class: 'sm-color-picker__swatches' });\n for (const hex of COLOR_PICKER_PALETTE) {\n const btn = h('button', {\n class: 'sm-color-picker__swatch',\n type: 'button',\n title: t('colorPicker.doubleClickConfirm', { hex }),\n style: `background:${hex}`,\n 'aria-label': hex,\n });\n btn.addEventListener('click', () => applyDraft(hex, false));\n btn.addEventListener('dblclick', (e) => {\n e.preventDefault();\n applyDraft(hex, true);\n teardown(true);\n });\n swatchGrid.append(btn);\n }\n\n native.addEventListener('input', () => applyDraft(native.value, false));\n\n hexInput.addEventListener('input', () => {\n const n = normalizeAccentHex(hexInput.value);\n if (n) applyDraft(n, false);\n });\n hexInput.addEventListener('keydown', (e) => {\n const ke = e as KeyboardEvent;\n if (ke.key === 'Enter') {\n ke.preventDefault();\n const n = normalizeAccentHex(hexInput.value);\n if (n) {\n applyDraft(n, true);\n teardown(true);\n }\n }\n });\n\n const footKids: HTMLElement[] = [];\n if (opts.allowClear) {\n footKids.push(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--ghost sm-color-picker__clear',\n type: 'button',\n onclick: () => {\n opts.onClear?.();\n teardown(false);\n },\n },\n [t('common.clear')],\n ),\n );\n }\n\n panel.append(head, swatchGrid, native, hexInput);\n if (footKids.length) panel.append(h('div', { class: 'sm-color-picker__foot' }, footKids));\n\n layer.append(panel);\n guardInlineEditFocus(layer);\n opts.layerRoot.append(layer);\n positionLayer(layer, opts.anchor, opts.layerRoot);\n\n closeBtn.addEventListener('click', (e) => {\n e.preventDefault();\n teardown(true);\n });\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n if (initialHex) opts.onPreview?.(initialHex);\n teardown(false);\n }\n };\n\n const onDoc = (ev: MouseEvent) => {\n const t = ev.target as Node;\n if (layer.contains(t) || opts.anchor.contains(t)) return;\n teardown(true);\n };\n\n document.addEventListener('keydown', onKey, true);\n setTimeout(() => document.addEventListener('mousedown', onDoc, true), 0);\n\n activeTeardown = () => teardown(true);\n if (opts.autoFocusHex !== false) hexInput.focus();\n}\n\nexport interface BindColorPickerInputOptions\n extends Omit<ColorPickerPopoverOptions, 'anchor' | 'layerRoot' | 'value'> {\n layerRoot?: HTMLElement;\n getValue?: () => string;\n}\n\n/** 拦截色卡点击,改为打开自定义色板。 */\nexport function bindColorPickerInput(\n pick: HTMLInputElement,\n opts: BindColorPickerInputOptions,\n): void {\n const t = opts.t ?? createI18nContext().t;\n if (!pick.title) pick.title = t('colorPicker.openTitle');\n\n pick.addEventListener('mousedown', (e) => {\n e.preventDefault();\n opts.onBeforeOpen?.();\n });\n\n pick.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const layerRoot =\n opts.layerRoot ?? (pick.closest('.sm-root') as HTMLElement | null) ?? document.body;\n const value = opts.getValue?.() ?? pick.value;\n openColorPickerPopover({\n ...opts,\n anchor: pick,\n layerRoot,\n value,\n });\n });\n}\n","/**\n * 把任意 DOM 元素临时变成 contenteditable,并暴露提交/取消/选区事件。\n *\n * 设计要点:\n * - 不直接同步到 store。编辑过程中只在本地累积,提交(blur / Esc / 单行 Enter)时一次性回调,\n * 避免每次按键都触发画布全量重渲染导致光标丢失。\n * - mode=plain 时仅取 textContent,并在 paste/keydown 上拦截换行;\n * mode=rich 时保留 inline HTML,但会在提交时做一次清理(白名单标签 + inline style);\n * mode=html 时提交原始 innerHTML(用于 mj-raw 等),不挂富文本浮动条。\n * - 选区变化通过 `onSelectionChange` 实时回调,便于浮动工具条同步按钮状态/位置。\n */\nimport { normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport {\n findListAtSelection,\n getListIndent,\n LIST_INDENT_DEFAULT_PX,\n resolveGlobalListIndentPx,\n setListIndent as applyListIndentToElement,\n type ListIndentValue,\n} from '../utils/emailListStyles';\nimport type { GlobalStyles } from '../types';\nimport {\n applyListCommandForSelection,\n detectListFormats,\n findListItem,\n getListItemsInRange,\n getCaretTextOffsetAtRangeEnd,\n insertSelectionBoundaryMarkers,\n mergeListItemOnBackspace,\n mergeAdjacentSameTypeLists,\n mergeNextListItemOnDelete,\n removeSelectionBoundaryMarkers,\n restoreCaretAfterListMutation,\n restoreCaretToEndOfListInSelectionBounds,\n splitListItemOnEnter,\n} from '../utils/inlineListEditing';\nimport {\n richTextExecCommand,\n richTextQueryCommandState,\n richTextQueryCommandValue,\n} from '../utils/richTextCommand';\nimport {\n isRichHtmlEffectivelyEmpty,\n isRichHtmlEditorSeedOnly,\n hasRichHtmlLineBreak,\n getRichHtmlPlainText,\n} from '../utils/richHtmlEmpty';\nimport { isColorPickerOpen } from './ColorPickerPopover';\n\nexport interface InlineEditorOptions {\n el: HTMLElement;\n initialValue: string;\n mode: 'rich' | 'plain' | 'html';\n multiline: boolean;\n placeholder?: string;\n onCommit: (value: string) => void;\n onCancel: () => void;\n onSelectionChange?: (state: SelectionState | null) => void;\n /** 文档全局列表默认缩进(px),用于工具条展示继承值 */\n globalStyles?: GlobalStyles;\n}\n\nexport interface SelectionState {\n hasSelection: boolean;\n rect: DOMRect | null;\n /** queryCommandState 的若干常用值,用于工具条按钮高亮 */\n formats: {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n unorderedList: boolean;\n orderedList: boolean;\n align: 'left' | 'center' | 'right' | 'justify' | null;\n link: string | null;\n foreColor: string | null;\n fontSize: string | null;\n fontName: string | null;\n fontWeight: string | null;\n backColor: string | null;\n /** 光标是否在 ul/ol 内 */\n inList: boolean;\n /** null = 跟随邮件全局;非 null = 本列表显式 px */\n listIndentPx: ListIndentValue;\n /** 邮件全局列表默认缩进(px) */\n listIndentGlobalPx: number;\n /** 当前列表实际生效的缩进(px) */\n listIndentEffectivePx: number;\n };\n}\n\nexport class InlineEditor {\n private opts: InlineEditorOptions;\n private el: HTMLElement;\n private listeners: Array<() => void> = [];\n private committed = false;\n private originalContent: string;\n /** 防止 selectionchange 在我们 destroy 之后还回调 */\n private alive = true;\n /**\n * 上一次\"用户在编辑区内\"时的有效选区。\n * 当用户去工具条点 select / input 时焦点会离开 contenteditable,\n * execCommand 在那种状态下会哑火——必须先 focus 回来,再恢复选区,再执行命令。\n */\n private savedRange: Range | null = null;\n /** 富文本工具条控件会抢走焦点,此时 getSelection 已不在编辑区内;保留上一帧状态避免工具条整栏收起。 */\n private lastSelectionState: SelectionState | null = null;\n /** hiliteColor 在输入前不写 DOM;记录「待输入背景色 + 锚点」以便 bar 即时同步,移开光标后清除 */\n private pendingHiliteColor: string | null = null;\n private pendingHiliteAnchor: string | null = null;\n /** 进入编辑时空内容;用于忽略未改动就失焦时的占位 <br> */\n private initiallyEmpty = false;\n private edited = false;\n /** 是否曾有过文本(含空格);用于区分「仅换行」与「输入后清空残留的 <br>」 */\n private hadTextInSession = false;\n /** 工具条执行列表命令时,跳过 input 里的相邻列表合并(避免合并后再用旧偏移恢复光标) */\n private suppressListMerge = false;\n\n constructor(opts: InlineEditorOptions) {\n this.opts = opts;\n this.el = opts.el;\n this.originalContent = this.el.innerHTML;\n this._mount();\n }\n\n /** 立即提交并销毁。 */\n commit() {\n if (this.committed) return;\n this.committed = true;\n let value: string;\n if (this.opts.mode === 'plain') {\n value = (this.el.textContent ?? '').replace(/\\u200b/g, '');\n } else if (this.opts.mode === 'html') {\n value = this.el.innerHTML;\n } else {\n const sanitized = sanitizeRichHtml(this.el.innerHTML);\n const text = (this.el.textContent ?? '').replace(/\\u200b/g, '');\n if (text.length > 0) {\n value = sanitized;\n } else if (\n this.initiallyEmpty &&\n !this.edited &&\n isRichHtmlEditorSeedOnly(sanitized)\n ) {\n value = '';\n } else if (hasRichHtmlLineBreak(sanitized) && !this.hadTextInSession) {\n // 从未有过文本,仅换行(含单个 <br>)视为有效\n value = sanitized;\n } else {\n // 曾有过文本后清空,或无文本无换行\n value = '';\n }\n }\n\n this.opts.onCommit(value);\n this.destroy(false);\n }\n\n /** 放弃编辑、还原 DOM 并销毁。 */\n cancel() {\n if (this.committed) return;\n this.committed = true;\n this.el.innerHTML = this.originalContent;\n this.opts.onCancel();\n this.destroy(false);\n }\n\n destroy(restore = true) {\n if (!this.alive) return;\n this.alive = false;\n this.listeners.forEach((off) => off());\n this.listeners = [];\n this.el.removeAttribute('contenteditable');\n this.el.classList.remove('sm-inline-editing');\n if (restore && !this.committed) this.el.innerHTML = this.originalContent;\n }\n\n /**\n * 保存当前在编辑区内的选区。Toolbar 在 mousedown(capture)阶段调用:\n * 在浏览器把焦点切到 select/input 之前抢先存档。\n */\n saveSelection() {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n if (!this.el.contains(range.startContainer) || !this.el.contains(range.endContainer)) return;\n this.savedRange = range.cloneRange();\n }\n\n /** 直接对当前选区执行命令(供 Toolbar 调用)。 */\n exec(command: string, value?: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const sel = window.getSelection();\n let hiliteAnchor: string | null = null;\n if (command === 'hiliteColor' && sel?.rangeCount) {\n hiliteAnchor = selectionAnchorKey(sel.getRangeAt(0));\n }\n // 列表:Chrome 等在 styleWithCSS=true 下 insertOrderedList / insertUnorderedList 常失灵,需退回 HTML 列表标签\n const isListCmd = command === 'insertOrderedList' || command === 'insertUnorderedList';\n if (isListCmd && sel?.rangeCount) {\n const range = sel.getRangeAt(0);\n const itemsInRange = range.collapsed\n ? []\n : getListItemsInRange(range, this.el);\n const savedOffset = getCaretTextOffsetAtRangeEnd(this.el, range);\n const boundaryMarkers = insertSelectionBoundaryMarkers(range);\n this.suppressListMerge = true;\n try {\n const wantUl = command === 'insertUnorderedList';\n if (applyListCommandForSelection(this.el, range, wantUl, itemsInRange)) {\n restoreCaretAfterListMutation(this.el, boundaryMarkers.end, savedOffset);\n } else {\n richTextExecCommand('styleWithCSS', false, 'false');\n richTextExecCommand(command, false, value);\n if (!restoreCaretToEndOfListInSelectionBounds(this.el)) {\n restoreCaretAfterListMutation(this.el, boundaryMarkers.end, savedOffset);\n }\n }\n } finally {\n this.suppressListMerge = false;\n removeSelectionBoundaryMarkers(this.el);\n }\n this.saveSelection();\n this._emitSelection();\n return;\n } else {\n richTextExecCommand('styleWithCSS', false, isListCmd ? 'false' : 'true');\n richTextExecCommand(command, false, value);\n }\n if (command === 'hiliteColor') {\n this.pendingHiliteColor = value ?? null;\n this.pendingHiliteAnchor = hiliteAnchor;\n }\n // 命令执行后选区可能已经变化(例如插入链接会扩展),刷新存档\n this.saveSelection();\n this._emitSelection();\n }\n\n /** 设置当前列表缩进;null 表示恢复默认(不设值) */\n setListIndent(px: ListIndentValue) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const sel = window.getSelection();\n if (!sel?.rangeCount) return;\n const list = findListAtSelection(sel.anchorNode, this.el);\n if (!list) return;\n applyListIndentToElement(list, px);\n this.saveSelection();\n this._emitSelection();\n }\n\n /**\n * 设置或移除超链接:已有 &lt;a&gt; 则改 href;否则 createLink。\n * (仅用 createLink 在链接内需改 URL 时浏览器行为不一致。)\n */\n setLink(url: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const trimmed = url.trim();\n if (!trimmed) {\n richTextExecCommand('unlink');\n this.saveSelection();\n this._emitSelection();\n return;\n }\n const safe = /^https?:|^mailto:|^tel:|^\\{\\{/i.test(trimmed) ? trimmed : `https://${trimmed}`;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const anchor = findAncestorAnchor(sel.anchorNode, this.el);\n if (anchor) {\n anchor.setAttribute('href', safe);\n if (!anchor.getAttribute('rel')) anchor.setAttribute('rel', 'noopener');\n } else {\n richTextExecCommand('styleWithCSS', false, 'true');\n richTextExecCommand('createLink', false, safe);\n }\n this.saveSelection();\n this._emitSelection();\n }\n\n /** 在当前光标处插入纯文本(供\"插入变量\"使用)。 */\n insertText(text: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n richTextExecCommand('insertText', false, text);\n this.saveSelection();\n }\n\n /** 在当前光标处插入 HTML 片段(供链接类变量使用)。 */\n insertHtml(html: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n richTextExecCommand('insertHTML', false, html);\n this.saveSelection();\n }\n\n /** Toolbar 关闭某个面板/控件后调用,把选区还给编辑区,方便用户继续输入。 */\n refocus() {\n this._ensureFocus();\n this._restoreSelection();\n }\n\n /** 字号:走原生 fontSize 命令(styleWithCSS 下浏览器会写 span),与 foreColor 同类 */\n applyFontSize(px: string) {\n this.exec('fontSize', pxToLegacyFontSize(px));\n }\n\n /**\n * 字重:浏览器只有 bold 命令,没有 font-weight:500/600 的原生 API,需包 span。\n * 有选区包裹内容;折叠光标插入 typing span,后续输入沿用。\n */\n applyFontWeight(weight: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n if (!this.el.contains(range.startContainer) || !this.el.contains(range.endContainer)) return;\n\n if (!range.collapsed) {\n const span = document.createElement('span');\n span.setAttribute('style', `font-weight:${weight};`);\n try {\n span.appendChild(range.extractContents());\n range.insertNode(span);\n const newRange = document.createRange();\n newRange.selectNodeContents(span);\n sel.removeAllRanges();\n sel.addRange(newRange);\n } catch {\n return;\n }\n } else {\n const span = document.createElement('span');\n span.setAttribute('style', `font-weight:${weight};`);\n span.appendChild(document.createTextNode('\\u200b'));\n range.insertNode(span);\n const caret = document.createRange();\n caret.setStart(span.firstChild!, 1);\n caret.collapse(true);\n sel.removeAllRanges();\n sel.addRange(caret);\n }\n\n this.saveSelection();\n this._emitSelection();\n }\n\n /** 内联编辑根节点(如 `.sm-text-content`)的盒模型矩形,供富文本条贴在正文区域外沿定位 */\n getAnchorRect(): DOMRect {\n return this.el.getBoundingClientRect();\n }\n\n private _restoreSelection() {\n if (!this.savedRange) return;\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(this.savedRange);\n }\n\n /* -------------------------------- 内部 ---------------------------------- */\n\n private _mount() {\n const { el, mode, multiline } = this.opts;\n el.setAttribute('contenteditable', 'true');\n el.classList.add('sm-inline-editing');\n el.classList.remove('is-empty');\n\n const initial = this.opts.initialValue ?? '';\n const initiallyEmpty =\n mode === 'plain' ? !initial.trim() : isRichHtmlEffectivelyEmpty(initial);\n this.initiallyEmpty = initiallyEmpty;\n this.edited = false;\n this.hadTextInSession =\n mode === 'plain'\n ? initial.replace(/\\u200b/g, '').length > 0\n : getRichHtmlPlainText(initial).length > 0;\n\n if (initiallyEmpty) {\n // 空 rich 块需一个 <br> 锚点,浏览器才能稳定接收输入/换行;不在编辑态显示 placeholder\n el.innerHTML = mode === 'plain' ? '' : '<br>';\n } else {\n el.innerHTML = mode === 'plain' ? escapeHtml(initial) : initial;\n }\n\n // 初始聚焦并把光标移到末尾,便于\"双击 → 直接输入\"\n requestAnimationFrame(() => {\n el.focus();\n placeCaretAtEnd(el);\n });\n\n let imeComposing = false;\n /** 部分浏览器在 compositionend 之后才派发 Enter keydown,需吞掉紧随其后的这一次 */\n let suppressNextEnter = false;\n\n const onCompositionStart = () => {\n imeComposing = true;\n };\n const onCompositionEnd = () => {\n imeComposing = false;\n suppressNextEnter = true;\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.cancel();\n return;\n }\n if (e.key === 'Enter') {\n // 拼音等 IME 用 Enter 上屏:不可 preventDefault / insertLineBreak\n if (e.isComposing || imeComposing || e.keyCode === 229) return;\n if (suppressNextEnter) {\n suppressNextEnter = false;\n return;\n }\n if (!multiline) {\n e.preventDefault();\n this.commit();\n return;\n }\n if (mode === 'rich') {\n if (e.shiftKey) {\n e.preventDefault();\n richTextExecCommand('insertLineBreak');\n this.saveSelection();\n this._emitSelection();\n return;\n }\n const sel = window.getSelection();\n if (sel?.rangeCount) {\n const range = sel.getRangeAt(0);\n const li = findListItem(range.startContainer, el);\n if (li && el.contains(li)) {\n e.preventDefault();\n splitListItemOnEnter(li, range);\n this.saveSelection();\n this._emitSelection();\n return;\n }\n }\n }\n // 非列表:回车默认会插入 <div>,强制 <br> 避免出现各种奇怪嵌套\n e.preventDefault();\n richTextExecCommand('insertLineBreak');\n return;\n }\n if (e.key === 'Backspace' && mode === 'rich' && multiline) {\n if (e.isComposing || imeComposing) return;\n const sel = window.getSelection();\n if (!sel?.rangeCount) return;\n const range = sel.getRangeAt(0);\n const li = findListItem(range.startContainer, el);\n if (li && el.contains(li) && mergeListItemOnBackspace(li, range)) {\n e.preventDefault();\n this.saveSelection();\n this._emitSelection();\n }\n return;\n }\n if (e.key === 'Delete' && mode === 'rich' && multiline) {\n if (e.isComposing || imeComposing) return;\n const sel = window.getSelection();\n if (!sel?.rangeCount) return;\n const range = sel.getRangeAt(0);\n const li = findListItem(range.startContainer, el);\n if (li && el.contains(li) && mergeNextListItemOnDelete(li, range)) {\n e.preventDefault();\n this.saveSelection();\n this._emitSelection();\n }\n }\n };\n const onBlur = (e: FocusEvent) => {\n // 给点钟摆余地,避免点击工具条按钮时立刻提交\n setTimeout(() => {\n if (!this.alive) return;\n const active = document.activeElement as HTMLElement | null;\n if (active && (active === el || el.contains(active))) return;\n if (isColorPickerOpen()) return;\n if (active?.closest?.('.sm-floating-toolbar, .sm-color-picker, .sm-color-picker-layer')) return;\n if (active?.closest?.('.sm-topbar, .sm-popover, .sm-panel--variable-picker')) return;\n // 从左栏拖入 / 画布内 Sortable 排序:mousedown 会先 blur,若在此时提交会触发画布重渲染并拆掉 drop 目标\n if (active?.closest?.('.sm-panel--left')) return;\n if (active?.closest?.('.sm-block__handle, .sm-section__handle')) return;\n const related = e.relatedTarget as HTMLElement | null;\n if (related?.closest?.('.sm-panel--left')) return;\n if (related?.closest?.('.sm-block-card')) return;\n if (related?.closest?.('.sm-block__handle, .sm-section__handle')) return;\n if (related?.closest?.('.sm-color-picker, .sm-color-picker-layer')) return;\n if (related?.closest?.('.sm-topbar, .sm-popover, .sm-panel--variable-picker')) return;\n if (document.querySelector('.sm-root .sm-drag, .sm-root .sm-chosen')) return;\n this.commit();\n }, 0);\n };\n const markEdited = () => {\n this.edited = true;\n };\n\n const syncTextPresence = () => {\n const t = (el.textContent ?? '').replace(/\\u200b/g, '');\n if (t.length > 0) this.hadTextInSession = true;\n };\n\n const onPaste = (e: ClipboardEvent) => {\n if (mode === 'rich' && multiline && !e.clipboardData?.getData('text/html')) {\n e.preventDefault();\n markEdited();\n const text = e.clipboardData?.getData('text/plain') ?? '';\n richTextExecCommand('insertHTML', false, plainTextToRichHtml(text));\n syncTextPresence();\n this.saveSelection();\n this._emitSelection();\n return;\n }\n if (mode !== 'plain') return;\n e.preventDefault();\n markEdited();\n const text = e.clipboardData?.getData('text/plain') ?? '';\n const safe = multiline ? text : text.replace(/\\r?\\n/g, ' ');\n richTextExecCommand('insertText', false, safe);\n };\n\n const onSelChange = () => {\n if (!this.alive) return;\n this._syncPendingHiliteAnchor();\n this.saveSelection();\n this._emitSelection();\n };\n\n const onInput = () => {\n markEdited();\n syncTextPresence();\n if (mode === 'rich' && multiline && !this.suppressListMerge) {\n mergeAdjacentSameTypeLists(el);\n }\n onSelChange();\n };\n\n const linkInsideEditing = (t: EventTarget | null): HTMLAnchorElement | null => {\n if (!(t instanceof Element)) return null;\n const a = t.closest('a');\n if (!a || !el.contains(a)) return null;\n const href = a.getAttribute('href');\n if (href == null || href === '' || href === '#') return null;\n return a;\n };\n\n /** Chrome:contenteditable 里的 <a href> 仍会在 click 时导航;mousedown 不拦截以保留拖选 */\n const stopLinkActivate = (e: MouseEvent) => {\n if (mode !== 'rich' && mode !== 'html') return;\n if (!linkInsideEditing(e.target)) return;\n e.preventDefault();\n };\n\n el.addEventListener('keydown', onKeyDown);\n el.addEventListener('compositionstart', onCompositionStart);\n el.addEventListener('compositionend', onCompositionEnd);\n el.addEventListener('blur', onBlur);\n el.addEventListener('paste', onPaste);\n document.addEventListener('selectionchange', onSelChange);\n el.addEventListener('input', onInput);\n el.addEventListener('mouseup', onSelChange);\n if (mode === 'rich' || mode === 'html') {\n el.addEventListener('click', stopLinkActivate, true);\n el.addEventListener('auxclick', stopLinkActivate, true);\n }\n\n this.listeners.push(\n () => el.removeEventListener('keydown', onKeyDown),\n () => el.removeEventListener('compositionstart', onCompositionStart),\n () => el.removeEventListener('compositionend', onCompositionEnd),\n () => el.removeEventListener('blur', onBlur),\n () => el.removeEventListener('paste', onPaste),\n () => document.removeEventListener('selectionchange', onSelChange),\n () => el.removeEventListener('input', onInput),\n () => el.removeEventListener('mouseup', onSelChange),\n ...(mode === 'rich' || mode === 'html'\n ? [\n () => el.removeEventListener('click', stopLinkActivate, true),\n () => el.removeEventListener('auxclick', stopLinkActivate, true),\n ]\n : []),\n );\n }\n\n private _ensureFocus() {\n if (document.activeElement !== this.el) {\n this.el.focus();\n }\n }\n\n private _syncPendingHiliteAnchor() {\n if (!this.pendingHiliteColor || !this.pendingHiliteAnchor) return;\n const sel = window.getSelection();\n if (!sel?.rangeCount) {\n this._clearPendingHilite();\n return;\n }\n if (selectionAnchorKey(sel.getRangeAt(0)) !== this.pendingHiliteAnchor) {\n this._clearPendingHilite();\n }\n }\n\n private _clearPendingHilite() {\n this.pendingHiliteColor = null;\n this.pendingHiliteAnchor = null;\n }\n\n private _emitSelection() {\n if (!this.opts.onSelectionChange) return;\n if (this.opts.mode === 'plain' || this.opts.mode === 'html') {\n this.opts.onSelectionChange(null); // plain / 原始 HTML 不挂富文本浮动条\n return;\n }\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) {\n this._emitSelectionOrKeepToolbar(null);\n return;\n }\n if (!this.el.contains(sel.anchorNode)) {\n this._emitSelectionOrKeepToolbar(null);\n return;\n }\n const range = sel.getRangeAt(0);\n const rect = sel.isCollapsed ? this._caretRect(range) : range.getBoundingClientRect();\n\n const align: SelectionState['formats']['align'] = richTextQueryCommandState('justifyCenter')\n ? 'center'\n : richTextQueryCommandState('justifyRight')\n ? 'right'\n : richTextQueryCommandState('justifyFull')\n ? 'justify'\n : 'left';\n\n const link = (() => {\n const a = findAncestorAnchor(sel.anchorNode, this.el);\n return a?.getAttribute('href') ?? null;\n })();\n\n const inline = resolveInlineFormatsAtSelection(this.el, sel);\n\n let foreColor = inline.foreColor ?? safeQueryValue('foreColor');\n let backColor = inline.backColor;\n if (\n !backColor &&\n range.collapsed &&\n this.pendingHiliteColor &&\n this.pendingHiliteAnchor === selectionAnchorKey(range)\n ) {\n backColor = this.pendingHiliteColor;\n }\n if (inline.backColor) this._clearPendingHilite();\n\n const listFormats = detectListFormats(sel.anchorNode, this.el);\n const activeList = findListAtSelection(sel.anchorNode, this.el);\n const listIndentPx = activeList ? getListIndent(activeList) : null;\n const listIndentGlobalPx = this.opts.globalStyles\n ? resolveGlobalListIndentPx(this.opts.globalStyles)\n : LIST_INDENT_DEFAULT_PX;\n const listIndentEffectivePx =\n listIndentPx != null ? listIndentPx : listIndentGlobalPx;\n\n const state: SelectionState = {\n hasSelection: true,\n rect,\n formats: {\n bold: richTextQueryCommandState('bold'),\n italic: richTextQueryCommandState('italic'),\n underline: richTextQueryCommandState('underline'),\n strikethrough: richTextQueryCommandState('strikeThrough'),\n unorderedList:\n listFormats.unorderedList || richTextQueryCommandState('insertUnorderedList'),\n orderedList: listFormats.orderedList || richTextQueryCommandState('insertOrderedList'),\n align,\n link,\n foreColor,\n fontSize: inline.fontSize,\n fontName: safeQueryValue('fontName'),\n fontWeight: inline.fontWeight,\n backColor,\n inList: !!activeList,\n listIndentPx,\n listIndentGlobalPx,\n listIndentEffectivePx,\n },\n };\n this.lastSelectionState = state;\n this.opts.onSelectionChange(state);\n }\n\n /** 焦点在浮动工具条上时沿用上一帧选区,避免点开链接框 / 颜色等控件后工具条消失。 */\n private _emitSelectionOrKeepToolbar(fallback: null) {\n if (\n fallback === null &&\n this.lastSelectionState &&\n isColorPickerOpen() ||\n document.activeElement?.closest?.(\n '.sm-floating-toolbar, .sm-color-picker, .sm-color-picker-layer',\n )\n ) {\n this.opts.onSelectionChange?.(this.lastSelectionState);\n return;\n }\n if (fallback === null) this.lastSelectionState = null;\n this.opts.onSelectionChange?.(fallback);\n }\n\n private _caretRect(range: Range): DOMRect | null {\n const rects = range.getClientRects();\n if (rects.length) return rects[0];\n // 折叠选区在空段落上时 rects 为空,造一个零宽 range 拿到位置\n const tmp = range.cloneRange();\n tmp.collapse(true);\n const span = document.createElement('span');\n span.appendChild(document.createTextNode('\\u200b'));\n tmp.insertNode(span);\n const r = span.getBoundingClientRect();\n span.remove();\n return r;\n }\n}\n\n/* ----------------------------- helpers ----------------------------- */\n\nfunction findAncestorAnchor(node: Node | null, root: HTMLElement): HTMLAnchorElement | null {\n while (node && node !== root) {\n if (node.nodeType === 1 && (node as HTMLElement).tagName === 'A') {\n return node as HTMLAnchorElement;\n }\n node = node.parentNode;\n }\n return null;\n}\n\nfunction placeCaretAtEnd(el: HTMLElement) {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nfunction safeQueryValue(cmd: string): string | null {\n try {\n const v = richTextQueryCommandValue(cmd);\n return v ? v : null;\n } catch {\n return null;\n }\n}\n\n/** 光标/选区处的字号、字重、文字色、背景色(queryCommandValue 对 span style 与链接内颜色不可靠) */\nfunction resolveInlineFormatsAtSelection(\n root: HTMLElement,\n sel: Selection,\n): {\n fontSize: string | null;\n fontWeight: string | null;\n foreColor: string | null;\n backColor: string | null;\n} {\n const host = selectionHostElement(sel, root);\n if (!host) return { fontSize: null, fontWeight: null, foreColor: null, backColor: null };\n\n let fontWeight: string | null = null;\n for (let el: HTMLElement | null = host; el && root.contains(el) && el !== root; el = el.parentElement) {\n if (el.style.fontWeight) fontWeight = el.style.fontWeight;\n }\n\n const foreColor = resolveForeColorAtSelection(root, host);\n const backColor = resolveBackColorAtSelection(root, host);\n // 用 computed px,避免读到 .sm-text-content 块级默认字号盖掉 <font>/span 上的真实字号\n const fontSize = window.getComputedStyle(host).fontSize;\n\n if (!fontWeight) {\n fontWeight = richTextQueryCommandState('bold')\n ? '700'\n : normalizeFontWeightStep(window.getComputedStyle(host).fontWeight);\n } else {\n fontWeight = normalizeFontWeightStep(fontWeight);\n }\n\n return { fontSize, fontWeight, foreColor, backColor };\n}\n\n/** 光标处文字色(foreColor / 链接局部 color;queryCommandValue 在 <a> 内常不准) */\nfunction resolveForeColorAtSelection(root: HTMLElement, host: HTMLElement): string | null {\n for (let el: HTMLElement | null = host; el && root.contains(el) && el !== root; el = el.parentElement) {\n const inline = el.style.color?.trim();\n if (inline) return inline;\n\n const fromAttr = readColorFromStyleAttr(el.getAttribute('style'));\n if (fromAttr) return fromAttr;\n }\n\n const computed = window.getComputedStyle(host).color;\n return computed || null;\n}\n\nfunction readColorFromStyleAttr(styleAttr: string | null): string | null {\n if (!styleAttr) return null;\n const m = styleAttr.match(/(?:^|;)\\s*color\\s*:\\s*([^;]+)/i);\n if (!m) return null;\n const c = m[1].trim();\n return c || null;\n}\n\n/** 光标处文字背景/高亮色(hiliteColor 的 queryCommandValue 在 Chrome 常为空,需读 DOM) */\nfunction resolveBackColorAtSelection(root: HTMLElement, host: HTMLElement): string | null {\n for (let el: HTMLElement | null = host; el && root.contains(el) && el !== root; el = el.parentElement) {\n const inline = el.style.backgroundColor?.trim();\n if (inline && !isTransparentColor(inline)) return inline;\n\n const fromAttr = readBackgroundFromStyleAttr(el.getAttribute('style'));\n if (fromAttr) return fromAttr;\n\n const computed = window.getComputedStyle(el).backgroundColor;\n if (computed && !isTransparentColor(computed)) return computed;\n }\n\n // 不用 queryCommandValue('hiliteColor'):它返回的是「下次输入用的颜色」,光标在无高亮处时仍会带上一次配置\n return null;\n}\n\nfunction readBackgroundFromStyleAttr(styleAttr: string | null): string | null {\n if (!styleAttr) return null;\n const m = styleAttr.match(/background(?:-color)?\\s*:\\s*([^;]+)/i);\n if (!m) return null;\n const c = m[1].trim();\n return c && !isTransparentColor(c) ? c : null;\n}\n\nfunction selectionHostElement(sel: Selection, root: HTMLElement): HTMLElement | null {\n const node = sel.anchorNode;\n if (!node || !root.contains(node)) return null;\n return node.nodeType === Node.TEXT_NODE ? node.parentElement : (node as HTMLElement);\n}\n\nfunction selectionAnchorKey(range: Range): string {\n return `${range.startContainer.nodeType}:${range.startOffset}:${range.endContainer.nodeType}:${range.endOffset}`;\n}\n\n/** execCommand fontSize 只认 1–7,与工具条 px 互转 */\nfunction pxToLegacyFontSize(px: string): string {\n const map: Record<string, string> = {\n '10px': '1',\n '12px': '2',\n '13px': '3',\n '14px': '3',\n '15px': '4',\n '16px': '4',\n '18px': '4',\n '20px': '5',\n '24px': '6',\n '28px': '6',\n '32px': '7',\n };\n const key = px.trim().toLowerCase();\n if (map[key]) return map[key];\n const num = parseFloat(key);\n if (Number.isNaN(num)) return '4';\n const steps: [number, string][] = [\n [10, '1'],\n [12, '2'],\n [14, '3'],\n [16, '4'],\n [20, '5'],\n [24, '6'],\n [32, '7'],\n ];\n let best = '4';\n let bestD = Infinity;\n for (const [size, legacy] of steps) {\n const d = Math.abs(size - num);\n if (d < bestD) {\n bestD = d;\n best = legacy;\n }\n }\n return best;\n}\n\nfunction isTransparentColor(c: string): boolean {\n const s = c.trim().toLowerCase();\n if (s === 'transparent' || s === 'inherit' || s === 'initial' || s === 'unset') return true;\n if (s === 'rgba(0, 0, 0, 0)' || s === 'rgba(0,0,0,0)') return true;\n const rgba = s.match(/^rgba?\\(\\s*(\\d+)[,\\s]+(\\d+)[,\\s]+(\\d+)(?:[,\\s/]+([\\d.]+))?\\s*\\)$/);\n if (rgba) {\n const a = rgba[4] !== undefined ? parseFloat(rgba[4]) : 1;\n return a === 0;\n }\n return false;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction plainTextToRichHtml(text: string): string {\n return escapeHtml(text).replace(/\\r\\n?/g, '\\n').replace(/\\n/g, '<br>');\n}\n\n/**\n * 邮件 HTML 必须只用一组保守的标签 + inline style。\n * 这里做一次轻量清理:\n * - 白名单标签:保留 a/b/strong/i/em/u/s/strike/span/br/p/div/ul/ol/li/h1-h6/font\n * - 标准化:<b> -> <strong>,<i> -> <em>,<font color> -> <span style=\"color:..\">\n * - 属性白名单:href / target / rel / style / class(保留邮件常见属性)\n */\nexport function sanitizeRichHtml(html: string): string {\n const tpl = document.createElement('template');\n tpl.innerHTML = html;\n walk(tpl.content);\n return tpl.innerHTML.replace(/\\u200b/g, '');\n\n function walk(root: Node) {\n const toRemove: Element[] = [];\n const all = (root as ParentNode).querySelectorAll('*');\n all.forEach((el) => {\n const tag = el.tagName.toLowerCase();\n if (tag === 'span' && el.getAttribute('data-sm-caret') === '1') {\n while (el.firstChild) el.parentNode?.insertBefore(el.firstChild, el);\n el.remove();\n return;\n }\n // <font color=\"...\" size=\"...\" face=\"...\"> → 转成 span style\n if (tag === 'font') {\n const span = document.createElement('span');\n const color = el.getAttribute('color');\n const size = el.getAttribute('size');\n const face = el.getAttribute('face');\n const styles: string[] = [el.getAttribute('style') ?? ''];\n if (color) styles.push(`color:${color}`);\n if (size) styles.push(`font-size:${fontSizeFromLegacy(size)}`);\n if (face) styles.push(`font-family:${face}`);\n const cleaned = styles.filter(Boolean).join(';');\n if (cleaned) span.setAttribute('style', cleaned);\n while (el.firstChild) span.appendChild(el.firstChild);\n el.parentNode?.replaceChild(span, el);\n return;\n }\n // 标签级白名单\n const allowed = [\n 'a',\n 'b',\n 'strong',\n 'i',\n 'em',\n 'u',\n 's',\n 'strike',\n 'span',\n 'br',\n 'p',\n 'div',\n 'ul',\n 'ol',\n 'li',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n ];\n if (!allowed.includes(tag)) {\n toRemove.push(el);\n return;\n }\n // 属性白名单\n const allowedAttrs = ['href', 'target', 'rel', 'style', 'class'];\n const listExtraAttrs = ['data-sm-list-indent'];\n [...el.attributes].forEach((attr) => {\n const name = attr.name.toLowerCase();\n const ok =\n allowedAttrs.includes(name) ||\n ((tag === 'ul' || tag === 'ol') && listExtraAttrs.includes(name));\n if (!ok) el.removeAttribute(attr.name);\n });\n // 链接安全\n if (tag === 'a') {\n const href = el.getAttribute('href') ?? '';\n if (/^javascript:/i.test(href)) el.setAttribute('href', '#');\n if (!el.getAttribute('rel')) el.setAttribute('rel', 'noopener');\n }\n if ((tag === 'p' || /^h[1-6]$/.test(tag)) && !hasMarginStyle(el)) {\n appendStyle(el, 'margin:0');\n }\n });\n toRemove.forEach((el) => {\n while (el.firstChild) el.parentNode?.insertBefore(el.firstChild, el);\n el.remove();\n });\n }\n}\n\nfunction hasMarginStyle(el: Element): boolean {\n const style = el.getAttribute('style') ?? '';\n return /(?:^|;)\\s*margin(?:-(?:top|right|bottom|left))?\\s*:/i.test(style);\n}\n\nfunction appendStyle(el: Element, style: string) {\n const raw = (el.getAttribute('style') ?? '').trim();\n el.setAttribute('style', raw ? `${raw.replace(/;+\\s*$/, '')};${style}` : style);\n}\n\nfunction fontSizeFromLegacy(size: string): string {\n // 旧 <font size=\"1..7\"> → px 近似\n const map: Record<string, string> = {\n '1': '10px',\n '2': '12px',\n '3': '14px',\n '4': '16px',\n '5': '20px',\n '6': '24px',\n '7': '32px',\n };\n return map[size] ?? size;\n}\n","import Sortable from 'sortablejs';\nimport type { Registry } from '../registry/registry';\nimport {\n createSection,\n findBlockLocation,\n findSection,\n pruneSectionIfEmpty,\n type Store,\n} from '../store/store';\nimport type {\n Block,\n Column,\n EditorUiOptions,\n EmailDoc,\n PaletteDropResult,\n RenderContext,\n Section,\n SectionAttrs,\n SectionLayout,\n} from '../types';\nimport { getSectionDynamicVariantKey } from '../utils/dynamicVariantSection';\nimport { blockButtonWidthCss, docContentWidthCss } from '../utils/contentWidth';\nimport { globalListIndentCssVarValue } from '../utils/emailListStyles';\nimport { normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport { clear, escapeHtml, h } from '../utils/dom';\nimport {\n defaultPaddingForLockedBlock,\n resolveLockedMjmlCanvasContent,\n} from '../utils/lockedMjml';\nimport { layoutHumanLabel } from '../utils/sectionLayout';\nimport { BlockCodeModal } from './BlockCodeModal';\nimport { InlineEditor, type SelectionState } from './InlineEditor';\nimport type { RichTextToolbar } from './RichTextToolbar';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface CanvasOptions {\n store: Store;\n registry: Registry;\n /** 富文本工具条由 Editor 主类创建,Canvas 只负责调用 attach/detach/update */\n toolbar: RichTextToolbar;\n /** 是否允许 Block 落到 sections 之间空白处时自动裹一列 Section */\n autoWrapSection: boolean;\n /**\n * 为 true 时:点击中栏灰色衬底、白底画布上未落到 Section/块的空白、空文档提示区等会提交内联编辑并清空选中。\n * 默认不绑定(由 MailEditor 的 clearSelectionOnCanvasMargin 控制)。\n */\n clearSelectionOnCanvasMargin?: boolean;\n /**\n * 画布内弹层(如「编辑组件代码」)挂接到此节点,以继承 `.sm-root` 上的主题 CSS 变量。\n * 应传入 MailEditor 根节点;若挂到 `document.body`,`var(--sm-code-bg)` 等会失效,弹框背景会变透明。\n */\n layerRoot: HTMLElement;\n /** 与 MailEditor.opts.ui 对齐 */\n ui?: EditorUiOptions;\n t: SimpleMailT;\n}\n\n/**\n * 画布。负责:\n * 1. 根据 doc 渲染轻量预览 DOM(非真实邮件 HTML)\n * 2. 选中态/悬浮态/工具条\n * 3. SortableJS 两级拖拽(仅 hover 显示的拖拽 handle 触发):\n * - 顶层(sections 组):Section 列表纵向排序,并接收左栏布局拖入\n * - 列内(blocks 组):Block 列表纵向排序,并接收左栏内容/自定义拖入\n * 4. 双击 Block 进入\"内联编辑\"——文本类直接富文本编辑,按钮文字单行编辑\n * 5. 设计画布内所有 <a href> 拦截默认行为,避免误跳转;真实跳转仅在「预览」iframe 中可用。\n *\n * 关键约束:所有数据变更走 store.update(),UI 通过 subscribe 全量重渲染。\n * 内联编辑是例外:编辑期间不再每次输入都 update,避免 contenteditable 因重渲染丢光标。\n */\nexport class Canvas {\n el: HTMLElement;\n private inner: HTMLElement;\n private addBar: HTMLElement;\n private opts: CanvasOptions;\n private sortableRefs: Sortable[] = [];\n /** 正在内联编辑的 block id;进入时画布不会被 store 触发的重渲染干扰它 */\n private editingBlockId: string | null = null;\n private inlineEditor: InlineEditor | null = null;\n /** 当 store 在编辑期间触发了 change(外部调用之类),延迟到编辑结束再重渲染 */\n private pendingRender = false;\n /** 设计模式下禁用画布内超链接导航(预览弹框 iframe 不在此 DOM 内,不受影响) */\n private linkNavSuppression = new AbortController();\n /** clearSelectionOnCanvasMargin:记录本次指针是否从编辑区内按下(区分拖选松手 vs 点空白退出) */\n private clearSelectionGestureTracking = new AbortController();\n private pointerGestureStartedInInlineEdit = false;\n private blockCodeModal: BlockCodeModal;\n\n constructor(opts: CanvasOptions) {\n this.opts = opts;\n this.el = h('div', { class: 'sm-canvas-wrap' });\n this.inner = h('div', { class: 'sm-canvas' });\n this.addBar = this._renderAddBar();\n this.el.append(this.inner, this.addBar);\n this.blockCodeModal = new BlockCodeModal({\n store: opts.store,\n registry: opts.registry,\n mountParent: opts.layerRoot,\n t: opts.t,\n });\n\n this._bindDesignModeLinkSuppression();\n if (opts.clearSelectionOnCanvasMargin) {\n this._bindClearSelectionGestureTracking();\n this._bindClearSelectionOnCanvasWhitespace();\n this._bindClearSelectionOnCanvasMargin();\n }\n\n this.inner.addEventListener('dblclick', (e: MouseEvent) => {\n this._onEmptyCanvasDblClick(e);\n });\n\n this._render();\n\n opts.store.subscribe((detail) => {\n // 编辑态下若走了文档级 undo/redo,必须丢弃未提交 DOM,否则失焦提交会与 store 脱节(整节消失等)\n if (this.editingBlockId && detail?.source === 'history') {\n this.abortInlineEdit();\n this._render();\n return;\n }\n if (this.editingBlockId) {\n this.pendingRender = true;\n return;\n }\n this._render();\n });\n opts.store.subscribeSelection(() => this._syncSelection());\n }\n\n setWidth(width: number) {\n this.inner.style.maxWidth = `${width}px`;\n }\n\n /** 暴露给 Editor,用于\"插入变量\"等外部交互直接写入到当前富文本光标处。 */\n get currentInlineEditor(): InlineEditor | null {\n return this.inlineEditor;\n }\n\n /** 强制提交并退出当前内联编辑(切换源码模式、destroy 前等场景) */\n commitInlineEdit() {\n this.inlineEditor?.commit();\n }\n\n get isInlineEditing(): boolean {\n return this.editingBlockId != null;\n }\n\n /**\n * 放弃未提交的内联编辑(不写入 store)。\n * 用于文档级撤销/重做:编辑期间画布不重绘,若直接 undo 会导致 DOM 与 doc 不一致。\n */\n abortInlineEdit() {\n if (!this.editingBlockId) return;\n const id = this.editingBlockId;\n this.editingBlockId = null;\n this.pendingRender = false;\n if (this.inlineEditor) {\n this.inlineEditor.destroy(false);\n this.inlineEditor = null;\n }\n this.opts.toolbar.detach();\n const blockEl = this.inner.querySelector(\n `.sm-block[data-id=\"${cssEscape(id)}\"]`,\n ) as HTMLElement | null;\n blockEl?.classList.remove('is-editing');\n }\n\n /** 强制重绘(内联编辑中会延迟到 commit 后) */\n refresh() {\n if (this.editingBlockId) {\n this.pendingRender = true;\n return;\n }\n this._render();\n }\n\n destroy() {\n this.linkNavSuppression.abort();\n this.clearSelectionGestureTracking.abort();\n this._exitEditing(false);\n this._destroySortables();\n this.blockCodeModal.destroy();\n }\n\n /**\n * clearSelectionOnCanvasMargin:mousedown 在编辑区内、mouseup 落在灰底/留白时,\n * 浏览器仍可能对 mouseup 目标派发 click;需与 Section padding 的拖选抑制同理。\n */\n private _bindClearSelectionGestureTracking() {\n const opts = { capture: true, signal: this.clearSelectionGestureTracking.signal } as const;\n document.addEventListener(\n 'mousedown',\n (e: MouseEvent) => {\n if (e.button !== 0) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n if (!this.editingBlockId) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n const editingEl = this.inner.querySelector('.sm-inline-editing');\n if (!editingEl) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n const t = e.target;\n if (!(t instanceof Node)) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n const node = t.nodeType === Node.TEXT_NODE ? t.parentNode : t;\n this.pointerGestureStartedInInlineEdit = !!(node && editingEl.contains(node));\n },\n opts,\n );\n }\n\n /**\n * 点击画布白底上未落到 Section 内的区域(如 min-height 下方留白、空文档提示)时清空选中,\n * Section/Block 上的点击会在冒泡到此前被 stopPropagation,不会误清。\n */\n private _bindClearSelectionOnCanvasWhitespace() {\n this.inner.addEventListener('click', (e: MouseEvent) => {\n const t = e.target;\n if (!(t instanceof Node)) return;\n const el = t instanceof Element ? t : t.parentElement;\n if (!el) return;\n if (el === this.inner || el.closest('.sm-empty-doc')) {\n if (this._shouldSuppressClearSelectionFromTextDrag()) return;\n this.commitInlineEdit();\n this.opts.store.setSelection(null);\n }\n });\n }\n\n /** 点击中栏灰色衬底(非白底画布、非底部添加 Section 条)时取消选中 */\n private _bindClearSelectionOnCanvasMargin() {\n this.el.addEventListener('click', (e: MouseEvent) => {\n const t = e.target;\n if (!(t instanceof Node)) return;\n if (!this.el.contains(t)) return;\n if (this.inner.contains(t)) return;\n if (this.addBar.contains(t)) return;\n if (this._shouldSuppressClearSelectionFromTextDrag()) return;\n this.commitInlineEdit();\n this.opts.store.setSelection(null);\n });\n }\n\n /** 捕获阶段拦截 <a href>,防止 Chrome 等在画布预览 DOM 上触发跳转(含未进入内联编辑时点到按钮块链接) */\n private _bindDesignModeLinkSuppression() {\n const opts = { capture: true, signal: this.linkNavSuppression.signal } as const;\n const linkFromTarget = (target: EventTarget | null): HTMLAnchorElement | null => {\n if (!(target instanceof Element)) return null;\n const a = target.closest('a');\n if (!a || !this.inner.contains(a)) return null;\n if (!a.hasAttribute('href')) return null;\n return a;\n };\n this.inner.addEventListener(\n 'mousedown',\n (e: MouseEvent) => {\n const a = linkFromTarget(e.target);\n if (!a) return;\n // 内联编辑时保留 mousedown 默认行为,以便在链接文字上拖选\n if (a.closest('.sm-inline-editing')) return;\n e.preventDefault();\n },\n opts,\n );\n const stopNavigate = (e: MouseEvent) => {\n if (!linkFromTarget(e.target)) return;\n e.preventDefault();\n };\n this.inner.addEventListener('click', stopNavigate, opts);\n this.inner.addEventListener('auxclick', stopNavigate, opts);\n }\n\n /* -------------------------------- 渲染 ---------------------------------- */\n\n private _render() {\n this._destroySortables();\n clear(this.inner);\n\n const { doc } = this.opts.store;\n this.inner.style.maxWidth = docContentWidthCss(doc.meta.width);\n this.inner.style.background = doc.styles.contentBackgroundColor;\n this.inner.style.fontFamily = doc.styles.fontFamily;\n this.inner.style.fontSize = doc.styles.fontSize;\n this.inner.style.fontWeight = normalizeFontWeightStep(doc.styles.fontWeight);\n this.inner.style.color = doc.styles.color;\n this.inner.style.lineHeight = doc.styles.lineHeight ?? '1.25';\n this.inner.style.setProperty('--sm-editor-link-color', doc.styles.linkColor);\n this.inner.style.setProperty(\n '--sm-list-indent-default',\n globalListIndentCssVarValue(doc.styles),\n );\n\n if (!doc.sections.length) {\n this.inner.append(\n h('div', { class: 'sm-empty-doc' }, [\n this.opts.t('canvas.emptyHint'),\n ]),\n );\n } else {\n for (let si = 0; si < doc.sections.length; si++) {\n this.inner.append(this._renderSection(doc.sections[si], doc, si));\n }\n }\n\n // 顶层 Sortable:负责 Section 排序。\n // put 规则随 autoWrapSection 切换:\n // - autoWrapSection=true:同时接收 sections 与 blocks(block 落到这里时由 path B/C 自动套壳)\n // - autoWrapSection=false:仅接收 sections(block 落不下来,SortableJS 会显示禁止)\n // pull:false 始终:Section 不允许被拖到 column 里(保持四层模型)\n const topPut: string[] = this.opts.autoWrapSection ? ['sections', 'blocks'] : ['sections'];\n const top = Sortable.create(this.inner, {\n group: { name: 'sections', pull: false, put: topPut },\n animation: 150,\n handle: '.sm-section__handle',\n draggable: '> .sm-section-host',\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n onAdd: (e) => this._handleSectionAdd(e),\n onUpdate: (e) => this._handleSectionMove(e),\n });\n this.sortableRefs.push(top);\n\n this._syncSelection();\n }\n\n private _renderSection(section: Section, doc: EmailDoc, sectionIndex: number) {\n const a = section.attrs;\n const padding = `${a.paddingTop ?? 0}px ${a.paddingRight ?? 0}px ${\n a.paddingBottom ?? 0\n }px ${a.paddingLeft ?? 0}px`;\n\n const layoutShort =\n section.layout === '1' ? this.opts.t('rightPanel.layout.oneColumn') : layoutHumanLabel(section.layout);\n const dvKey =\n this.opts.ui?.enableDynamicVariantKey === true\n ? getSectionDynamicVariantKey(section)\n : undefined;\n const sectionChip = dvKey\n ? this.opts.t('canvas.dynamicSectionLabel', {\n index: sectionIndex + 1,\n token: `{{${dvKey}}}`,\n })\n : this.opts.t('canvas.sectionLabel', { index: sectionIndex + 1, layout: layoutShort });\n\n const sw = blockButtonWidthCss(a.width);\n const box =\n sw != null ? `max-width:${sw};width:100%;margin-left:auto;margin-right:auto;box-sizing:border-box;` : '';\n\n const host = h('div', {\n class: 'sm-section-host',\n 'data-id': section.id,\n });\n\n const wrap = h('div', {\n class: `sm-section${dvKey ? ' sm-section--dynamic-variant' : ''}`,\n title: this.opts.t('canvas.sectionTitle', { chip: sectionChip }),\n style: `padding:${padding};${a.backgroundColor ? `background:${a.backgroundColor};` : ''}${box}`,\n });\n\n const toolbar = h('div', { class: 'sm-section__toolbar' }, [\n h('span', { class: 'sm-section__toolbar-label', title: sectionChip }, [sectionChip]),\n h('div', { class: 'sm-section__toolbar-actions' }, [\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-section__handle',\n type: 'button',\n title: this.opts.t('common.dragSort'),\n },\n [iconDrag()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.copy'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._duplicateSection(section.id);\n },\n },\n [iconCopy()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-tool-btn--danger',\n type: 'button',\n title: this.opts.t('common.delete'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._removeSection(section.id);\n },\n },\n [iconTrash()],\n ),\n ]),\n ]);\n\n const cols = h('div', {\n class: 'sm-section__columns',\n style: layoutFlexStyle(section.layout, section.attrs.columnGap),\n });\n\n section.columns.forEach((col, i) => {\n cols.append(this._renderColumn(section, col, i, doc));\n });\n\n wrap.append(cols);\n\n host.append(wrap, toolbar);\n\n host.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).closest('.sm-block')) return;\n // 文本拖选时在 Section padding 等区域松开会冒泡 click,不应误切成 Section 选中\n if (!e.altKey && this._shouldSuppressSectionSelectFromTextInteraction()) return;\n e.stopPropagation();\n this.opts.store.setSelection({ kind: 'section', sectionId: section.id });\n });\n\n return host;\n }\n\n private _renderColumn(\n section: Section,\n column: Column,\n columnIndex: number,\n doc: EmailDoc,\n ): HTMLElement {\n const isEmpty = column.blocks.length === 0;\n const colEl = h('div', {\n class: `sm-column ${isEmpty ? 'is-empty' : ''}`,\n 'data-section-id': section.id,\n 'data-column-index': String(columnIndex),\n 'data-empty-hint': this.opts.t('canvas.emptyColumnHint'),\n style: `flex:${layoutFlexValue(section.layout, columnIndex)};${\n column.attrs.backgroundColor ? `background:${column.attrs.backgroundColor};` : ''\n }${column.attrs.verticalAlign ? `align-self:${vaToFlex(column.attrs.verticalAlign)};` : ''}`,\n });\n\n for (const block of column.blocks) {\n colEl.append(this._renderBlock(section, columnIndex, block, doc));\n }\n\n if (isEmpty) {\n colEl.addEventListener('dblclick', (e: MouseEvent) => {\n if ((e.target as HTMLElement).closest('.sm-block')) return;\n e.preventDefault();\n e.stopPropagation();\n this._insertEmptyTextAndEdit(section.id, columnIndex);\n });\n }\n\n // 列内 Sortable:负责块排序,并且:\n // - put: ['blocks'] 接受外来 block(同 group)\n // - pull: true(默认) 允许把内部 block 拖出到其他列 / 或顶层(自动裹一列)\n // - handle 限制为 .sm-block__handle:点选/编辑文本不会误触拖拽\n const sortable = Sortable.create(colEl, {\n group: { name: 'blocks', put: ['blocks'] },\n animation: 150,\n draggable: '.sm-block',\n handle: '.sm-block__handle',\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n onAdd: (e) => this._handleBlockAdd(e, section.id, columnIndex),\n onUpdate: (e) => this._handleBlockMove(e, section.id, columnIndex),\n onRemove: () => {\n /* DOM 调整由 store 重渲染负责;这里不处理。\n 源 column 把 block 拖出后,store 会被 onAdd 同步从源数组里移除该 block。 */\n },\n });\n this.sortableRefs.push(sortable);\n\n return colEl;\n }\n\n private _renderBlock(\n section: Section,\n columnIndex: number,\n block: Block,\n doc: EmailDoc,\n ): HTMLElement {\n const ctx: RenderContext = { doc, engine: 'mjml' };\n const def = this.opts.registry.get(block.type);\n let inner = '';\n if (block.lockedMjml) {\n const isHtmlLike = block.type === 'html' || def?.inlineEditable?.mode === 'html';\n const padding = defaultPaddingForLockedBlock(\n block.type,\n block.lockedMjml,\n block.props as {\n paddingTop?: number;\n paddingRight?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n },\n );\n const resolved = resolveLockedMjmlCanvasContent(block.lockedMjml, padding);\n if (resolved.mode === 'preview') {\n const wrapClass = isHtmlLike ? 'sm-html-content' : 'sm-locked-preview';\n inner = `<div class=\"${wrapClass}\">${resolved.html}</div>`;\n } else {\n inner = `<div style=\"padding:8px;color:#92400e;background:#fffbeb;border:1px dashed #f59e0b;font-family:monospace;font-size:11px;white-space:pre-wrap;\">${escapeHtml(\n resolved.source,\n )}</div>`;\n }\n } else if (def?.renderPreview) {\n inner = def.renderPreview(block.props as any, ctx);\n } else if (def) {\n inner = `<div style=\"padding:16px;color:#6b7280;background:#f9fafb;border:1px dashed #d1d5db;text-align:center;\">${escapeHtml(\n def.name,\n )}</div>`;\n } else {\n inner = `<div style=\"padding:8px;color:#dc2626;\">${escapeHtml(\n this.opts.t('canvas.unknownBlock', { type: block.type }),\n )}</div>`;\n }\n\n const displayName = def?.name ?? block.type;\n\n const el = h('div', {\n class: `sm-block ${block.lockedMjml ? 'is-locked' : ''}`,\n 'data-id': block.id,\n 'data-section-id': section.id,\n 'data-column-index': String(columnIndex),\n 'data-locked-label': this.opts.t('canvas.lockedCode'),\n });\n\n // 内容容器:renderPreview 输出放这里,便于精确定位 inlineEditable selector\n const content = h('div', { class: 'sm-block__content', html: inner });\n\n // 块工具条:hover 仅名称;选中 / 编辑中显示全部按钮;贴在块顶边之上不压内容\n const blockToolbar = h('div', { class: 'sm-block__toolbar' }, [\n h('span', { class: 'sm-block__toolbar-name', title: displayName }, [displayName]),\n h('div', { class: 'sm-block__toolbar-actions' }, [\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-block__handle',\n type: 'button',\n title: this.opts.t('common.dragSort'),\n onclick: (e: Event) => e.stopPropagation(),\n },\n [iconDrag()],\n ),\n def?.inlineEditable && !block.lockedMjml\n ? h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.editText'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._enterEditing(block);\n },\n },\n [iconEdit()],\n )\n : null,\n h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.editCode'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this.blockCodeModal.open(block.id, displayName);\n },\n },\n [iconCode()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.copy'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._duplicateBlock(block.id);\n },\n },\n [iconCopy()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-tool-btn--danger',\n type: 'button',\n title: this.opts.t('common.delete'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._removeBlock(block.id);\n },\n },\n [iconTrash()],\n ),\n ]),\n ]);\n\n el.append(blockToolbar, content);\n\n el.addEventListener('click', (e) => {\n if (this.editingBlockId === block.id) return; // 编辑中不抢焦点\n /** Alt(mac Option):穿透选中父级 Section,解决单列内边距为 0 时块铺满无法点到 Section */\n if (e.altKey) {\n e.stopPropagation();\n this.opts.store.setSelection({ kind: 'section', sectionId: section.id });\n return;\n }\n e.stopPropagation();\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: section.id,\n columnIndex,\n blockId: block.id,\n });\n });\n\n if (block.lockedMjml) {\n el.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.blockCodeModal.open(block.id, displayName);\n });\n } else if (def?.inlineEditable) {\n el.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n this._enterEditing(block);\n });\n }\n\n return el;\n }\n\n private _renderAddBar(): HTMLElement {\n const layouts: { layout: SectionLayout; label: string }[] = [\n { layout: '1', label: this.opts.t('leftPanel.oneColumn') },\n { layout: '1-1', label: this.opts.t('leftPanel.multiColumn') },\n ];\n const bar = h('div', { class: 'sm-add-section-bar' }, [\n h('span', {}, [this.opts.t('canvas.addSection')]),\n ]);\n for (const l of layouts) {\n bar.append(\n h(\n 'button',\n {\n class: 'sm-add-section-bar__btn',\n type: 'button',\n onclick: () =>\n this.opts.store.update((d) => {\n d.sections.push(createSection(l.layout));\n }),\n },\n [l.label],\n ),\n );\n }\n return bar;\n }\n\n /* ----------------------------- 内联编辑 -------------------------------- */\n\n /** 空文档时:在画布白底区域双击,插入一列 Section + 空文本并进入编辑 */\n private _onEmptyCanvasDblClick(e: MouseEvent) {\n if (this.opts.store.doc.sections.length > 0) return;\n const t = e.target as HTMLElement | null;\n if (!t || !this.inner.contains(t)) return;\n e.preventDefault();\n e.stopPropagation();\n this._bootstrapEmptyDocWithText();\n }\n\n /** 无任何 Section 时:创建单栏布局并放入空正文块,再进入内联编辑 */\n private _bootstrapEmptyDocWithText() {\n const reg = this.opts.registry;\n if (!reg.get('text')?.inlineEditable) return;\n this.opts.store.update((d) => {\n if (d.sections.length > 0) return;\n const newBlock = reg.createBlock('text');\n (newBlock.props as { content: string }).content = '';\n const section = createSection('1');\n section.columns[0].blocks.push(newBlock);\n d.sections.push(section);\n });\n\n const doc = this.opts.store.doc;\n const firstBlock = doc.sections[0]?.columns[0]?.blocks[0];\n if (!firstBlock) return;\n\n requestAnimationFrame(() => {\n const loc = findBlockLocation(this.opts.store.doc, firstBlock.id);\n if (loc) this._enterEditing(loc.block);\n });\n }\n\n /** 空列双击:插入正文组件(content 为空)并直接进入编辑 */\n private _insertEmptyTextAndEdit(sectionId: string, columnIndex: number) {\n const reg = this.opts.registry;\n if (!reg.get('text')?.inlineEditable) return;\n const newBlock = reg.createBlock('text');\n (newBlock.props as { content: string }).content = '';\n\n this.opts.store.update((d) => {\n const sec = findSection(d, sectionId);\n if (!sec) return;\n const col = sec.columns[columnIndex];\n if (!col || col.blocks.length > 0) return;\n col.blocks.push(newBlock);\n });\n\n requestAnimationFrame(() => {\n const loc = findBlockLocation(this.opts.store.doc, newBlock.id);\n if (loc) this._enterEditing(loc.block);\n });\n }\n\n private _enterEditing(block: Block) {\n if (this.editingBlockId === block.id) return;\n this._exitEditing(true);\n\n const def = this.opts.registry.get(block.type);\n if (!def?.inlineEditable) return;\n\n const blockEl = this.inner.querySelector(\n `.sm-block[data-id=\"${cssEscape(block.id)}\"]`,\n ) as HTMLElement | null;\n const contentRoot = blockEl?.querySelector('.sm-block__content') as HTMLElement | null;\n if (!contentRoot) return;\n\n const target = (\n def.inlineEditable.selector\n ? contentRoot.querySelector(def.inlineEditable.selector)\n : contentRoot.firstElementChild\n ) as HTMLElement | null;\n if (!target) return;\n\n this.editingBlockId = block.id;\n blockEl?.classList.add('is-editing');\n\n const initial =\n def.inlineEditable.mode === 'plain'\n ? String((block.props as any)[def.inlineEditable.propKey] ?? '')\n : String((block.props as any)[def.inlineEditable.propKey] ?? '');\n\n this.inlineEditor = new InlineEditor({\n el: target,\n initialValue: initial,\n mode: def.inlineEditable.mode,\n multiline: !!def.inlineEditable.multiline,\n placeholder: def.inlineEditable.placeholder,\n globalStyles: this.opts.store.doc.styles,\n onCommit: (value) => {\n const propKey = def.inlineEditable!.propKey;\n const editingId = block.id;\n this._exitEditing(false);\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, editingId);\n if (loc) (loc.block.props as any)[propKey] = value;\n });\n },\n onCancel: () => this._exitEditing(true),\n onSelectionChange: (state: SelectionState | null) => {\n this.opts.toolbar.update(state);\n },\n });\n\n if (def.inlineEditable.mode === 'rich') {\n this.opts.toolbar.attach(this.inlineEditor);\n }\n\n // 选中该 block,便于属性面板同步\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: blockEl!.getAttribute('data-section-id')!,\n columnIndex: Number(blockEl!.getAttribute('data-column-index')),\n blockId: block.id,\n });\n }\n\n /** restoreUI=true:编辑器自身恢复原 DOM(取消场景);false:保留新内容(提交场景,等待 store 回写后重渲染) */\n private _exitEditing(restoreUI: boolean) {\n if (!this.editingBlockId) return;\n const id = this.editingBlockId;\n this.editingBlockId = null;\n if (this.inlineEditor) {\n this.inlineEditor.destroy(restoreUI);\n this.inlineEditor = null;\n }\n this.opts.toolbar.detach();\n const blockEl = this.inner.querySelector(\n `.sm-block[data-id=\"${cssEscape(id)}\"]`,\n ) as HTMLElement | null;\n blockEl?.classList.remove('is-editing');\n\n if (this.pendingRender) {\n this.pendingRender = false;\n this._render();\n }\n }\n\n /* -------------------------------- 拖拽 ---------------------------------- */\n\n /** 结构变更(拖入/排序)前提交内联编辑,避免编辑态 pendingRender 与 Sortable DOM 不同步 */\n private _commitEditingBeforeStructureChange() {\n if (this.editingBlockId) this.commitInlineEdit();\n }\n\n private _resolvePaletteDrop(blockType: string): PaletteDropResult {\n const def = this.opts.registry.get(blockType);\n if (def?.expandPaletteDrop) {\n const out = def.expandPaletteDrop((t) => this.opts.registry.createBlock(t));\n if (Array.isArray(out)) return { blocks: out };\n return out;\n }\n return { blocks: [this.opts.registry.createBlock(blockType)] };\n }\n\n private _applySectionAttrs(target: Section, partial?: Partial<SectionAttrs>) {\n if (!partial) return;\n const { meta, ...rest } = partial;\n Object.assign(target.attrs, rest);\n if (meta && typeof meta === 'object') {\n target.attrs.meta = { ...(target.attrs.meta ?? {}), ...meta };\n }\n }\n\n /** 未开启 `enableDynamicVariantKey` 时剥离 palette 上的动态变量节属性 */\n private _paletteSectionAttrsForDrop(\n sectionAttrs?: Partial<SectionAttrs>,\n ): Partial<SectionAttrs> | undefined {\n if (!sectionAttrs) return undefined;\n if (this.opts.ui?.enableDynamicVariantKey === true) return sectionAttrs;\n const { dynamicVariantKey: _dv, ...rest } = sectionAttrs;\n return Object.keys(rest).length ? rest : undefined;\n }\n\n private _handleSectionAdd(e: Sortable.SortableEvent) {\n this._commitEditingBeforeStructureChange();\n const item = e.item;\n const layout = item.getAttribute('data-layout') as SectionLayout | null;\n const blockType = item.getAttribute('data-block-type');\n const fromBlockId = item.getAttribute('data-id');\n const sourceGroup = item.getAttribute('data-source-group');\n const newIndex = e.newIndex ?? 0;\n\n // 路径 A:左栏布局卡片\n if (layout) {\n item.parentElement?.removeChild(item);\n this.opts.store.update((d) => {\n d.sections.splice(newIndex, 0, createSection(layout));\n });\n return;\n }\n\n // 路径 B:左栏内容/自定义卡片拖到 sections 之间 → 自动裹一列 Section\n if (sourceGroup === 'blocks' && blockType) {\n item.parentElement?.removeChild(item);\n const { blocks, sectionAttrs } = this._resolvePaletteDrop(blockType);\n const newSection = createSection('1');\n this._applySectionAttrs(newSection, this._paletteSectionAttrsForDrop(sectionAttrs));\n newSection.columns[0].blocks.splice(newIndex, 0, ...blocks);\n this.opts.store.update((d) => {\n d.sections.splice(newIndex, 0, newSection);\n });\n const head = blocks[0];\n if (head) {\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: newSection.id,\n columnIndex: 0,\n blockId: head.id,\n });\n }\n return;\n }\n\n // 路径 C:从某个已有 column 把 block 拖到 sections 之间 → 自动裹一列 Section\n if (fromBlockId) {\n item.parentElement?.removeChild(item);\n const newSection = createSection('1');\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, fromBlockId);\n if (!loc) return;\n const fromCol = loc.section.columns[loc.columnIndex];\n const idx = fromCol.blocks.findIndex((b) => b.id === fromBlockId);\n if (idx < 0) return;\n const [moved] = fromCol.blocks.splice(idx, 1);\n newSection.columns[0].blocks.push(moved);\n // 注意:newIndex 是 SortableJS 把 item 放进 DOM 后看到的索引;\n // 由于来源 column 内的 block 不属于 inner 的直接子节点,\n // newIndex 在 inner 的可视位置上是准确的。\n d.sections.splice(newIndex, 0, newSection);\n pruneSectionIfEmpty(d, loc.section.id);\n });\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: newSection.id,\n columnIndex: 0,\n blockId: fromBlockId,\n });\n }\n }\n\n private _handleSectionMove(e: Sortable.SortableEvent) {\n this._commitEditingBeforeStructureChange();\n const oldIndex = e.oldIndex ?? 0;\n const newIndex = e.newIndex ?? 0;\n if (oldIndex === newIndex) return;\n this.opts.store.update((d) => {\n const [moved] = d.sections.splice(oldIndex, 1);\n d.sections.splice(newIndex, 0, moved);\n });\n }\n\n private _handleBlockAdd(e: Sortable.SortableEvent, sectionId: string, columnIndex: number) {\n this._commitEditingBeforeStructureChange();\n const item = e.item;\n const newIndex = e.newIndex ?? 0;\n const sourceGroup = item.getAttribute('data-source-group');\n const blockType = item.getAttribute('data-block-type');\n const fromBlockId = item.getAttribute('data-id');\n\n if (sourceGroup === 'blocks' && blockType) {\n item.parentElement?.removeChild(item);\n const drop = this._resolvePaletteDrop(blockType);\n const paletteSectionAttrs = this._paletteSectionAttrsForDrop(drop.sectionAttrs);\n if (paletteSectionAttrs?.dynamicVariantKey) {\n const newSection = createSection('1');\n this._applySectionAttrs(newSection, paletteSectionAttrs);\n newSection.columns[0].blocks.push(...drop.blocks);\n this.opts.store.update((d) => {\n const secIdx = d.sections.findIndex((s) => s.id === sectionId);\n const insertAt = secIdx >= 0 ? secIdx + 1 : d.sections.length;\n d.sections.splice(insertAt, 0, newSection);\n });\n const head = drop.blocks[0];\n if (head) {\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: newSection.id,\n columnIndex: 0,\n blockId: head.id,\n });\n }\n return;\n }\n const blocks = drop.blocks;\n this.opts.store.update((d) => {\n const sec = d.sections.find((s) => s.id === sectionId);\n if (!sec) return;\n sec.columns[columnIndex]?.blocks.splice(newIndex, 0, ...blocks);\n });\n const head = blocks[0];\n if (head) {\n this.opts.store.setSelection({\n kind: 'block',\n sectionId,\n columnIndex,\n blockId: head.id,\n });\n }\n return;\n }\n\n if (fromBlockId) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, fromBlockId);\n if (!loc) return;\n const fromCol = loc.section.columns[loc.columnIndex];\n const idx = fromCol.blocks.findIndex((b) => b.id === fromBlockId);\n if (idx < 0) return;\n const [moved] = fromCol.blocks.splice(idx, 1);\n const targetSec = d.sections.find((s) => s.id === sectionId);\n targetSec?.columns[columnIndex]?.blocks.splice(newIndex, 0, moved);\n pruneSectionIfEmpty(d, loc.section.id);\n });\n }\n }\n\n private _handleBlockMove(e: Sortable.SortableEvent, sectionId: string, columnIndex: number) {\n this._commitEditingBeforeStructureChange();\n const oldIndex = e.oldIndex ?? 0;\n const newIndex = e.newIndex ?? 0;\n if (oldIndex === newIndex) return;\n this.opts.store.update((d) => {\n const sec = d.sections.find((s) => s.id === sectionId);\n const col = sec?.columns[columnIndex];\n if (!col) return;\n const [moved] = col.blocks.splice(oldIndex, 1);\n col.blocks.splice(newIndex, 0, moved);\n });\n }\n\n /* -------------------------------- 操作 ---------------------------------- */\n\n private _removeSection(id: string) {\n this.opts.store.update((d) => {\n d.sections = d.sections.filter((s) => s.id !== id);\n });\n this.opts.store.setSelection(null);\n }\n\n private _duplicateSection(id: string) {\n this.opts.store.update((d) => {\n const idx = d.sections.findIndex((s) => s.id === id);\n if (idx < 0) return;\n const clone = structuredClone(d.sections[idx]);\n clone.id = `${clone.id}_c${Date.now().toString(36)}`;\n clone.columns = clone.columns.map((c) => ({\n ...c,\n id: `${c.id}_c${Date.now().toString(36)}`,\n blocks: c.blocks.map((b) => ({ ...b, id: `${b.id}_c${Date.now().toString(36)}` })),\n }));\n d.sections.splice(idx + 1, 0, clone);\n });\n }\n\n private _removeBlock(id: string) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, id);\n if (!loc) return;\n const col = loc.section.columns[loc.columnIndex];\n col.blocks = col.blocks.filter((b) => b.id !== id);\n pruneSectionIfEmpty(d, loc.section.id);\n });\n this.opts.store.setSelection(null);\n }\n\n private _duplicateBlock(id: string) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, id);\n if (!loc) return;\n const col = loc.section.columns[loc.columnIndex];\n const idx = col.blocks.findIndex((b) => b.id === id);\n if (idx < 0) return;\n const clone = structuredClone(col.blocks[idx]);\n clone.id = `${clone.id}_c${Date.now().toString(36)}`;\n col.blocks.splice(idx + 1, 0, clone);\n });\n }\n\n /**\n * 内联编辑中从编辑区拖选文字,若 mouseup 落在 Section padding / 灰底 / 留白,\n * 浏览器仍可能对 mouseup 目标派发 click;选区仍在编辑区内时不应提交或改选中。\n */\n private _shouldSuppressClearSelectionFromTextDrag(): boolean {\n return (\n this.pointerGestureStartedInInlineEdit &&\n this._shouldSuppressSectionSelectFromTextInteraction()\n );\n }\n\n private _shouldSuppressSectionSelectFromTextInteraction(): boolean {\n if (!this.editingBlockId) return false;\n const editingEl = this.inner.querySelector('.sm-inline-editing');\n if (!editingEl) return false;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return false;\n const nodeInEditing = (n: Node | null): boolean => {\n if (!n) return false;\n const el = n.nodeType === Node.TEXT_NODE ? n.parentNode : n;\n return !!el && editingEl.contains(el);\n };\n return nodeInEditing(sel.anchorNode) || nodeInEditing(sel.focusNode);\n }\n\n private _syncSelection() {\n const sel = this.opts.store.selection;\n this.inner.querySelectorAll('.is-selected').forEach((el) => el.classList.remove('is-selected'));\n if (!sel) return;\n if (sel.kind === 'section') {\n this.inner\n .querySelector(`.sm-section-host[data-id=\"${cssEscape(sel.sectionId)}\"]`)\n ?.classList.add('is-selected');\n } else {\n this.inner\n .querySelector(`.sm-block[data-id=\"${cssEscape(sel.blockId)}\"]`)\n ?.classList.add('is-selected');\n }\n }\n\n private _destroySortables() {\n for (const s of this.sortableRefs) s.destroy();\n this.sortableRefs = [];\n }\n}\n\n/* ---------------------------------- utils --------------------------------- */\n\nfunction layoutFlexStyle(_layout: SectionLayout, columnGap?: number): string {\n const gap =\n columnGap != null && columnGap > 0 ? `gap:${Math.min(columnGap, 200)}px;` : '';\n return `display:flex;flex-wrap:nowrap;width:100%;${gap}`;\n}\n\nfunction layoutFlexValue(layout: SectionLayout, index: number): string {\n const parts = layout.split('-').map(Number);\n const total = parts.reduce((s, x) => s + x, 0);\n const ratio = parts[index] ?? 1;\n return `${ratio} 1 0;min-width:0;width:${((ratio / total) * 100).toFixed(2)}%`;\n}\n\nfunction vaToFlex(va: 'top' | 'middle' | 'bottom'): string {\n return va === 'top' ? 'flex-start' : va === 'bottom' ? 'flex-end' : 'center';\n}\n\nfunction cssEscape(s: string): string {\n if (typeof CSS !== 'undefined' && CSS.escape) return CSS.escape(s);\n return s.replace(/[^\\w-]/g, '\\\\$&');\n}\n\nfunction svg(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '12');\n el.setAttribute('height', '12');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML = inner;\n return el;\n}\nfunction iconDrag() {\n return svg(\n '<circle cx=\"7\" cy=\"5\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"13\" cy=\"5\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"7\" cy=\"10\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"13\" cy=\"10\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"7\" cy=\"15\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"13\" cy=\"15\" r=\"1.4\" fill=\"currentColor\"/>',\n );\n}\nfunction iconCopy() {\n return svg(\n '<rect x=\"6\" y=\"6\" width=\"10\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><path d=\"M4 12V5a1 1 0 011-1h7\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/>',\n );\n}\nfunction iconTrash() {\n return svg(\n '<path d=\"M5 6h10M8 6V4h4v2M6 6l1 10h6l1-10\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\" stroke-linejoin=\"round\"/>',\n );\n}\nfunction iconEdit() {\n return svg(\n '<path d=\"M4 14l8-8 2 2-8 8H4v-2z\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\" stroke-linejoin=\"round\"/>',\n );\n}\nfunction iconCode() {\n return svg(\n '<path d=\"M7 7l-3 3 3 3M13 7l3 3-3 3\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n );\n}\n","import { EditorState } from '@codemirror/state';\nimport { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { Store } from '../store/store';\nimport { prettyHtml } from '../utils/html';\nimport { h } from '../utils/dom';\nimport { richTextExecCommand } from '../utils/richTextCommand';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface ExportModalOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n /** 替换 {{var}} 为 sample 值 */\n withSampleVariables?: boolean;\n}\n\n/**\n * 导出 HTML 弹框:\n * - body 用 CodeMirror 只读展示当前文档编译产物\n * - footer:复制、美化、下载 三个动作\n */\nexport class ExportModal {\n private opts: ExportModalOptions;\n private modal: Modal;\n private cm: EditorView | null = null;\n private current: string = '';\n\n constructor(opts: ExportModalOptions) {\n this.opts = opts;\n this.modal = new Modal({\n title: opts.t('export.title'),\n className: 'sm-modal--export',\n width: 'min(960px, 96vw)',\n height: 'min(720px, 88vh)',\n onClose: () => this._destroyCm(),\n t: opts.t,\n });\n\n const editorHost = h('div', { class: 'sm-export__editor' });\n this.modal.body.append(editorHost);\n\n const copyBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this._copy() },\n [this.opts.t('export.copyHtml')],\n );\n const beautifyBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this._beautify() },\n [this.opts.t('common.beautify')],\n );\n const downloadBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => this._download(),\n },\n [this.opts.t('export.downloadHtml')],\n );\n this.modal.footer.append(copyBtn, beautifyBtn, downloadBtn);\n\n // 初始化 CodeMirror(在 open 时填充 doc)\n this.cm = new EditorView({\n parent: editorHost,\n state: EditorState.create({\n doc: '',\n extensions: [basicSetup, cmHtml(), EditorState.readOnly.of(true)],\n }),\n });\n }\n\n open(parent?: HTMLElement) {\n this._compile();\n this.modal.open(parent);\n }\n\n private _compile() {\n const result = renderDoc(this.opts.store.doc, this.opts.registry, {\n withSampleVariables: this.opts.withSampleVariables ?? false,\n });\n this.current = result.html;\n this._setText(result.html);\n }\n\n private _setText(text: string) {\n if (!this.cm) return;\n this.cm.dispatch({\n changes: { from: 0, to: this.cm.state.doc.length, insert: text },\n });\n }\n\n private async _copy() {\n try {\n await navigator.clipboard.writeText(this.current);\n this._toast(this.opts.t('toast.copiedToClipboard'));\n } catch {\n const ta = document.createElement('textarea');\n ta.value = this.current;\n document.body.appendChild(ta);\n ta.select();\n richTextExecCommand('copy');\n document.body.removeChild(ta);\n this._toast(this.opts.t('toast.copied'));\n }\n }\n\n private _beautify() {\n this.current = prettyHtml(this.current);\n this._setText(this.current);\n }\n\n private _download() {\n const blob = new Blob([this.current], { type: 'text/html;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `email-${Date.now()}.html`;\n a.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n\n private _toast(text: string) {\n const t = h('div', { class: 'sm-toast' }, [text]);\n this.modal.body.append(t);\n requestAnimationFrame(() => t.classList.add('is-visible'));\n setTimeout(() => {\n t.classList.remove('is-visible');\n setTimeout(() => t.remove(), 200);\n }, 1400);\n }\n\n private _destroyCm() {\n this.cm?.destroy();\n this.cm = null;\n }\n}\n","import Sortable from 'sortablejs';\nimport type { Registry } from '../registry/registry';\nimport type { BlockDefinition, SectionLayout } from '../types';\nimport { clear, h } from '../utils/dom';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface LeftPanelOptions {\n registry: Registry;\n t: SimpleMailT;\n /** 合并后的组件分组标题 */\n blockGroupTitle?: string;\n /** custom 类块默认 tooltip 后缀(无 paletteTooltip 时) */\n customPaletteTooltipSuffix?: string;\n /** 不显示在左栏的 block type(仍可在 Registry 中 createBlock) */\n hiddenPaletteBlockTypes?: string[];\n}\n\ninterface LayoutCard {\n layout: SectionLayout;\n nameKey: string;\n icon: string;\n titleKey?: string;\n}\n\nconst LAYOUT_CARDS: LayoutCard[] = [\n { layout: '1', nameKey: 'leftPanel.oneColumn', icon: layoutSvg([1]) },\n /** 默认 1:1;1:2 / 2:1 / 1:1:1 在选中 Section 后于右栏「列布局」切换 */\n {\n layout: '1-1',\n nameKey: 'leftPanel.multiColumn',\n icon: layoutSvg([1, 1]),\n titleKey: 'leftPanel.multiColumnTitle',\n },\n];\n\n/**\n * 左栏分两类:\n * - 布局(layout):决定 Section 结构,拖入到画布顶层(group: 'sections')\n * - 组件:内置与 custom 合并为一组,作为 Block 拖入 Column(group: 'blocks')\n *\n * 通过 SortableJS 的 group + clone + sort:false 实现。\n * 这两个组分开,画布顶层只接 'sections',列内只接 'blocks',\n * 严格两层拖拽,禁止跨级别——这是解决 GrapesJS 嵌套混乱的核心。\n */\nexport class LeftPanel {\n el: HTMLElement;\n private opts: LeftPanelOptions;\n\n constructor(opts: LeftPanelOptions) {\n this.opts = opts;\n this.el = h('aside', { class: 'sm-panel sm-panel--left' });\n this._render();\n }\n\n refresh() {\n this._render();\n }\n\n private _render() {\n clear(this.el);\n const hiddenPalette = new Set(this.opts.hiddenPaletteBlockTypes ?? []);\n const filterPalette = (defs: BlockDefinition[]) =>\n defs.filter((d) => !hiddenPalette.has(d.type));\n const paletteBlocks = [\n ...filterPalette(this.opts.registry.byCategory('content')),\n ...filterPalette(this.opts.registry.byCategory('custom')),\n ];\n\n const wrap = h('div', { class: 'sm-blocks' });\n\n wrap.append(this._renderLayoutGroup());\n if (paletteBlocks.length) {\n wrap.append(\n this._renderBlockGroup(\n this.opts.blockGroupTitle ?? this.opts.t('leftPanel.components'),\n paletteBlocks,\n ),\n );\n }\n\n this.el.append(wrap);\n }\n\n private _renderLayoutGroup(): HTMLElement {\n const grid = h('div', { class: 'sm-blocks__grid' });\n for (const c of LAYOUT_CARDS) {\n const name = this.opts.t(c.nameKey);\n grid.append(\n h(\n 'div',\n {\n class: 'sm-block-card',\n 'data-source-group': 'sections',\n 'data-layout': c.layout,\n title: c.titleKey ? this.opts.t(c.titleKey) : name,\n },\n [\n h('span', { class: 'sm-block-card__icon', html: c.icon }),\n h('span', { class: 'sm-block-card__name' }, [name]),\n ],\n ),\n );\n }\n Sortable.create(grid, {\n group: { name: 'sections', pull: 'clone', put: false },\n sort: false,\n animation: 120,\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n });\n return h('section', { class: 'sm-blocks__group' }, [\n h('div', { class: 'sm-panel__title' }, [this.opts.t('leftPanel.layout')]),\n grid,\n ]);\n }\n\n private _blockCardTitle(def: BlockDefinition): string {\n if (def.paletteTooltip?.trim()) return def.paletteTooltip.trim();\n if (def.category === 'custom') {\n const suffix =\n this.opts.customPaletteTooltipSuffix ?? this.opts.t('leftPanel.customTooltipSuffix');\n return `${def.name} — ${suffix}`;\n }\n return def.name;\n }\n\n private _renderBlockGroup(title: string, defs: BlockDefinition[]): HTMLElement {\n const grid = h('div', { class: 'sm-blocks__grid' });\n for (const def of defs) {\n const isCustom = def.category === 'custom';\n const children: HTMLElement[] = [];\n if (isCustom) {\n children.push(h('span', { class: 'sm-block-card__dot', 'aria-hidden': 'true' }));\n }\n children.push(\n h('span', { class: 'sm-block-card__icon', html: def.icon }),\n h('span', { class: 'sm-block-card__name' }, [def.name]),\n );\n grid.append(\n h(\n 'div',\n {\n class: 'sm-block-card',\n 'data-source-group': 'blocks',\n 'data-block-type': def.type,\n title: this._blockCardTitle(def),\n },\n children,\n ),\n );\n }\n Sortable.create(grid, {\n group: { name: 'blocks', pull: 'clone', put: false },\n sort: false,\n animation: 120,\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n });\n return h('section', { class: 'sm-blocks__group' }, [\n h('div', { class: 'sm-panel__title' }, [title]),\n grid,\n ]);\n }\n}\n\nfunction layoutSvg(parts: number[]): string {\n const total = parts.reduce((s, x) => s + x, 0);\n const w = 24;\n const gap = 1;\n const innerW = w - gap * (parts.length - 1);\n let x = 0;\n const rects = parts\n .map((p) => {\n const rw = (p / total) * innerW;\n const rect = `<rect x=\"${x}\" y=\"6\" width=\"${rw.toFixed(\n 2,\n )}\" height=\"12\" fill=\"currentColor\" opacity=\"0.8\" rx=\"1\"/>`;\n x += rw + gap;\n return rect;\n })\n .join('');\n return `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">${rects}</svg>`;\n}\n","import type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { Store } from '../store/store';\nimport { h } from '../utils/dom';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport type PreviewDevice = 'pc' | 'pad' | 'phone';\n\ninterface DeviceSpec {\n width: number;\n label: string;\n}\n\nconst DEVICES: Record<PreviewDevice, DeviceSpec> = {\n pc: { width: 800, label: 'PC' },\n pad: { width: 640, label: 'Pad' },\n phone: { width: 375, label: 'Phone' },\n};\n\nexport interface PreviewModalOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n}\n\n/**\n * 预览弹框:用 iframe 渲染真实 mjml 编译产物。\n * 通过 srcdoc 写入 HTML,避免跨域;默认保留 {{var}} 占位符,与画布编辑态一致。\n * 三个设备宽度切换:800 / 640 / 375,按邮件常见宽度档位。\n */\nexport class PreviewModal {\n private opts: PreviewModalOptions;\n private modal: Modal;\n private device: PreviewDevice = 'pc';\n private iframe: HTMLIFrameElement;\n private viewport: HTMLElement;\n private deviceBtns: Record<PreviewDevice, HTMLButtonElement> = {} as any;\n private iframeRo?: ResizeObserver;\n private layoutRaf: number | null = null;\n private onWinResize?: () => void;\n\n constructor(opts: PreviewModalOptions) {\n this.opts = opts;\n this.modal = new Modal({\n title: opts.t('preview.title'),\n className: 'sm-modal--preview',\n width: 'min(960px, calc(100vw - 32px))',\n /** 高度随 iframe 内容测量,见 _fitPreviewHeight;不超过屏高由 CSS max-height 约束 */\n onClose: () => this._teardownLayoutHooks(),\n t: opts.t,\n });\n\n this.iframe = h('iframe', {\n class: 'sm-preview__frame',\n sandbox: 'allow-same-origin',\n title: 'preview',\n }) as HTMLIFrameElement;\n this.iframe.addEventListener('load', () => {\n this._bindIframeResizeObserver();\n this._scheduleFitPreviewHeight();\n });\n\n this.viewport = h('div', { class: 'sm-preview__viewport' }, [this.iframe]);\n this.modal.body.classList.add('sm-modal__body--center');\n this.modal.body.append(this.viewport);\n\n // 设备切换工具条放在 header 右侧\n const switcher = h('div', { class: 'sm-segmented' });\n (['pc', 'pad', 'phone'] as PreviewDevice[]).forEach((d) => {\n const btn = h(\n 'button',\n {\n class: `sm-segmented__item ${d === this.device ? 'sm-segmented__item--active' : ''}`,\n type: 'button',\n onclick: () => this.setDevice(d),\n },\n [iconForDevice(d), DEVICES[d].label],\n ) as HTMLButtonElement;\n this.deviceBtns[d] = btn;\n switcher.append(btn);\n });\n this.modal.appendHeaderTool(switcher);\n }\n\n open(parent?: HTMLElement) {\n this._render();\n this.setDevice(this.device);\n this.modal.open(parent);\n this.onWinResize = () => this._scheduleFitPreviewHeight();\n window.addEventListener('resize', this.onWinResize);\n }\n\n setDevice(d: PreviewDevice) {\n this.device = d;\n const spec = DEVICES[d];\n this.viewport.style.setProperty('--sm-preview-w', `${spec.width}px`);\n for (const k of Object.keys(this.deviceBtns) as PreviewDevice[]) {\n this.deviceBtns[k].classList.toggle('sm-segmented__item--active', k === d);\n }\n requestAnimationFrame(() =>\n requestAnimationFrame(() => this._scheduleFitPreviewHeight()),\n );\n }\n\n private _render() {\n const result = renderDoc(this.opts.store.doc, this.opts.registry, {\n withSampleVariables: false,\n });\n // 用 srcdoc 而非 src=blob:,避免 about:srcdoc 偶发的相对资源问题\n this.iframe.srcdoc = result.html;\n }\n\n /** 标题栏 + body 上下 padding + 与视口的小间距 */\n private static readonly VIEWPORT_RESERVED_Y = 112;\n\n private _scheduleFitPreviewHeight() {\n if (this.layoutRaf != null) cancelAnimationFrame(this.layoutRaf);\n this.layoutRaf = requestAnimationFrame(() => {\n this.layoutRaf = null;\n this._fitPreviewHeight();\n });\n }\n\n private _fitPreviewHeight() {\n if (!this.iframe.isConnected) return;\n try {\n const doc = this.iframe.contentDocument;\n const root = doc?.documentElement;\n const body = doc?.body;\n if (!root || !body) return;\n const raw = Math.max(root.scrollHeight, body.scrollHeight);\n const maxPx = Math.max(\n 240,\n window.innerHeight - PreviewModal.VIEWPORT_RESERVED_Y,\n );\n const minPx = 200;\n const next = Math.min(Math.max(Math.ceil(raw), minPx), maxPx);\n this.viewport.style.height = `${next}px`;\n } catch {\n /* srcdoc 同域,极端情况下忽略 */\n }\n }\n\n private _bindIframeResizeObserver() {\n this.iframeRo?.disconnect();\n try {\n const doc = this.iframe.contentDocument;\n const body = doc?.body;\n if (!body || typeof ResizeObserver === 'undefined') return;\n this.iframeRo = new ResizeObserver(() => this._scheduleFitPreviewHeight());\n this.iframeRo.observe(body);\n const html = doc.documentElement;\n if (html) this.iframeRo.observe(html);\n } catch {\n /* ignore */\n }\n }\n\n private _teardownLayoutHooks() {\n if (this.onWinResize) {\n window.removeEventListener('resize', this.onWinResize);\n this.onWinResize = undefined;\n }\n this.iframeRo?.disconnect();\n this.iframeRo = undefined;\n if (this.layoutRaf != null) {\n cancelAnimationFrame(this.layoutRaf);\n this.layoutRaf = null;\n }\n }\n}\n\nfunction iconForDevice(d: PreviewDevice): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '14');\n el.setAttribute('height', '14');\n el.setAttribute('viewBox', '0 0 20 20');\n if (d === 'pc')\n el.innerHTML =\n '<rect x=\"2\" y=\"4\" width=\"16\" height=\"11\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><path d=\"M7 18h6\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>';\n else if (d === 'pad')\n el.innerHTML =\n '<rect x=\"4\" y=\"2\" width=\"12\" height=\"16\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"10\" cy=\"16\" r=\"0.6\" fill=\"currentColor\"/>';\n else\n el.innerHTML =\n '<rect x=\"6\" y=\"2\" width=\"8\" height=\"16\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"10\" cy=\"16\" r=\"0.6\" fill=\"currentColor\"/>';\n return el;\n}\n","import { bindColorPickerInput } from './ColorPickerPopover';\nimport { h } from '../utils/dom';\nimport { FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport { LIST_INDENT_PRESETS_PX, type ListIndentValue } from '../utils/emailListStyles';\nimport type { InlineEditor, SelectionState } from './InlineEditor';\nimport type { SimpleMailT } from '../i18n';\n\n/**\n * 富文本浮动工具条。\n *\n * 关键设计:\n * - 工具条挂在 editor root 上,跨 block 实例复用;切换编辑对象时调用 attach()。\n * - **mousedown 在工具条任意位置时(capture 阶段)先调用 editor.saveSelection()**:\n * 在浏览器把焦点切到 select/input 之前抢先把选区存到 InlineEditor,\n * 后续 exec 时会自动 focus 回 contenteditable + 恢复选区——这是\n * \"切字体/字号/颜色失灵\"问题的根本修复。\n * - 按钮全部 mousedown.preventDefault:不抢焦点;select/color/url 这些\n * 必须 takeFocus 的控件不能 preventDefault,但因为 mousedown 已经存档了选区,\n * onChange/onClick 时调 exec 即可。\n * - 定位:优先贴在当前内联编辑根节点(正文容器)**上沿外**,可覆盖上方块工具区;\n * 滚出中栏画布视口时钳制在 `.sm-canvas-wrap` 可见区域内(按需吸顶)。\n */\nexport interface RichTextToolbarOptions {\n /** 工具条的定位上下文:rect 是相对该容器计算的 */\n positionRoot: HTMLElement;\n /** 中栏画布滚动容器;省略时从 positionRoot 内查找 `.sm-canvas-wrap` */\n scrollRoot?: HTMLElement;\n t: SimpleMailT;\n}\n\nconst FONT_FAMILIES = [\n { labelKey: 'toolbar.fontDefault', label: 'Default', value: '' },\n { label: 'Inter', value: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' },\n { labelKey: 'toolbar.fontPingFang', label: 'PingFang SC', value: '\"PingFang SC\", \"Helvetica Neue\", Arial, sans-serif' },\n { labelKey: 'toolbar.fontMicrosoftYaHei', label: 'Microsoft YaHei', value: '\"Microsoft YaHei\", \"Segoe UI\", sans-serif' },\n { labelKey: 'toolbar.fontSimSun', label: 'SimSun', value: 'SimSun, \"Songti SC\", serif' },\n { label: 'Helvetica', value: '\"Helvetica Neue\", Arial, sans-serif' },\n { label: 'Arial', value: 'Arial, sans-serif' },\n { label: 'Georgia', value: 'Georgia, serif' },\n { label: 'Courier', value: '\"Courier New\", monospace' },\n];\n\nconst FONT_SIZES = ['12px', '13px', '14px', '15px', '16px', '18px', '20px', '24px', '28px', '32px'];\n\nexport class RichTextToolbar {\n el: HTMLElement;\n private opts: RichTextToolbarOptions;\n private editor: InlineEditor | null = null;\n private btns: Record<string, HTMLButtonElement> = {};\n private selectFontFamily!: HTMLSelectElement;\n private selectFontSize!: HTMLSelectElement;\n private selectFontWeight!: HTMLSelectElement;\n private inputColor!: HTMLInputElement;\n private inputBgColor!: HTMLInputElement;\n private inputLink!: HTMLInputElement;\n private linkPanel!: HTMLElement;\n /** 最近一次选区推断出的链接,供打开面板时预填 */\n private lastLinkHref: string | null = null;\n private listIndentGroup!: HTMLElement;\n private selectListIndent!: HTMLSelectElement;\n private syncingListIndentUi = false;\n private scrollListenersBound = false;\n private repositionRaf = 0;\n private readonly boundReposition = () => this._scheduleReposition();\n\n constructor(opts: RichTextToolbarOptions) {\n this.opts = opts;\n this.el = h('div', { class: 'sm-floating-toolbar', role: 'toolbar' });\n this._build();\n this.hide();\n opts.positionRoot.append(this.el);\n\n // 关键:用 capture 阶段在所有控件之前抢先 save selection\n this.el.addEventListener(\n 'mousedown',\n () => {\n this.editor?.saveSelection();\n },\n true,\n );\n }\n\n attach(editor: InlineEditor) {\n this.editor = editor;\n }\n\n detach() {\n this.editor = null;\n this.hide();\n }\n\n show() {\n this.el.classList.add('is-visible');\n this._bindScrollListeners();\n }\n\n hide() {\n this.el.classList.remove('is-visible');\n this.linkPanel.classList.remove('is-visible');\n this._unbindScrollListeners();\n if (this.repositionRaf) {\n cancelAnimationFrame(this.repositionRaf);\n this.repositionRaf = 0;\n }\n }\n\n /** 由 InlineEditor 推选区状态进来 */\n update(state: SelectionState | null) {\n if (!state || !this.editor) {\n this.hide();\n return;\n }\n this.show();\n\n const f = state.formats;\n this._setActive('bold', f.bold);\n this._setActive('italic', f.italic);\n this._setActive('underline', f.underline);\n this._setActive('strikethrough', f.strikethrough);\n this._setActive('ul', f.unorderedList);\n this._setActive('ol', f.orderedList);\n this._setActive('alignLeft', f.align === 'left');\n this._setActive('alignCenter', f.align === 'center');\n this._setActive('alignRight', f.align === 'right');\n\n const hasLink = !!f.link;\n this.lastLinkHref = f.link;\n this.btns.unlink.style.display = hasLink ? '' : 'none';\n\n if (f.foreColor) {\n const hex = colorToHexInput(f.foreColor);\n if (hex) this.inputColor.value = hex;\n }\n this.inputBgColor.value = f.backColor\n ? (colorToHexInput(f.backColor) ?? '#ffffff')\n : '#ffffff';\n if (f.fontName) this.selectFontFamily.value = matchFamily(f.fontName);\n this.selectFontSize.value = matchFontSize(f.fontSize);\n this.selectFontWeight.value = matchFontWeight(f.fontWeight);\n this._syncListIndentUi(f.inList, f.listIndentPx);\n\n this._scheduleReposition();\n }\n\n destroy() {\n this._unbindScrollListeners();\n if (this.repositionRaf) cancelAnimationFrame(this.repositionRaf);\n this.el.remove();\n }\n\n /* -------------------------------- 内部 ---------------------------------- */\n\n private _build() {\n const sep = () => h('div', { class: 'sm-floating-toolbar__sep' });\n const t = this.opts.t;\n\n // 这些按钮 mousedown.preventDefault 阻止抢焦点;点击时直接 exec\n const exec = (cmd: string, val?: string) => () => this.editor?.exec(cmd, val);\n\n this.btns.bold = this._btn('B', t('toolbar.bold'), exec('bold'), { fontWeight: '700' });\n this.btns.italic = this._btn('I', t('toolbar.italic'), exec('italic'), { fontStyle: 'italic' });\n this.btns.underline = this._btn('U', t('toolbar.underline'), exec('underline'), {\n textDecoration: 'underline',\n });\n this.btns.strikethrough = this._btn('S', t('toolbar.strikethrough'), exec('strikeThrough'), {\n textDecoration: 'line-through',\n });\n\n this.btns.alignLeft = this._iconBtn(\n svgIcon(\n '<path d=\"M3 5h14M3 9h10M3 13h14M3 17h10\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.alignLeft'),\n exec('justifyLeft'),\n );\n this.btns.alignCenter = this._iconBtn(\n svgIcon(\n '<path d=\"M3 5h14M5 9h10M3 13h14M5 17h10\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.alignCenter'),\n exec('justifyCenter'),\n );\n this.btns.alignRight = this._iconBtn(\n svgIcon(\n '<path d=\"M3 5h14M7 9h10M3 13h14M7 17h10\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.alignRight'),\n exec('justifyRight'),\n );\n\n this.btns.ul = this._iconBtn(\n svgIcon(\n '<circle cx=\"4\" cy=\"6\" r=\"1.2\" fill=\"currentColor\"/><circle cx=\"4\" cy=\"10\" r=\"1.2\" fill=\"currentColor\"/><circle cx=\"4\" cy=\"14\" r=\"1.2\" fill=\"currentColor\"/><path d=\"M8 6h9M8 10h9M8 14h9\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.unorderedList'),\n exec('insertUnorderedList'),\n );\n this.btns.ol = this._iconBtn(\n svgIcon(\n '<text x=\"2\" y=\"8\" font-size=\"6\" font-weight=\"600\" fill=\"currentColor\">1</text><text x=\"2\" y=\"14\" font-size=\"6\" font-weight=\"600\" fill=\"currentColor\">2</text><path d=\"M8 6h9M8 12h9\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.orderedList'),\n exec('insertOrderedList'),\n );\n\n this.selectListIndent = h('select', {\n class: 'sm-floating-toolbar__select sm-floating-toolbar__select--list-indent',\n title: t('toolbar.listIndent'),\n onchange: (e: Event) => {\n if (this.syncingListIndentUi) return;\n const raw = (e.target as HTMLSelectElement).value;\n if (raw === '') this.editor?.setListIndent(null);\n else this.editor?.setListIndent(Number(raw));\n },\n }) as HTMLSelectElement;\n {\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = t('toolbar.indent');\n this.selectListIndent.append(placeholder);\n for (const px of LIST_INDENT_PRESETS_PX) {\n const opt = document.createElement('option');\n opt.value = String(px);\n opt.textContent = String(px);\n this.selectListIndent.append(opt);\n }\n }\n this.listIndentGroup = this._group([this.selectListIndent]);\n this.listIndentGroup.style.display = 'none';\n\n // 字体:select 不能 preventDefault(否则下拉打不开);mousedown(capture) 已存档选区\n this.selectFontFamily = h('select', {\n class: 'sm-floating-toolbar__select',\n title: t('toolbar.fontFamily'),\n onchange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v) this.editor?.exec('fontName', v);\n else this.editor?.exec('removeFormat');\n },\n });\n for (const f of FONT_FAMILIES) {\n const opt = document.createElement('option');\n opt.value = f.value;\n opt.textContent = f.labelKey ? t(f.labelKey) : f.label;\n this.selectFontFamily.append(opt);\n }\n\n // 字号\n this.selectFontSize = h('select', {\n class: 'sm-floating-toolbar__select',\n title: t('toolbar.fontSize'),\n onchange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v) this.editor?.applyFontSize(v);\n },\n });\n {\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = t('toolbar.fontSize');\n this.selectFontSize.append(placeholder);\n }\n for (const px of FONT_SIZES) {\n const opt = document.createElement('option');\n opt.value = px;\n opt.textContent = px;\n this.selectFontSize.append(opt);\n }\n\n // 字重\n this.selectFontWeight = h('select', {\n class: 'sm-floating-toolbar__select',\n title: t('toolbar.fontWeight'),\n onchange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v) this.editor?.applyFontWeight(v);\n },\n });\n {\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = t('toolbar.fontWeight');\n this.selectFontWeight.append(placeholder);\n }\n for (const w of FONT_WEIGHT_STEP_OPTIONS) {\n const opt = document.createElement('option');\n opt.value = w.value;\n opt.textContent = w.label;\n this.selectFontWeight.append(opt);\n }\n\n // 文字颜色\n this.inputColor = h('input', {\n class: 'sm-floating-toolbar__color',\n type: 'color',\n title: t('toolbar.textColor'),\n value: '#433f3f',\n }) as HTMLInputElement;\n bindColorPickerInput(this.inputColor, {\n layerRoot: this.opts.positionRoot,\n liveCommit: true,\n autoFocusHex: false,\n t,\n onBeforeOpen: () => this.editor?.saveSelection(),\n onCommit: (hex) => this.editor?.exec('foreColor', hex),\n onClosed: () => this.editor?.refocus(),\n });\n\n // 文字背景色\n this.inputBgColor = h('input', {\n class: 'sm-floating-toolbar__color',\n type: 'color',\n title: t('toolbar.textBackground'),\n value: '#fff7e6',\n }) as HTMLInputElement;\n bindColorPickerInput(this.inputBgColor, {\n layerRoot: this.opts.positionRoot,\n liveCommit: true,\n autoFocusHex: false,\n t,\n onBeforeOpen: () => this.editor?.saveSelection(),\n onCommit: (hex) => this.editor?.exec('hiliteColor', hex),\n onClosed: () => this.editor?.refocus(),\n });\n\n // 链接:插入链接(无链接时显示)\n this.btns.link = this._iconBtn(\n svgIcon(\n '<path d=\"M9 11.5l1.5 1.5a3.5 3.5 0 005-5l-2-2a3.5 3.5 0 00-5 0M11 8.5L9.5 7a3.5 3.5 0 00-5 5l2 2a3.5 3.5 0 005 0\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n ),\n t('toolbar.insertLink'),\n () => this._toggleLinkPanel(),\n );\n\n // 取消链接(有链接时显示)\n this.btns.unlink = this._iconBtn(\n svgIcon(\n '<path d=\"M9 11.5l1.5 1.5a3.5 3.5 0 005-5l-2-2\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\"/><path d=\"M3 3l14 14\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.unlink'),\n exec('unlink'),\n );\n\n // 清除格式:图标改为 Tx,避免被误认为\"关闭工具条\"\n this.btns.clear = this._iconBtn(\n svgIcon(\n '<text x=\"2\" y=\"14\" font-size=\"11\" font-weight=\"700\" fill=\"currentColor\">T</text><text x=\"11\" y=\"9\" font-size=\"7\" font-weight=\"700\" fill=\"currentColor\">x</text><path d=\"M11 11l5 5M16 11l-5 5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.clearFormat'),\n exec('removeFormat'),\n );\n\n this.linkPanel = h('div', { class: 'sm-floating-toolbar__link-panel' });\n this.inputLink = h('input', {\n class: 'sm-input',\n type: 'url',\n placeholder: 'https://...',\n onkeydown: ((e: Event) => {\n const ke = e as KeyboardEvent;\n if (ke.key === 'Enter') {\n ke.preventDefault();\n this._applyLink();\n } else if (ke.key === 'Escape') {\n ke.preventDefault();\n this.linkPanel.classList.remove('is-visible');\n this.editor?.refocus();\n }\n }) as EventListener,\n }) as HTMLInputElement;\n const applyLinkBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onmousedown: (e: Event) => e.preventDefault(),\n onclick: () => this._applyLink(),\n },\n [t('toolbar.apply')],\n );\n this.linkPanel.append(this.inputLink, applyLinkBtn);\n\n this.el.append(\n this._group([this.btns.bold, this.btns.italic, this.btns.underline, this.btns.strikethrough]),\n sep(),\n this._group([this.selectFontFamily, this.selectFontSize, this.selectFontWeight]),\n sep(),\n this._group([this.inputColor, this.inputBgColor]),\n sep(),\n this._group([this.btns.alignLeft, this.btns.alignCenter, this.btns.alignRight]),\n sep(),\n this._group([this.btns.ul, this.btns.ol]),\n this.listIndentGroup,\n sep(),\n this._group([this.btns.link, this.btns.unlink, this.btns.clear]),\n this.linkPanel,\n );\n }\n\n private _toggleLinkPanel() {\n const opening = !this.linkPanel.classList.contains('is-visible');\n this.linkPanel.classList.toggle('is-visible');\n if (this.linkPanel.classList.contains('is-visible')) {\n if (opening) {\n this.inputLink.value = this.lastLinkHref ?? '';\n }\n requestAnimationFrame(() => this.inputLink.focus());\n } else {\n this.editor?.refocus();\n }\n }\n\n private _applyLink() {\n if (!this.editor) return;\n const url = this.inputLink.value.trim();\n this.editor.setLink(url);\n this.linkPanel.classList.remove('is-visible');\n this.inputLink.value = '';\n }\n\n private _getScrollRoot(): HTMLElement {\n return (\n this.opts.scrollRoot ??\n (this.opts.positionRoot.querySelector('.sm-canvas-wrap') as HTMLElement | null) ??\n this.opts.positionRoot\n );\n }\n\n private _scheduleReposition() {\n if (this.repositionRaf) cancelAnimationFrame(this.repositionRaf);\n const ed = this.editor;\n this.repositionRaf = requestAnimationFrame(() => {\n this.repositionRaf = 0;\n if (!this.editor || ed !== this.editor || !this.el.classList.contains('is-visible')) return;\n this._positionForAnchor(this.editor.getAnchorRect());\n });\n }\n\n private _bindScrollListeners() {\n if (this.scrollListenersBound) return;\n this.scrollListenersBound = true;\n const scrollRoot = this._getScrollRoot();\n scrollRoot.addEventListener('scroll', this.boundReposition, { passive: true });\n this.opts.positionRoot\n .querySelector('.sm-body')\n ?.addEventListener('scroll', this.boundReposition, { passive: true });\n window.addEventListener('resize', this.boundReposition, { passive: true });\n }\n\n private _unbindScrollListeners() {\n if (!this.scrollListenersBound) return;\n this.scrollListenersBound = false;\n const scrollRoot = this._getScrollRoot();\n scrollRoot.removeEventListener('scroll', this.boundReposition);\n this.opts.positionRoot\n .querySelector('.sm-body')\n ?.removeEventListener('scroll', this.boundReposition);\n window.removeEventListener('resize', this.boundReposition);\n }\n\n /**\n * 相对 `positionRoot` 定位:默认贴在**正文容器**上沿上方,可覆盖上方块工具区;\n * 上方空间不足时吸到中栏画布可见区顶部,此时才可能压进正文。\n */\n private _positionForAnchor(anchor: DOMRect) {\n const rootRect = this.opts.positionRoot.getBoundingClientRect();\n const viewRect = this._getScrollRoot().getBoundingClientRect();\n const gap = 6;\n const edge = 8;\n const bar = this.el.getBoundingClientRect();\n const tw = bar.width || this.el.offsetWidth;\n const th = bar.height || this.el.offsetHeight || 40;\n\n const viewTop = viewRect.top - rootRect.top + edge;\n const viewBottom = viewRect.bottom - rootRect.top - th - edge;\n const viewLeft = viewRect.left - rootRect.left + edge;\n const viewRight = viewRect.right - rootRect.left - tw - edge;\n\n const anchorTop = anchor.top - rootRect.top;\n let top = anchorTop - th - gap;\n top = Math.max(viewTop, Math.min(top, viewBottom));\n\n let left = anchor.left - rootRect.left + anchor.width / 2 - tw / 2;\n left = Math.max(viewLeft, Math.min(left, viewRight));\n\n this.el.style.top = `${top}px`;\n this.el.style.left = `${left}px`;\n }\n\n private _syncListIndentUi(inList: boolean, indent: ListIndentValue) {\n this.listIndentGroup.style.display = inList ? '' : 'none';\n if (!inList) return;\n\n this.syncingListIndentUi = true;\n if (indent === null) {\n this.selectListIndent.value = '';\n } else {\n const preset = LIST_INDENT_PRESETS_PX.find((px) => px === indent);\n const shown =\n preset ??\n LIST_INDENT_PRESETS_PX.reduce((best, px) =>\n Math.abs(px - indent) < Math.abs(best - indent) ? px : best,\n );\n this.selectListIndent.value = String(shown);\n }\n this.syncingListIndentUi = false;\n }\n\n private _setActive(key: string, on: boolean) {\n this.btns[key]?.classList.toggle('is-active', on);\n }\n\n private _btn(\n text: string,\n title: string,\n onClick: () => void,\n style: Partial<CSSStyleDeclaration> = {},\n ): HTMLButtonElement {\n const b = h(\n 'button',\n {\n class: 'sm-floating-toolbar__btn',\n type: 'button',\n title,\n onmousedown: (e: Event) => e.preventDefault(),\n onclick: onClick,\n },\n [text],\n ) as HTMLButtonElement;\n Object.assign(b.style, style);\n return b;\n }\n\n private _iconBtn(icon: SVGElement, title: string, onClick: () => void): HTMLButtonElement {\n return h(\n 'button',\n {\n class: 'sm-floating-toolbar__btn',\n type: 'button',\n title,\n onmousedown: (e: Event) => e.preventDefault(),\n onclick: onClick,\n },\n [icon],\n ) as HTMLButtonElement;\n }\n\n private _group(children: HTMLElement[]): HTMLElement {\n return h('div', { class: 'sm-floating-toolbar__group' }, children);\n }\n}\n\nfunction svgIcon(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '14');\n el.setAttribute('height', '14');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML = inner;\n return el;\n}\n\nfunction matchFamily(name: string): string {\n const lower = name.toLowerCase().replace(/['\"]/g, '').split(',')[0].trim();\n for (const f of FONT_FAMILIES) {\n if (!f.value) continue;\n if (f.value.toLowerCase().includes(lower)) return f.value;\n }\n return '';\n}\n\nfunction matchFontSize(raw: string | null): string {\n if (!raw) return '';\n const m = raw.trim().match(/^(\\d+(?:\\.\\d+)?)px$/i);\n if (!m) return '';\n const px = `${Math.round(parseFloat(m[1]))}px`;\n if (FONT_SIZES.includes(px)) return px;\n const num = parseFloat(px);\n let best = FONT_SIZES[0];\n let bestD = Infinity;\n for (const s of FONT_SIZES) {\n const d = Math.abs(parseFloat(s) - num);\n if (d < bestD) {\n bestD = d;\n best = s;\n }\n }\n return best;\n}\n\nfunction matchFontWeight(raw: string | null): string {\n if (!raw) return '';\n const step = normalizeFontWeightStep(raw);\n return FONT_WEIGHT_STEP_OPTIONS.some((w) => w.value === step) ? step : '';\n}\n\nfunction colorToHexInput(color: string): string | null {\n const s = color.trim();\n if (!s) return null;\n if (s.startsWith('#')) {\n if (/^#[0-9a-f]{3}$/i.test(s)) {\n const r = s[1];\n const g = s[2];\n const b = s[3];\n return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();\n }\n if (/^#[0-9a-f]{6}$/i.test(s)) return s.toLowerCase();\n return s;\n }\n const m = s.match(/^rgba?\\(\\s*(\\d+)[,\\s]+(\\d+)[,\\s]+(\\d+)/i);\n if (!m) return null;\n const toHex = (n: string) => Number(n).toString(16).padStart(2, '0');\n return `#${toHex(m[1])}${toHex(m[2])}${toHex(m[3])}`;\n}\n","/** 与 blocks 中社交图标预设背景一致;core 不可依赖 blocks,供属性面板展示默认背景色 */\nexport function defaultSocialIconBackground(network: string): string {\n const m: Record<string, string> = {\n wechat: '#1AAD19',\n weibo: '#E6162D',\n x: '#000000',\n linkedin: '#0A66C2',\n github: '#181717',\n facebook: '#1877F2',\n instagram: '#E4405F',\n ig: '#E4405F',\n youtube: '#FF0000',\n tiktok: '#000000',\n rabbit: '#FF2442',\n website: '#6b7280',\n web: '#6b7280',\n };\n return m[network] ?? '#6b7280';\n}\n","/**\n * 右侧「图片地址」类字段:宿主可选手输 URL、本地上传、内置图库弹层或完全自管图库回调。\n * 编辑器最终只把 URL 写入 props。\n */\n\nexport interface ImageFieldContext {\n /** 当前选中的 Block id */\n blockId: string;\n /** 对应 `block.props` 的字段名,如 `src`、`backgroundUrl` */\n propKey: string;\n /** 输入框当前值,便于宿主作为默认筛选或回填参考 */\n currentUrl: string;\n}\n\n/** 图库列表中的一条资源 */\nexport interface GalleryItem {\n id: string;\n /** 写入邮件字段的最终图片地址(建议 HTTPS 绝对 URL) */\n url: string;\n thumbnailUrl?: string;\n title?: string;\n}\n\nexport interface ImageGalleryListResult {\n items: GalleryItem[];\n hasMore: boolean;\n}\n\n/**\n * 资源动作权限的语义标识。宿主在 `ImageAssetPermissions.check` 中据此返回是否有权限:\n * - `'upload'`:右栏「上传」按钮、图库弹层「上传」按钮(对应创建/上传权限)\n * - `'addUrl'`:图库弹层「添加链接」按钮(对应创建权限)\n * - `'delete'`:图库弹层缩略图删除按钮(对应删除权限)\n */\nexport type AssetPermissionAction = 'upload' | 'addUrl' | 'delete';\n\n/**\n * 图片资源动作的权限管控配置。未配置 `check` 时视为全部有权限(不做管控)。\n */\nexport interface ImageAssetPermissions {\n /**\n * 权限校验:返回 `false` 表示该动作无权限。\n * 未配置时视为全部有权限。\n */\n check?: (action: AssetPermissionAction) => boolean;\n /**\n * 无权限时的表现:\n * - `'disable'`(默认):按钮置灰禁用,hover 提示无权限。\n * - `'hide'`:直接隐藏对应按钮。\n */\n noPermissionMode?: 'disable' | 'hide';\n /**\n * 无权限禁用时 hover 提示文案;未配置或为空时使用编辑器默认文案(`common.noPermission`)。\n */\n noPermissionTip?: string;\n}\n\n/** `resolveAssetPermission` 的结果。 */\nexport interface ResolvedAssetPermission {\n /** `true` 表示有权限 */\n allowed: boolean;\n /** 无权限时的表现(仅在 `allowed === false` 时有意义) */\n mode: 'disable' | 'hide';\n /** 无权限禁用时的 hover 提示文案(仅在 `allowed === false` 且 `mode === 'disable'` 时有意义) */\n tip: string;\n}\n\n/**\n * 解析某个动作的权限状态。未配置 `permissions` 或 `check` 时视为有权限。\n * @param defaultNoPermissionTip 编辑器默认的无权限提示文案(由调用方从 i18n 传入)\n */\nexport function resolveAssetPermission(\n permissions: ImageAssetPermissions | undefined,\n action: AssetPermissionAction,\n defaultNoPermissionTip: string,\n): ResolvedAssetPermission {\n if (!permissions?.check) return { allowed: true, mode: 'disable', tip: '' };\n const allowed = permissions.check(action);\n if (allowed) return { allowed: true, mode: 'disable', tip: '' };\n const mode: 'disable' | 'hide' = permissions.noPermissionMode === 'hide' ? 'hide' : 'disable';\n const tip = (permissions.noPermissionTip ?? '').trim() || defaultNoPermissionTip;\n return { allowed: false, mode, tip };\n}\n\n/**\n * 内置图库弹层的数据与扩展能力。实现 `listItems` 即可;上传、链接添加、删除等仅在提供对应方法时显示。\n */\nexport interface ImageGalleryAdapter {\n /** 搜索 + 分页;`query` 为搜索框当前文本,`page` 从 0 起 */\n listItems: (args: { query: string; page: number }) => Promise<ImageGalleryListResult>;\n /** 在弹层内「上传到图库」:成功后编辑器会重新拉取第 0 页 */\n uploadFile?: (file: File) => Promise<void | string>;\n /** 在弹层内「通过链接添加」:校验/落库后编辑器会重新拉取第 0 页 */\n addByUrl?: (url: string) => Promise<void>;\n /** 从图库删除一条;提供后每张缩略图右上角显示删除按钮 */\n deleteItem?: (id: string) => Promise<void>;\n}\n\nexport interface ImageAssetsHandlers {\n /**\n * 用户点击右侧「上传」并选择本地文件。宿主完成上传后返回 **绝对 HTTPS URL**。\n */\n uploadImage?: (file: File, ctx: ImageFieldContext) => Promise<string>;\n\n /**\n * 完全自管图库:与内置 `imageGallery` 可并存;\n * **同时配置时优先使用内置 `imageGallery` 弹层**。\n */\n pickImageFromGallery?: (ctx: ImageFieldContext) => Promise<string | null>;\n\n /**\n * 内置图库:实现 `listItems` 等后,将 `showGallery: true`,由本库渲染弹层;\n * 无需再写自有弹框 DOM。\n */\n imageGallery?: ImageGalleryAdapter;\n\n /**\n * 是否显示「上传」按钮。仅当配置了 `uploadImage` 时有效。\n * 默认 `true`;设为 `false` 可关闭(仍可手输 URL)。\n */\n showUpload?: boolean;\n\n /**\n * 是否显示「图库」按钮。在配置了 `pickImageFromGallery` 或 `imageGallery` 时有效。\n * 默认 `false`;需显式设为 `true` 才展示入口。\n */\n showGallery?: boolean;\n\n /**\n * 资源动作权限管控。配置后,「上传 / 添加链接 / 删除」按钮将按 `check` 结果禁用或隐藏。\n * 默认无权限时禁用并 hover 提示。右栏「上传」与图库弹层内按钮共用同一份配置。\n */\n permissions?: ImageAssetPermissions;\n}\n","import type { Registry } from '../registry/registry';\nimport type { Store } from '../store/store';\nimport { findBlockLocation, findSection } from '../store/store';\nimport { clear, h } from '../utils/dom';\nimport type { SectionLayout } from '../types';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface FocusBreadcrumbOptions {\n store: Store;\n registry: Registry;\n /** 文档级根节点文案(如「邮件」/「版式」) */\n docRootLabel: string;\n t: SimpleMailT;\n onFocusDocument: () => void;\n onFocusSection: (sectionId: string) => void;\n}\n\ninterface CrumbItem {\n label: string;\n current: boolean;\n onClick?: () => void;\n}\n\n/**\n * 右栏聚焦路径:邮件 > 一列 > 文本。\n * 点击父级等同 Esc 上浮(块 → Section → 文档级面板)。\n */\nexport class FocusBreadcrumb {\n el: HTMLElement;\n private opts: FocusBreadcrumbOptions;\n\n constructor(opts: FocusBreadcrumbOptions) {\n this.opts = opts;\n this.el = h('nav', {\n class: 'sm-focus-crumb',\n 'aria-label': opts.t('rightPanel.breadcrumb.selected'),\n });\n opts.store.subscribeSelection(() => this.sync());\n opts.store.subscribe(() => this.sync());\n this.sync();\n }\n\n setVisible(on: boolean) {\n this.el.hidden = !on;\n }\n\n sync() {\n clear(this.el);\n const items = this._buildItems();\n if (!items.length) {\n this.el.hidden = true;\n return;\n }\n this.el.hidden = false;\n\n items.forEach((item, i) => {\n if (i > 0) {\n this.el.append(h('span', { class: 'sm-focus-crumb__sep', 'aria-hidden': 'true' }, ['›']));\n }\n if (item.current || !item.onClick) {\n this.el.append(\n h(\n 'span',\n {\n class: `sm-focus-crumb__item sm-focus-crumb__item--current`,\n title: item.label,\n },\n [item.label],\n ),\n );\n } else {\n this.el.append(\n h(\n 'button',\n {\n type: 'button',\n class: 'sm-focus-crumb__item',\n title: this.opts.t('rightPanel.breadcrumb.selectTitle', { label: item.label }),\n onclick: () => item.onClick!(),\n },\n [item.label],\n ),\n );\n }\n });\n }\n\n private _buildItems(): CrumbItem[] {\n const { store, registry, docRootLabel, onFocusDocument, onFocusSection } = this.opts;\n const sel = store.selection;\n const doc = store.doc;\n\n if (!sel) {\n return [{ label: docRootLabel, current: true }];\n }\n\n if (sel.kind === 'section') {\n const sec = findSection(doc, sel.sectionId);\n if (!sec) return [{ label: docRootLabel, current: true }];\n return [\n { label: docRootLabel, current: false, onClick: onFocusDocument },\n { label: this._layoutLabel(sec.layout), current: true },\n ];\n }\n\n const sec = findSection(doc, sel.sectionId);\n const loc = findBlockLocation(doc, sel.blockId);\n if (!sec || !loc) {\n return [{ label: docRootLabel, current: true }];\n }\n\n const blockName = registry.get(loc.block.type)?.name ?? loc.block.type;\n return [\n {\n label: this._layoutLabel(sec.layout),\n current: false,\n onClick: () => onFocusSection(sel.sectionId),\n },\n { label: blockName, current: true },\n ];\n }\n\n private _layoutLabel(layout: SectionLayout): string {\n if (layout === '1') return this.opts.t('rightPanel.layout.oneColumn');\n if (layout === '1-1') return this.opts.t('rightPanel.layout.columns');\n return layout;\n }\n}\n","import { type SimpleMailT, createI18nContext } from '../i18n';\nimport { clear, h } from '../utils/dom';\nimport { Modal } from './Modal';\nimport {\n type AssetPermissionAction,\n type GalleryItem,\n type ImageAssetPermissions,\n type ImageGalleryAdapter,\n resolveAssetPermission,\n} from './imageAssets';\n\nexport interface OpenImageGalleryModalOptions {\n adapter: ImageGalleryAdapter;\n onPick: (url: string) => void;\n t?: SimpleMailT;\n /** 挂载父节点,默认 `document.body` */\n parent?: HTMLElement;\n onClose?: () => void;\n /**\n * 资源动作权限管控。未配置或未提供 `check` 时弹层内按钮不做管控;\n * 配置后「添加 / 上传 / 删除」按 `check` 结果禁用(默认)或隐藏,禁用时 hover 提示无权限。\n */\n permissions?: ImageAssetPermissions;\n}\n\n/**\n * 打开内置图库弹层:搜索、分页、选图插入;可选「链接添加」「上传到图库」「删除」由 adapter 决定。\n */\nexport function openImageGalleryModal(opts: OpenImageGalleryModalOptions): void {\n const { adapter, onPick, parent = document.body, onClose, permissions } = opts;\n const t = opts.t ?? createI18nContext().t;\n\n /** 默认无权限提示文案(i18n),按动作取对应文案 */\n const noPermissionTip = (action: AssetPermissionAction): string => {\n switch (action) {\n case 'upload':\n return t('common.noPermissionUpload');\n case 'addUrl':\n return t('common.noPermissionAdd');\n case 'delete':\n return t('common.noPermissionDelete');\n default:\n return t('common.noPermission');\n }\n };\n const perm = (action: AssetPermissionAction) =>\n resolveAssetPermission(permissions, action, noPermissionTip(action));\n\n const modal = new Modal({\n title: t('gallery.title'),\n width: 'min(760px, 94vw)',\n height: 'min(580px, 88vh)',\n className: 'sm-modal--gallery',\n onClose,\n t,\n });\n\n const wrap = h('div', { class: 'sm-gallery-modal' });\n\n let query = '';\n let page = 0;\n let hasMore = false;\n let loading = false;\n let selected: GalleryItem | null = null;\n\n const errEl = h('div', {\n class: 'sm-gallery-modal__error',\n style: 'display:none',\n role: 'alert',\n });\n\n const searchInp = h('input', {\n class: 'sm-input sm-gallery-modal__search',\n type: 'search',\n placeholder: t('gallery.searchPlaceholder'),\n 'aria-label': t('gallery.searchAria'),\n });\n\n let debounceId: ReturnType<typeof setTimeout> | null = null;\n searchInp.addEventListener('input', () => {\n if (debounceId) clearTimeout(debounceId);\n debounceId = setTimeout(() => {\n query = (searchInp as HTMLInputElement).value;\n void loadFirst();\n }, 320);\n });\n\n const gridEl = h('div', { class: 'sm-gallery-modal__grid' });\n\n const loadMoreBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-gallery-modal__loadmore',\n type: 'button',\n style: 'display:none',\n onclick: () => {\n if (!hasMore || loading) return;\n void loadPage(page + 1, true);\n },\n },\n [t('gallery.loadMore')],\n ) as HTMLButtonElement;\n\n const confirmBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n disabled: true,\n onclick: () => finishPick(),\n },\n [t('common.insert')],\n ) as HTMLButtonElement;\n\n function setError(msg: string | null) {\n if (msg) {\n errEl.textContent = msg;\n errEl.style.display = '';\n } else {\n errEl.textContent = '';\n errEl.style.display = 'none';\n }\n }\n\n function syncSelectionStyles() {\n const cells = gridEl.querySelectorAll('.sm-gallery-modal__cell');\n cells.forEach((c) => {\n const id = (c as HTMLElement).dataset.id;\n c.classList.toggle('is-selected', !!selected && id === selected.id);\n });\n }\n\n function renderCells(items: GalleryItem[], append: boolean) {\n if (!append) clear(gridEl);\n if (items.length === 0 && !append) {\n gridEl.append(h('div', { class: 'sm-gallery-modal__empty' }, [t('gallery.empty')]));\n loadMoreBtn.style.display = hasMore ? '' : 'none';\n return;\n }\n for (const it of items) {\n const thumb = it.thumbnailUrl || it.url;\n const cellWrap = h('div', { class: 'sm-gallery-modal__cell-wrap' });\n const cell = h(\n 'button',\n {\n type: 'button',\n class: 'sm-gallery-modal__cell',\n title: it.title || it.url,\n 'data-id': it.id,\n onclick: () => {\n selected = it;\n syncSelectionStyles();\n confirmBtn.disabled = false;\n },\n ondblclick: (e: Event) => {\n e.preventDefault();\n selected = it;\n finishPick();\n },\n },\n [],\n );\n const img = h('img', {\n class: 'sm-gallery-modal__thumb',\n alt: '',\n loading: 'lazy',\n decoding: 'async',\n }) as HTMLImageElement;\n img.src = thumb;\n img.onerror = () => {\n img.style.opacity = '0.72';\n };\n const cap = h('div', { class: 'sm-gallery-modal__caption' }, [\n it.title?.trim() ? it.title : t('common.image'),\n ]);\n cell.append(img, cap);\n cellWrap.append(cell);\n\n if (adapter.deleteItem) {\n const deletePerm = perm('delete');\n if (!deletePerm.allowed && deletePerm.mode === 'hide') {\n // 无删除权限且配置为隐藏:不渲染删除按钮\n } else {\n const delBtn = h(\n 'button',\n {\n type: 'button',\n class: 'sm-gallery-modal__cell-delete',\n title: deletePerm.allowed ? t('gallery.deleteTitle') : deletePerm.tip,\n disabled: !deletePerm.allowed,\n ...(deletePerm.allowed\n ? {\n onclick: async (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n if (!window.confirm(t('gallery.deleteConfirm'))) return;\n try {\n await adapter.deleteItem!(it.id);\n if (selected?.id === it.id) {\n selected = null;\n confirmBtn.disabled = true;\n }\n await loadFirst();\n } catch (err) {\n setError(err instanceof Error ? err.message : t('gallery.deleteFailed'));\n }\n },\n }\n : {}),\n },\n ['×'],\n );\n cellWrap.append(delBtn);\n }\n }\n\n gridEl.append(cellWrap);\n }\n loadMoreBtn.style.display = hasMore ? '' : 'none';\n }\n\n async function loadPage(p: number, append: boolean) {\n if (loading) return;\n loading = true;\n loadMoreBtn.disabled = true;\n setError(null);\n try {\n const res = await adapter.listItems({ query, page: p });\n hasMore = res.hasMore;\n page = p;\n renderCells(res.items, append);\n } catch (e) {\n setError(e instanceof Error ? e.message : t('gallery.loadFailed'));\n } finally {\n loading = false;\n loadMoreBtn.disabled = false;\n }\n }\n\n async function loadFirst() {\n page = 0;\n selected = null;\n confirmBtn.disabled = true;\n clear(gridEl);\n await loadPage(0, false);\n syncSelectionStyles();\n }\n\n function finishPick() {\n if (!selected?.url?.trim()) return;\n onPick(selected.url.trim());\n modal.close();\n }\n\n /** 搜索、链接、添加、上传同一行(窄屏可换行) */\n const toolbar = h('div', { class: 'sm-gallery-modal__toolbar' });\n const toolRow = h('div', { class: 'sm-gallery-modal__toolbar-row' });\n toolRow.append(searchInp);\n\n if (adapter.addByUrl) {\n const addPerm = perm('addUrl');\n if (!addPerm.allowed && addPerm.mode === 'hide') {\n // 无添加权限且配置为隐藏:不渲染添加链接输入框与按钮\n } else {\n const urlInp = h('input', {\n class: 'sm-input sm-gallery-modal__addurl-input',\n type: 'url',\n placeholder: t('gallery.addUrlPlaceholder'),\n disabled: !addPerm.allowed,\n }) as HTMLInputElement;\n const addBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-gallery-modal__toolbar-action',\n type: 'button',\n title: addPerm.allowed ? '' : addPerm.tip,\n disabled: !addPerm.allowed,\n ...(addPerm.allowed\n ? {\n onclick: async () => {\n const u = urlInp.value.trim();\n if (!u) return;\n try {\n await adapter.addByUrl!(u);\n urlInp.value = '';\n await loadFirst();\n } catch (e) {\n setError(e instanceof Error ? e.message : t('gallery.addFailed'));\n }\n },\n }\n : {}),\n },\n [t('common.add')],\n );\n toolRow.append(urlInp, addBtn);\n }\n }\n\n if (adapter.uploadFile) {\n const uploadPerm = perm('upload');\n if (!uploadPerm.allowed && uploadPerm.mode === 'hide') {\n // 无上传权限且配置为隐藏:不渲染上传按钮\n } else {\n const fileInp = h('input', {\n type: 'file',\n accept: 'image/*',\n class: 'sm-gallery-modal__file',\n });\n fileInp.addEventListener('change', async () => {\n const f = (fileInp as HTMLInputElement).files?.[0];\n (fileInp as HTMLInputElement).value = '';\n if (!f) return;\n try {\n await adapter.uploadFile!(f);\n await loadFirst();\n } catch (e) {\n setError(e instanceof Error ? e.message : t('gallery.uploadFailed'));\n }\n });\n const upBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-gallery-modal__toolbar-action',\n type: 'button',\n title: uploadPerm.allowed ? '' : uploadPerm.tip,\n disabled: !uploadPerm.allowed,\n ...(uploadPerm.allowed ? { onclick: () => fileInp.click() } : {}),\n },\n [t('common.upload')],\n );\n toolRow.append(upBtn, fileInp);\n }\n }\n\n toolbar.append(toolRow);\n\n const scrollArea = h('div', { class: 'sm-gallery-modal__scroll' }, [gridEl, loadMoreBtn]);\n\n wrap.append(toolbar, errEl, scrollArea);\n\n modal.body.append(wrap);\n modal.footer.append(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary',\n type: 'button',\n onclick: () => modal.close(),\n },\n [t('common.cancel')],\n ),\n confirmBtn,\n );\n\n modal.open(parent);\n void loadFirst();\n}\n","import type { Variable } from '../types';\nimport { variablePlaceholder } from '../variables';\nimport { h } from '../utils/dom';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface VariablePickerHandlers {\n onPickKey: (v: Variable) => void;\n onPickElement: (v: Variable) => void;\n onCopy: (token: string) => void;\n onClose: () => void;\n}\n\nexport interface VariablePickerHeadOptions {\n pinned: boolean;\n t: SimpleMailT;\n onClose: () => void;\n /** 切换固定状态,返回切换后的 pinned */\n onTogglePin: () => boolean;\n}\n\n/** 右栏变量列表头部(标题 + 固定 + 关闭) */\nexport function buildVariablePickerHead(options: VariablePickerHeadOptions): HTMLElement {\n let pinned = options.pinned;\n const t = options.t;\n const syncPinBtn = (btn: HTMLButtonElement) => {\n btn.classList.toggle('is-pinned', pinned);\n btn.setAttribute('aria-pressed', String(pinned));\n btn.title = pinned ? t('variablePicker.unpinTitle') : t('variablePicker.pinTitle');\n };\n const pinBtn = h(\n 'button',\n {\n class: 'sm-var-picker__pin',\n type: 'button',\n 'aria-label': t('variablePicker.pin'),\n onclick: () => {\n pinned = options.onTogglePin();\n syncPinBtn(pinBtn);\n },\n },\n [iconPin()],\n ) as HTMLButtonElement;\n syncPinBtn(pinBtn);\n\n const closeBtn = h(\n 'button',\n {\n class: 'sm-modal__close sm-var-picker__close',\n type: 'button',\n title: t('common.close'),\n 'aria-label': t('variablePicker.closeTitle'),\n onclick: () => options.onClose(),\n },\n [iconClose()],\n );\n\n return h('div', { class: 'sm-var-picker__head' }, [\n h('div', { class: 'sm-panel__title sm-var-picker__title' }, [t('variablePicker.title')]),\n h('div', { class: 'sm-var-picker__actions' }, [pinBtn, closeBtn]),\n ]);\n}\n\nfunction iconClose(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M5 5l10 10M15 5L5 15\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>';\n return el;\n}\n\nfunction iconPin(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 1024 1024');\n el.innerHTML =\n '<path d=\"M393.846154 64.174932l117.454119 0.399843H512.499805l117.454119-0.399843-10.395939 10.395939c-18.89262 18.89262-28.488872 44.982429-26.28973 71.472081l20.292073 250.502148c2.998829 36.68567 18.092932 72.171808 42.483405 99.661069l34.186646 38.684889-122.252245-0.899648-55.478329-0.399844h-0.99961l-55.478329 0.399844-122.452167 0.799687 34.186646-38.684888c24.390472-27.589223 39.484576-62.9754 42.483405-99.66107l20.292074-250.402187c2.199141-26.589613-7.397111-52.679422-26.289731-71.472081l-10.395939-10.395939m281.889887-64.174932h-0.199922L512.399844 0.599766h-0.799688L348.36392 0h-0.199922c-20.891839 0-39.684498 13.494729-45.582194 33.58688-4.098399 13.994533-1.899258 30.887934 17.79305 47.581414l38.584927 38.584927c5.597813 5.597813 8.39672 13.294807 7.796955 21.091761L346.464662 391.247169c-1.899258 23.190941-11.195627 45.08239-26.589613 62.475596l-61.87583 69.872706c-8.696603 9.796173-13.894572 22.291292-14.394377 35.386177-0.299883 8.996486 1.599375 18.89262 8.596642 27.28934 6.897306 8.296759 17.293245 12.894963 27.989067 12.894963h0.299882l175.931277-1.199532 55.178446 422.834831 0.399844 3.098789 0.399844-3.098789 55.178446-422.834831 175.931277 1.199532h0.299882c10.795783 0 21.191722-4.598204 27.989067-12.894963 6.897306-8.39672 8.796564-18.292854 8.596642-27.28934-0.399844-13.094885-5.697774-25.590004-14.394377-35.386177l-61.87583-69.872706c-15.393987-17.393206-24.690355-39.284654-26.589613-62.475596l-20.292074-250.402187c-0.599766-7.796954 2.199141-15.593909 7.796955-21.091761l38.584927-38.584927c19.692308-16.693479 21.891449-33.58688 17.79305-47.581414-5.997657-19.992191-24.790316-33.58688-45.682155-33.58688z\" fill=\"currentColor\"/>';\n return el;\n}\n\n/** 右栏可滚动变量列表(交互与旧 popover 一致) */\nexport function buildVariablePickerBody(\n vars: Variable[],\n handlers: VariablePickerHandlers,\n t: SimpleMailT,\n): HTMLElement {\n const wrap = h('div', { class: 'sm-var-picker' });\n if (!vars.length) {\n wrap.append(\n h('div', { class: 'sm-empty-form' }, [t('variablePicker.empty')]),\n );\n return wrap;\n }\n for (const v of vars) {\n const token = variablePlaceholder(v.key);\n const row = h('div', { class: 'sm-popover__row' });\n const actions = h('div', { class: 'sm-popover__actions' });\n if (v.kind === 'link' || v.kind === 'image') {\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action',\n type: 'button',\n onclick: (e: Event) => {\n e.stopPropagation();\n handlers.onPickElement(v);\n },\n },\n [t('variablePicker.insertElement')],\n ),\n );\n }\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action sm-popover__action--copy',\n type: 'button',\n title: t('variablePicker.copyTitle', { token }),\n onclick: (e: Event) => {\n e.stopPropagation();\n handlers.onCopy(token);\n },\n },\n [t('common.copy')],\n ),\n );\n row.append(\n h(\n 'button',\n {\n class: 'sm-popover__item',\n type: 'button',\n onclick: () => handlers.onPickKey(v),\n },\n [\n h('span', { class: 'sm-popover__label' }, [v.label]),\n h('span', { class: 'sm-popover__key' }, [token]),\n ],\n ),\n actions,\n );\n wrap.append(row);\n }\n return wrap;\n}\n","import { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport { EditorState } from '@codemirror/state';\nimport type { Registry } from '../registry/registry';\nimport { htmlContainsMjmlTags } from '../utils/lockedMjml';\nimport {\n findBlockLocation,\n findSection,\n isMultiColumnLayout,\n setSectionLayout,\n type Store,\n type DocChangedDetail,\n} from '../store/store';\nimport type {\n Block,\n BlockSchemaField,\n EditorUiOptions,\n EmailDoc,\n Section,\n SectionLayout,\n Variable,\n} from '../types';\nimport { getSectionDynamicVariantKey } from '../utils/dynamicVariantSection';\nimport { defaultSocialIconBackground } from '../socialDefaults';\nimport { bindColorPickerInput } from './ColorPickerPopover';\nimport { normalizeAccentHex } from '../utils/accentColor';\nimport { clear, h } from '../utils/dom';\nimport { metaWidthInputString, parseMetaWidthFromUserInput, parseSectionWidthFromUserInput, sectionWidthInputString } from '../utils/contentWidth';\nimport {\n LIST_INDENT_PRESETS_PX,\n normalizeGlobalListIndentStorage,\n resolveGlobalListIndentPx,\n} from '../utils/emailListStyles';\nimport { FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport { resolveAssetPermission, type ImageAssetsHandlers, type ImageFieldContext } from './imageAssets';\nimport { FocusBreadcrumb } from './FocusBreadcrumb';\nimport { openImageGalleryModal } from './ImageGalleryModal';\nimport {\n buildVariablePickerBody,\n buildVariablePickerHead,\n type VariablePickerHandlers,\n} from './VariablePickerPanel';\nimport type { SimpleMailT } from '../i18n';\n\n/** 与社交组 block 中每行元素结构一致(core 不依赖 blocks) */\ntype SocialLinkRow = {\n network: string;\n href: string;\n label?: string;\n iconSrc?: string;\n backgroundColor?: string;\n};\n\n/** 宽度滑块:解析右栏当前字符串 */\nfunction classifyLayoutWidth(raw: string): 'auto' | 'px' | '%' | 'custom' {\n const t = (raw ?? '').trim();\n if (!t || t.toLowerCase() === 'auto') return 'auto';\n if (/^\\d+(\\.\\d+)?%$/.test(t)) return '%';\n if (/^\\d+(\\.\\d+)?px$/i.test(t)) return 'px';\n if (/^\\d+(\\.\\d+)?$/.test(t)) return 'px';\n return 'custom';\n}\n\nfunction layoutWidthNumeric(raw: string, mode: 'px' | '%'): number {\n const t = (raw ?? '').trim();\n if (!t) return mode === '%' ? 100 : 280;\n const m = t.match(/^(\\d+(\\.\\d+)?)/);\n const n = m ? parseFloat(m[1]) : mode === '%' ? 100 : 280;\n if (mode === '%') return Math.min(100, Math.max(1, Math.round(n)));\n return Math.min(1200, Math.max(1, Math.round(n)));\n}\n\nexport interface RightPanelOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n /** 聚焦路径根节点文案(文档级),默认「邮件」 */\n docRootLabel?: string;\n /** 点击路径中的 Section 层级 */\n onFocusSection: (sectionId: string) => void;\n /** 点击路径中的文档级层级(等同 Esc 从 Section 上浮) */\n onFocusDocument: () => void;\n /**\n * 可选。配置后,schema 中 `type: 'image'` 的字段会显示「上传 / 图库」按钮并调用对应回调。\n */\n imageAssets?: ImageAssetsHandlers;\n /** 与 MailEditor.opts.ui 对齐 */\n ui?: EditorUiOptions;\n}\n\ntype RightTab = 'props' | 'code';\n\n/**\n * 右栏:选中 Section/Block 时显示对应配置;未选中显示文档级配置(标题/宽度/全局样式)。\n * Block 选中时多一个\"代码\"Tab,可编辑该 Block 的 MJML 片段(CodeMirror)。\n */\nexport class RightPanel {\n el: HTMLElement;\n private opts: RightPanelOptions;\n private headEl: HTMLElement;\n private contentEl: HTMLElement;\n private focusCrumb: FocusBreadcrumb;\n private currentTab: RightTab = 'props';\n private codeView: EditorView | null = null;\n private variablePickerOpen = false;\n private variablePickerPinned = false;\n private variablePickerHandlers: VariablePickerHandlers | null = null;\n\n private _preferSliderControls(): boolean {\n return this.opts.ui?.preferSliderControls === true;\n }\n\n private _hideMailMeta(): boolean {\n return this.opts.ui?.hideMailMeta === true;\n }\n\n constructor(opts: RightPanelOptions) {\n this.opts = opts;\n this.el = h('aside', { class: 'sm-panel sm-panel--right' });\n this.focusCrumb = new FocusBreadcrumb({\n store: opts.store,\n registry: opts.registry,\n docRootLabel: opts.docRootLabel ?? opts.t('rightPanel.docRoot.mail'),\n t: opts.t,\n onFocusDocument: () => opts.onFocusDocument(),\n onFocusSection: (id) => opts.onFocusSection(id),\n });\n this.headEl = h('div', { class: 'sm-panel__head' }, [this.focusCrumb.el]);\n this.contentEl = h('div', { class: 'sm-panel__body' });\n this.el.append(this.headEl, this.contentEl);\n this._syncHeadVisibility();\n this._render();\n opts.store.subscribe((detail?: DocChangedDetail) => {\n if (this.variablePickerOpen) return;\n if (detail?.source === 'history') {\n this._renderPreservingFieldFocus();\n return;\n }\n if (detail?.source === 'replace') {\n this._render();\n return;\n }\n // update() 每打一字符都会 notify;整栏 clear 会拆掉输入框导致失焦\n if (this._shouldSkipRenderBecauseFocused()) return;\n this._render();\n });\n opts.store.subscribeSelection(() => {\n if (this.variablePickerOpen) return;\n this.currentTab = 'props';\n this._syncHeadVisibility();\n this._render();\n });\n }\n\n /** 在右栏展示变量列表(顶替属性面板,不遮挡画布) */\n openVariablePicker(vars: Variable[], handlers: VariablePickerHandlers) {\n this.variablePickerOpen = true;\n this.variablePickerPinned = false;\n this.variablePickerHandlers = handlers;\n this._renderVariablePicker(vars);\n }\n\n closeVariablePicker() {\n if (!this.variablePickerOpen) return;\n this.variablePickerOpen = false;\n this.variablePickerPinned = false;\n this.variablePickerHandlers = null;\n this.el.classList.remove('sm-panel--variable-picker');\n clear(this.headEl);\n this.headEl.append(this.focusCrumb.el);\n this._syncHeadVisibility();\n this._render();\n }\n\n isVariablePickerOpen(): boolean {\n return this.variablePickerOpen;\n }\n\n isVariablePickerPinned(): boolean {\n return this.variablePickerPinned;\n }\n\n toggleVariablePickerPin(): boolean {\n this.variablePickerPinned = !this.variablePickerPinned;\n return this.variablePickerPinned;\n }\n\n /** 文档级(无选中)时不展示面包屑,避免与「邮件设置」标题重复 */\n private _syncHeadVisibility() {\n if (this.variablePickerOpen) return;\n const show = !!this.opts.store.selection;\n this.headEl.hidden = !show;\n }\n\n private _renderVariablePicker(vars: Variable[]) {\n const handlers = this.variablePickerHandlers;\n if (!handlers) return;\n this._destroyCodeView();\n clear(this.headEl);\n clear(this.contentEl);\n this.el.classList.add('sm-panel--variable-picker');\n this.headEl.hidden = false;\n this.headEl.append(\n buildVariablePickerHead({\n pinned: this.variablePickerPinned,\n t: this.opts.t,\n onClose: () => handlers.onClose(),\n onTogglePin: () => this.toggleVariablePickerPin(),\n }),\n );\n this.contentEl.append(buildVariablePickerBody(vars, handlers, this.opts.t));\n }\n\n /** 焦点在右栏可编辑控件上时不要整栏重渲染(避免输入/CodeMirror 失焦) */\n private _shouldSkipRenderBecauseFocused(): boolean {\n const ae = document.activeElement as HTMLElement | null;\n if (!ae || !this.el.contains(ae)) return false;\n if (ae.closest('.cm-editor')) return true;\n const tag = ae.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;\n return false;\n }\n\n /** undo/redo 后整栏重绘,但尽量回到同一输入框与光标位置 */\n private _renderPreservingFieldFocus() {\n if (this.variablePickerOpen) return;\n const ae = document.activeElement as HTMLElement | null;\n let token: string | null = null;\n let selStart = 0;\n let selEnd = 0;\n if (ae && this.el.contains(ae)) {\n token = ae.getAttribute('data-sm-focus');\n if (\n token &&\n (ae instanceof HTMLInputElement || ae instanceof HTMLTextAreaElement)\n ) {\n selStart = ae.selectionStart ?? 0;\n selEnd = ae.selectionEnd ?? 0;\n }\n }\n this._render();\n if (!token) return;\n const next = this._findFocusEl(token);\n next?.focus();\n if (next instanceof HTMLInputElement || next instanceof HTMLTextAreaElement) {\n const len = next.value.length;\n next.setSelectionRange(Math.min(selStart, len), Math.min(selEnd, len));\n }\n }\n\n private _findFocusEl(token: string): HTMLElement | null {\n for (const el of this.el.querySelectorAll('[data-sm-focus]')) {\n if ((el as HTMLElement).getAttribute('data-sm-focus') === token) return el as HTMLElement;\n }\n return null;\n }\n\n private _render() {\n if (this.variablePickerOpen) return;\n this._destroyCodeView();\n clear(this.contentEl);\n\n const sel = this.opts.store.selection;\n const doc = this.opts.store.doc;\n\n if (!sel) {\n this.contentEl.append(this._renderDocForm(doc));\n return;\n }\n\n if (sel.kind === 'section') {\n const section = findSection(doc, sel.sectionId);\n if (!section) return;\n this.contentEl.append(this._renderSectionForm(section));\n return;\n }\n\n // block\n const loc = findBlockLocation(doc, sel.blockId);\n if (!loc) {\n const tabs = h('div', { class: 'sm-tabs' }, [\n this._tabBtn('props', this.opts.t('rightPanel.tabs.props')),\n this._tabBtn('code', this.opts.t('rightPanel.tabs.code')),\n ]);\n this.contentEl.append(tabs);\n this.contentEl.append(\n h('div', { class: 'sm-empty-form' }, [this.opts.t('rightPanel.block.deleted')]),\n );\n return;\n }\n const def = this.opts.registry.get(loc.block.type);\n\n const tabs = h('div', { class: 'sm-tabs' }, [\n this._tabBtn('props', this.opts.t('rightPanel.tabs.props')),\n this._tabBtn('code', this.opts.t('rightPanel.tabs.code')),\n ]);\n this.contentEl.append(tabs);\n\n if (this.currentTab === 'props') {\n if (loc.block.lockedMjml) {\n this.contentEl.append(\n h('div', { class: 'sm-empty-form' }, [\n this.opts.t('rightPanel.block.locked'),\n h('div', { style: 'margin-top:8px;' }, [\n h(\n 'button',\n {\n class: 'sm-btn',\n type: 'button',\n onclick: () => {\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, loc.block.id);\n if (l) delete l.block.lockedMjml;\n });\n },\n },\n [this.opts.t('rightPanel.block.restoreProps')],\n ),\n ]),\n ]),\n );\n } else if (def) {\n this.contentEl.append(this._renderBlockForm(loc.block, def.schema));\n } else {\n this.contentEl.append(\n h('div', { class: 'sm-empty-form' }, [\n this.opts.t('rightPanel.block.unregistered', { type: loc.block.type }),\n ]),\n );\n }\n } else {\n this.contentEl.append(this._renderBlockCodeView(loc.block));\n }\n }\n\n private _tabBtn(tab: RightTab, label: string) {\n return h(\n 'button',\n {\n class: `sm-tabs__item ${this.currentTab === tab ? 'sm-tabs__item--active' : ''}`,\n type: 'button',\n onclick: () => {\n this.currentTab = tab;\n this._render();\n },\n },\n [label],\n );\n }\n\n /* ------------------------------ 文档级表单 ------------------------------- */\n\n private _renderDocForm(doc: EmailDoc): HTMLElement {\n const hideMeta = this._hideMailMeta();\n const rows: HTMLElement[] = [];\n if (!hideMeta) {\n rows.push(\n h('div', { class: 'sm-panel__title' }, [this.opts.t('rightPanel.doc.title')]),\n this._textField(this.opts.t('rightPanel.doc.subject'), doc.meta.subject, (v) =>\n this.opts.store.update((d) => {\n d.meta.subject = v;\n }),\n '',\n 'doc:meta.subject',\n ),\n this._textField(this.opts.t('rightPanel.doc.preheader'), doc.meta.preheader ?? '', (v) =>\n this.opts.store.update((d) => {\n d.meta.preheader = v;\n }),\n '',\n 'doc:meta.preheader',\n ),\n );\n } else {\n rows.push(h('div', { class: 'sm-panel__title' }, [this.opts.t('rightPanel.doc.layoutTitle')]));\n }\n rows.push(\n this._textField(\n this.opts.t('rightPanel.doc.contentWidth'),\n metaWidthInputString(doc.meta.width),\n (v) =>\n this.opts.store.update((d) => {\n d.meta.width = parseMetaWidthFromUserInput(v);\n }),\n this.opts.t('rightPanel.doc.contentWidthPlaceholder'),\n 'doc:meta.width',\n ),\n h('div', { class: 'sm-panel__title' }, [this.opts.t('rightPanel.doc.globalStyles')]),\n this._colorField(\n this.opts.t('rightPanel.doc.pageBackground'),\n doc.styles.backgroundColor,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.backgroundColor = v;\n }),\n 'doc:styles.backgroundColor',\n ),\n this._colorField(\n this.opts.t('rightPanel.doc.contentBackground'),\n doc.styles.contentBackgroundColor,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.contentBackgroundColor = v;\n }),\n 'doc:styles.contentBackgroundColor',\n ),\n this._textField(\n this.opts.t('rightPanel.doc.fontFamily'),\n doc.styles.fontFamily,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.fontFamily = v;\n }),\n '',\n 'doc:styles.fontFamily',\n ),\n this._docFontSizeField(\n doc.styles.fontSize,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.fontSize = v;\n }),\n 'doc:styles.fontSize',\n ),\n this._docFontWeightField(\n doc.styles.fontWeight ?? '400',\n (v) =>\n this.opts.store.update((d) => {\n d.styles.fontWeight = v;\n }),\n 'doc:styles.fontWeight',\n ),\n this._textField(\n this.opts.t('rightPanel.doc.lineHeight'),\n doc.styles.lineHeight ?? '1.25',\n (v) =>\n this.opts.store.update((d) => {\n d.styles.lineHeight = v;\n }),\n this.opts.t('rightPanel.doc.lineHeightPlaceholder'),\n 'doc:styles.lineHeight',\n ),\n this._colorField(\n this.opts.t('rightPanel.doc.textColor'),\n doc.styles.color,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.color = v;\n }),\n 'doc:styles.color',\n ),\n this._colorField(\n this.opts.t('rightPanel.doc.linkColor'),\n doc.styles.linkColor,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.linkColor = v;\n }),\n 'doc:styles.linkColor',\n ),\n this._listIndentDefaultField(doc),\n );\n return h('form', { class: 'sm-form', onsubmit: (e: Event) => e.preventDefault() }, rows);\n }\n\n /* ------------------------------ Section 表单 ----------------------------- */\n\n private _renderSectionForm(section: Section): HTMLElement {\n const a = section.attrs;\n const dvUiEnabled = this.opts.ui?.enableDynamicVariantKey === true;\n const dvKey = dvUiEnabled ? getSectionDynamicVariantKey(section) : undefined;\n const dynamicVariantKeyField = dvUiEnabled\n ? (() => {\n const field = this._textField(\n this.opts.t('rightPanel.section.dynamicKey'),\n a.dynamicVariantKey ?? '',\n (v) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (!s) return;\n const trimmed = v.trim();\n s.attrs.dynamicVariantKey = trimmed || undefined;\n }),\n this.opts.t('rightPanel.section.dynamicKeyPlaceholder'),\n `section:${section.id}:attrs.dynamicVariantKey`,\n );\n field.append(\n h('div', { class: 'sm-field__help' }, [\n this.opts.t('rightPanel.section.dynamicKeyHelp'),\n ]),\n );\n return field;\n })()\n : null;\n return h('form', { class: 'sm-form', onsubmit: (e: Event) => e.preventDefault() }, [\n h('div', { class: 'sm-panel__title' }, [\n this.opts.t(dvKey ? 'rightPanel.section.dynamicTitle' : 'rightPanel.section.title'),\n ]),\n ...(dynamicVariantKeyField ? [dynamicVariantKeyField] : []),\n ...(isMultiColumnLayout(section.layout)\n ? [\n this._multiColumnLayoutField(\n section.layout,\n (layout) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) setSectionLayout(s, layout);\n }),\n `section:${section.id}:layout`,\n ),\n ]\n : []),\n this._colorField(\n this.opts.t('rightPanel.section.backgroundColor'),\n a.backgroundColor ?? '',\n (v) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.backgroundColor = v || undefined;\n }),\n `section:${section.id}:attrs.bg`,\n this.opts.t('rightPanel.section.transparentPlaceholder'),\n ),\n this._layoutWidthField(\n this.opts.t('rightPanel.section.width'),\n sectionWidthInputString(a.width),\n (v) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.width = parseSectionWidthFromUserInput(v);\n }),\n `section:${section.id}:attrs.width`,\n this.opts.t('rightPanel.section.widthHelp'),\n ),\n this._spacingField(\n this.opts.t('rightPanel.section.padding'),\n [a.paddingTop, a.paddingRight, a.paddingBottom, a.paddingLeft],\n (vals) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (!s) return;\n [s.attrs.paddingTop, s.attrs.paddingRight, s.attrs.paddingBottom, s.attrs.paddingLeft] =\n vals;\n }),\n `section:${section.id}:attrs.pad`,\n [0, 0, 0, 0],\n ),\n section.layout !== '1'\n ? this._numberField(\n this.opts.t('rightPanel.section.columnGap'),\n a.columnGap ?? 0,\n 0,\n 64,\n (v) => {\n const g = Math.max(0, Math.min(64, Math.round(v)));\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.columnGap = g > 0 ? g : undefined;\n });\n },\n 1,\n `section:${section.id}:attrs.columnGap`,\n )\n : null,\n section.layout !== '1'\n ? this._switchField(\n this.opts.t('rightPanel.section.preserveMobile'),\n !!a.preserveColumnsOnMobile,\n (checked) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.preserveColumnsOnMobile = checked || undefined;\n }),\n this.opts.t('rightPanel.section.preserveMobileHelp'),\n `section:${section.id}:attrs.preserveMobile`,\n )\n : null,\n ]);\n }\n\n /* ------------------------------- Block 表单 ----------------------------- */\n\n private _renderBlockForm(block: Block, schema: BlockSchemaField[]): HTMLElement {\n const form = h('form', { class: 'sm-form', onsubmit: (e: Event) => e.preventDefault() });\n for (const field of schema) {\n form.append(this._field(field, block));\n }\n return form;\n }\n\n private _updateBlock(blockId: string, key: string, value: unknown) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, blockId);\n if (!loc) return;\n (loc.block.props as any)[key] = value;\n });\n }\n\n private _field(field: BlockSchemaField, block: Block): HTMLElement {\n const blockId = block.id;\n const fp = `block:${blockId}:${field.key}`;\n const def = this.opts.registry.get(block.type);\n const defaults = def?.defaultProps as Record<string, unknown> | undefined;\n const raw = (block.props as Record<string, unknown>)[field.key];\n const value: unknown =\n raw !== undefined && raw !== null ? raw : defaults?.[field.key];\n const onChange = (v: any) => this._updateBlock(blockId, field.key, v);\n\n switch (field.type) {\n case 'textarea':\n if (block.type === 'html' && field.key === 'html') {\n return this._textareaField(\n field.label,\n String(value ?? ''),\n onChange,\n field.help,\n fp,\n (v) =>\n htmlContainsMjmlTags(v)\n ? this.opts.t('rightPanel.block.mjmlWarning')\n : null,\n );\n }\n return this._textareaField(field.label, String(value ?? ''), onChange, field.help, fp);\n case 'number':\n return this._numberField(\n field.label,\n Number(value ?? 0),\n field.min ?? 0,\n field.max ?? 9999,\n onChange,\n field.step ?? 1,\n fp,\n );\n case 'color': {\n const rawColor = (block.props as Record<string, unknown>)[field.key];\n const stored =\n rawColor !== undefined && rawColor !== null ? String(rawColor).trim() : '';\n return this._colorField(\n field.label,\n stored,\n (v) => onChange(v.trim()),\n fp,\n field.placeholder ?? '',\n );\n }\n case 'select': {\n const isFw = field.key === 'fontWeight' || field.key === 'labelFontWeight';\n const opts = field.options?.length\n ? field.options\n : isFw\n ? FONT_WEIGHT_STEP_OPTIONS\n : [];\n if (isFw && field.inheritGlobal) {\n const stored =\n raw !== undefined && raw !== null ? String(raw).trim() : '';\n return this._fontWeightInheritField(\n field.label,\n stored,\n normalizeFontWeightStep(this.opts.store.doc.styles.fontWeight),\n (v) => onChange(v),\n fp,\n opts,\n field.help,\n );\n }\n const displayVal = isFw\n ? normalizeFontWeightStep(String(value ?? ''))\n : String(value ?? '');\n if (isFw || field.selectVariant === 'segmented') {\n const el = this._segmentedSelectField(field.label, displayVal, opts, onChange, fp);\n if (field.help) el.append(h('div', { class: 'sm-field__help' }, [field.help]));\n return el;\n }\n return this._selectField(field.label, displayVal, opts, onChange, fp);\n }\n case 'switch':\n return this._switchField(field.label, !!value, onChange, field.help, fp);\n case 'image':\n return this._imageField(\n field.label,\n String(value ?? ''),\n onChange,\n field.placeholder ?? 'https://',\n fp,\n { blockId, propKey: field.key },\n );\n case 'url':\n case 'text': {\n if (field.key === 'width' && this._preferSliderControls()) {\n return this._layoutWidthField(\n field.label,\n String(value ?? ''),\n (v) => onChange(v),\n fp,\n field.help,\n );\n }\n if (field.key === 'fontSize' && field.inheritGlobal) {\n const rawFs =\n raw !== undefined && raw !== null ? String(raw).trim() : '';\n return this._fontSizeSliderField(\n field.label,\n rawFs,\n (v) => onChange(v.trim()),\n fp,\n field.help,\n this.opts.store.doc.styles.fontSize,\n );\n }\n const row = this._textField(\n field.label,\n String(value ?? ''),\n onChange,\n field.placeholder ?? '',\n fp,\n );\n if (field.help) row.append(h('div', { class: 'sm-field__help' }, [field.help]));\n return row;\n }\n case 'spacing': {\n /** 与各 block 约定:四边分别存 paddingTop / paddingRight / paddingBottom / paddingLeft */\n const p = block.props as Record<string, unknown>;\n const quad = [\n Number(p.paddingTop ?? 0),\n Number(p.paddingRight ?? 0),\n Number(p.paddingBottom ?? 0),\n Number(p.paddingLeft ?? 0),\n ];\n const def = this.opts.registry.get(block.type);\n const dp = def?.defaultProps as Record<string, unknown> | undefined;\n const resetQuad: [number, number, number, number] = [\n Number(dp?.paddingTop ?? 0),\n Number(dp?.paddingRight ?? 0),\n Number(dp?.paddingBottom ?? 0),\n Number(dp?.paddingLeft ?? 0),\n ];\n return this._spacingField(field.label, quad, (vals) => {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, blockId);\n if (!loc) return;\n const pr = loc.block.props as Record<string, number>;\n [pr.paddingTop, pr.paddingRight, pr.paddingBottom, pr.paddingLeft] = vals;\n });\n }, `${fp}:pad`, resetQuad);\n }\n case 'socialLinkList': {\n const rows = Array.isArray(value)\n ? (value as SocialLinkRow[])\n : Array.isArray(defaults?.[field.key])\n ? (defaults[field.key] as SocialLinkRow[])\n : [];\n return this._socialLinkListField(\n field.label,\n rows,\n field.options ?? [],\n blockId,\n field.key,\n field.help,\n fp,\n );\n }\n default:\n return h('div');\n }\n }\n\n /**\n * 社交组:每行含平台、链接、可选标签/图标 URL/图标背景色。\n * 注意:右栏在输入框聚焦时会跳过整栏 _render(),故更新 elements 必须在 store.update 内\n * 读取当前 props 再合并,禁止依赖闭包里的 items 快照(否则改一行会覆盖其它行已编辑未重绘的数据)。\n */\n private _socialLinkListField(\n label: string,\n items: SocialLinkRow[],\n networkOptions: { label: string; value: string }[],\n blockId: string,\n elementsKey: string,\n help: string | undefined,\n focusPrefix: string,\n ): HTMLElement {\n const firstVal = networkOptions[0]?.value ?? 'weibo';\n const wrap = h('div', { class: 'sm-field' });\n wrap.append(h('label', { class: 'sm-field__label' }, [label]));\n\n const listEl = h('div', { class: 'sm-social-link-list' });\n\n const patchElements = (mutate: (rows: SocialLinkRow[]) => SocialLinkRow[]) => {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, blockId);\n if (!loc) return;\n const props = loc.block.props as Record<string, unknown>;\n const raw = props[elementsKey];\n const cur: SocialLinkRow[] = Array.isArray(raw)\n ? (raw as SocialLinkRow[]).map((x) => ({ ...x }))\n : [];\n props[elementsKey] = mutate(cur);\n });\n };\n\n const syncItem = (index: number, patch: Partial<SocialLinkRow>) => {\n patchElements((rows) =>\n rows.map((x, i) => (i === index ? { ...x, ...patch } : x)),\n );\n };\n\n const removeAt = (index: number) => {\n patchElements((rows) => rows.filter((_, i) => i !== index));\n };\n\n for (let i = 0; i < items.length; i++) {\n const rowData = items[i];\n const rowWrap = h('div', { class: 'sm-social-link-list__row' });\n const mainRow = h('div', { class: 'sm-social-link-list__row-main' });\n const sel = h('select', {\n class: 'sm-select sm-social-link-list__network',\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:net` } : {}),\n onchange: (e: Event) =>\n syncItem(i, { network: (e.target as HTMLSelectElement).value }),\n });\n for (const o of networkOptions) {\n const opt = document.createElement('option');\n opt.value = o.value;\n opt.textContent = o.label;\n if (o.value === rowData.network) opt.selected = true;\n sel.append(opt);\n }\n if (!networkOptions.some((o) => o.value === rowData.network) && rowData.network) {\n const opt = document.createElement('option');\n opt.value = rowData.network;\n opt.textContent = rowData.network;\n opt.selected = true;\n sel.insertBefore(opt, sel.firstChild);\n }\n const inp = h('input', {\n class: 'sm-input sm-social-link-list__href',\n type: 'url',\n placeholder: 'https://',\n value: rowData.href,\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:href` } : {}),\n oninput: (e: Event) => syncItem(i, { href: (e.target as HTMLInputElement).value }),\n });\n const rm = h(\n 'button',\n {\n class: 'sm-social-link-list__remove',\n type: 'button',\n title: this.opts.t('common.delete'),\n onclick: () => removeAt(i),\n },\n ['×'],\n );\n mainRow.append(sel, inp, rm);\n rowWrap.append(mainRow);\n\n const extras = h('div', { class: 'sm-social-link-list__row-extras' });\n const bgResolved = defaultSocialIconBackground(rowData.network);\n const bgStored = rowData.backgroundColor?.trim();\n const bgDisplay =\n bgStored && bgStored.startsWith('#') ? bgStored : bgResolved;\n extras.append(\n h('input', {\n class: 'sm-input sm-social-link-list__label',\n type: 'text',\n placeholder: this.opts.t('rightPanel.social.labelPlaceholder'),\n value: rowData.label ?? '',\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:label` } : {}),\n oninput: (e: Event) => syncItem(i, { label: (e.target as HTMLInputElement).value }),\n }),\n h('input', {\n class: 'sm-input sm-social-link-list__iconsrc',\n type: 'url',\n placeholder: this.opts.t('rightPanel.social.iconUrlPlaceholder'),\n value: rowData.iconSrc ?? '',\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:icon` } : {}),\n oninput: (e: Event) => syncItem(i, { iconSrc: (e.target as HTMLInputElement).value }),\n }),\n );\n const bgPick = h('input', {\n class: 'sm-social-link-list__color sm-social-link-list__color--compact',\n type: 'color',\n value: bgDisplay.length >= 4 ? bgDisplay : bgResolved,\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:bg` } : {}),\n }) as HTMLInputElement;\n bindColorPickerInput(bgPick, {\n liveCommit: true,\n t: this.opts.t,\n onCommit: (hex) => syncItem(i, { backgroundColor: hex }),\n });\n extras.append(bgPick);\n rowWrap.append(extras);\n\n listEl.append(rowWrap);\n }\n\n const addBtn = h(\n 'button',\n {\n class: 'sm-btn sm-social-link-list__add',\n type: 'button',\n onclick: () =>\n patchElements((rows) => [\n ...rows,\n {\n network: firstVal,\n href: 'https://',\n label: '',\n iconSrc: '',\n },\n ]),\n },\n [this.opts.t('rightPanel.social.add')],\n );\n\n wrap.append(listEl, addBtn);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n /* --------------------------------- 控件 --------------------------------- */\n\n private _textField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n placeholder = '',\n focusToken?: string,\n ) {\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n h('input', {\n class: 'sm-input',\n type: 'text',\n value,\n placeholder,\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n oninput: (e: Event) => onChange((e.target as HTMLInputElement).value),\n }),\n ]);\n }\n\n /** `type: 'image'`:URL 输入 + 可选上传、图库(由 `imageAssets` 注入) */\n private _imageField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n placeholder: string,\n focusToken: string | undefined,\n ids: Pick<ImageFieldContext, 'blockId' | 'propKey'>,\n ): HTMLElement {\n const assets = this.opts.imageAssets;\n const showUploadBtn = !!assets?.uploadImage && assets.showUpload !== false;\n const showGalleryBtn =\n assets?.showGallery === true &&\n (!!assets.imageGallery || !!assets.pickImageFromGallery);\n const hasAssetCallbacks = !!(\n assets?.uploadImage ||\n assets?.pickImageFromGallery ||\n assets?.imageGallery\n );\n const hasAnyPickerBtn = showUploadBtn || showGalleryBtn;\n\n const row = h('div', { class: 'sm-image-field__row' });\n const urlInp = h('input', {\n class: 'sm-input sm-image-field__url',\n type: 'url',\n value,\n placeholder,\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n oninput: (e: Event) => onChange((e.target as HTMLInputElement).value),\n });\n const getCtx = (): ImageFieldContext => ({\n blockId: ids.blockId,\n propKey: ids.propKey,\n currentUrl: urlInp.value,\n });\n row.append(urlInp);\n\n const applyUrl = (url: string) => {\n const t = url.trim();\n if (!t) return;\n onChange(t);\n urlInp.value = t;\n };\n\n const runAsync = (p: Promise<string | null | void>, labelErr: string) => {\n p.catch((e) => {\n console.error(`[simple-mail] ${labelErr}`, e);\n });\n };\n\n if (showUploadBtn) {\n const fileInp = h('input', {\n type: 'file',\n accept: 'image/*',\n class: 'sm-image-field__file',\n onchange: (e: Event) => {\n const el = e.target as HTMLInputElement;\n const f = el.files?.[0];\n el.value = '';\n if (!f) return;\n runAsync(\n assets.uploadImage!(f, getCtx()).then((url) => applyUrl(String(url))),\n 'uploadImage',\n );\n },\n });\n const uploadPerm = resolveAssetPermission(\n assets?.permissions,\n 'upload',\n this.opts.t('common.noPermissionUpload'),\n );\n if (!uploadPerm.allowed && uploadPerm.mode === 'hide') {\n // 无权限且配置为隐藏:不渲染上传按钮(fileInp 同样不渲染)\n } else {\n row.append(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-image-field__btn',\n type: 'button',\n title: uploadPerm.allowed\n ? this.opts.t('rightPanel.image.uploadTitle')\n : uploadPerm.tip,\n disabled: !uploadPerm.allowed,\n ...(uploadPerm.allowed\n ? { onclick: () => fileInp.click() }\n : {}),\n },\n [this.opts.t('rightPanel.image.upload')],\n ),\n );\n row.append(fileInp);\n }\n }\n\n if (showGalleryBtn) {\n row.append(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-image-field__btn',\n type: 'button',\n title: this.opts.t('rightPanel.image.galleryTitle'),\n onclick: () => {\n if (assets.imageGallery) {\n openImageGalleryModal({\n adapter: assets.imageGallery,\n permissions: assets?.permissions,\n onPick: (url) => applyUrl(url),\n t: this.opts.t,\n parent: this.el.closest('.sm-root') as HTMLElement | undefined,\n });\n return;\n }\n if (assets.pickImageFromGallery) {\n runAsync(\n assets.pickImageFromGallery(getCtx()).then((url) => {\n if (url != null && String(url).trim()) applyUrl(String(url));\n }),\n 'pickImageFromGallery',\n );\n }\n },\n },\n [this.opts.t('rightPanel.image.gallery')],\n ),\n );\n }\n\n let helpBody: string;\n if (hasAnyPickerBtn) {\n const bits: string[] = [this.opts.t('rightPanel.image.helpManual')];\n if (showUploadBtn) bits.push(this.opts.t('rightPanel.image.helpUpload'));\n if (showGalleryBtn) bits.push(this.opts.t('rightPanel.image.helpGallery'));\n helpBody = `${bits.join(this.opts.t('rightPanel.image.helpSeparator'))}${this.opts.t(\n 'rightPanel.image.helpEnd',\n )}`;\n } else if (hasAssetCallbacks) {\n helpBody = this.opts.t('rightPanel.image.helpAssetsConfigured');\n } else {\n helpBody = this.opts.t('rightPanel.image.helpNoAssets');\n }\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n row,\n h('div', { class: 'sm-field__help' }, [helpBody]),\n ]);\n }\n private _textareaField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n help?: string,\n focusToken?: string,\n warn?: (v: string) => string | null,\n ) {\n const warnEl = h('div', { class: 'sm-field__warn', style: 'display:none' });\n const ta = h('textarea', {\n class: 'sm-textarea',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n oninput: (e: Event) => {\n const v = (e.target as HTMLTextAreaElement).value;\n onChange(v);\n if (warn) {\n const msg = warn(v);\n warnEl.textContent = msg ?? '';\n warnEl.style.display = msg ? '' : 'none';\n }\n },\n });\n ta.value = value;\n if (warn) {\n const msg = warn(value);\n if (msg) {\n warnEl.textContent = msg;\n warnEl.style.display = '';\n }\n }\n return h(\n 'div',\n { class: 'sm-field' },\n [\n h('label', { class: 'sm-field__label' }, [label]),\n ta,\n warnEl,\n help ? h('div', { class: 'sm-field__help' }, [help]) : null,\n ],\n );\n }\n private _numberField(\n label: string,\n value: number,\n min: number,\n max: number,\n onChange: (v: number) => void,\n step = 1,\n focusToken?: string,\n ) {\n const snap = (n: number) => {\n const c = Math.min(max, Math.max(min, n));\n if (!step || step <= 0) return c;\n const k = Math.round((c - min) / step);\n return Number((min + k * step).toPrecision(12));\n };\n\n if (!this._preferSliderControls()) {\n const inp = h('input', {\n class: 'sm-input',\n type: 'number',\n value: String(value),\n min,\n max,\n step,\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const commitPlain = () => {\n const t = inp.value.trim();\n const fb = snap(value);\n if (t === '') {\n inp.value = String(fb);\n onChange(fb);\n return;\n }\n const v = Number(t);\n const s = snap(Number.isNaN(v) ? fb : v);\n inp.value = String(s);\n onChange(s);\n };\n\n /** min>0 时中途输入会被 snap 打断(如想输入 16 会先变成 10),仅失焦/Enter 提交 */\n if (min > 0) {\n inp.addEventListener('blur', commitPlain);\n inp.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') inp.blur();\n });\n } else {\n inp.addEventListener('input', () => {\n const t = inp.value.trim();\n if (t === '') return;\n const v = Number(t);\n if (Number.isNaN(v)) return;\n onChange(snap(v));\n });\n inp.addEventListener('blur', commitPlain);\n inp.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') commitPlain();\n });\n }\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n inp,\n ]);\n }\n\n const v0 = snap(value);\n const range = h('input', {\n type: 'range',\n min,\n max,\n step,\n value: String(v0),\n }) as HTMLInputElement;\n\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min,\n max,\n step,\n value: String(v0),\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const syncFromSlider = (n: number) => {\n const s = snap(n);\n range.value = String(s);\n num.value = String(s);\n onChange(s);\n };\n\n range.addEventListener('input', () => {\n syncFromSlider(Number(range.value));\n });\n\n num.addEventListener('input', () => {\n const t = num.value.trim();\n if (t === '') return;\n const raw = Number(t);\n if (Number.isNaN(raw)) return;\n range.value = String(snap(raw));\n });\n\n num.addEventListener('blur', () => {\n const t = num.value.trim();\n const fb = snap(Number(range.value));\n if (t === '') {\n syncFromSlider(fb);\n return;\n }\n const raw = Number(t);\n if (Number.isNaN(raw)) {\n syncFromSlider(fb);\n return;\n }\n syncFromSlider(raw);\n });\n\n num.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n h('div', { class: 'sm-field__slider-row' }, [range, num]),\n ]);\n }\n private _colorField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n focusPrefix?: string,\n placeholder = '#ffffff',\n ) {\n const pickToken = focusPrefix ? `${focusPrefix}:pick` : undefined;\n const textToken = focusPrefix ? `${focusPrefix}:text` : undefined;\n const pick = h('input', {\n type: 'color',\n ...(pickToken ? { 'data-sm-focus': pickToken } : {}),\n }) as HTMLInputElement;\n const text = h('input', {\n class: 'sm-input',\n type: 'text',\n placeholder,\n ...(textToken ? { 'data-sm-focus': textToken } : {}),\n }) as HTMLInputElement;\n\n let lastValid = value.trim();\n\n const applyPickInherit = () => {\n pick.value = '#808080';\n pick.classList.add('sm-color-row__pick--inherit');\n pick.title = placeholder || this.opts.t('rightPanel.color.unset');\n };\n\n const applyStored = (stored: string) => {\n const trimmed = stored.trim();\n text.value = trimmed;\n const hex = normalizeAccentHex(trimmed);\n if (hex) {\n pick.value = hex;\n pick.classList.remove('sm-color-row__pick--inherit');\n pick.title = '';\n } else {\n applyPickInherit();\n }\n };\n\n applyStored(value);\n\n const previewPick = (hex: string) => {\n text.value = hex;\n pick.value = hex;\n pick.classList.remove('sm-color-row__pick--inherit');\n pick.title = '';\n lastValid = hex;\n };\n\n const commitPick = (hex: string) => {\n previewPick(hex);\n onChange(hex);\n };\n\n bindColorPickerInput(pick, {\n getValue: () => text.value.trim() || pick.value,\n placeholder,\n allowClear: true,\n t: this.opts.t,\n onPreview: previewPick,\n onCommit: commitPick,\n onClear: () => {\n applyStored('');\n lastValid = '';\n onChange('');\n },\n });\n\n text.addEventListener('input', () => {\n const raw = text.value;\n const hex = normalizeAccentHex(raw);\n if (hex) {\n pick.value = hex;\n pick.classList.remove('sm-color-row__pick--inherit');\n pick.title = '';\n lastValid = hex;\n } else if (!raw.trim()) {\n applyPickInherit();\n lastValid = '';\n }\n onChange(raw);\n });\n\n text.addEventListener('blur', () => {\n const raw = text.value.trim();\n if (!raw) {\n applyStored('');\n lastValid = '';\n onChange('');\n return;\n }\n const hex = normalizeAccentHex(raw);\n if (hex) {\n applyStored(hex);\n lastValid = hex;\n if (hex !== raw) onChange(hex);\n return;\n }\n applyStored(lastValid);\n onChange(lastValid);\n });\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n h('div', { class: 'sm-color-row' }, [pick, text]),\n ]);\n }\n private _selectField(\n label: string,\n value: string,\n options: { label: string; value: string }[],\n onChange: (v: string) => void,\n focusToken?: string,\n ) {\n const sel = h('select', {\n class: 'sm-select',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n onchange: (e: Event) => onChange((e.target as HTMLSelectElement).value),\n });\n for (const o of options) {\n const opt = document.createElement('option');\n opt.value = o.value;\n opt.textContent = o.label;\n if (o.value === value) opt.selected = true;\n sel.append(opt);\n }\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n sel,\n ]);\n }\n\n /** 邮件设置:列表默认缩进(平铺);未配置时初始为 24px */\n private _listIndentDefaultField(doc: EmailDoc): HTMLElement {\n const current = String(resolveGlobalListIndentPx(doc.styles));\n const options = LIST_INDENT_PRESETS_PX.map((px) => ({\n label: String(px),\n value: String(px),\n }));\n const help = h('div', { class: 'sm-field__help' }, [\n this.opts.t('rightPanel.doc.listIndentHelp'),\n ]);\n const field = this._segmentedSelectField(\n this.opts.t('rightPanel.doc.listIndent'),\n current,\n options,\n (v) =>\n this.opts.store.update((d) => {\n const stored = normalizeGlobalListIndentStorage(Number(v));\n if (stored === undefined) delete d.styles.listIndentDefaultPx;\n else d.styles.listIndentDefaultPx = stored;\n }),\n 'doc:styles.listIndentDefaultPx',\n true,\n );\n field.append(help);\n return field;\n }\n\n /** select 平铺:与顶栏 sm-segmented 视觉一致,占满右栏宽度 */\n private _segmentedSelectField(\n label: string,\n value: string,\n options: { label: string; value: string }[],\n onChange: (v: string) => void,\n focusToken?: string,\n wrap = false,\n ) {\n const group = h('div', {\n class: `sm-segmented sm-segmented--fill${wrap ? ' sm-segmented--wrap' : ''}`,\n role: 'group',\n 'aria-label': label,\n });\n for (const o of options) {\n const active = o.value === value;\n group.append(\n h(\n 'button',\n {\n type: 'button',\n class: `sm-segmented__item${active ? ' sm-segmented__item--active' : ''}`,\n 'aria-pressed': active ? 'true' : 'false',\n title: o.label,\n ...(focusToken ? { 'data-sm-focus': `${focusToken}:${o.value}` } : {}),\n onclick: () => onChange(o.value),\n },\n [o.label],\n ),\n );\n }\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n group,\n ]);\n }\n private _switchField(\n label: string,\n value: boolean,\n onChange: (v: boolean) => void,\n help?: string,\n focusToken?: string,\n ): HTMLElement {\n const row = h('label', {\n class: 'sm-field',\n style: 'flex-direction:row;align-items:center;gap:8px;',\n }, [\n h('input', {\n type: 'checkbox',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n onchange: (e: Event) => onChange((e.target as HTMLInputElement).checked),\n ...(value ? { checked: true } : {}),\n } as any),\n h('span', { class: 'sm-field__label' }, [label]),\n ]);\n if (!help) return row;\n return h('div', { class: 'sm-field', style: 'flex-direction:column;align-items:flex-start;gap:6px;' }, [\n row,\n h('div', { class: 'sm-field__help' }, [help]),\n ]);\n }\n private _spacingField(\n label: string,\n [t, r, b, l]: (number | undefined)[],\n onChange: (vals: number[]) => void,\n focusPrefix?: string,\n resetQuad?: [number, number, number, number],\n ) {\n const titles = [\n this.opts.t('rightPanel.spacing.top'),\n this.opts.t('rightPanel.spacing.right'),\n this.opts.t('rightPanel.spacing.bottom'),\n this.opts.t('rightPanel.spacing.left'),\n ];\n const clampPad = (n: number) => Math.max(0, Math.min(200, Math.round(n)));\n\n /** 右栏聚焦时会跳过整栏重绘,闭包里的 t/r/b/l 会过时;用同一数组累积四边,避免改一边再改另一边时覆盖。 */\n const current: number[] = [\n clampPad(Number(t ?? 0)),\n clampPad(Number(r ?? 0)),\n clampPad(Number(b ?? 0)),\n clampPad(Number(l ?? 0)),\n ];\n const emit = () => onChange([...current]);\n\n const makePlain = (v: number | undefined, idx: number) => {\n const inp = h('input', {\n class: 'sm-input',\n type: 'number',\n min: 0,\n max: 200,\n value: String(v ?? 0),\n title: titles[idx],\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:${idx}` } : {}),\n }) as HTMLInputElement;\n inp.addEventListener('input', () => {\n const t = inp.value.trim();\n if (t === '') return;\n const raw = Number(t);\n if (Number.isNaN(raw)) return;\n current[idx] = clampPad(raw);\n emit();\n });\n inp.addEventListener('blur', () => {\n const t = inp.value.trim();\n if (t === '') {\n inp.value = String(current[idx]);\n return;\n }\n const raw = Number(t);\n const c = clampPad(Number.isNaN(raw) ? current[idx] : raw);\n inp.value = String(c);\n current[idx] = c;\n emit();\n });\n inp.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') inp.blur();\n });\n return inp;\n };\n\n const makeSliderRow = (v: number | undefined, idx: number) => {\n const cur = clampPad(v ?? 0);\n const range = h('input', {\n type: 'range',\n min: 0,\n max: 200,\n step: 1,\n value: String(cur),\n title: titles[idx],\n }) as HTMLInputElement;\n\n range.addEventListener('input', () => {\n const c = clampPad(Number(range.value));\n current[idx] = c;\n num.value = String(c);\n emit();\n });\n\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min: 0,\n max: 200,\n value: String(cur),\n title: titles[idx],\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:${idx}` } : {}),\n }) as HTMLInputElement;\n\n num.addEventListener('input', () => {\n const t = num.value.trim();\n if (t === '') return;\n const rawN = Number(t);\n if (Number.isNaN(rawN)) return;\n const c = clampPad(rawN);\n range.value = String(c);\n current[idx] = c;\n emit();\n });\n\n num.addEventListener('blur', () => {\n const t = num.value.trim();\n if (t === '') {\n num.value = String(current[idx]);\n range.value = String(current[idx]);\n return;\n }\n const rawN = Number(t);\n const c = clampPad(Number.isNaN(rawN) ? current[idx] : rawN);\n num.value = String(c);\n range.value = String(c);\n current[idx] = c;\n emit();\n });\n\n num.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n return h('div', { class: 'sm-spacing-row' }, [\n h('span', { class: 'sm-spacing-row__axis' }, [titles[idx]]),\n range,\n num,\n ]);\n };\n\n return h('div', { class: 'sm-field' }, [\n h('div', { class: 'sm-spacing-field__label-row' }, [\n h('label', { class: 'sm-field__label' }, [`${label}${this.opts.t('rightPanel.spacing.suffix')}`]),\n resetQuad\n ? h(\n 'button',\n {\n type: 'button',\n class: 'sm-btn sm-btn--ghost sm-spacing-field__reset',\n onclick: () => {\n const next = resetQuad.map((n) => clampPad(Number(n)));\n for (let i = 0; i < 4; i++) current[i] = next[i];\n onChange([...current]);\n },\n },\n [this.opts.t('rightPanel.spacing.reset')],\n )\n : null,\n ]),\n this._preferSliderControls()\n ? h(\n 'div',\n { class: 'sm-spacing-rows' },\n [0, 1, 2, 3].map((idx) => makeSliderRow([t, r, b, l][idx], idx)),\n )\n : h(\n 'div',\n { class: 'sm-spacing-grid' },\n [0, 1, 2, 3].map((idx) => makePlain([t, r, b, l][idx], idx)),\n ),\n ]);\n }\n\n /** 「继承全局」开关行:开=跟随邮件全局,关=块级固定值 */\n private _globalInheritSwitch(\n inheritOn: boolean,\n globalDisplay: string,\n onToggle: (inherit: boolean) => void,\n focusToken?: string,\n ): { el: HTMLElement; setInherit: (on: boolean, display?: string) => void } {\n const input = h('input', {\n type: 'checkbox',\n class: 'sm-inherit-switch__input',\n role: 'switch',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n ...(inheritOn ? { checked: true } : {}),\n }) as HTMLInputElement;\n const valueEl = h('span', {\n class: 'sm-inherit-switch__value',\n hidden: !inheritOn,\n }, [globalDisplay]);\n const el = h('div', { class: 'sm-inherit-switch' }, [\n h('label', { class: 'sm-inherit-switch__label' }, [\n input,\n h('span', { class: 'sm-inherit-switch__text' }, [this.opts.t('rightPanel.inheritGlobal')]),\n ]),\n valueEl,\n ]);\n input.addEventListener('change', () => onToggle(input.checked));\n const setInherit = (on: boolean, display?: string) => {\n input.checked = on;\n if (display !== undefined) valueEl.textContent = display;\n valueEl.hidden = !on;\n };\n return { el, setInherit };\n }\n\n private _fontWeightInheritField(\n label: string,\n stored: string,\n globalWeight: string,\n onChange: (v: string) => void,\n focusToken: string,\n options: { label: string; value: string }[],\n help?: string,\n ): HTMLElement {\n let inheriting = !stored;\n const group = h('div', {\n class: 'sm-segmented sm-segmented--fill',\n role: 'group',\n 'aria-label': label,\n });\n\n const syncGroup = () => {\n group.classList.toggle('sm-segmented--disabled', inheriting);\n const display = inheriting ? '' : normalizeFontWeightStep(stored || globalWeight);\n clear(group);\n for (const o of options) {\n const active = !inheriting && o.value === display;\n group.append(\n h(\n 'button',\n {\n type: 'button',\n class: `sm-segmented__item${active ? ' sm-segmented__item--active' : ''}`,\n 'aria-pressed': active ? 'true' : 'false',\n title: o.label,\n ...(focusToken ? { 'data-sm-focus': `${focusToken}:${o.value}` } : {}),\n onclick: () => {\n inheriting = false;\n stored = o.value;\n inheritSwitch.setInherit(false);\n syncGroup();\n onChange(o.value);\n },\n },\n [o.label],\n ),\n );\n }\n };\n\n const inheritSwitch = this._globalInheritSwitch(\n inheriting,\n globalWeight,\n (on) => {\n if (on) {\n inheriting = true;\n stored = '';\n inheritSwitch.setInherit(true, globalWeight);\n syncGroup();\n onChange('');\n return;\n }\n inheriting = false;\n stored = globalWeight;\n inheritSwitch.setInherit(false);\n syncGroup();\n onChange(globalWeight);\n },\n `${focusToken}:inherit`,\n );\n\n syncGroup();\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n inheritSwitch.el,\n group,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _fontSizeInheritTextField(\n label: string,\n stored: string,\n onChange: (v: string) => void,\n focusToken: string,\n globalFontSize: string,\n help?: string,\n ): HTMLElement {\n const globalPx = this._snapFontSizeToPx(globalFontSize);\n let inheriting = !stored.trim();\n const input = h('input', {\n class: 'sm-input',\n type: 'text',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const syncInput = () => {\n input.disabled = inheriting;\n input.value = inheriting ? '' : stored;\n input.placeholder = inheriting ? '' : this.opts.t('rightPanel.fontSize.placeholder');\n input.classList.toggle('sm-input--inherit-disabled', inheriting);\n };\n\n const inheritSwitch = this._globalInheritSwitch(\n inheriting,\n `${globalPx}px`,\n (on) => {\n if (on) {\n inheriting = true;\n stored = '';\n inheritSwitch.setInherit(true, `${globalPx}px`);\n syncInput();\n onChange('');\n return;\n }\n inheriting = false;\n stored = `${globalPx}px`;\n inheritSwitch.setInherit(false);\n syncInput();\n onChange(stored);\n },\n `${focusToken}:inherit`,\n );\n\n syncInput();\n\n input.addEventListener('input', () => {\n if (inheriting) return;\n stored = input.value;\n onChange(stored);\n });\n\n input.addEventListener('blur', () => {\n if (inheriting) return;\n const t = input.value.trim();\n if (!t) {\n stored = `${globalPx}px`;\n input.value = stored;\n onChange(stored);\n }\n });\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n inheritSwitch.el,\n input,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _snapFontSizeToPx(value: string): number {\n const t = (value ?? '').trim();\n const m = t.match(/^(\\d+(\\.\\d+)?)/);\n if (m) return Math.min(48, Math.max(10, Math.round(parseFloat(m[1]))));\n return 16;\n }\n\n private _fontSizeSliderField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n focusToken: string,\n help?: string,\n globalFontSize?: string,\n ) {\n const inheritGlobal = globalFontSize !== undefined;\n if (!this._preferSliderControls()) {\n if (inheritGlobal) {\n return this._fontSizeInheritTextField(\n label,\n value,\n onChange,\n focusToken,\n globalFontSize,\n help,\n );\n }\n return this._textField(label, value ?? '', onChange, '', focusToken);\n }\n\n const min = 10;\n const max = 48;\n const step = 1;\n const snap = (n: number) => Math.min(max, Math.max(min, Math.round(n)));\n const globalPx = snap(this._snapFontSizeToPx(globalFontSize ?? value ?? '16px'));\n let stored = value.trim();\n let inheriting = inheritGlobal && !stored;\n\n const sliderRow = h('div', { class: 'sm-field__slider-row' });\n const range = h('input', {\n type: 'range',\n min,\n max,\n step,\n }) as HTMLInputElement;\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min,\n max,\n step,\n 'data-sm-focus': focusToken,\n }) as HTMLInputElement;\n sliderRow.append(range, num);\n\n const syncSlider = () => {\n sliderRow.classList.toggle('sm-field__slider-row--inherit', inheriting);\n num.disabled = inheriting;\n if (inheriting) {\n range.value = String(globalPx);\n num.value = '';\n } else {\n const s = snap(this._snapFontSizeToPx(stored || `${globalPx}px`));\n range.value = String(s);\n num.value = String(s);\n }\n };\n\n let inheritSwitch: ReturnType<RightPanel['_globalInheritSwitch']> | null = null;\n if (inheritGlobal) {\n inheritSwitch = this._globalInheritSwitch(\n inheriting,\n `${globalPx}px`,\n (on) => {\n if (on) {\n inheriting = true;\n stored = '';\n inheritSwitch!.setInherit(true, `${globalPx}px`);\n syncSlider();\n onChange('');\n return;\n }\n inheriting = false;\n stored = `${globalPx}px`;\n inheritSwitch!.setInherit(false);\n syncSlider();\n onChange(stored);\n },\n `${focusToken}:inherit`,\n );\n }\n\n syncSlider();\n\n const leaveInherit = () => {\n if (!inheriting) return;\n inheriting = false;\n inheritSwitch?.setInherit(false);\n syncSlider();\n };\n\n range.addEventListener('input', () => {\n leaveInherit();\n const s = snap(Number(range.value));\n num.value = String(s);\n stored = `${s}px`;\n onChange(stored);\n });\n\n num.addEventListener('input', () => {\n if (inheriting) return;\n const rawN = Number(num.value);\n if (Number.isNaN(rawN)) return;\n range.value = String(snap(rawN));\n });\n\n num.addEventListener('blur', () => {\n if (inheriting) return;\n const t = num.value.trim();\n const fb = snap(Number(range.value));\n const s = snap(t === '' || Number.isNaN(Number(t)) ? fb : Number(t));\n stored = `${s}px`;\n num.value = String(s);\n range.value = String(s);\n onChange(stored);\n });\n\n num.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n ...(inheritSwitch ? [inheritSwitch.el] : []),\n sliderRow,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _docFontSizeField(value: string, onChange: (v: string) => void, focusToken: string) {\n return this._fontSizeSliderField(\n this.opts.t('rightPanel.doc.fontSize'),\n value,\n onChange,\n focusToken,\n this.opts.t('rightPanel.doc.fontSizeHelp'),\n );\n }\n\n private _layoutWidthField(\n label: string,\n raw: string,\n onChange: (v: string) => void,\n focusToken: string,\n help?: string,\n ) {\n if (!this._preferSliderControls()) {\n const tf = this._textField(label, raw, onChange, '', focusToken);\n if (help) tf.append(h('div', { class: 'sm-field__help' }, [help]));\n return tf;\n }\n\n const kind = classifyLayoutWidth(raw);\n if (kind === 'custom') {\n const wrap = h('div', { class: 'sm-field' });\n wrap.append(h('label', { class: 'sm-field__label' }, [label]));\n wrap.append(\n h('div', { class: 'sm-field__help' }, [\n this.opts.t('rightPanel.width.customHelp'),\n ]),\n );\n wrap.append(\n h('input', {\n class: 'sm-input',\n type: 'text',\n value: raw,\n placeholder: this.opts.t('rightPanel.width.customPlaceholder'),\n 'data-sm-focus': focusToken,\n oninput: (e: Event) => onChange((e.target as HTMLInputElement).value),\n }),\n );\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n const mode: 'auto' | 'px' | '%' = kind;\n const max = mode === '%' ? 100 : 1200;\n const min = 1;\n const displayN = mode === 'auto' ? 280 : layoutWidthNumeric(raw, mode === '%' ? '%' : 'px');\n\n const clampW = (n: number) => Math.max(min, Math.min(max, Math.round(n)));\n\n const range = h('input', {\n type: 'range',\n min,\n max,\n step: 1,\n value: String(displayN),\n disabled: mode === 'auto',\n }) as HTMLInputElement;\n\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min,\n max,\n step: 1,\n value: String(displayN),\n disabled: mode === 'auto',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const emitW = (c: number) => {\n const v = clampW(c);\n range.value = String(v);\n num.value = String(v);\n onChange(mode === '%' ? `${v}%` : `${v}px`);\n };\n\n range.addEventListener('input', () => {\n if (mode === 'auto') return;\n emitW(Number(range.value));\n });\n\n num.addEventListener('input', () => {\n if (mode === 'auto') return;\n const t = num.value.trim();\n if (t === '') return;\n const rawN = Number(t);\n if (Number.isNaN(rawN)) return;\n range.value = String(clampW(rawN));\n });\n\n num.addEventListener('blur', () => {\n if (mode === 'auto') return;\n const t = num.value.trim();\n const fb = clampW(Number(range.value));\n if (t === '') {\n emitW(fb);\n return;\n }\n const rawN = Number(t);\n emitW(Number.isNaN(rawN) ? fb : rawN);\n });\n\n num.addEventListener('keydown', (e) => {\n if (mode === 'auto') return;\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n const sliderRow = h(\n 'div',\n { class: `sm-width-field__slider-row ${mode === 'auto' ? 'is-disabled' : ''}` },\n [range, num],\n );\n\n const modesWrap = h('div', { class: 'sm-segmented sm-segmented--wrap sm-width-field__modes' });\n const addModeBtn = (m: 'auto' | 'px' | '%', text: string) => {\n modesWrap.append(\n h(\n 'button',\n {\n type: 'button',\n class: `sm-segmented__item ${mode === m ? 'sm-segmented__item--active' : ''}`,\n onclick: () => {\n if (m === 'auto') onChange('');\n else if (m === 'px') onChange(`${layoutWidthNumeric(raw, 'px')}px`);\n else onChange(`${layoutWidthNumeric(raw, '%')}%`);\n },\n },\n [text],\n ),\n );\n };\n addModeBtn('auto', this.opts.t('rightPanel.width.auto'));\n addModeBtn('px', 'px');\n addModeBtn('%', '%');\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n modesWrap,\n sliderRow,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _docFontWeightField(value: string, onChange: (v: string) => void, focusToken: string) {\n const cur = normalizeFontWeightStep(value);\n return this._segmentedSelectField(this.opts.t('rightPanel.doc.fontWeight'), cur, FONT_WEIGHT_STEP_OPTIONS, onChange, focusToken);\n }\n\n private _multiColumnLayoutField(\n layout: SectionLayout,\n onChange: (layout: SectionLayout) => void,\n focusToken: string,\n ) {\n return this._segmentedSelectField(\n this.opts.t('rightPanel.section.columnLayout'),\n layout,\n [\n { label: '1:1', value: '1-1' },\n { label: '1:2', value: '1-2' },\n { label: '2:1', value: '2-1' },\n { label: '1:1:1', value: '1-1-1' },\n ],\n (v) => onChange(v as SectionLayout),\n focusToken,\n );\n }\n\n private _renderBlockCodeView(block: Block): HTMLElement {\n const def = this.opts.registry.get(block.type);\n const initial =\n block.lockedMjml ??\n (def ? def.toMjml(block.props as any, { doc: this.opts.store.doc, engine: 'mjml' }) : '');\n\n const wrap = h('div', { class: 'sm-code-pane' });\n\n const header = h('div', { class: 'sm-code-pane__header' }, [\n h('div', { class: 'sm-code-pane__title' }, [this.opts.t('rightPanel.code.title')]),\n ]);\n\n const editorHost = h('div', { class: 'sm-code' });\n\n const view = new EditorView({\n parent: editorHost,\n state: EditorState.create({\n doc: initial,\n extensions: [basicSetup, cmHtml()],\n }),\n });\n this.codeView = view;\n\n const actions = h('div', { class: 'sm-code-pane__header' }, [\n h(\n 'button',\n {\n class: 'sm-btn',\n type: 'button',\n onclick: () => {\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, block.id);\n if (l) delete l.block.lockedMjml;\n });\n },\n },\n [this.opts.t('rightPanel.code.restoreDefault')],\n ),\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => {\n const text = view.state.doc.toString();\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, block.id);\n if (l) l.block.lockedMjml = text;\n });\n },\n },\n [this.opts.t('rightPanel.code.saveLocked')],\n ),\n ]);\n\n wrap.append(\n header,\n editorHost,\n h('div', { class: 'sm-field__help' }, [this.opts.t('rightPanel.code.help')]),\n actions,\n );\n return wrap;\n }\n\n private _destroyCodeView() {\n if (this.codeView) {\n this.codeView.destroy();\n this.codeView = null;\n }\n }\n}\n","import { EditorState } from '@codemirror/state';\nimport { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { Store } from '../store/store';\nimport { clear, h } from '../utils/dom';\nimport { richTextExecCommand } from '../utils/richTextCommand';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface SourceViewOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n}\n\ntype SourceTab = 'mjml' | 'html';\n\n/**\n * 文档级源码视图:只读地展示当前文档编译出的 MJML 与 HTML。\n *\n * 本期不支持把源码直接回写到数据模型——MJML/HTML 反推 doc 风险大且不必要,\n * 用户若需要直接写源码,可在右栏对单个 Block 走\"组件级代码模式\"。\n */\nexport class SourceView {\n el: HTMLElement;\n private opts: SourceViewOptions;\n private currentTab: SourceTab = 'mjml';\n private body: HTMLElement;\n private cm: EditorView | null = null;\n\n constructor(opts: SourceViewOptions) {\n this.opts = opts;\n this.el = h('div', { class: 'sm-doc-source' });\n this.body = h('div', { class: 'sm-doc-source__body' });\n this._render();\n opts.store.subscribe(() => {\n if (this._isVisible()) this._renderEditor();\n });\n }\n\n /**\n * 设计态运行时 SourceView 不在 DOM,`store.subscribe` 里的 `_renderEditor()` 全部被跳过,\n * CodeMirror 里仍是构造函数那一刻的快照。**切到「源码」模式后必须手动调一次**,\n * 否则会看到空文档 / 旧文档,但「导出」「预览」「MJML→HTML」却一直是当前 doc ——这正是用户报告的错位。\n */\n refreshDoc() {\n this._renderEditor();\n }\n\n private _isVisible(): boolean {\n return this.el.isConnected && (this.el.offsetParent !== null || this.el.getClientRects().length > 0);\n }\n\n private _render() {\n clear(this.el);\n const bar = h('div', { class: 'sm-doc-source__bar' }, [\n this._tabBtn('mjml', 'MJML'),\n this._tabBtn('html', this.opts.t('source.compiledHtml')),\n h('div', { class: 'sm-topbar__spacer' }),\n h(\n 'button',\n {\n class: 'sm-btn',\n type: 'button',\n onclick: () => this._copy(),\n },\n [this.opts.t('common.copy')],\n ),\n ]);\n this.el.append(bar, this.body);\n this._renderEditor();\n }\n\n private _tabBtn(tab: SourceTab, label: string) {\n return h(\n 'button',\n {\n class: `sm-segmented__item ${tab === this.currentTab ? 'sm-segmented__item--active' : ''}`,\n type: 'button',\n onclick: () => {\n this.currentTab = tab;\n this._render();\n },\n },\n [label],\n );\n }\n\n private _renderEditor() {\n this._destroyCm();\n clear(this.body);\n const result = renderDoc(this.opts.store.doc, this.opts.registry, {\n withSampleVariables: false,\n });\n const text = this.currentTab === 'mjml' ? result.mjml : result.html;\n this.cm = new EditorView({\n parent: this.body,\n state: EditorState.create({\n doc: text,\n extensions: [basicSetup, cmHtml(), EditorState.readOnly.of(true)],\n }),\n });\n }\n\n private async _copy() {\n if (!this.cm) return;\n const text = this.cm.state.doc.toString();\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n const ta = document.createElement('textarea');\n ta.value = text;\n document.body.appendChild(ta);\n ta.select();\n richTextExecCommand('copy');\n document.body.removeChild(ta);\n }\n }\n\n private _destroyCm() {\n if (this.cm) {\n this.cm.destroy();\n this.cm = null;\n }\n }\n\n destroy() {\n this._destroyCm();\n }\n}\n","import type { Store } from '../store/store';\nimport { bindColorPickerInput } from './ColorPickerPopover';\nimport { normalizeAccentHex, rgbCssToHex } from '../utils/accentColor';\nimport { h, clear } from '../utils/dom';\nimport type { EditorTheme } from './theme';\nimport type { SimpleMailT } from '../i18n';\n\nexport type EditorMode = 'design' | 'source';\n\nexport interface TopbarOptions {\n store: Store;\n t: SimpleMailT;\n mode: EditorMode;\n theme: EditorTheme;\n /** 顶栏仅图标(tooltip 说明),适合窄屏嵌入 */\n compact?: boolean;\n /** 用于读取解析后的 `--sm-primary`,同步到原生 color 输入 */\n accentPickerRoot?: HTMLElement;\n /** 为 true 时在顶栏显示主题色拾取器(需同时提供 `onAccentChange`) */\n showAccentColorPicker?: boolean;\n onAccentChange?: (hex: string) => void;\n onThemeChange: (t: EditorTheme) => void;\n onModeChange: (m: EditorMode) => void;\n onUndo: () => void;\n onRedo: () => void;\n /** 清空画布选中并回到右栏「邮件设置 / 全局样式」 */\n onMailSettings: () => void;\n onInsertVariable: (anchor: HTMLElement) => void;\n onPreview: () => void;\n onExport: () => void;\n /** 切换编辑器根节点浏览器全屏(由 Editor 实现 Fullscreen API) */\n onFullscreenToggle?: () => void;\n /** 切换画布 Section / Block 布局虚线边框 */\n onLayoutBordersToggle?: () => void;\n /** 为 false 时不展示全屏按钮(也可用 `ui.hideTopbarFullscreen`) */\n showFullscreenButton?: boolean;\n /** 为 false 时不展示「邮件设置」按钮(也可用 `ui.hideTopbarMailSettings`) */\n showMailSettingsButton?: boolean;\n /** 为 false 时不渲染左侧产品标题 */\n showTitle?: boolean;\n /** 为 false 时不展示「清空画布」 */\n showClearCanvasButton?: boolean;\n onClearCanvas?: () => void;\n /** 为 false 时不展示「重置内容」 */\n showResetContentButton?: boolean;\n onResetContent?: () => void;\n /** 为 false 时不展示「复制设计稿」「导入设计稿」 */\n showDocClipboardButtons?: boolean;\n onCopyDocDesign?: () => void;\n onImportDocDesign?: () => void;\n /** 为 false 时不展示「插入变量」 */\n showInsertVariableButton?: boolean;\n}\n\nexport class Topbar {\n el: HTMLElement;\n private opts: TopbarOptions;\n private undoBtn!: HTMLButtonElement;\n private redoBtn!: HTMLButtonElement;\n private themeButtons!: Record<EditorTheme, HTMLButtonElement>;\n private modeButtons: Record<EditorMode, HTMLButtonElement> = {} as any;\n private accentInput?: HTMLInputElement;\n private fullscreenBtn?: HTMLButtonElement;\n private layoutBordersBtn?: HTMLButtonElement;\n private insertVariableBtn?: HTMLButtonElement;\n\n constructor(opts: TopbarOptions) {\n this.opts = opts;\n this.el = h('header', { class: 'sm-topbar' });\n this.setCompact(opts.compact === true);\n this._render();\n opts.store.subscribe(() => this._sync());\n this._sync();\n }\n\n /** 切换顶栏紧凑样式(仅图标布局,文案由 CSS 隐藏) */\n setCompact(compact: boolean) {\n this.el.classList.toggle('sm-topbar--compact', compact);\n }\n\n setMode(m: EditorMode) {\n this.opts.mode = m;\n for (const k of ['design', 'source'] as EditorMode[]) {\n this.modeButtons[k].classList.toggle('sm-segmented__item--active', k === m);\n }\n }\n\n syncTheme(t: EditorTheme) {\n this.opts.theme = t;\n for (const k of ['light', 'dark', 'system'] as const) {\n const on = k === t;\n this.themeButtons[k].classList.toggle('sm-segmented__item--active', on);\n this.themeButtons[k].setAttribute('aria-pressed', on ? 'true' : 'false');\n }\n }\n\n /** 根据 `.sm-root` 上计算后的 `--sm-primary` 更新拾取器显示(无拾取器或未挂 root 时忽略) */\n syncAccentPicker() {\n if (!this.accentInput || !this.opts.accentPickerRoot) return;\n const raw = getComputedStyle(this.opts.accentPickerRoot).getPropertyValue('--sm-primary').trim();\n const base = normalizeAccentHex(raw) || rgbCssToHex(raw);\n if (!base) return;\n const norm = normalizeAccentHex(base);\n if (!norm) return;\n const forInput = `#${norm.slice(1).toLowerCase()}`;\n if (this.accentInput.value.toLowerCase() !== forInput) this.accentInput.value = forInput;\n }\n\n /** 与 document fullscreen 状态同步图标与 aria(按钮不存在时忽略) */\n setFullscreenActive(active: boolean) {\n const btn = this.fullscreenBtn;\n if (!btn) return;\n btn.replaceChildren(active ? iconFullscreenExit() : iconFullscreenEnter());\n const title = active ? this.opts.t('topbar.exitFullscreen') : this.opts.t('topbar.fullscreen');\n btn.title = title;\n btn.setAttribute('aria-label', title);\n btn.setAttribute('aria-pressed', active ? 'true' : 'false');\n }\n\n /** 与画布布局边框开关同步按钮高亮(按钮不存在时忽略) */\n setLayoutBordersActive(active: boolean) {\n const btn = this.layoutBordersBtn;\n if (!btn) return;\n btn.setAttribute('aria-pressed', active ? 'true' : 'false');\n const title = active ? this.opts.t('topbar.hideLayoutBorders') : this.opts.t('topbar.showLayoutBorders');\n btn.title = title;\n btn.setAttribute('aria-label', title);\n }\n\n /** 变量列表在右栏打开(设计态)或浮层打开(源码态)时高亮顶栏按钮 */\n setInsertVariableActive(active: boolean) {\n const btn = this.insertVariableBtn;\n if (!btn) return;\n btn.setAttribute('aria-pressed', active ? 'true' : 'false');\n btn.classList.toggle('sm-topbar__insert-var--active', active);\n }\n\n private _render() {\n clear(this.el);\n const t = this.opts.t;\n\n const segmented = h('div', { class: 'sm-segmented sm-topbar__mode-seg', role: 'group', 'aria-label': t('topbar.mode') });\n const designBtn = modeSegBtn({\n active: this.opts.mode === 'design',\n title: t('topbar.design'),\n icon: iconDesign(),\n label: t('topbar.design'),\n onclick: () => this.opts.onModeChange('design'),\n });\n const sourceBtn = modeSegBtn({\n active: this.opts.mode === 'source',\n title: t('topbar.source'),\n icon: iconSource(),\n label: t('topbar.source'),\n onclick: () => this.opts.onModeChange('source'),\n });\n segmented.append(designBtn, sourceBtn);\n this.modeButtons = { design: designBtn, source: sourceBtn };\n\n const themeSeg = h('div', {\n class: 'sm-segmented sm-topbar__theme-seg',\n role: 'group',\n 'aria-label': t('topbar.theme'),\n });\n const themeBtn = (theme: EditorTheme, title: string, icon: SVGElement) =>\n h(\n 'button',\n {\n class: 'sm-segmented__item sm-topbar__theme-btn',\n type: 'button',\n title,\n 'aria-label': title,\n 'aria-pressed': theme === this.opts.theme ? 'true' : 'false',\n onclick: () => this.opts.onThemeChange(theme),\n },\n [icon],\n ) as HTMLButtonElement;\n this.themeButtons = {\n light: themeBtn('light', t('topbar.light'), iconSun()),\n dark: themeBtn('dark', t('topbar.dark'), iconMoon()),\n system: themeBtn('system', t('topbar.system'), iconThemeAuto()),\n };\n themeSeg.append(this.themeButtons.light, this.themeButtons.dark, this.themeButtons.system);\n\n const themeGroupKids: Node[] = [themeSeg];\n if (this.opts.showAccentColorPicker && this.opts.onAccentChange) {\n const inputEl = h('input', {\n type: 'color',\n class: 'sm-topbar__accent-input',\n 'aria-label': t('topbar.accentColor'),\n title: t('topbar.accentColor'),\n value: '#4f46e5',\n }) as HTMLInputElement;\n bindColorPickerInput(inputEl, {\n layerRoot: this.opts.accentPickerRoot,\n liveCommit: true,\n t,\n onCommit: (hex) => this.opts.onAccentChange!(hex),\n });\n this.accentInput = inputEl;\n themeGroupKids.push(h('div', { class: 'sm-topbar__accent' }, [inputEl]));\n } else {\n this.accentInput = undefined;\n }\n\n this.undoBtn = actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.undoTitle'),\n icon: iconUndo(),\n label: t('topbar.undo'),\n onclick: this.opts.onUndo,\n });\n this.redoBtn = actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.redoTitle'),\n icon: iconRedo(),\n label: t('topbar.redo'),\n onclick: this.opts.onRedo,\n });\n\n const contentActionKids: HTMLElement[] = [];\n if (this.opts.showClearCanvasButton !== false && typeof this.opts.onClearCanvas === 'function') {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.clearCanvasTitle'),\n icon: iconClearCanvas(),\n label: t('topbar.clearCanvas'),\n onclick: () => this.opts.onClearCanvas!(),\n }),\n );\n }\n if (\n this.opts.showResetContentButton !== false &&\n typeof this.opts.onResetContent === 'function'\n ) {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.resetContentTitle'),\n icon: iconResetContent(),\n label: t('topbar.resetContent'),\n onclick: () => this.opts.onResetContent!(),\n }),\n );\n }\n if (this.opts.showDocClipboardButtons !== false) {\n if (typeof this.opts.onCopyDocDesign === 'function') {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.copyDesignTitle'),\n icon: iconCopyDoc(),\n label: t('topbar.copyDesign'),\n onclick: () => this.opts.onCopyDocDesign!(),\n }),\n );\n }\n if (typeof this.opts.onImportDocDesign === 'function') {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.importDesignTitle'),\n icon: iconImportDoc(),\n label: t('topbar.importDesign'),\n onclick: () => this.opts.onImportDocDesign!(),\n }),\n );\n }\n }\n const contentActionsGroup =\n contentActionKids.length > 0 && h('div', { class: 'sm-topbar__group' }, contentActionKids);\n\n const previewBtn = actionBtn({\n title: t('topbar.preview'),\n icon: iconEye(),\n label: t('topbar.preview'),\n onclick: this.opts.onPreview,\n });\n\n const exportBtn = actionBtn({\n class: 'sm-btn--primary',\n title: t('topbar.exportHtml'),\n icon: iconExport(),\n label: t('topbar.exportHtml'),\n onclick: this.opts.onExport,\n });\n\n const showMailSettings = this.opts.showMailSettingsButton !== false;\n const trailingGroup: HTMLElement[] = [];\n if (showMailSettings) {\n trailingGroup.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.mailSettingsTitle'),\n icon: iconSettings(),\n label: t('topbar.mailSettings'),\n onclick: () => this.opts.onMailSettings(),\n }),\n );\n }\n if (this.opts.showInsertVariableButton !== false) {\n trailingGroup.push(\n (this.insertVariableBtn = actionBtn({\n class: 'sm-topbar__insert-var',\n title: t('topbar.insertVariable'),\n icon: iconVariable(),\n label: t('topbar.insertVariable'),\n onclick: (e: Event) => this.opts.onInsertVariable(e.currentTarget as HTMLElement),\n })),\n );\n } else {\n this.insertVariableBtn = undefined;\n }\n trailingGroup.push(previewBtn, exportBtn);\n\n const canvasToolKids: HTMLElement[] = [];\n\n if (typeof this.opts.onLayoutBordersToggle === 'function') {\n canvasToolKids.push(\n (this.layoutBordersBtn = iconOnlyBtn({\n class: 'sm-btn--ghost sm-topbar__toggle-btn',\n title: t('topbar.showLayoutBorders'),\n icon: iconLayoutBorders(),\n pressed: false,\n onclick: () => this.opts.onLayoutBordersToggle!(),\n }) as HTMLButtonElement),\n );\n } else {\n this.layoutBordersBtn = undefined;\n }\n\n const showFs =\n this.opts.showFullscreenButton !== false &&\n typeof this.opts.onFullscreenToggle === 'function';\n if (showFs) {\n canvasToolKids.push(\n (this.fullscreenBtn = iconOnlyBtn({\n class: 'sm-btn--ghost sm-topbar__toggle-btn',\n title: t('topbar.fullscreen'),\n icon: iconFullscreenEnter(),\n pressed: false,\n onclick: () => this.opts.onFullscreenToggle!(),\n }) as HTMLButtonElement),\n );\n } else {\n this.fullscreenBtn = undefined;\n }\n\n const canvasToolsGroup =\n canvasToolKids.length > 0 && h('div', { class: 'sm-topbar__group' }, canvasToolKids);\n\n const headKids: HTMLElement[] = [];\n if (this.opts.showTitle !== false) {\n headKids.push(h('div', { class: 'sm-topbar__title' }, ['Simple Mail Editor']));\n }\n\n this.el.append(\n ...headKids,\n h('div', { class: 'sm-topbar__group' }, [segmented]),\n h('div', { class: 'sm-topbar__group sm-topbar__theme-group' }, themeGroupKids),\n h('div', { class: 'sm-topbar__group' }, [this.undoBtn, this.redoBtn]),\n ...(contentActionsGroup ? [contentActionsGroup] : []),\n ...(canvasToolsGroup ? [canvasToolsGroup] : []),\n h('div', { class: 'sm-topbar__spacer' }),\n h('div', { class: 'sm-topbar__group' }, trailingGroup),\n );\n\n this.setMode(this.opts.mode);\n this.syncTheme(this.opts.theme);\n }\n\n private _sync() {\n this.undoBtn.disabled = !this.opts.store.canUndo();\n this.redoBtn.disabled = !this.opts.store.canRedo();\n }\n}\n\nfunction topbarLabel(text: string): HTMLElement {\n return h('span', { class: 'sm-topbar__btn-label' }, [text]);\n}\n\nfunction actionBtn(opts: {\n class?: string;\n title: string;\n icon: SVGElement;\n label: string;\n onclick: (e: Event) => void;\n}): HTMLButtonElement {\n const extra = opts.class ? ` ${opts.class}` : '';\n return h(\n 'button',\n {\n class: `sm-btn sm-topbar__action-btn${extra}`,\n type: 'button',\n title: opts.title,\n 'aria-label': opts.title,\n onclick: opts.onclick,\n },\n [opts.icon, topbarLabel(opts.label)],\n ) as HTMLButtonElement;\n}\n\nfunction modeSegBtn(opts: {\n active: boolean;\n title: string;\n icon: SVGElement;\n label: string;\n onclick: () => void;\n}): HTMLButtonElement {\n const cls = opts.active\n ? 'sm-segmented__item sm-topbar__mode-btn sm-segmented__item--active'\n : 'sm-segmented__item sm-topbar__mode-btn';\n return h(\n 'button',\n {\n class: cls,\n type: 'button',\n title: opts.title,\n 'aria-label': opts.title,\n onclick: opts.onclick,\n },\n [opts.icon, topbarLabel(opts.label)],\n ) as HTMLButtonElement;\n}\n\nfunction iconOnlyBtn(opts: {\n class?: string;\n title: string;\n icon: SVGElement;\n pressed: boolean;\n onclick: () => void;\n}): HTMLButtonElement {\n const extra = opts.class ? ` ${opts.class}` : '';\n return h(\n 'button',\n {\n class: `sm-btn sm-btn--ghost sm-topbar__icon-btn${extra}`,\n type: 'button',\n title: opts.title,\n 'aria-label': opts.title,\n 'aria-pressed': opts.pressed ? 'true' : 'false',\n onclick: opts.onclick,\n },\n [opts.icon],\n ) as HTMLButtonElement;\n}\n\nconst ICON_UNDO_PATH =\n 'M596.16 284.064H258.56l101.376-101.44a31.968 31.968 0 1 0-45.248-45.216L178.56 273.504c-11.904 11.872-18.496 27.84-18.56 44.8a63.04 63.04 0 0 0 18.56 45.28l136.128 136.16a31.904 31.904 0 0 0 45.248 0 31.968 31.968 0 0 0 0-45.248l-106.752-106.496H596.16c114.88 0 208.32 93.312 208.32 208s-93.44 208-208.32 208h-223.36a32 32 0 0 0 0 64h223.36c150.144 0 272.32-122.016 272.32-272 0-149.984-122.176-272-272.32-272';\n\nfunction iconUndo(): SVGElement {\n return svgPathFill(ICON_UNDO_PATH);\n}\nfunction iconRedo(): SVGElement {\n return svgPathFill(ICON_UNDO_PATH, { flipX: true });\n}\nfunction iconEye(): SVGElement {\n return svgPathFill([\n 'M506.84131 829.259446C229.561713 829.259446 10.31738 575.193955 1.289673 564.876574c-7.738035-9.027708-7.738035-23.214106 0-33.531486 9.027708-10.31738 228.27204-264.382872 505.551637-264.382871 277.279597 0 496.523929 254.065491 505.551637 264.382871 7.738035 9.027708 7.738035 23.214106 0 33.531486-10.31738 10.31738-228.27204 264.382872-505.551637 264.382872z m-451.385391-281.148615c52.876574 55.455919 237.299748 229.561713 451.385391 229.561713s397.219144-174.105793 451.38539-229.561713c-52.876574-55.455919-237.299748-229.561713-451.38539-229.561713S108.332494 492.654912 55.455919 548.110831z',\n 'M497.813602 713.188917c-90.277078 0-163.788413-73.511335-163.788413-163.788413S407.536524 386.901763 497.813602 386.901763c90.277078 0 163.788413 73.511335 163.788413 163.788413s-73.511335 162.498741-163.788413 162.498741z m0-274.700252c-61.904282 0-112.201511 50.297229-112.201511 112.201511 0 61.904282 50.297229 112.201511 112.201511 112.201512s112.201511-50.297229 112.201511-112.201512c0-61.904282-50.297229-112.201511-112.201511-112.201511z',\n ]);\n}\nfunction iconDesign(): SVGElement {\n return svgPathFill(\n 'M947.96 199.329l-92.764 92.549L731.54 168.443l92.768-92.548c17.025-17.03 44.746-17.03 61.825 0l61.828 61.715c17.084 17.028 17.084 44.695 0 61.719z m-649.486 401.09l123.657 123.434-164.804 41.092 41.147-164.526z m525.834-277.653l-371.02 370.257-123.654-123.436L700.597 199.33l123.711 123.436zM154.843 196.272v673.501h673.503V383.884l87.856-87.854v617.673c0 24.287-19.641 43.93-43.927 43.93H110.917c-24.282 0-43.928-19.642-43.928-43.93V152.345c0-24.281 19.646-43.927 43.928-43.927h620.185l-87.855 87.854H154.843z',\n );\n}\nfunction iconSource(): SVGElement {\n return svgPathFill(\n 'M153.770667 517.558857l200.387047-197.241905L302.86019 268.190476 48.761905 518.290286l254.439619 243.614476 50.590476-52.833524-200.021333-191.512381zM658.285714 320.316952L709.583238 268.190476l254.098286 250.09981L709.241905 761.904762l-50.590476-52.833524 200.021333-191.512381L658.285714 320.316952z m-112.981333-86.186666L393.99619 785.554286l70.534096 19.358476 151.30819-551.399619-70.534095-19.358476z',\n );\n}\n/** 邮件设置齿轮(镂空路径用 evenodd) */\nfunction iconSettings(): SVGElement {\n return svgPathFill(\n 'M664.586139 993.077228c-18.756436 0-36.49901-7.60396-48.158416-20.277228-15.714851-17.235644-65.90099-62.352475-106.962376-62.352475-41.061386 0-91.754455 45.623762-106.455446 61.338614-11.659406 12.673267-29.40198 20.277228-47.651485 20.277227-8.617822 0-17.235644-1.520792-24.332673-5.069307l-1.520793-0.50693-125.211881-69.956436-1.013861-1.013861c-22.811881-15.714851-31.429703-47.144554-20.277228-72.491089 0 0 11.659406-26.360396 11.659406-50.69307 0-72.99802-59.310891-132.308911-132.308911-132.308911h-5.576237c-20.784158 0-38.019802-18.756436-43.59604-47.144554-0.506931-2.534653-10.645545-56.776238-10.645545-99.865347s10.138614-97.330693 10.645545-99.865346c5.576238-28.89505 22.811881-47.651485 44.10297-47.144555h4.562377c72.99802 0 132.308911-59.310891 132.30891-132.30891 0-23.825743-11.659406-50.693069-11.659405-50.69307-11.152475-25.346535-2.534653-56.269307 20.277227-72.491089l1.520792-1.013861 131.801981-72.491089 1.520792-1.520792c7.60396-3.041584 15.714851-4.562376 24.332673-4.562377 18.249505 0 35.992079 7.60396 48.158416 19.770297 15.714851 16.221782 64.887129 58.80396 104.934653 58.803961 39.540594 0 88.712871-41.568317 103.920792-57.790099 11.659406-12.166337 29.40198-19.263366 47.651485-19.263367 8.617822 0 17.235644 1.520792 24.839604 5.069307l1.520792 0.506931 127.239604 70.970297 1.013862 1.013861c22.811881 15.714851 31.429703 47.144554 20.277227 72.49109 0 0-11.659406 26.360396-11.659405 50.693069 0 72.99802 59.310891 132.308911 132.30891 132.308911h4.562377c21.291089-0.506931 38.526733 18.249505 44.10297 47.144554 0.506931 2.534653 10.645545 56.776238 10.645545 99.865347s-10.138614 97.330693-10.645545 99.865346c-5.576238 28.89505-22.811881 47.651485-44.10297 47.144555h-4.562377c-72.99802 0-132.308911 59.310891-132.30891 132.308911 0 23.825743 11.659406 50.693069 11.659405 50.693069 11.152475 25.346535 2.534653 56.269307-20.277227 72.491089l-1.520792 1.013861-129.774258 71.477228-1.520792 0.506931c-7.09703 3.548515-15.207921 5.069307-23.825742 5.069307z m-3.548515-60.831683c0.506931 0.506931 2.027723 1.013861 4.055445 1.013861l121.156436-66.914852c-3.041584-6.590099-16.221782-39.540594-16.221782-74.011881 0-102.906931 81.108911-187.057426 182.495049-192.126732 1.520792-8.110891 9.631683-53.227723 9.631683-87.69901 0-33.964356-8.110891-79.588119-9.631683-87.69901-101.386139-5.069307-182.49505-89.726733-182.495049-192.126733 0-34.471287 13.180198-67.421782 16.221782-74.011881l-119.128713-65.90099h-0.506931c-2.027723 0-4.055446 0.506931-4.562376 1.013861-2.027723 2.027723-19.263366 19.770297-44.10297 37.005941-36.49901 25.853465-71.477228 39.033663-102.906931 39.033663-31.936634 0-66.914851-13.180198-103.920792-39.540594-24.839604-17.742574-42.075248-35.485149-44.10297-37.512871-0.506931-0.506931-2.534653-1.013861-4.562376-1.013862h-0.506931L238.257426 158.669307c3.041584 7.09703 16.221782 39.540594 16.221782 74.011881 0 102.906931-81.108911 187.057426-182.49505 192.126733-1.520792 8.110891-9.631683 53.227723-9.631683 87.69901 0 33.964356 8.110891 79.588119 9.631683 87.69901 101.386139 5.069307 182.49505 89.726733 182.49505 192.126732 0 34.471287-13.687129 67.421782-16.221782 74.011881l116.594059 65.39406h0.506931c1.520792 0 3.548515-0.506931 4.055445-1.013862 2.027723-2.534653 19.770297-20.784158 44.609901-39.033663 37.512871-27.374257 72.99802-41.568317 105.948515-41.568317 32.950495 0 68.942574 14.194059 106.455446 42.075248 24.839604 18.756436 42.075248 37.512871 44.609901 40.047525z m-151.065347-243.833664c-97.330693 0-176.411881-79.081188-176.411881-176.411881 0-97.330693 79.081188-176.411881 176.411881-176.411881 97.330693 0 176.411881 79.081188 176.411881 176.411881 0 96.823762-79.588119 176.411881-176.411881 176.411881z m0-293.00594c-64.380198 0-116.594059 52.213861-116.594059 116.594059s52.213861 116.594059 116.594059 116.594059 116.594059-52.213861 116.59406-116.594059c-0.506931-64.380198-52.720792-116.594059-116.59406-116.594059z',\n { fillRule: 'evenodd' },\n );\n}\nfunction iconVariable(): SVGElement {\n return svgPathFill(\n 'M212.48 768v-157.866667c0-35.349333-28.373333-55.466667-63.36-55.466666A42.645333 42.645333 0 0 1 106.666667 512c0-23.445333 18.986667-42.666667 42.453333-42.666667 34.986667 0 63.36-20.117333 63.36-55.466666V256c0-85.333333 55.637333-128 125.610667-128h6.442666a39.466667 39.466667 0 0 1 0 78.933333h-6.442666c-23.317333 0-42.24 25.493333-42.24 49.066667v174.933333a85.290667 85.290667 0 0 1-58.026667 81.066667 85.290667 85.290667 0 0 1 58.026667 81.066667V768c0 23.573333 18.922667 49.066667 42.24 49.066667h6.442666a39.466667 39.466667 0 0 1 0 78.933333h-6.442666c-69.973333 0-125.610667-42.666667-125.610667-128z m599.04-157.866667V768c0 85.333333-55.850667 128-125.845333 128h-6.208a39.466667 39.466667 0 0 1 0-78.933333h6.208c23.338667 0 42.24-25.493333 42.24-49.066667v-174.933333a85.290667 85.290667 0 0 1 58.026666-81.066667 85.290667 85.290667 0 0 1-58.026666-81.066667V256c0-23.573333-18.901333-49.066667-42.24-49.066667h-6.208a39.466667 39.466667 0 0 1 0-78.933333h6.208c69.973333 0 125.866667 42.666667 125.866666 128v157.866667c0 35.349333 28.352 55.466667 63.36 55.466666 23.424 0 42.432 19.221333 42.432 42.666667s-18.986667 42.666667-42.453333 42.666667c-34.986667 0-63.36 20.117333-63.36 55.466666z',\n );\n}\nfunction iconExport(): SVGElement {\n return svg(\n '<path d=\"M10 4.5v8.5M7.2 11.2 10 14l2.8-2.8M5.5 15.5h9\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n );\n}\nfunction iconClearCanvas(): SVGElement {\n return svgPathFill(\n 'M744.5 695L641.9 592.4l44.5-51.3L789 650.5l102.6-109.4 51.3 51.3L833.5 695l109.4 102.6-51.3 44.5L789 739.5 686.4 842.1l-44.5-44.5L744.5 695zM64 182h896v65H64v-65z m0 191.5h896v65H64v-65zM577 630H64v-61.6h513V630zM64 824.9v-65h513v65H64z',\n );\n}\nfunction iconResetContent(): SVGElement {\n return svgPathFill(\n 'M864 512a352 352 0 0 0-600.96-248.96c-15.744 15.872-40.704 42.88-63.232 67.648H320a32 32 0 1 1 0 64H128a31.872 31.872 0 0 1-32-32v-192a32 32 0 1 1 64 0v108.672c20.544-22.528 42.688-46.4 57.856-61.504a416 416 0 1 1 0 588.288 32 32 0 1 1 45.248-45.248A352 352 0 0 0 864 512z',\n );\n}\nfunction iconCopyDoc(): SVGElement {\n return svg(\n '<rect x=\"6.5\" y=\"6.5\" width=\"9\" height=\"11\" rx=\"1.2\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><rect x=\"4.5\" y=\"3.5\" width=\"9\" height=\"11\" rx=\"1.2\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"var(--sm-surface, #fff)\"/>',\n );\n}\nfunction iconImportDoc(): SVGElement {\n return svg(\n '<path d=\"M10 4.5v6.5M7.2 9.2 10 12l2.8-2.8M5.5 14.5h9\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><rect x=\"4\" y=\"14\" width=\"12\" height=\"2.5\" rx=\".6\" fill=\"currentColor\"/>',\n );\n}\n/** 显示边框:圆角矩形描边(开启时由 toggle 样式点亮 currentColor) */\nfunction iconLayoutBorders(): SVGElement {\n return svgPathFill(\n 'M64 832V192a128 128 0 0 1 128-128h640a128 128 0 0 1 128 128v640a128 128 0 0 1-128 128H192a128 128 0 0 1-128-128z m64 0q0 26.496 18.752 45.248T192 896h640q26.496 0 45.248-18.752T896 832V192q0-26.496-18.752-45.248T832 128H192q-26.496 0-45.248 18.752T128 192v640z',\n );\n}\n/** 进入全屏:四角向外 */\nfunction iconFullscreenEnter(): SVGElement {\n return svg(\n '<path d=\"M6 4H4v2M14 4h2v2M6 16H4v-2M14 16h2v-2M4 6V4h2M16 6V4h-2M4 14v2h2M16 14v2h-2\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>',\n );\n}\n/** 退出全屏 / 缩小:四角向内 */\nfunction iconFullscreenExit(): SVGElement {\n return svgPathFill(\n 'M705.92 124.117333a38.826667 38.826667 0 1 0-77.568 0v232.704c0 21.461333 17.365333 38.826667 38.784 38.826667h232.746667a38.826667 38.826667 0 0 0 0-77.568h-193.962667V124.117333zM356.864 395.648a38.826667 38.826667 0 0 0 38.784-38.784V124.16a38.826667 38.826667 0 1 0-77.568 0v193.962667H124.117333a38.826667 38.826667 0 0 0 0 77.568h232.746667zM899.882667 705.92a38.826667 38.826667 0 0 0 0-77.568h-232.704a38.826667 38.826667 0 0 0-38.826667 38.784v232.746667a38.826667 38.826667 0 0 0 77.610667 0v-193.962667h193.92zM356.864 628.352a38.826667 38.826667 0 0 1 38.826667 38.826667v232.704a38.826667 38.826667 0 0 1-77.610667 0v-193.92H124.16a38.826667 38.826667 0 1 1 0-77.610667h232.746667z',\n );\n}\nfunction iconSun(): SVGElement {\n return svgTheme(\n '<circle cx=\"10\" cy=\"10\" r=\"3.2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M10 3.5V5M10 15v1.5M16.5 10H15M5 10H3.5M14.1 5.9 13 7M7 13 5.9 14.1M14.1 14.1 13 13M7 7 5.9 5.9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>',\n );\n}\nfunction iconMoon(): SVGElement {\n return svgPathFill(\n 'M524.490551 1023.43355c-140.102939 0-271.81403-54.547017-370.878782-153.611769S0 639.045939 0 498.943c0-115.183242 36.995772-223.867918 106.944903-314.336142a523.825343 523.825343 0 0 1 119.276826-112.266563A533.035909 533.035909 0 0 1 376.55863 1.11192a25.584905 25.584905 0 0 1 30.036679 36.228225c-33.004527 64.320451-48.35547 125.621883-48.355471 193.012523 0 239.832899 195.110485 434.943383 434.943384 434.943383 67.39064 0 128.692072-15.350943 193.012523-48.35547a25.584905 25.584905 0 0 1 36.228225 30.036678 534.468663 534.468663 0 0 1-71.228375 150.336902 523.825343 523.825343 0 0 1-112.266563 119.276826 509.395457 509.395457 0 0 1-314.336142 106.944903zM336.18565 69.884144C163.538712 143.82452 51.16981 309.819383 51.16981 498.943 51.16981 759.90903 263.524521 972.26374 524.490551 972.26374c189.123617 0 355.11848-112.420072 429.058855-285.01584A451.98293 451.98293 0 0 1 793.132052 716.414691c-129.868977 0-251.908974-50.555772-343.707612-142.354411S307.018859 360.170475 307.018859 230.301498c0-55.109885 9.619924-108.019469 29.166791-160.417354z',\n { scale: 0.86 },\n );\n}\n/** 显示器:表示跟随系统外观 */\nfunction iconThemeAuto(): SVGElement {\n return svgTheme(\n '<path d=\"M5 5.5h10c.8 0 1.5.7 1.5 1.5v6c0 .8-.7 1.5-1.5 1.5H5c-.8 0-1.5-.7-1.5-1.5v-6c0-.8.7-1.5 1.5-1.5z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M8 16h4M10 14.2V16\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>',\n );\n}\n/** 1024 系 fill 图标,颜色随 currentColor;flipX 用于 redo 镜像;scale 用于夜间图标略缩小 */\nfunction svgPathFill(\n d: string | string[],\n opts?: { viewBox?: string; flipX?: boolean; scale?: number; fillRule?: 'evenodd' | 'nonzero' },\n): SVGElement {\n const viewBox = opts?.viewBox ?? '0 0 1024 1024';\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '18');\n el.setAttribute('height', '18');\n el.setAttribute('viewBox', viewBox);\n el.setAttribute('aria-hidden', 'true');\n const host = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n const transforms: string[] = [];\n if (opts?.scale && opts.scale !== 1) {\n const s = opts.scale;\n transforms.push(`translate(512,512) scale(${s}) translate(-512,-512)`);\n }\n if (opts?.flipX) transforms.push('translate(1024,0) scale(-1,1)');\n if (transforms.length) host.setAttribute('transform', transforms.join(' '));\n const paths = Array.isArray(d) ? d : [d];\n for (const pd of paths) {\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path.setAttribute('d', pd);\n path.setAttribute('fill', 'currentColor');\n if (opts?.fillRule) path.setAttribute('fill-rule', opts.fillRule);\n host.append(path);\n }\n el.append(host);\n return el;\n}\n\nfunction svg(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '18');\n el.setAttribute('height', '18');\n el.setAttribute('viewBox', '0 0 20 20');\n el.setAttribute('aria-hidden', 'true');\n el.innerHTML = inner;\n return el;\n}\nfunction svgTheme(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '18');\n el.setAttribute('height', '18');\n el.setAttribute('viewBox', '0 0 20 20');\n el.setAttribute('aria-hidden', 'true');\n el.innerHTML = inner;\n return el;\n}\n","import type { EmailDoc, Section } from '../types';\nimport { uid } from './id';\n\n/** 剪贴板 / 文件 interchange 信封标识 */\nexport const DOC_CLIPBOARD_KIND = 'simple-mail/doc' as const;\nexport const DOC_CLIPBOARD_FORMAT_VERSION = 1 as const;\n\nexport interface DocClipboardEnvelope {\n kind: typeof DOC_CLIPBOARD_KIND;\n formatVersion: typeof DOC_CLIPBOARD_FORMAT_VERSION;\n doc: EmailDoc;\n}\n\nexport function serializeDocClipboard(doc: EmailDoc): string {\n const envelope: DocClipboardEnvelope = {\n kind: DOC_CLIPBOARD_KIND,\n formatVersion: DOC_CLIPBOARD_FORMAT_VERSION,\n doc,\n };\n return JSON.stringify(envelope);\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction isEmailDocShape(v: unknown): v is EmailDoc {\n if (!isRecord(v)) return false;\n if (v.version !== '1') return false;\n if (!isRecord(v.meta)) return false;\n if (!Array.isArray(v.sections)) return false;\n for (const sec of v.sections) {\n if (!isRecord(sec) || !Array.isArray(sec.columns)) return false;\n for (const col of sec.columns) {\n if (!isRecord(col) || !Array.isArray(col.blocks)) return false;\n }\n }\n return true;\n}\n\n/**\n * 解析剪贴板或手动粘贴的 JSON。支持信封格式与裸 `EmailDoc`(version: '1')。\n */\nexport function parseDocClipboard(raw: string): EmailDoc | null {\n const trimmed = (raw || '').trim();\n if (!trimmed) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n return null;\n }\n if (!isRecord(parsed)) return null;\n\n if (parsed.kind === DOC_CLIPBOARD_KIND) {\n if (parsed.formatVersion !== DOC_CLIPBOARD_FORMAT_VERSION) return null;\n const doc = parsed.doc;\n if (!isEmailDocShape(doc)) return null;\n return structuredClone(doc);\n }\n\n if (isEmailDocShape(parsed)) {\n return structuredClone(parsed);\n }\n\n return null;\n}\n\n/** 导入前重生成 section / column / block id,避免与当前文档冲突。 */\nexport function regenerateDocIds(doc: EmailDoc): EmailDoc {\n const next = structuredClone(doc);\n next.sections = next.sections.map((sec) => remapSectionIds(sec));\n return next;\n}\n\nfunction remapSectionIds(sec: Section): Section {\n return {\n ...sec,\n id: uid('sec'),\n columns: sec.columns.map((col) => ({\n ...col,\n id: uid('col'),\n blocks: col.blocks.map((blk) => ({\n ...blk,\n id: uid('blk'),\n })),\n })),\n };\n}\n","import type { EmailDoc } from '../types';\nimport { h, clear } from '../utils/dom';\nimport { parseDocClipboard } from '../utils/docClipboard';\nimport { richTextExecCommand } from '../utils/richTextCommand';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface ImportDocModalOptions {\n /** 读取剪贴板初始内容(失败时返回空字符串) */\n readClipboard?: () => Promise<string>;\n onApply: (doc: EmailDoc) => void;\n t: SimpleMailT;\n}\n\n/**\n * 导入设计稿:展示 JSON 文本区,支持从剪贴板填入后覆盖当前画布。\n */\nexport class ImportDocModal {\n private modal: Modal;\n private textarea: HTMLTextAreaElement;\n private hintEl: HTMLElement;\n private opts: ImportDocModalOptions;\n\n constructor(opts: ImportDocModalOptions) {\n this.opts = opts;\n const t = opts.t;\n this.modal = new Modal({\n title: t('importDoc.title'),\n className: 'sm-modal--import-doc',\n width: 'min(720px, 96vw)',\n height: 'auto',\n t,\n });\n\n this.hintEl = h('p', { class: 'sm-import-doc__hint' }, [\n t('importDoc.hint1'),\n t('importDoc.hint2'),\n t('importDoc.hint3'),\n ]);\n\n this.textarea = h('textarea', {\n class: 'sm-import-doc__input',\n spellcheck: 'false',\n placeholder: t('importDoc.placeholder'),\n rows: '14',\n }) as HTMLTextAreaElement;\n\n this.modal.body.append(this.hintEl, this.textarea);\n\n const cancelBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this.modal.close() },\n [t('common.cancel')],\n );\n const pasteBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => void this._fillFromClipboard() },\n [t('importDoc.pasteFromClipboard')],\n );\n const applyBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => this._apply(),\n },\n [t('importDoc.apply')],\n );\n this.modal.footer.append(cancelBtn, pasteBtn, applyBtn);\n }\n\n async open(parent?: HTMLElement) {\n this.hintEl.classList.remove('sm-import-doc__hint--error');\n this.textarea.value = '';\n this.modal.open(parent);\n const initial = (await this.opts.readClipboard?.()) ?? '';\n if (initial.trim()) this.textarea.value = initial;\n }\n\n private async _fillFromClipboard() {\n const text = (await this.opts.readClipboard?.()) ?? '';\n if (!text.trim()) {\n this._setHint(this.opts.t('importDoc.clipboardEmpty'), true);\n return;\n }\n this.textarea.value = text;\n this._setHint(this.opts.t('importDoc.clipboardFilled'), false);\n }\n\n private _apply() {\n const raw = this.textarea.value.trim();\n if (!raw) {\n this._setHint(this.opts.t('importDoc.empty'), true);\n return;\n }\n const doc = parseDocClipboard(raw);\n if (!doc) {\n this._setHint(this.opts.t('importDoc.invalid'), true);\n return;\n }\n this.opts.onApply(doc);\n this.modal.close();\n }\n\n private _setHint(message: string, isError: boolean) {\n clear(this.hintEl);\n this.hintEl.classList.toggle('sm-import-doc__hint--error', isError);\n this.hintEl.append(message);\n }\n}\n\nexport async function readTextFromClipboard(): Promise<string> {\n try {\n return (await navigator.clipboard.readText()) || '';\n } catch {\n return '';\n }\n}\n\nexport async function writeTextToClipboard(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n const ta = document.createElement('textarea');\n ta.value = text;\n document.body.appendChild(ta);\n ta.select();\n const ok = richTextExecCommand('copy');\n document.body.removeChild(ta);\n return ok;\n }\n}\n","import { Registry, defineBlock } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport { Store, createSection, findBlockLocation, pruneSectionIfEmpty } from '../store/store';\nimport type {\n Block,\n BlockDefinition,\n EditorUiOptions,\n EmailDoc,\n RenderEngine,\n Selection,\n Variable,\n} from '../types';\nimport {\n buildLinkVariableHtml,\n normalizeVariable,\n variablePlaceholder,\n} from '../variables';\nimport { clear, h } from '../utils/dom';\nimport { appendInlineToRichHtml } from '../utils/richHtmlInsert';\nimport { Canvas } from './Canvas';\nimport { ExportModal } from './ExportModal';\nimport { LeftPanel } from './LeftPanel';\nimport { PreviewModal } from './PreviewModal';\nimport { RichTextToolbar } from './RichTextToolbar';\nimport { RightPanel } from './RightPanel';\nimport { SourceView } from './SourceView';\nimport { Topbar, type EditorMode } from './Topbar';\nimport type { EditorTheme } from './theme';\nimport type { ImageAssetsHandlers } from './imageAssets';\nimport { accentPrimarySoftRgba, normalizeAccentHex } from '../utils/accentColor';\nimport {\n parseDocClipboard,\n regenerateDocIds,\n serializeDocClipboard,\n} from '../utils/docClipboard';\nimport { ImportDocModal, readTextFromClipboard, writeTextToClipboard } from './ImportDocModal';\nimport {\n createI18nContext,\n type SimpleMailI18nContext,\n type SimpleMailLocale,\n type SimpleMailMessagesInput,\n type SimpleMailT,\n} from '../i18n';\n\nimport './styles.css';\n\nexport interface EditorOptions {\n /** 挂载点 */\n container: HTMLElement;\n /** 初始文档;不传时使用空文档 */\n initialDoc?: Partial<EmailDoc>;\n /** 自定义组件定义(除内置组件之外) */\n blocks?: BlockDefinition<any>[];\n /** 渲染引擎,目前仅 'mjml'。预留 'table' 切换 */\n engine?: RenderEngine;\n /**\n * 把 Block 拖到 sections 之间的空白处时,是否自动包一个一列 Section。\n * - true(默认):宽容,运营即使没瞄准列也能落下,自动加壳\n * - false:严格,只允许拖到现有列内;落到顶层会被 SortableJS 显示为禁止\n */\n autoWrapSection?: boolean;\n /**\n * 为 true 时:点击中栏灰色衬底、画布内空白(未点到 Section/块)等会提交内联编辑并清空选中,\n * 右栏回到文档级面板(邮件设置 / 版式与全局样式;若 `ui.hideMailMeta` 则仅版式与全局样式)。\n * 默认 false;需要「点空白取消选中」的宿主再设为 true。\n */\n clearSelectionOnCanvasMargin?: boolean;\n /** 文档变更回调(防抖发出) */\n onChange?: (doc: EmailDoc) => void;\n /**\n * 品牌/主题色(#RRGGBB),映射为界面上的 --sm-primary / --sm-primary-soft(强调、选区、主按钮等)。\n * 不传则使用 styles 里与 light/dark/system 配套的默认紫/靛。\n */\n accentColor?: string;\n /** 为 true 时在顶栏显示主题色拾取(原生 color 控件);默认 false,仅通过 accentColor / setAccentColor 由宿主控制也可 */\n showAccentColorPicker?: boolean;\n /**\n * 编辑器外框主题。`system` 随 `prefers-color-scheme`;邮件画布仍默认白纸以便预览成品。\n * @default 'light'\n */\n theme?: EditorTheme;\n /**\n * 可选。为 `type: 'image'` 提供上传 / 图库;`showUpload` 默认 true(有 uploadImage 时),`showGallery` 默认 false。\n */\n imageAssets?: ImageAssetsHandlers;\n /** 右栏控件形态等可选 UI 偏好。 */\n ui?: EditorUiOptions;\n /** 编辑器 UI 语言。默认 zh-CN。 */\n locale?: SimpleMailLocale;\n /** 覆盖或补充 simple-mail 内置文案。 */\n messages?: SimpleMailMessagesInput;\n /**\n * 顶栏「重置内容」恢复的目标文档(与 `initialDoc` 独立;编辑已保存邮件时仍应指向业务预置模板)。\n * 未传时与构造时的 `initialDoc` 合并结果一致。\n */\n presetDoc?: Partial<EmailDoc>;\n}\n\n/**\n * 编辑器主类。所有外部能力都通过它暴露。\n *\n * 使用示例(vanilla):\n * const editor = new MailEditor({\n * container: document.getElementById('app')!,\n * blocks: [/* 自定义组件 *\\/],\n * // imageAssets: { uploadImage, pickImageFromGallery, showGallery: true } // 可选,见 README\n * });\n * editor.setVariables([{ key: 'user.name', label: '用户名', sample: '张三' }]);\n * editor.export(); // -> { mjml, html }\n */\nexport class MailEditor {\n readonly store: Store;\n readonly registry: Registry;\n private opts: EditorOptions;\n private root: HTMLElement;\n private theme: EditorTheme;\n private mode: EditorMode = 'design';\n private topbar!: Topbar;\n private leftPanel!: LeftPanel;\n private canvas!: Canvas;\n private rightPanel!: RightPanel;\n private sourceView!: SourceView;\n private toolbar!: RichTextToolbar;\n private body: HTMLElement;\n /** 浮层(变量列表、toast),避免挂到 grid 的 .sm-root 上被挤成窄条 */\n private overlayLayer!: HTMLElement;\n /** design 态右栏变量列表:未固定时点击外部收起 */\n private variablePickerOutsideClick: ((ev: MouseEvent) => void) | null = null;\n private changeTimer: number | null = null;\n /** 显式品牌色时覆盖 CSS 变量;未设置则由 styles 按 light/dark 使用默认紫/靛 */\n private accentColorOverride: string | undefined;\n /** 顶栏开关:是否在画布上始终显示 Section / Block 轻量虚线边框 */\n private showLayoutBorders = false;\n /** 「重置内容」时恢复的文档快照(与当前画布内容无关) */\n private presetContentDoc: EmailDoc;\n /** 宿主通过 setVariables 注入的列表;setValue 恢复文档后仍会写回,避免被 doc JSON 里的空数组覆盖 */\n private configuredVariables: Variable[] = [];\n private importDocModal: ImportDocModal | null = null;\n private topbarLayoutObserver: ResizeObserver | null = null;\n private topbarLayoutRaf = 0;\n private systemThemeMq: MediaQueryList | null = null;\n private i18n: SimpleMailI18nContext;\n private readonly _onSystemThemeMqChange = () => {\n if (this.accentColorOverride) this._applyAccentVars();\n };\n\n private readonly _onFullscreenChange = () => {\n const fs = smGetFullscreenElement() === this.root;\n this.topbar?.setFullscreenActive(fs);\n this._syncTopbarLayout();\n };\n\n /** design 态 Esc:块 → 父级 Section → 文档级面板(邮件设置或版式/全局样式,取决于 `ui.hideMailMeta`) */\n private _mailEscHandler = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n if (this.rightPanel.isVariablePickerOpen()) {\n e.preventDefault();\n this._closeVariablePicker();\n return;\n }\n if (this.mode !== 'design') return;\n if (!this.store.selection) return;\n if (document.querySelector('.sm-modal__mask.is-open')) return;\n const t = e.target as HTMLElement | null;\n if (t?.closest?.('.sm-modal__mask')) return;\n const ae = document.activeElement as HTMLElement | null;\n if (ae && (ae.tagName === 'INPUT' || ae.tagName === 'TEXTAREA' || ae.isContentEditable)) return;\n if (ae && ae !== document.body && !this.root.contains(ae)) return;\n e.preventDefault();\n const sel = this.store.selection;\n if (sel.kind === 'block') {\n this.canvas.commitInlineEdit();\n this.store.setSelection({ kind: 'section', sectionId: sel.sectionId });\n return;\n }\n this._focusMailSettings();\n };\n\n /**\n * 文档级撤销/重做(捕获阶段)。\n * - 画布内联 contenteditable:交给浏览器撤销文字,不走 store。\n * - 右栏 input / CodeMirror:控件自带撤销,不走 store。\n * - 其余区域:在 store 有历史时拦截并 undo/redo 整份文档。\n */\n private _mailUndoRedoHandler = (e: KeyboardEvent) => {\n const meta = e.metaKey || e.ctrlKey;\n if (!meta) return;\n const k = e.key.toLowerCase();\n if (k !== 'z') return;\n const t = e.target as Node | null;\n if (!t || !this.root.contains(t)) return;\n if (this._shouldDeferToLocalUndoRedo(t)) return;\n const undo = !e.shiftKey;\n const redo = e.shiftKey;\n if (undo && !this.store.canUndo()) return;\n if (redo && !this.store.canRedo()) return;\n e.preventDefault();\n if (undo) this._storeUndo();\n else this._storeRedo();\n };\n\n /** 内联编辑、右栏表单等应使用控件/浏览器本地撤销,而非文档 history */\n private _shouldDeferToLocalUndoRedo(target: Node): boolean {\n const el =\n target instanceof Element ? target : (target.parentElement as Element | null);\n if (!el) return false;\n if (el.closest('.sm-inline-editing')) return true;\n if (el.closest('.cm-editor')) return true;\n const panelField = el.closest('.sm-panel--right input, .sm-panel--right textarea, .sm-panel--right select');\n if (panelField) return true;\n return false;\n }\n\n private _storeUndo() {\n if (this.canvas.isInlineEditing) this.canvas.abortInlineEdit();\n this._blurRightPanelIfFocused();\n this.store.undo();\n }\n\n private _storeRedo() {\n if (this.canvas.isInlineEditing) this.canvas.abortInlineEdit();\n this._blurRightPanelIfFocused();\n this.store.redo();\n }\n\n constructor(opts: EditorOptions) {\n this.opts = opts;\n this.i18n = createI18nContext({ locale: opts.locale, messages: opts.messages });\n this.registry = new Registry();\n\n // 注册外部 blocks\n if (opts.blocks) {\n for (const def of opts.blocks) this.registry.register(def);\n }\n\n const initialDoc = createDefaultDoc(opts.initialDoc);\n applyLocalizedDefaultMeta(initialDoc, opts.initialDoc, this.i18n.t);\n const presetSource = opts.presetDoc ?? opts.initialDoc;\n const presetContentDoc = createDefaultDoc(presetSource);\n applyLocalizedDefaultMeta(presetContentDoc, presetSource, this.i18n.t);\n this.presetContentDoc = structuredClone(presetContentDoc);\n this.store = new Store(initialDoc);\n\n const initialAccent = normalizeAccentHex(this.opts.accentColor ?? '');\n if (\n this.opts.accentColor != null &&\n String(this.opts.accentColor).trim() !== '' &&\n !initialAccent\n ) {\n console.warn('[simple-mail] accentColor 无效,已忽略:', this.opts.accentColor);\n }\n this.accentColorOverride = initialAccent ?? undefined;\n\n this.theme = opts.theme ?? 'light';\n this.root = h('div', { class: 'sm-root' });\n this._applyThemeAttr();\n this.body = h('div', { class: 'sm-body' });\n opts.container.append(this.root);\n\n this._buildUI();\n this._bindKeyboard();\n this._bindFullscreen();\n this._bindTopbarLayoutWatch();\n\n this._applyAccentVars();\n this._refreshAccentMqBinding();\n this._syncTopbarAccentPicker();\n\n this.store.subscribe(() => this._onChange());\n }\n\n /* ------------------------------ Public API ------------------------------ */\n\n setValue(doc: EmailDoc) {\n this._blurRightPanelIfFocused();\n this.store.replace(doc);\n this._applyConfiguredVariables();\n }\n\n getValue(): EmailDoc {\n return this.store.doc;\n }\n\n /**\n * 清空画布:移除所有 Section/Block,保留 meta、styles、variables。\n * 会提交内联编辑并清空选中。\n */\n clearCanvas(): void {\n this.canvas.commitInlineEdit();\n this._blurRightPanelIfFocused();\n this.store.update((d) => {\n d.sections = [];\n });\n this.store.setSelection(null);\n }\n\n /**\n * 将画布恢复为 `presetDoc` 快照(未传时等同构造时的预置合并结果)。\n * 记入撤销栈(⌘Z 可恢复);与 `setValue` 不同,不会清空 history。\n */\n resetToPreset(): void {\n this.canvas.commitInlineEdit();\n this._blurRightPanelIfFocused();\n const preset = structuredClone(this.presetContentDoc);\n const configuredVars = this.configuredVariables.length\n ? this.configuredVariables.map((v) => ({ ...v }))\n : null;\n this.store.update((d) => {\n Object.assign(d, preset);\n if (configuredVars) d.variables = configuredVars;\n });\n this.store.setSelection(null);\n }\n\n /** 更新「重置内容」的目标(例如宿主异步加载默认模板后)。 */\n setPresetDoc(partial: Partial<EmailDoc>): void {\n const presetDoc = createDefaultDoc(partial);\n applyLocalizedDefaultMeta(presetDoc, partial, this.i18n.t);\n this.presetContentDoc = structuredClone(presetDoc);\n }\n\n setVariables(vars: Variable[]) {\n this.configuredVariables = vars.map(normalizeVariable);\n this._applyConfiguredVariables();\n }\n\n getVariables(): Variable[] {\n if (this.configuredVariables.length) return this.configuredVariables;\n return this.store.doc.variables;\n }\n\n private _applyConfiguredVariables() {\n if (!this.configuredVariables.length) return;\n const snapshot = this.configuredVariables.map((v) => ({ ...v }));\n this.store.update((d) => {\n d.variables = snapshot;\n });\n }\n\n /**\n * 插入变量 key(`{{key}}`)。\n * @returns 是否成功插入\n */\n insertVariableKey(v: Variable): boolean {\n const normalized = normalizeVariable(v);\n return this._insertAtFocus(variablePlaceholder(normalized.key), false);\n }\n\n /**\n * 插入链接 / 图片变量对应元素(`<a>` / image 块等)。\n * 非 link/image 时退化为 insertVariableKey。\n */\n insertVariableElement(v: Variable): boolean {\n const normalized = normalizeVariable(v);\n if (normalized.kind === 'image') {\n return this._insertImageVariable(normalized);\n }\n if (normalized.kind === 'link') {\n const token = variablePlaceholder(normalized.key);\n if (this._tryApplyLinkVariableToken(token)) return true;\n const html = buildLinkVariableHtml(\n token,\n this.store.doc.styles.linkColor || '#ff5a00',\n );\n return this._insertAtFocus(html, true);\n }\n return this.insertVariableKey(normalized);\n }\n\n /** 同 {@link insertVariableKey} */\n insertVariable(v: Variable): boolean {\n return this.insertVariableKey(v);\n }\n\n /** 当前界面主题(`system` 不解析为 light/dark)。 */\n getTheme(): EditorTheme {\n return this.theme;\n }\n\n /** 切换界面主题;写入 `data-sm-theme`,顶栏选择器同步。 */\n setTheme(t: EditorTheme) {\n if (this.theme === t) return;\n this.theme = t;\n this._applyThemeAttr();\n this._applyAccentVars();\n this._refreshAccentMqBinding();\n this.topbar?.syncTheme(t);\n this._syncTopbarAccentPicker();\n }\n\n /**\n * 品牌/主题色(#RRGGBB)。传 null、undefined 或空字符串则恢复为 light/dark/system 下的 CSS 默认色。\n */\n setAccentColor(hex: string | null | undefined) {\n if (hex == null || String(hex).trim() === '') {\n this.accentColorOverride = undefined;\n } else {\n const n = normalizeAccentHex(String(hex));\n if (!n) {\n console.warn('[simple-mail] setAccentColor 无效,已忽略:', hex);\n return;\n }\n this.accentColorOverride = n;\n }\n this._applyAccentVars();\n this._refreshAccentMqBinding();\n this._syncTopbarAccentPicker();\n }\n\n /** 当前由选项或 setAccentColor 显式设置的品牌色;未覆盖时为 undefined。 */\n getAccentColor(): string | undefined {\n return this.accentColorOverride;\n }\n\n /** 导出 MJML 与编译后的 HTML。withSampleVariables=true 时把 {{var}} 替换为 sample 值用于预览。 */\n export(opts: { withSampleVariables?: boolean } = {}) {\n return renderDoc(this.store.doc, this.registry, {\n engine: this.opts.engine ?? 'mjml',\n withSampleVariables: opts.withSampleVariables ?? false,\n });\n }\n\n /**\n * 将当前画布设计稿(EmailDoc JSON 信封)写入剪贴板,供另一实例「导入设计稿」使用。\n */\n async copyDocDesign(): Promise<boolean> {\n this.canvas.commitInlineEdit();\n const ok = await writeTextToClipboard(serializeDocClipboard(this.store.doc));\n this._showToast(ok ? this.i18n.t('toast.copyDesignOk') : this.i18n.t('toast.copyDesignFailed'));\n return ok;\n }\n\n /** 打开导入设计稿对话框(从剪贴板或手动粘贴 JSON,覆盖当前画布)。 */\n openImportDocDesign(): void {\n this.canvas.commitInlineEdit();\n this._ensureImportDocModal();\n void this.importDocModal!.open(this.root);\n }\n\n /**\n * 程序化导入设计稿(与对话框「应用」相同逻辑)。\n * @returns 是否成功解析并应用\n */\n importDocDesignFromJson(raw: string): boolean {\n const parsed = parseDocClipboard(raw);\n if (!parsed) return false;\n this._applyImportedDoc(parsed);\n return true;\n }\n\n registerBlock<P extends object>(def: BlockDefinition<P>) {\n this.registry.register(def);\n this.leftPanel?.refresh();\n }\n\n setSelection(sel: Selection | null) {\n this.store.setSelection(sel);\n }\n\n destroy() {\n this._closeVariablePicker();\n this._unbindFullscreen();\n this._unbindTopbarLayoutWatch();\n this._unbindSystemThemeMqForAccent();\n if (this.changeTimer) window.clearTimeout(this.changeTimer);\n if (smGetFullscreenElement() === this.root) void smExitFullscreen();\n document.removeEventListener('keydown', this._mailEscHandler, true);\n document.removeEventListener('keydown', this._mailUndoRedoHandler, true);\n this.canvas?.destroy?.();\n this.sourceView?.destroy?.();\n this.toolbar?.destroy?.();\n this.root.remove();\n }\n\n /* -------------------------------- 私有 ---------------------------------- */\n\n private _applyThemeAttr() {\n this.root.setAttribute('data-sm-theme', this.theme);\n }\n\n private _chromeIsEffectivelyDark(): boolean {\n if (this.theme === 'dark') return true;\n if (this.theme === 'light') return false;\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n private _applyAccentVars() {\n if (!this.accentColorOverride) {\n this.root.style.removeProperty('--sm-primary');\n this.root.style.removeProperty('--sm-primary-soft');\n return;\n }\n const dark = this._chromeIsEffectivelyDark();\n this.root.style.setProperty('--sm-primary', this.accentColorOverride);\n this.root.style.setProperty('--sm-primary-soft', accentPrimarySoftRgba(this.accentColorOverride, dark));\n }\n\n private _unbindSystemThemeMqForAccent() {\n if (this.systemThemeMq) {\n this.systemThemeMq.removeEventListener('change', this._onSystemThemeMqChange);\n this.systemThemeMq = null;\n }\n }\n\n /** `system` 主题且存在品牌色覆盖时,随系统深浅刷新 --sm-primary-soft */\n private _refreshAccentMqBinding() {\n this._unbindSystemThemeMqForAccent();\n if (this.theme === 'system' && this.accentColorOverride) {\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n mq.addEventListener('change', this._onSystemThemeMqChange);\n this.systemThemeMq = mq;\n }\n }\n\n private _syncTopbarAccentPicker() {\n this.topbar?.syncAccentPicker();\n }\n\n private _buildUI() {\n this.topbar = new Topbar({\n store: this.store,\n t: this.i18n.t,\n mode: this.mode,\n theme: this.theme,\n accentPickerRoot: this.root,\n showAccentColorPicker: this.opts.showAccentColorPicker === true,\n onAccentChange: (hx) => this.setAccentColor(hx),\n onThemeChange: (t) => this.setTheme(t),\n onModeChange: (m) => this._setMode(m),\n onUndo: () => {\n this._storeUndo();\n },\n onRedo: () => {\n this._storeRedo();\n },\n onMailSettings: () => this._focusMailSettings(),\n showMailSettingsButton: this.opts.ui?.hideTopbarMailSettings !== true,\n showTitle: this.opts.ui?.hideTopbarTitle !== true,\n showInsertVariableButton: this.opts.ui?.hideTopbarInsertVariable !== true,\n onInsertVariable: (anchor) => this._toggleVariablePanel(anchor),\n onPreview: () => this._showPreview(),\n onExport: () => this._showExport(),\n showFullscreenButton: this.opts.ui?.hideTopbarFullscreen !== true,\n onFullscreenToggle: () => void this._toggleFullscreen(),\n onLayoutBordersToggle: () => this._toggleLayoutBorders(),\n showClearCanvasButton: this.opts.ui?.hideTopbarClearCanvas !== true,\n onClearCanvas: () => this.clearCanvas(),\n showResetContentButton: this.opts.ui?.hideTopbarResetContent !== true,\n onResetContent: () => this.resetToPreset(),\n showDocClipboardButtons: this.opts.ui?.hideTopbarDocClipboard !== true,\n onCopyDocDesign: () => void this.copyDocDesign(),\n onImportDocDesign: () => this.openImportDocDesign(),\n compact: !topbarPrefersLabels(this.opts.ui, this._topbarLayoutContext()),\n });\n\n this.toolbar = new RichTextToolbar({ positionRoot: this.root, t: this.i18n.t });\n const ui = this.opts.ui;\n this.leftPanel = new LeftPanel({\n registry: this.registry,\n t: this.i18n.t,\n blockGroupTitle:\n ui?.paletteBlockGroupTitle ?? ui?.blockCategoryLabels?.content,\n customPaletteTooltipSuffix: ui?.customPaletteTooltipSuffix,\n hiddenPaletteBlockTypes: ui?.hiddenPaletteBlockTypes,\n });\n const autoWrap = this.opts.autoWrapSection !== false;\n this.root.classList.toggle('sm-allow-auto-wrap', autoWrap);\n this.canvas = new Canvas({\n store: this.store,\n registry: this.registry,\n toolbar: this.toolbar,\n autoWrapSection: autoWrap,\n clearSelectionOnCanvasMargin: this.opts.clearSelectionOnCanvasMargin === true,\n layerRoot: this.root,\n ui: this.opts.ui,\n t: this.i18n.t,\n });\n this.rightPanel = new RightPanel({\n store: this.store,\n registry: this.registry,\n docRootLabel: this.opts.ui?.hideMailMeta\n ? this.i18n.t('rightPanel.docRoot.layout')\n : this.i18n.t('rightPanel.docRoot.mail'),\n onFocusSection: (sectionId) => {\n this.canvas.commitInlineEdit();\n this.store.setSelection({ kind: 'section', sectionId });\n },\n onFocusDocument: () => this._focusMailSettings(),\n imageAssets: this.opts.imageAssets,\n ui: this.opts.ui,\n t: this.i18n.t,\n });\n this.sourceView = new SourceView({\n store: this.store,\n registry: this.registry,\n t: this.i18n.t,\n });\n\n this.body.append(this.leftPanel.el, this.canvas.el, this.rightPanel.el);\n this.overlayLayer = h('div', { class: 'sm-overlay-layer' });\n this.root.append(this.topbar.el, this.body, this.overlayLayer);\n }\n\n /** 撤销/替换文档前先失焦右栏,否则 RightPanel 会因「保留焦点」跳过重绘而仍显示旧值 */\n private _blurRightPanelIfFocused() {\n const ae = document.activeElement as HTMLElement | null;\n if (ae && this.rightPanel.el.contains(ae)) ae.blur();\n }\n\n /** 提交内联编辑并清空选中,右栏回到文档级面板 */\n private _focusMailSettings() {\n this._closeVariablePicker();\n this.canvas.commitInlineEdit();\n this.store.setSelection(null);\n }\n\n private _setMode(m: EditorMode) {\n if (this.mode === m) return;\n this._closeVariablePicker();\n this._dismissVariablePopover();\n if (m !== 'design') this.canvas.commitInlineEdit();\n this.mode = m;\n this.topbar.setMode(m);\n clear(this.body);\n if (m === 'design') {\n this.body.classList.remove('sm-body--source');\n this.body.style.removeProperty('grid-template-columns');\n this.body.append(this.leftPanel.el, this.canvas.el, this.rightPanel.el);\n } else {\n this.body.classList.add('sm-body--source');\n this.body.style.removeProperty('grid-template-columns');\n this.body.append(this.sourceView.el);\n // 见 SourceView.refreshDoc:设计态源码面板未挂载时不更新,否则会一直显示构造函数时的旧快照\n queueMicrotask(() => this.sourceView.refreshDoc());\n }\n }\n\n private _bindKeyboard() {\n this.root.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' || e.key === 'Backspace') {\n const tag = (e.target as HTMLElement).tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || (e.target as HTMLElement).isContentEditable) {\n return;\n }\n const sel = this.store.selection;\n if (!sel) return;\n e.preventDefault();\n if (sel.kind === 'section') {\n this.store.update((d) => {\n d.sections = d.sections.filter((s) => s.id !== sel.sectionId);\n });\n this.store.setSelection(null);\n } else {\n this.store.update((d) => {\n const sec = d.sections.find((s) => s.id === sel.sectionId);\n if (!sec) return;\n const col = sec.columns[sel.columnIndex];\n if (!col) return;\n col.blocks = col.blocks.filter((b) => b.id !== sel.blockId);\n pruneSectionIfEmpty(d, sel.sectionId);\n });\n this.store.setSelection(null);\n }\n }\n });\n document.addEventListener('keydown', this._mailUndoRedoHandler, true);\n document.addEventListener('keydown', this._mailEscHandler, true);\n this.root.tabIndex = 0;\n }\n\n private _onChange() {\n if (!this.opts.onChange) return;\n if (this.changeTimer) window.clearTimeout(this.changeTimer);\n this.changeTimer = window.setTimeout(() => {\n this.opts.onChange?.(this.store.doc);\n this.changeTimer = null;\n }, 60) as unknown as number;\n }\n\n private _unbindVariablePickerOutsideClick() {\n if (!this.variablePickerOutsideClick) return;\n document.removeEventListener('click', this.variablePickerOutsideClick, true);\n this.variablePickerOutsideClick = null;\n }\n\n private _bindVariablePickerOutsideClick(anchor: HTMLElement) {\n this._unbindVariablePickerOutsideClick();\n const handler = (ev: MouseEvent) => {\n if (!this.rightPanel.isVariablePickerOpen() || this.rightPanel.isVariablePickerPinned()) return;\n const target = ev.target as Node;\n if (this.rightPanel.el.contains(target)) return;\n if (anchor.contains(target) || target === anchor) return;\n this._closeVariablePicker();\n };\n this.variablePickerOutsideClick = handler;\n setTimeout(() => {\n if (this.variablePickerOutsideClick === handler) {\n document.addEventListener('click', handler, true);\n }\n }, 0);\n }\n\n private _closeVariablePicker() {\n this._unbindVariablePickerOutsideClick();\n if (!this.rightPanel.isVariablePickerOpen()) return;\n this.rightPanel.closeVariablePicker();\n this.topbar.setInsertVariableActive(false);\n }\n\n private _toggleVariablePanel(anchor: HTMLElement) {\n this.canvas.currentInlineEditor?.saveSelection();\n\n const vars = this.getVariables();\n if (!vars.length) {\n this._showToast(this.i18n.t('toast.noVariables'));\n return;\n }\n\n if (this.mode === 'design') {\n if (this.rightPanel.isVariablePickerOpen()) {\n this._closeVariablePicker();\n return;\n }\n this._dismissVariablePopover();\n this._blurRightPanelIfFocused();\n this.rightPanel.openVariablePicker(vars, {\n onPickKey: (v) => {\n this.insertVariableKey(v);\n if (!this.rightPanel.isVariablePickerPinned()) this._closeVariablePicker();\n },\n onPickElement: (v) => {\n this.insertVariableElement(v);\n if (!this.rightPanel.isVariablePickerPinned()) this._closeVariablePicker();\n },\n onCopy: (token) => {\n void copyVariableToken(token).then((ok) => {\n if (!ok) return;\n this._showToast(this.i18n.t('toast.variableCopied'));\n });\n },\n onClose: () => this._closeVariablePicker(),\n });\n this._bindVariablePickerOutsideClick(anchor);\n this.topbar.setInsertVariableActive(true);\n return;\n }\n\n this._toggleVariablePopover(anchor, vars);\n }\n\n private _dismissVariablePopover() {\n this.overlayLayer.querySelector('.sm-popover')?.remove();\n }\n\n /** 源码模式无右栏时仍用浮层选择变量 */\n private _toggleVariablePopover(anchor: HTMLElement, vars: Variable[]) {\n const existing = this.overlayLayer.querySelector('.sm-popover');\n if (existing) {\n existing.remove();\n this.topbar.setInsertVariableActive(false);\n return;\n }\n\n const pop = h('div', { class: 'sm-popover sm-popover--variables' });\n let onDocClick: ((ev: MouseEvent) => void) | null = null;\n const dismissPopover = () => {\n pop.remove();\n if (onDocClick) document.removeEventListener('click', onDocClick, true);\n this.topbar.setInsertVariableActive(false);\n };\n\n for (const v of vars) {\n const token = variablePlaceholder(v.key);\n const row = h('div', { class: 'sm-popover__row' });\n const actions = h('div', { class: 'sm-popover__actions' });\n if (v.kind === 'link' || v.kind === 'image') {\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action',\n type: 'button',\n onclick: (e: Event) => {\n e.stopPropagation();\n this.insertVariableElement(v);\n dismissPopover();\n },\n },\n [this.i18n.t('variablePicker.insertElement')],\n ),\n );\n }\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action sm-popover__action--copy',\n type: 'button',\n title: this.i18n.t('variablePicker.copyTitle', { token }),\n onclick: (e: Event) => {\n e.stopPropagation();\n void copyVariableToken(token).then((ok) => {\n if (!ok) return;\n dismissPopover();\n this._showToast(this.i18n.t('toast.variableCopied'));\n });\n },\n },\n [this.i18n.t('common.copy')],\n ),\n );\n row.append(\n h(\n 'button',\n {\n class: 'sm-popover__item',\n type: 'button',\n onclick: () => {\n this.insertVariableKey(v);\n dismissPopover();\n },\n },\n [\n h('span', { class: 'sm-popover__label' }, [v.label]),\n h('span', { class: 'sm-popover__key' }, [token]),\n ],\n ),\n actions,\n );\n pop.append(row);\n }\n\n this.overlayLayer.append(pop);\n positionAnchoredLayer(pop, anchor, this.root);\n\n onDocClick = (ev: MouseEvent) => {\n if (!pop.contains(ev.target as Node) && ev.target !== anchor) {\n dismissPopover();\n }\n };\n setTimeout(() => {\n if (onDocClick) document.addEventListener('click', onDocClick, true);\n }, 0);\n this.topbar.setInsertVariableActive(true);\n }\n\n private _showToast(text: string) {\n const t = h('div', { class: 'sm-toast' }, [text]);\n this.overlayLayer.append(t);\n requestAnimationFrame(() => t.classList.add('is-visible'));\n setTimeout(() => {\n t.classList.remove('is-visible');\n setTimeout(() => t.remove(), 200);\n }, 1400);\n }\n\n private _insertImageVariable(v: Variable): boolean {\n const token = variablePlaceholder(v.key);\n const block = this.registry.createBlock('image');\n const props = block.props as { src: string; alt: string };\n props.src = token;\n props.alt = v.label?.trim() || v.key;\n const sel = this.store.selection;\n this.store.update((d) => {\n this._insertBlockRelativeToSelection(d, sel, block);\n });\n return true;\n }\n\n /**\n * 按当前选中插入块:block → 其后;section → 该 section 首列末尾;无选中 → 文档最后一节首列末尾。\n */\n private _insertBlockRelativeToSelection(\n d: EmailDoc,\n sel: Selection | null,\n block: Block,\n ): void {\n if (sel?.kind === 'block') {\n const sec = d.sections.find((s) => s.id === sel.sectionId);\n const col = sec?.columns[sel.columnIndex];\n if (col) {\n const idx = col.blocks.findIndex((b) => b.id === sel.blockId);\n col.blocks.splice(idx >= 0 ? idx + 1 : col.blocks.length, 0, block);\n return;\n }\n }\n if (sel?.kind === 'section') {\n const sec = d.sections.find((s) => s.id === sel.sectionId);\n sec?.columns[0]?.blocks.push(block);\n return;\n }\n let section = d.sections[d.sections.length - 1];\n if (!section) {\n section = createSection('1');\n d.sections.push(section);\n }\n section.columns[0]?.blocks.push(block);\n }\n\n /** 链接变量:写入图片/按钮等块的 `href`(MJML 可点击),而非 alt 或右栏纯文本。 */\n private _tryApplyLinkVariableToken(token: string): boolean {\n const active = document.activeElement as HTMLInputElement | HTMLTextAreaElement | null;\n if (\n active &&\n (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA') &&\n this.root.contains(active)\n ) {\n const focusToken = active.getAttribute('data-sm-focus');\n if (focusToken?.startsWith('block:')) {\n const parts = focusToken.split(':');\n const blockId = parts[1];\n const propKey = parts[2];\n if (blockId && propKey && this._setBlockUrlProp(blockId, propKey, token)) {\n active.value = token;\n active.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n }\n }\n\n const sel = this.store.selection;\n if (sel?.kind !== 'block') return false;\n const loc = findBlockLocation(this.store.doc, sel.blockId);\n if (!loc) return false;\n const urlKey = this._schemaUrlPropKey(this.registry.get(loc.block.type));\n if (!urlKey) return false;\n this.store.update((d) => {\n const l = findBlockLocation(d, sel.blockId);\n if (l) (l.block.props as Record<string, unknown>)[urlKey] = token;\n });\n return true;\n }\n\n private _schemaUrlPropKey(def: BlockDefinition | undefined): string | undefined {\n return def?.schema.find((f) => f.type === 'url')?.key;\n }\n\n private _setBlockUrlProp(blockId: string, propKey: string, token: string): boolean {\n const loc = findBlockLocation(this.store.doc, blockId);\n if (!loc) return false;\n const field = this.registry.get(loc.block.type)?.schema.find((f) => f.key === propKey);\n if (field?.type !== 'url') return false;\n this.store.update((d) => {\n const l = findBlockLocation(d, blockId);\n if (l) (l.block.props as Record<string, unknown>)[propKey] = token;\n });\n return true;\n }\n\n /** 在焦点处插入文本或 HTML;失败时返回 false */\n private _insertAtFocus(content: string, asHtml: boolean): boolean {\n const inline = this.canvas.currentInlineEditor;\n if (inline) {\n if (asHtml) inline.insertHtml(content);\n else inline.insertText(content);\n return true;\n }\n\n const active = document.activeElement as HTMLInputElement | HTMLTextAreaElement | null;\n if (\n active &&\n (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA') &&\n this.root.contains(active)\n ) {\n if (asHtml) {\n const focusToken = active.getAttribute('data-sm-focus');\n if (focusToken?.startsWith('block:')) {\n const parts = focusToken.split(':');\n const blockId = parts[1];\n const propKey = parts[2];\n if (blockId && propKey) {\n const m = content.match(/\\{\\{[^}]+\\}\\}/);\n const token = m?.[0] ?? content;\n if (this._setBlockUrlProp(blockId, propKey, token)) {\n active.value = token;\n active.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n }\n }\n /* 链接 HTML 不写入 alt 等右栏文本框,落到下方新建文本块 */\n } else {\n const start = active.selectionStart ?? active.value.length;\n const end = active.selectionEnd ?? active.value.length;\n active.value = active.value.slice(0, start) + content + active.value.slice(end);\n active.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n }\n\n const sel = this.store.selection;\n if (sel?.kind === 'block') {\n let updated = false;\n this.store.update((d) => {\n for (const s of d.sections) {\n for (const c of s.columns) {\n const b = c.blocks.find((x) => x.id === sel.blockId);\n if (!b) continue;\n const def = this.registry.get(b.type);\n const key = def?.inlineEditable?.propKey;\n if (!key) continue;\n const cur = String((b.props as Record<string, unknown>)[key] ?? '');\n const richInline = def.inlineEditable!.mode !== 'plain';\n (b.props as Record<string, unknown>)[key] = richInline\n ? appendInlineToRichHtml(cur, content)\n : cur + content;\n updated = true;\n }\n }\n });\n if (updated) return true;\n }\n\n const block = this.registry.createBlock('text');\n const wrapped = appendInlineToRichHtml('', content);\n (block.props as { content: string }).content = wrapped;\n this.store.update((d) => {\n this._insertBlockRelativeToSelection(d, sel, block);\n });\n return true;\n }\n\n private _ensureImportDocModal() {\n if (this.importDocModal) return;\n this.importDocModal = new ImportDocModal({\n readClipboard: readTextFromClipboard,\n onApply: (doc) => this._applyImportedDoc(doc),\n t: this.i18n.t,\n });\n }\n\n private _applyImportedDoc(source: EmailDoc) {\n const current = this.store.doc;\n let next = regenerateDocIds(source);\n if (this.opts.ui?.hideMailMeta) {\n next = {\n ...next,\n meta: { ...current.meta },\n };\n }\n this.setValue(next);\n this.store.setSelection(null);\n this._showToast(this.i18n.t('toast.importDesignOk'));\n }\n\n private _showExport() {\n // 切回设计模式时如果还在内联编辑,先把内容提交进 store\n this.canvas.commitInlineEdit();\n const modal = new ExportModal({\n store: this.store,\n registry: this.registry,\n t: this.i18n.t,\n withSampleVariables: false,\n });\n modal.open(this.root);\n }\n\n private _showPreview() {\n this.canvas.commitInlineEdit();\n const modal = new PreviewModal({\n store: this.store,\n registry: this.registry,\n t: this.i18n.t,\n });\n modal.open(this.root);\n }\n\n private _topbarLayoutContext(): TopbarLayoutContext {\n return {\n fullscreenOnRoot: smGetFullscreenElement() === this.root,\n rootWidth: this.root.clientWidth,\n };\n }\n\n private _syncTopbarLayout() {\n const bar = this.topbar;\n if (!bar) return;\n const ctx = this._topbarLayoutContext();\n if (!topbarPrefersLabels(this.opts.ui, ctx)) {\n bar.setCompact(true);\n return;\n }\n // 在同一帧内展开并测量溢出,避免先展示文案、下一帧再收起的闪烁\n bar.setCompact(false);\n const el = bar.el;\n if (el.scrollWidth > el.clientWidth + 2) bar.setCompact(true);\n }\n\n private _bindTopbarLayoutWatch() {\n if (this.opts.ui?.topbarCompact !== true) return;\n this._syncTopbarLayout();\n this.topbarLayoutObserver = new ResizeObserver(() => {\n if (this.topbarLayoutRaf) cancelAnimationFrame(this.topbarLayoutRaf);\n this.topbarLayoutRaf = requestAnimationFrame(() => {\n this.topbarLayoutRaf = 0;\n this._syncTopbarLayout();\n });\n });\n this.topbarLayoutObserver.observe(this.root);\n }\n\n private _unbindTopbarLayoutWatch() {\n this.topbarLayoutObserver?.disconnect();\n this.topbarLayoutObserver = null;\n if (this.topbarLayoutRaf) {\n cancelAnimationFrame(this.topbarLayoutRaf);\n this.topbarLayoutRaf = 0;\n }\n }\n\n private _bindFullscreen() {\n if (this.opts.ui?.hideTopbarFullscreen === true) return;\n document.addEventListener('fullscreenchange', this._onFullscreenChange);\n document.addEventListener('webkitfullscreenchange', this._onFullscreenChange);\n this._onFullscreenChange();\n }\n\n private _unbindFullscreen() {\n document.removeEventListener('fullscreenchange', this._onFullscreenChange);\n document.removeEventListener('webkitfullscreenchange', this._onFullscreenChange);\n }\n\n private async _toggleFullscreen() {\n try {\n if (smGetFullscreenElement() === this.root) await smExitFullscreen();\n else await smRequestFullscreen(this.root);\n } catch (err) {\n console.warn('[simple-mail] 全屏不可用:', err);\n }\n }\n\n private _toggleLayoutBorders() {\n this.showLayoutBorders = !this.showLayoutBorders;\n this.root.classList.toggle('sm-show-layout-borders', this.showLayoutBorders);\n this.topbar.setLayoutBordersActive(this.showLayoutBorders);\n }\n}\n\n/** 在 .sm-root 坐标系下定位浮层,靠右的锚点右对齐,并限制在根节点内 */\nfunction positionAnchoredLayer(layer: HTMLElement, anchor: HTMLElement, root: HTMLElement) {\n const rect = anchor.getBoundingClientRect();\n const rootRect = root.getBoundingClientRect();\n const gap = 4;\n const margin = 8;\n layer.style.top = `${rect.bottom - rootRect.top + gap}px`;\n const w = layer.offsetWidth;\n let left = rect.left - rootRect.left;\n const anchorMid = rect.left + rect.width * 0.5;\n const rootMid = rootRect.left + rootRect.width * 0.5;\n if (anchorMid >= rootMid) {\n left = rect.right - rootRect.left - w;\n }\n left = Math.max(margin, Math.min(left, rootRect.width - w - margin));\n layer.style.left = `${left}px`;\n}\n\nexport const DEFAULT_TOPBAR_COMPACT_MIN_WIDTH = 1200;\n\nexport interface TopbarLayoutContext {\n fullscreenOnRoot: boolean;\n rootWidth: number;\n}\n\n/** 顶栏是否应展示按钮文案(紧凑模式下的策略;非 compact 配置恒为 true) */\nexport function topbarPrefersLabels(\n ui: EditorUiOptions | undefined,\n ctx: TopbarLayoutContext,\n): boolean {\n if (ui?.topbarCompact !== true) return true;\n const labels = ui.topbarLabels ?? 'auto';\n if (labels === 'always') return true;\n if (labels === 'never') return false;\n const minW = ui.topbarCompactMinWidth ?? DEFAULT_TOPBAR_COMPACT_MIN_WIDTH;\n return ctx.fullscreenOnRoot || ctx.rootWidth >= minW;\n}\n\nasync function copyVariableToken(token: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(token);\n return true;\n } catch {\n // fallback\n }\n try {\n const ta = document.createElement('textarea');\n ta.value = token;\n ta.setAttribute('readonly', 'true');\n ta.style.position = 'fixed';\n ta.style.left = '-9999px';\n document.body.appendChild(ta);\n ta.select();\n const ok = document.execCommand('copy');\n document.body.removeChild(ta);\n return ok;\n } catch {\n return false;\n }\n}\n\nfunction smGetFullscreenElement(): Element | null {\n const d = document as Document & { webkitFullscreenElement?: Element | null };\n return document.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n}\n\nasync function smRequestFullscreen(el: HTMLElement): Promise<void> {\n const anyEl = el as HTMLElement & { webkitRequestFullscreen?: () => Promise<void> | void };\n if (typeof anyEl.requestFullscreen === 'function') await anyEl.requestFullscreen();\n else if (typeof anyEl.webkitRequestFullscreen === 'function') await anyEl.webkitRequestFullscreen();\n}\n\nasync function smExitFullscreen(): Promise<void> {\n const d = document as Document & { webkitExitFullscreen?: () => Promise<void> | void };\n if (typeof document.exitFullscreen === 'function') await document.exitFullscreen();\n else if (typeof d.webkitExitFullscreen === 'function') await d.webkitExitFullscreen();\n}\n\n/* ----------------------------- 默认空文档 ------------------------------- */\n\nfunction applyLocalizedDefaultMeta(\n doc: EmailDoc,\n source: Partial<EmailDoc> | undefined,\n t: SimpleMailT,\n): void {\n if (source?.meta?.subject == null) doc.meta.subject = t('doc.defaultSubject');\n}\n\nfunction createDefaultDoc(partial?: Partial<EmailDoc>): EmailDoc {\n const mergedStyles = {\n backgroundColor: '#ffffff',\n contentBackgroundColor: '#ffffff',\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"PingFang SC\", \"Microsoft YaHei\", sans-serif',\n fontSize: '16px',\n fontWeight: '400',\n color: '#433f3f',\n linkColor: '#ff5a00',\n lineHeight: '1.25',\n ...(partial?.styles ?? {}),\n };\n return {\n version: '1',\n meta: {\n subject: '一封新邮件',\n preheader: '',\n width: 600,\n ...(partial?.meta ?? {}),\n },\n variables: partial?.variables ?? [],\n styles: {\n ...mergedStyles,\n fontWeight: mergedStyles.fontWeight ?? '400',\n lineHeight: mergedStyles.lineHeight ?? '1.25',\n },\n sections: partial?.sections ?? [],\n };\n}\n\nexport { defineBlock };\n"],"names":["Registry","__publicField","def","type","category","d","cryptoRandomId","ts","rand","defineBlock","DYNAMIC_VARIANT_HTML_ATTR","getSectionDynamicVariantKey","section","isDynamicVariantSection","dynamicVariantPlaceholder","key","sectionMjClassName","sectionId","serializeParsedHtml","doc","head","_a","body","_b","annotateDynamicVariantHtmlAttributes","html","slots","parsed","cls","candidates","target","el","LIST_GAP_ATTR","findListItem","node","root","findListRoot","li","parent","isIgnorableListSeparator","clone","br","findPreviousListOfSameType","list","findNextListOfSameType","mergeListInto","source","next","mergeAdjacentSameTypeLists","merged","prev","isLiEffectivelyEmpty","isCaretAtLiStart","range","probe","fragmentHasSubstantiveText","frag","box","isCaretAtLiEnd","after","placeCaretInElement","atStart","sel","placeCaretAtEndOfElement","visibleTextLength","text","getCaretTextOffset","container","setCaretByTextOffset","offset","walker","remaining","textNode","data","len","count","nodeOffset","i","getElementVisibleTextLength","CARET_MARKER_ATTR","RANGE_START_MARKER_ATTR","insertBoundaryMarker","attr","marker","insertSelectionBoundaryMarkers","startRange","endRange","removeSelectionBoundaryMarkers","m","getCaretTextOffsetAtRangeEnd","atEnd","restoreCaretMarker","normalizeSelectionSpan","start","end","listInSelectionSpan","anchor","far","afterAnchor","beforeFar","lastListInDocumentOrder","lists","best","placeCaretAtEndOfList","items","c","lastLi","restoreCaretToEndOfListInSelectionBounds","matched","restoreCaretAfterListMutation","fallbackOffset","ensureLiHasPlaceholder","exitListFromEmptyItem","index","afterItems","p","newList","item","splitListItemOnEnter","newLi","tailRange","tailProbe","fragment","mergeListItemOnBackspace","prevInList","prevList","prevLi","junctionOffset","prevLiEl","mergeNextListItemOnDelete","nextInList","nextLi","nextList","nextLiEl","rangeIntersectsNode","nodeRange","sortByDocumentOrder","nodes","a","b","pos","getListItemsInRange","copyListElementAttributes","from","to","indentAttr","style","appendListWithItems","tag","appendUnwrappedItems","replaceListWithSegments","before","middle","middleMode","origTag","applyListTypeToWholeList","wantUl","inUl","convertListTag","applyListCommandForSelection","affectedItems","byList","group","selected","allItems","selectedSet","toggleOff","indices","firstIdx","lastIdx","unwrapList","child","detectListFormats","LIST_INDENT_ATTR","LIST_INDENT_DEFAULT_PX","LIST_INDENT_SLIDER_MAX","LIST_INDENT_PRESETS_PX","normalizeGlobalListIndentStorage","px","n","clampListIndent","LIST_STYLE_KEYS","LI_STYLE_KEYS","parsePaddingLeftPx","raw","s","readStyleProp","styleAttr","prop","re","mergeInlineStyle","patch","managedKeys","map","part","idx","val","k","v","stripManagedListStyles","listMarkerType","applyExplicitListInline","paddingLeftPx","getListIndent","setListIndent","value","findListAtSelection","resolveExportPaddingPx","globalDefaultPx","explicit","resolveGlobalListIndentPx","styles","globalListIndentCssVarValue","normalizeEmailListsInHtml","src","serialized","doctype","coerceCssWidth","docContentWidthCss","parseMetaWidthFromUserInput","input","metaWidthInputString","blockButtonWidthCss","parseSectionWidthFromUserInput","sectionWidthInputString","h","attrs","children","clear","escapeHtml","escapeAttr","FONT_WEIGHT_STEP_VALUES","FONT_WEIGHT_STEP_OPTIONS","normalizeFontWeightStep","match","steps","bestD","st","mjRawCellTypographyFromStyles","cssForDoubleQuotedAttr","buildMjRawTdStyle","paddingCss","typo","fontSize","lineHeight","color","fontFamily","fontWeight","mjRawEmailTableWrap","cellInnerHtml","wrapLockedMjmlForMjColumn","lead","t","normalizeHtmlBlockLockedMjmlForCompile","mj","inner","divStrip","htmlContainsMjmlTags","extractHtmlUntilMatchingCloseTag","contentStart","tagName","openRe","closeRe","depth","nextOpen","nextClose","extractOutermostTableInner","open","innerFromPresentationTable","trimmed","tableInner","tdOpen","extractPreviewHtmlFromLockedMjml","lockedMjml","mjText","mjButton","label","mjRaw","tdInner","defaultPaddingForLockedBlock","_blockType","_lockedMjml","props","resolveLockedMjmlCanvasContent","padding","previewInner","pad","docToMjml","registry","ctx","sections","sectionToMjml","sectionWidthConstraintCss","w","bg","secW","dvKey","secCls","widths","layoutWidths","gapPx","columns","col","columnToMjml","grouped","indent","column","width","columnIndex","columnCount","columnGapPx","va","gapPad","half","pl","rawTypo","blocks","layout","parts","total","x","l","renderDoc","opts","engine","mjml","compiled","mjmlCompile","replaceVariables","e","vars","_counter","uid","prefix","Store","initial","fn","mutator","draft","detail","findSection","findBlockLocation","blockId","blk","pruneSectionIfEmpty","sec","pruneEmptySections","MULTI_COLUMN_LAYOUTS","TWO_COLUMN_LAYOUTS","isMultiColumnLayout","isTwoColumnLayout","setSectionLayout","nextCols","curCols","removed","last","createSection","colCount","tokenToVariableKey","token","variablePlaceholder","defaultVariableSample","normalizeVariable","kind","buildLinkVariableHtml","linkColor","safeHref","safeText","buildBodyVariableKeyInsert","normalized","buildBodyVariableElementInsert","options","alt","buildBodyVariableInsert","appendInlineToRichHtml","insert","blockClose","renderSectionBodyHtml","mini","replaceVariantMarkerInHtml","variantHtml","extractDynamicVariantSlots","resultHtml","variants","fromMarker","snippet","LAYOUT_LABELS","layoutHumanLabel","prettyHtml","VOID","PRESERVE","tokens","preserveStack","out","tok","inPreserve","selfClosing","txt","DEFAULT_MAX_WIDTH_RATIO","DEFAULT_MAX_HEIGHT_RATIO","getCodeEditorModalDefaultSize","getCodeEditorModalMaximizedSize","maxWidthRatio","maxHeightRatio","Modal","title","height","tools","closeBtn","_d","_c","iconClose","MAXIMIZED_PREF_KEY","BlockCodeModal","defaultSize","iconMaximize","beautifyBtn","saveBtn","componentLabel","loc","block","readMaximizedPref","EditorView","EditorState","basicSetup","cmHtml","size","writeMaximizedPref","iconRestore","id","maximized","asRichTextDoc","richTextExecCommand","commandId","showUI","richTextQueryCommandState","richTextQueryCommandValue","isRichHtmlEditorSeedOnly","hasRichHtmlLineBreak","tpl","getRichHtmlPlainText","isRichHtmlEffectivelyEmpty","normalizeRichHtmlForCommit","normalizeAccentHex","rgbCssToHex","rgb","accentPrimarySoftRgba","primaryHex","isDarkChrome","hex","r","g","zhCNMessages","enUSMessages","FALLBACK_LOCALE","createI18nContext","locale","messages","params","name","COLOR_PICKER_PALETTE","activeTeardown","isColorPickerOpen","closeActiveColorPicker","positionLayer","layer","layerRoot","rect","rootRect","popRect","guardInlineEditFocus","syncNativeInput","native","openColorPickerPopover","initialHex","closed","panel","hexInput","applyDraft","commit","teardown","onKey","onDoc","swatchGrid","btn","ke","footKids","ev","bindColorPickerInput","pick","InlineEditor","sanitized","sanitizeRichHtml","restore","off","command","hiliteAnchor","selectionAnchorKey","isListCmd","itemsInRange","savedOffset","boundaryMarkers","applyListIndentToElement","url","safe","findAncestorAnchor","pxToLegacyFontSize","weight","span","caret","newRange","mode","multiline","initiallyEmpty","placeCaretAtEnd","imeComposing","suppressNextEnter","onCompositionStart","onCompositionEnd","onKeyDown","onBlur","active","related","_e","_f","_g","_h","_i","markEdited","syncTextPresence","onPaste","plainTextToRichHtml","onSelChange","onInput","linkInsideEditing","href","stopLinkActivate","align","link","inline","resolveInlineFormatsAtSelection","foreColor","safeQueryValue","backColor","listFormats","activeList","listIndentPx","listIndentGlobalPx","listIndentEffectivePx","state","fallback","rects","tmp","cmd","host","selectionHostElement","resolveForeColorAtSelection","resolveBackColorAtSelection","fromAttr","readColorFromStyleAttr","isTransparentColor","readBackgroundFromStyleAttr","computed","num","legacy","rgba","walk","toRemove","face","fontSizeFromLegacy","cleaned","allowedAttrs","listExtraAttrs","hasMarginStyle","appendStyle","Canvas","blockEl","cssEscape","editingEl","linkFromTarget","stopNavigate","si","topPut","top","Sortable","sectionIndex","layoutShort","sectionChip","sw","wrap","toolbar","iconDrag","iconCopy","iconTrash","cols","layoutFlexStyle","isEmpty","colEl","layoutFlexValue","vaToFlex","sortable","isHtmlLike","resolved","displayName","content","blockToolbar","iconEdit","iconCode","layouts","bar","reg","newBlock","firstBlock","contentRoot","propKey","editingId","restoreUI","blockType","partial","meta","rest","sectionAttrs","_dv","fromBlockId","sourceGroup","newIndex","newSection","fromCol","moved","oldIndex","drop","paletteSectionAttrs","secIdx","insertAt","targetSec","nodeInEditing","_layout","columnGap","ratio","svg","ExportModal","editorHost","copyBtn","downloadBtn","result","ta","blob","LAYOUT_CARDS","layoutSvg","LeftPanel","hiddenPalette","filterPalette","defs","paletteBlocks","grid","suffix","isCustom","gap","innerW","rw","DEVICES","_PreviewModal","switcher","iconForDevice","spec","maxPx","PreviewModal","FONT_FAMILIES","FONT_SIZES","RichTextToolbar","editor","f","hasLink","colorToHexInput","matchFamily","matchFontSize","matchFontWeight","sep","exec","svgIcon","placeholder","opt","applyLinkBtn","opening","ed","viewRect","edge","tw","th","viewTop","viewBottom","viewLeft","viewRight","left","inList","shown","on","onClick","icon","lower","step","toHex","defaultSocialIconBackground","network","resolveAssetPermission","permissions","action","defaultNoPermissionTip","tip","FocusBreadcrumb","store","docRootLabel","onFocusDocument","onFocusSection","blockName","openImageGalleryModal","adapter","onPick","onClose","noPermissionTip","perm","modal","query","page","hasMore","loading","errEl","searchInp","debounceId","loadFirst","gridEl","loadMoreBtn","loadPage","confirmBtn","finishPick","setError","msg","syncSelectionStyles","renderCells","append","it","thumb","cellWrap","cell","img","cap","deletePerm","delBtn","err","res","toolRow","addPerm","urlInp","addBtn","u","uploadPerm","fileInp","upBtn","scrollArea","buildVariablePickerHead","pinned","syncPinBtn","pinBtn","iconPin","buildVariablePickerBody","handlers","row","actions","classifyLayoutWidth","layoutWidthNumeric","RightPanel","show","ae","selStart","selEnd","tabs","tab","hideMeta","rows","dvUiEnabled","dynamicVariantKeyField","field","vals","checked","schema","form","fp","defaults","onChange","rawColor","stored","isFw","displayVal","rawFs","quad","dp","resetQuad","pr","networkOptions","elementsKey","help","focusPrefix","firstVal","listEl","patchElements","mutate","cur","syncItem","removeAt","_","rowData","rowWrap","mainRow","o","inp","rm","extras","bgResolved","bgStored","bgDisplay","bgPick","focusToken","ids","assets","showUploadBtn","showGalleryBtn","hasAssetCallbacks","hasAnyPickerBtn","getCtx","applyUrl","runAsync","labelErr","helpBody","bits","warn","warnEl","min","max","snap","commitPlain","fb","v0","syncFromSlider","pickToken","textToken","lastValid","applyPickInherit","applyStored","previewPick","commitPick","current","titles","clampPad","emit","makePlain","makeSliderRow","rawN","inheritOn","globalDisplay","onToggle","valueEl","display","globalWeight","inheriting","syncGroup","inheritSwitch","globalFontSize","globalPx","syncInput","inheritGlobal","sliderRow","syncSlider","leaveInherit","tf","displayN","clampW","emitW","modesWrap","addModeBtn","header","view","SourceView","Topbar","compact","base","norm","forInput","iconFullscreenExit","iconFullscreenEnter","segmented","designBtn","modeSegBtn","iconDesign","sourceBtn","iconSource","themeSeg","themeBtn","theme","iconSun","iconMoon","iconThemeAuto","themeGroupKids","inputEl","actionBtn","iconUndo","iconRedo","contentActionKids","iconClearCanvas","iconResetContent","iconCopyDoc","iconImportDoc","contentActionsGroup","previewBtn","iconEye","exportBtn","iconExport","showMailSettings","trailingGroup","iconSettings","iconVariable","canvasToolKids","iconOnlyBtn","iconLayoutBorders","canvasToolsGroup","headKids","topbarLabel","extra","ICON_UNDO_PATH","svgPathFill","svgTheme","viewBox","transforms","paths","pd","path","DOC_CLIPBOARD_KIND","DOC_CLIPBOARD_FORMAT_VERSION","serializeDocClipboard","isRecord","isEmailDocShape","parseDocClipboard","regenerateDocIds","remapSectionIds","ImportDocModal","cancelBtn","pasteBtn","applyBtn","message","isError","readTextFromClipboard","writeTextToClipboard","ok","MailEditor","fs","smGetFullscreenElement","undo","redo","initialDoc","createDefaultDoc","applyLocalizedDefaultMeta","presetSource","presetContentDoc","initialAccent","preset","configuredVars","presetDoc","snapshot","smExitFullscreen","dark","mq","hx","topbarPrefersLabels","ui","autoWrap","handler","copyVariableToken","existing","pop","onDocClick","dismissPopover","positionAnchoredLayer","urlKey","asHtml","updated","richInline","wrapped","smRequestFullscreen","margin","anchorMid","rootMid","DEFAULT_TOPBAR_COMPACT_MIN_WIDTH","labels","minW","anyEl","mergedStyles"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/registry/registry.ts","../src/utils/dynamicVariantKey.ts","../src/utils/dynamicVariantHtml.ts","../src/utils/inlineListEditing.ts","../src/utils/emailListStyles.ts","../src/utils/contentWidth.ts","../src/utils/dom.ts","../src/utils/fontWeightSteps.ts","../src/utils/lockedMjml.ts","../src/renderer/mjml.ts","../src/renderer/index.ts","../src/utils/id.ts","../src/store/store.ts","../src/variables/index.ts","../src/utils/richHtmlInsert.ts","../src/utils/dynamicVariantSection.ts","../src/utils/sectionLayout.ts","../src/utils/html.ts","../src/utils/modalSize.ts","../src/editor/Modal.ts","../src/editor/BlockCodeModal.ts","../src/utils/richTextCommand.ts","../src/utils/richHtmlEmpty.ts","../src/utils/accentColor.ts","../src/i18n/index.ts","../src/editor/ColorPickerPopover.ts","../src/editor/InlineEditor.ts","../src/editor/Canvas.ts","../src/editor/ExportModal.ts","../src/editor/LeftPanel.ts","../src/editor/PreviewModal.ts","../src/editor/RichTextToolbar.ts","../src/socialDefaults.ts","../src/editor/imageAssets.ts","../src/editor/FocusBreadcrumb.ts","../src/editor/ImageGalleryModal.ts","../src/editor/VariablePickerPanel.ts","../src/editor/RightPanel.ts","../src/editor/SourceView.ts","../src/editor/Topbar.ts","../src/utils/docClipboard.ts","../src/editor/ImportDocModal.ts","../src/editor/Editor.ts"],"sourcesContent":["import type { Block, BlockDefinition } from '../types';\n\n/**\n * 组件注册表。所有内置/自定义组件都通过 `defineBlock` 注册进来;\n * 渲染、属性面板、左栏拖拽源、组件级代码模式四方都从这里读取。\n */\nexport class Registry {\n private map = new Map<string, BlockDefinition<any>>();\n\n register<P extends object>(def: BlockDefinition<P>) {\n if (this.map.has(def.type)) {\n console.warn(`[simple-mail] block type 重复注册: ${def.type},后注册的会覆盖前者`);\n }\n this.map.set(def.type, def as BlockDefinition<any>);\n return this;\n }\n\n get(type: string): BlockDefinition | undefined {\n return this.map.get(type);\n }\n\n /** 必须能找到,否则抛出。渲染/属性面板都用它,未注册即 bug。 */\n require(type: string): BlockDefinition {\n const def = this.map.get(type);\n if (!def) throw new Error(`[simple-mail] 未注册的 block type: ${type}`);\n return def;\n }\n\n list(): BlockDefinition[] {\n return [...this.map.values()];\n }\n\n byCategory(category: BlockDefinition['category']): BlockDefinition[] {\n return this.list().filter((d) => d.category === category);\n }\n\n /** 用注册表里的默认 props 创建一个新 block 实例。 */\n createBlock(type: string): Block {\n const def = this.require(type);\n return {\n id: cryptoRandomId(),\n type,\n props: structuredClone(def.defaultProps),\n };\n }\n}\n\nfunction cryptoRandomId() {\n const ts = Date.now().toString(36).slice(-4);\n const rand = Math.floor(Math.random() * 36 ** 4)\n .toString(36)\n .padStart(4, '0');\n return `blk_${ts}${rand}`;\n}\n\n/** 工厂函数,便于外部以函数式风格定义组件。 */\nexport function defineBlock<P extends object>(def: BlockDefinition<P>): BlockDefinition<P> {\n return def;\n}\n","import type { Section } from '../types';\n\n/**\n * 导出 HTML 上标记动态变量组合的宿主约定属性名(值为 `Section.attrs.dynamicVariantKey`)。\n */\nexport const DYNAMIC_VARIANT_HTML_ATTR = 'data-dv';\n\n/** 本节导出后替换为 `{{dynamicVariantKey}}`,内容由宿主写入 dynamicVariant */\nexport function getSectionDynamicVariantKey(section: Section): string | undefined {\n const key = String(section.attrs.dynamicVariantKey ?? '').trim();\n return key || undefined;\n}\n\nexport function isDynamicVariantSection(section: Section): boolean {\n return !!getSectionDynamicVariantKey(section);\n}\n\nexport function dynamicVariantPlaceholder(key: string): string {\n return `{{${String(key).trim()}}}`;\n}\n\nexport function sectionMjClassName(sectionId: string): string {\n return `sm-sec-${sectionId.replace(/[^a-zA-Z0-9_-]/g, '_')}`;\n}\n","import type { EmailDoc } from '../types';\nimport {\n DYNAMIC_VARIANT_HTML_ATTR,\n getSectionDynamicVariantKey,\n isDynamicVariantSection,\n sectionMjClassName,\n} from './dynamicVariantKey';\n\nfunction serializeParsedHtml(doc: Document): string {\n const head = doc.head?.innerHTML || '';\n const body = doc.body?.innerHTML || '';\n return `${head}${body}`;\n}\n\n/**\n * 编译后为带 `dynamicVariantKey` 的 Section 根节点写入 `data-dv=\"{key}\"`,供宿主 DOM 抽取。\n */\nexport function annotateDynamicVariantHtmlAttributes(html: string, doc: EmailDoc): string {\n const slots = doc.sections.filter(isDynamicVariantSection);\n if (!slots.length) return html;\n try {\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n for (const section of slots) {\n const key = getSectionDynamicVariantKey(section);\n if (!key) continue;\n const cls = sectionMjClassName(section.id);\n const marked = parsed.querySelector(`[${DYNAMIC_VARIANT_HTML_ATTR}=\"${key}\"]`);\n if (marked) continue;\n const candidates = parsed.querySelectorAll(`[class~=\"${cls}\"], [class*=\"${cls}\"]`);\n let target: Element | null = null;\n for (const el of candidates) {\n const cn = el.getAttribute('class') || '';\n if (cn.split(/\\s+/).includes(cls)) {\n target = el;\n break;\n }\n }\n if (!target && candidates.length) target = candidates[0];\n if (target) target.setAttribute(DYNAMIC_VARIANT_HTML_ATTR, key);\n }\n return serializeParsedHtml(parsed);\n } catch {\n return html;\n }\n}\n","/** contenteditable 内 ul/ol 的 Enter / Backspace / 退出列表等 DOM 操作 */\n\n/** 空列表项 Enter 退出后插入的正文段,勿当作可合并的分隔块 */\nexport const LIST_GAP_ATTR = 'data-sm-list-gap';\n\nexport function findListItem(node: Node | null, root: HTMLElement): HTMLLIElement | null {\n while (node && node !== root) {\n if (node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).tagName === 'LI') {\n return node as HTMLLIElement;\n }\n node = node.parentNode;\n }\n return null;\n}\n\nexport function findListRoot(\n li: HTMLLIElement,\n): HTMLUListElement | HTMLOListElement | null {\n const parent = li.parentElement;\n if (!parent) return null;\n if (parent.tagName === 'UL' || parent.tagName === 'OL') {\n return parent as HTMLUListElement | HTMLOListElement;\n }\n return null;\n}\n\ntype ListElement = HTMLUListElement | HTMLOListElement;\n\n/** 两个列表之间可忽略的分隔块(空段落、仅含 br 的 div 等) */\nexport function isIgnorableListSeparator(el: Element): boolean {\n if (el.hasAttribute(LIST_GAP_ATTR)) return false;\n if (el.tagName !== 'P' && el.tagName !== 'DIV') return false;\n const clone = el.cloneNode(true) as HTMLElement;\n clone.querySelectorAll('br').forEach((br) => br.remove());\n return (clone.textContent ?? '').replace(/\\u200b/g, '').trim() === '';\n}\n\nfunction findPreviousListOfSameType(list: ListElement): ListElement | null {\n let node: Element | null = list.previousElementSibling;\n while (node) {\n if (node.tagName === list.tagName) return node as ListElement;\n if (!isIgnorableListSeparator(node)) return null;\n node = node.previousElementSibling;\n }\n return null;\n}\n\nfunction findNextListOfSameType(list: ListElement): ListElement | null {\n let node: Element | null = list.nextElementSibling;\n while (node) {\n if (node.tagName === list.tagName) return node as ListElement;\n if (!isIgnorableListSeparator(node)) return null;\n node = node.nextElementSibling;\n }\n return null;\n}\n\n/** 将 source 的全部 li 并入 target,并移除中间分隔块与空的 source */\nfunction mergeListInto(target: ListElement, source: ListElement): void {\n let node: Element | null = target.nextElementSibling;\n while (node && node !== source) {\n const next = node.nextElementSibling;\n if (isIgnorableListSeparator(node)) node.remove();\n else break;\n node = next;\n }\n while (source.firstChild) target.appendChild(source.firstChild);\n source.remove();\n}\n\n/** 删除中间内容后,合并仅由空行分隔的同类型相邻列表 */\nexport function mergeAdjacentSameTypeLists(root: HTMLElement): boolean {\n let merged = false;\n for (const list of Array.from(root.querySelectorAll('ol, ul'))) {\n if (!root.contains(list)) continue;\n const prev = findPreviousListOfSameType(list as ListElement);\n if (prev && root.contains(prev)) {\n mergeListInto(prev, list as ListElement);\n merged = true;\n }\n }\n return merged;\n}\n\nexport function isLiEffectivelyEmpty(li: HTMLLIElement): boolean {\n const clone = li.cloneNode(true) as HTMLLIElement;\n clone.querySelectorAll('br').forEach((br) => br.remove());\n return (clone.textContent ?? '').replace(/\\u200b/g, '').trim() === '';\n}\n\nexport function isCaretAtLiStart(li: HTMLLIElement, range: Range): boolean {\n const probe = document.createRange();\n probe.selectNodeContents(li);\n probe.setEnd(range.startContainer, range.startOffset);\n return probe.toString().replace(/\\u200b/g, '').length === 0;\n}\n\nfunction fragmentHasSubstantiveText(frag: DocumentFragment): boolean {\n const box = document.createElement('div');\n box.appendChild(frag);\n box.querySelectorAll('br').forEach((br) => br.remove());\n return (box.textContent ?? '').replace(/\\u200b/g, '').trim().length > 0;\n}\n\n/** 光标后是否仅剩 br / 空块等可忽略内容(视为处于列表项末尾) */\nexport function isCaretAtLiEnd(li: HTMLLIElement, range: Range): boolean {\n const after = document.createRange();\n try {\n after.setStart(range.endContainer, range.endOffset);\n if (li.lastChild) after.setEndAfter(li.lastChild);\n else after.setEnd(li, 0);\n } catch {\n return false;\n }\n return !fragmentHasSubstantiveText(after.cloneContents());\n}\n\nexport function placeCaretInElement(el: HTMLElement, atStart: boolean): void {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(atStart);\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nexport function placeCaretAtEndOfElement(el: HTMLElement): void {\n placeCaretInElement(el, false);\n}\n\nfunction visibleTextLength(text: string): number {\n return text.replace(/\\u200b/g, '').length;\n}\n\n/** 容器内光标前的可见文本长度(忽略零宽空格) */\nexport function getCaretTextOffset(container: HTMLElement, range: Range): number {\n const probe = document.createRange();\n probe.selectNodeContents(container);\n probe.setEnd(range.startContainer, range.startOffset);\n return visibleTextLength(probe.toString());\n}\n\n/** 元素内可见文本偏移处放置光标;偏移超出则落在末尾 */\nexport function setCaretByTextOffset(container: HTMLElement, offset: number): void {\n const target = Math.max(0, offset);\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);\n let remaining = target;\n let textNode: Text | null = null;\n\n while ((textNode = walker.nextNode() as Text | null)) {\n const data = textNode.data ?? '';\n const len = visibleTextLength(data);\n if (remaining <= len) {\n let count = 0;\n let nodeOffset = data.length;\n for (let i = 0; i < data.length; i++) {\n if (data[i] === '\\u200b') continue;\n if (count === remaining) {\n nodeOffset = i;\n break;\n }\n count++;\n }\n const range = document.createRange();\n range.setStart(textNode, nodeOffset);\n range.collapse(true);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n return;\n }\n remaining -= len;\n }\n\n placeCaretAtEndOfElement(container);\n}\n\nexport function getElementVisibleTextLength(el: HTMLElement): number {\n return visibleTextLength(el.textContent ?? '');\n}\n\nconst CARET_MARKER_ATTR = 'data-sm-caret';\nconst RANGE_START_MARKER_ATTR = 'data-sm-sel-start';\n\nfunction insertBoundaryMarker(range: Range, attr: string): HTMLSpanElement | null {\n if (!range.collapsed) return null;\n const marker = document.createElement('span');\n marker.setAttribute(attr, '1');\n marker.appendChild(document.createTextNode('\\u200b'));\n try {\n range.insertNode(marker);\n return marker;\n } catch {\n marker.remove();\n return null;\n }\n}\n\n/** 在折叠光标处插入临时标记(空行/空列表项时比文本偏移更准) */\nexport function insertCaretMarker(range: Range): HTMLSpanElement | null {\n return insertBoundaryMarker(range, CARET_MARKER_ATTR);\n}\n\n/** 在选区起止处插入边界标记(用于列表命令后定位新建列表) */\nexport function insertSelectionBoundaryMarkers(range: Range): {\n start: HTMLSpanElement | null;\n end: HTMLSpanElement | null;\n} {\n const startRange = range.cloneRange();\n startRange.collapse(true);\n const endRange = range.cloneRange();\n endRange.collapse(false);\n return {\n start: insertBoundaryMarker(startRange, RANGE_START_MARKER_ATTR),\n end: insertBoundaryMarker(endRange, CARET_MARKER_ATTR),\n };\n}\n\n/** 在选区末尾插入光标标记(列表等命令后应落在选区末端) */\nexport function insertCaretMarkerAtRangeEnd(range: Range): HTMLSpanElement | null {\n const atEnd = range.cloneRange();\n atEnd.collapse(false);\n return insertCaretMarker(atEnd);\n}\n\nexport function removeSelectionBoundaryMarkers(root: HTMLElement): void {\n root\n .querySelectorAll(\n `span[${RANGE_START_MARKER_ATTR}=\"1\"], span[${CARET_MARKER_ATTR}=\"1\"]`,\n )\n .forEach((m) => m.remove());\n}\n\n/** 选区末尾在容器内的可见文本偏移 */\nexport function getCaretTextOffsetAtRangeEnd(\n container: HTMLElement,\n range: Range,\n): number {\n const atEnd = range.cloneRange();\n atEnd.collapse(false);\n return getCaretTextOffset(container, atEnd);\n}\n\n/** 将光标恢复到标记处并移除标记 */\nexport function restoreCaretMarker(root: HTMLElement): boolean {\n const marker = root.querySelector(`span[${CARET_MARKER_ATTR}=\"1\"]`);\n if (!(marker instanceof HTMLSpanElement) || !root.contains(marker)) return false;\n\n const range = document.createRange();\n range.setStartBefore(marker);\n range.collapse(true);\n marker.remove();\n\n const sel = window.getSelection();\n if (!sel) return false;\n sel.removeAllRanges();\n sel.addRange(range);\n return true;\n}\n\nfunction normalizeSelectionSpan(start: Node, end: Node): { anchor: Node; far: Node } {\n if (start.compareDocumentPosition(end) & Node.DOCUMENT_POSITION_FOLLOWING) {\n return { anchor: start, far: end };\n }\n return { anchor: end, far: start };\n}\n\nfunction listInSelectionSpan(list: Element, start: Node, end: Node): boolean {\n if (list.contains(start) || list.contains(end)) return true;\n\n const { anchor, far } = normalizeSelectionSpan(start, end);\n const afterAnchor =\n (list.compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;\n const beforeFar =\n (list.compareDocumentPosition(far) & Node.DOCUMENT_POSITION_PRECEDING) !== 0;\n return afterAnchor && beforeFar;\n}\n\nfunction lastListInDocumentOrder(lists: ListElement[]): ListElement | null {\n let best: ListElement | null = null;\n for (const list of lists) {\n if (\n !best ||\n (best.compareDocumentPosition(list) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0\n ) {\n best = list;\n }\n }\n return best;\n}\n\nfunction placeCaretAtEndOfList(list: ListElement): boolean {\n const items = Array.from(list.children).filter(\n (c): c is HTMLLIElement => c.tagName === 'LI',\n );\n const lastLi = items[items.length - 1];\n if (!lastLi) return false;\n placeCaretAtEndOfElement(lastLi);\n return true;\n}\n\n/**\n * 新建列表后:光标落在选区范围内(起止标记之间)文档顺序最靠后的列表末项。\n * 空行选中时末端标记常落在上方已有列表内,不能只看「标记所在列表」。\n */\nexport function restoreCaretToEndOfListInSelectionBounds(root: HTMLElement): boolean {\n const start = root.querySelector(`span[${RANGE_START_MARKER_ATTR}=\"1\"]`);\n const end = root.querySelector(`span[${CARET_MARKER_ATTR}=\"1\"]`);\n if (\n !(start instanceof HTMLSpanElement) ||\n !(end instanceof HTMLSpanElement) ||\n !root.contains(start) ||\n !root.contains(end)\n ) {\n return false;\n }\n\n const matched: ListElement[] = [];\n for (const node of root.querySelectorAll('ul, ol')) {\n if (!(node instanceof HTMLElement) || !root.contains(node)) continue;\n const list = node as ListElement;\n if (listInSelectionSpan(list, start, end)) matched.push(list);\n }\n\n start.remove();\n end.remove();\n\n const target = lastListInDocumentOrder(matched);\n if (!target) return false;\n return placeCaretAtEndOfList(target);\n}\n\n/** 列表操作后恢复光标:优先标记点,否则文本偏移 */\nexport function restoreCaretAfterListMutation(\n root: HTMLElement,\n marker: HTMLSpanElement | null,\n fallbackOffset: number,\n): void {\n if (restoreCaretMarker(root)) return;\n setCaretByTextOffset(root, fallbackOffset);\n}\n\nfunction ensureLiHasPlaceholder(li: HTMLLIElement): void {\n if (isLiEffectivelyEmpty(li)) {\n li.textContent = '';\n li.appendChild(document.createElement('br'));\n }\n}\n\n/** 空列表项 + Enter:退出列表(必要时拆成两段列表) */\nexport function exitListFromEmptyItem(li: HTMLLIElement): void {\n const list = findListRoot(li);\n if (!list) return;\n\n const items = Array.from(list.children).filter(\n (c): c is HTMLLIElement => c.tagName === 'LI',\n );\n const index = items.indexOf(li);\n if (index === -1) return;\n\n const afterItems = items.slice(index + 1);\n li.remove();\n\n const p = document.createElement('p');\n p.setAttribute(LIST_GAP_ATTR, '1');\n p.appendChild(document.createElement('br'));\n\n if (list.children.length === 0) {\n list.replaceWith(p);\n } else if (afterItems.length === 0) {\n list.after(p);\n } else if (index === 0) {\n list.before(p);\n } else {\n const newList = document.createElement(list.tagName.toLowerCase()) as\n | HTMLUListElement\n | HTMLOListElement;\n afterItems.forEach((item) => newList.appendChild(item));\n list.after(p);\n p.after(newList);\n }\n\n placeCaretInElement(p, true);\n}\n\n/** Enter:新列表项或拆分当前项 */\nexport function splitListItemOnEnter(li: HTMLLIElement, range: Range): void {\n const list = findListRoot(li);\n if (!list) return;\n\n if (isLiEffectivelyEmpty(li)) {\n exitListFromEmptyItem(li);\n return;\n }\n\n if (isCaretAtLiStart(li, range)) {\n const newLi = document.createElement('li');\n newLi.appendChild(document.createElement('br'));\n list.insertBefore(newLi, li);\n placeCaretInElement(newLi, true);\n return;\n }\n\n if (isCaretAtLiEnd(li, range)) {\n const newLi = document.createElement('li');\n newLi.appendChild(document.createElement('br'));\n if (li.nextSibling) list.insertBefore(newLi, li.nextSibling);\n else list.appendChild(newLi);\n placeCaretInElement(newLi, true);\n return;\n }\n\n const tailRange = document.createRange();\n tailRange.setStart(range.startContainer, range.startOffset);\n if (li.lastChild) tailRange.setEndAfter(li.lastChild);\n else tailRange.setEnd(li, 0);\n\n const tailProbe = document.createRange();\n tailProbe.setStart(range.startContainer, range.startOffset);\n if (li.lastChild) tailProbe.setEndAfter(li.lastChild);\n else tailProbe.setEnd(li, 0);\n if (!fragmentHasSubstantiveText(tailProbe.cloneContents())) {\n const newLi = document.createElement('li');\n newLi.appendChild(document.createElement('br'));\n if (li.nextSibling) list.insertBefore(newLi, li.nextSibling);\n else list.appendChild(newLi);\n placeCaretInElement(newLi, true);\n return;\n }\n\n const newLi = document.createElement('li');\n const fragment = tailRange.extractContents();\n newLi.appendChild(fragment);\n ensureLiHasPlaceholder(li);\n\n if (li.nextSibling) list.insertBefore(newLi, li.nextSibling);\n else list.appendChild(newLi);\n\n placeCaretInElement(newLi, true);\n}\n\n/** Backspace 在列表项行首:合并上一项、跨列表合并或退出列表 */\nexport function mergeListItemOnBackspace(li: HTMLLIElement, range: Range): boolean {\n if (!range.collapsed || !isCaretAtLiStart(li, range)) return false;\n\n const list = findListRoot(li);\n if (!list) return false;\n\n if (isLiEffectivelyEmpty(li)) {\n const prevInList = li.previousElementSibling;\n if (!prevInList || prevInList.tagName !== 'LI') {\n const prevList = findPreviousListOfSameType(list);\n if (prevList) {\n li.remove();\n mergeListInto(prevList, list);\n const lastLi = prevList.lastElementChild;\n if (lastLi instanceof HTMLLIElement) placeCaretAtEndOfElement(lastLi);\n return true;\n }\n }\n exitListFromEmptyItem(li);\n return true;\n }\n\n const prevInList = li.previousElementSibling;\n if (prevInList && prevInList.tagName === 'LI') {\n const prevLi = prevInList as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(prevLi);\n while (li.firstChild) prevLi.appendChild(li.firstChild);\n li.remove();\n setCaretByTextOffset(prevLi, junctionOffset);\n return true;\n }\n\n const prevList = findPreviousListOfSameType(list);\n if (prevList) {\n const prevLi = prevList.lastElementChild;\n if (prevLi && prevLi.tagName === 'LI') {\n const prevLiEl = prevLi as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(prevLiEl);\n while (li.firstChild) prevLiEl.appendChild(li.firstChild);\n li.remove();\n if (list.children.length === 0) mergeListInto(prevList, list);\n setCaretByTextOffset(prevLiEl, junctionOffset);\n return true;\n }\n }\n\n const p = document.createElement('p');\n while (li.firstChild) p.appendChild(li.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n li.remove();\n\n if (list.children.length === 0) {\n list.replaceWith(p);\n } else {\n list.before(p);\n }\n placeCaretAtEndOfElement(p);\n return true;\n}\n\n/** Delete 在列表项行末:整项合并下一项,或跨列表合并(含 Shift+Enter 软换行) */\nexport function mergeNextListItemOnDelete(li: HTMLLIElement, range: Range): boolean {\n if (!range.collapsed || !isCaretAtLiEnd(li, range)) return false;\n\n const list = findListRoot(li);\n if (!list) return false;\n\n const nextInList = li.nextElementSibling;\n if (nextInList && nextInList.tagName === 'LI') {\n const nextLi = nextInList as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(li);\n\n if (isLiEffectivelyEmpty(nextLi)) {\n nextLi.remove();\n setCaretByTextOffset(li, junctionOffset);\n return true;\n }\n\n while (nextLi.firstChild) li.appendChild(nextLi.firstChild);\n nextLi.remove();\n setCaretByTextOffset(li, junctionOffset);\n return true;\n }\n\n const nextList = findNextListOfSameType(list);\n if (!nextList) return false;\n\n const nextLi = nextList.firstElementChild;\n if (!nextLi || nextLi.tagName !== 'LI') return false;\n\n const nextLiEl = nextLi as HTMLLIElement;\n const junctionOffset = getElementVisibleTextLength(li);\n\n if (isLiEffectivelyEmpty(nextLiEl)) {\n nextLiEl.remove();\n if (nextList.children.length === 0) mergeListInto(list, nextList);\n setCaretByTextOffset(li, junctionOffset);\n return true;\n }\n\n while (nextLiEl.firstChild) li.appendChild(nextLiEl.firstChild);\n nextLiEl.remove();\n if (nextList.children.length === 0) mergeListInto(list, nextList);\n setCaretByTextOffset(li, junctionOffset);\n return true;\n}\n\nfunction rangeIntersectsNode(range: Range, node: Node): boolean {\n try {\n const nodeRange = document.createRange();\n nodeRange.selectNodeContents(node);\n return (\n range.compareBoundaryPoints(Range.END_TO_START, nodeRange) > -1 &&\n range.compareBoundaryPoints(Range.START_TO_END, nodeRange) < 1\n );\n } catch {\n return false;\n }\n}\n\nfunction sortByDocumentOrder<T extends Node>(nodes: T[]): T[] {\n return [...nodes].sort((a, b) => {\n const pos = a.compareDocumentPosition(b);\n if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;\n if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;\n return 0;\n });\n}\n\n/** 选区触及的列表项(块级,按文档顺序) */\nexport function getListItemsInRange(\n range: Range,\n root: HTMLElement,\n): HTMLLIElement[] {\n const items: HTMLLIElement[] = [];\n for (const node of root.querySelectorAll('li')) {\n if (!(node instanceof HTMLLIElement)) continue;\n if (!findListRoot(node)) continue;\n if (!rangeIntersectsNode(range, node)) continue;\n items.push(node);\n }\n return sortByDocumentOrder(items);\n}\n\nfunction copyListElementAttributes(from: ListElement, to: ListElement): void {\n const indentAttr = from.getAttribute('data-sm-list-indent');\n if (indentAttr != null) to.setAttribute('data-sm-list-indent', indentAttr);\n const style = from.getAttribute('style');\n if (style) to.setAttribute('style', style);\n}\n\nfunction appendListWithItems(\n frag: DocumentFragment,\n tag: 'ul' | 'ol',\n source: ListElement,\n items: HTMLLIElement[],\n): void {\n if (!items.length) return;\n const el = document.createElement(tag) as ListElement;\n copyListElementAttributes(source, el);\n items.forEach((li) => el.appendChild(li));\n frag.appendChild(el);\n}\n\nfunction appendUnwrappedItems(frag: DocumentFragment, items: HTMLLIElement[]): void {\n for (const li of items) {\n const p = document.createElement('p');\n while (li.firstChild) p.appendChild(li.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n frag.appendChild(p);\n }\n}\n\ntype ListSegmentMiddle =\n | 'unwrap'\n | { tag: 'ul' | 'ol' };\n\n/** 将列表拆成前/中/后三段:中段改类型或取消列表 */\nfunction replaceListWithSegments(\n list: ListElement,\n before: HTMLLIElement[],\n middle: HTMLLIElement[],\n after: HTMLLIElement[],\n middleMode: ListSegmentMiddle,\n): void {\n const parent = list.parentNode;\n if (!parent) return;\n\n const origTag = list.tagName.toLowerCase() as 'ul' | 'ol';\n const frag = document.createDocumentFragment();\n\n appendListWithItems(frag, origTag, list, before);\n\n if (middleMode === 'unwrap') {\n appendUnwrappedItems(frag, middle);\n } else {\n appendListWithItems(frag, middleMode.tag, list, middle);\n }\n\n appendListWithItems(frag, origTag, list, after);\n\n parent.insertBefore(frag, list);\n list.remove();\n}\n\nfunction applyListTypeToWholeList(list: ListElement, wantUl: boolean): void {\n const inUl = list.tagName === 'UL';\n const toggleOff = wantUl === inUl;\n if (toggleOff) unwrapList(list);\n else convertListTag(list, wantUl ? 'ul' : 'ol');\n}\n\n/**\n * 切换列表类型。\n * - 折叠光标在列表内:整表转换/取消。\n * - 有选区:仅影响选区触及的 li;选满整表时仍整表处理。\n * wantUl=true 为无序;与当前类型相同时为取消列表。\n */\nexport function applyListCommandForSelection(\n root: HTMLElement,\n range: Range,\n wantUl: boolean,\n /** 非折叠选区在 DOM 变更前算好的 li;折叠时忽略 */\n affectedItems?: HTMLLIElement[],\n): boolean {\n if (range.collapsed) {\n const li = findListItem(range.startContainer, root);\n const list = li ? findListRoot(li) : null;\n if (!list) return false;\n applyListTypeToWholeList(list, wantUl);\n return true;\n }\n\n const items = affectedItems ?? getListItemsInRange(range, root);\n if (!items.length) return false;\n\n const byList = new Map<ListElement, HTMLLIElement[]>();\n for (const li of items) {\n const list = findListRoot(li);\n if (!list) continue;\n const group = byList.get(list) ?? [];\n group.push(li);\n byList.set(list, group);\n }\n\n const lists = sortByDocumentOrder([...byList.keys()]).reverse();\n\n for (const list of lists) {\n const selected = sortByDocumentOrder(byList.get(list) ?? []);\n const allItems = Array.from(list.children).filter(\n (c): c is HTMLLIElement => c.tagName === 'LI',\n );\n const selectedSet = new Set(selected);\n const allSelected =\n selected.length === allItems.length &&\n allItems.every((li) => selectedSet.has(li));\n\n if (allSelected) {\n applyListTypeToWholeList(list, wantUl);\n continue;\n }\n\n const inUl = list.tagName === 'UL';\n const toggleOff = wantUl === inUl;\n\n const indices = selected\n .map((li) => allItems.indexOf(li))\n .filter((i) => i >= 0)\n .sort((a, b) => a - b);\n if (!indices.length) continue;\n\n const firstIdx = indices[0]!;\n const lastIdx = indices[indices.length - 1]!;\n const before = allItems.slice(0, firstIdx);\n const middle = allItems.slice(firstIdx, lastIdx + 1);\n const after = allItems.slice(lastIdx + 1);\n\n if (toggleOff) {\n replaceListWithSegments(list, before, middle, after, 'unwrap');\n } else {\n replaceListWithSegments(list, before, middle, after, {\n tag: wantUl ? 'ul' : 'ol',\n });\n }\n }\n return true;\n}\n\n/** 取消列表:每个 li 拆成段落 */\nexport function unwrapList(list: HTMLUListElement | HTMLOListElement): void {\n const parent = list.parentNode;\n if (!parent) return;\n const fragment = document.createDocumentFragment();\n for (const child of Array.from(list.children)) {\n if (child.tagName !== 'LI') continue;\n const p = document.createElement('p');\n while (child.firstChild) p.appendChild(child.firstChild);\n if (!p.hasChildNodes()) p.appendChild(document.createElement('br'));\n fragment.appendChild(p);\n }\n parent.insertBefore(fragment, list);\n list.remove();\n}\n\n/** 有序 ↔ 无序 */\nexport function convertListTag(\n list: HTMLUListElement | HTMLOListElement,\n tag: 'ul' | 'ol',\n): HTMLUListElement | HTMLOListElement {\n if (list.tagName.toLowerCase() === tag) return list;\n const next = document.createElement(tag) as HTMLUListElement | HTMLOListElement;\n while (list.firstChild) next.appendChild(list.firstChild);\n const indentAttr = list.getAttribute('data-sm-list-indent');\n if (indentAttr != null) next.setAttribute('data-sm-list-indent', indentAttr);\n const style = list.getAttribute('style');\n if (style) next.setAttribute('style', style);\n list.replaceWith(next);\n return next;\n}\n\nexport function detectListFormats(node: Node | null, root: HTMLElement): {\n unorderedList: boolean;\n orderedList: boolean;\n} {\n const li = findListItem(node, root);\n const list = li ? findListRoot(li) : null;\n return {\n unorderedList: list?.tagName === 'UL',\n orderedList: list?.tagName === 'OL',\n };\n}\n","import type { GlobalStyles } from '../types';\nimport { findListItem, findListRoot } from './inlineListEditing';\n\n/** 标记显式列表缩进;无此属性表示「默认」(画布 CSS + 导出时注入标准内联样式) */\nexport const LIST_INDENT_ATTR = 'data-sm-list-indent';\n\n/** 导出/邮件客户端默认缩进(与画布 1.5em @16px 对齐) */\nexport const LIST_INDENT_DEFAULT_PX = 24;\n\nexport const LIST_INDENT_SLIDER_MAX = 48;\n\nexport const LIST_INDENT_PRESETS_PX = [0, 16, 24, 32, 40] as const;\n\n/** 全局配置存库:内置默认 24 时不写入 listIndentDefaultPx */\nexport function normalizeGlobalListIndentStorage(px: number): number | undefined {\n const n = clampListIndent(px);\n return n === LIST_INDENT_DEFAULT_PX ? undefined : n;\n}\n\n/** null = 不设值(默认);number = 显式左缩进 px,0 为与正文左缘对齐 */\nexport type ListIndentValue = number | null;\n\nconst LIST_STYLE_KEYS = [\n 'padding-left',\n 'margin',\n 'margin-top',\n 'margin-bottom',\n 'margin-left',\n 'margin-right',\n 'list-style-position',\n 'list-style-type',\n] as const;\n\nconst LI_STYLE_KEYS = ['margin', 'padding'] as const;\n\nfunction parsePaddingLeftPx(raw: string | null | undefined): number | null {\n const s = (raw ?? '').trim();\n if (!s) return null;\n const m = s.match(/^(-?\\d+(?:\\.\\d+)?)(px)?$/i);\n if (!m) return null;\n const n = Number(m[1]);\n return Number.isFinite(n) ? Math.max(0, Math.round(n)) : null;\n}\n\nfunction readStyleProp(styleAttr: string | null, prop: string): string {\n if (!styleAttr) return '';\n const re = new RegExp(`(?:^|;)\\\\s*${prop}\\\\s*:\\\\s*([^;]+)`, 'i');\n const m = styleAttr.match(re);\n return m?.[1]?.trim() ?? '';\n}\n\nfunction mergeInlineStyle(\n el: HTMLElement,\n patch: Record<string, string | null>,\n managedKeys: readonly string[],\n): void {\n const map = new Map<string, string>();\n const prev = el.getAttribute('style') ?? '';\n for (const part of prev.split(';')) {\n const idx = part.indexOf(':');\n if (idx < 0) continue;\n const key = part.slice(0, idx).trim().toLowerCase();\n const val = part.slice(idx + 1).trim();\n if (key && val) map.set(key, val);\n }\n for (const key of managedKeys) map.delete(key);\n for (const [key, val] of Object.entries(patch)) {\n if (val == null || val === '') map.delete(key);\n else map.set(key, val);\n }\n const next = [...map.entries()].map(([k, v]) => `${k}:${v}`).join(';');\n if (next) el.setAttribute('style', next);\n else el.removeAttribute('style');\n}\n\nfunction stripManagedListStyles(list: HTMLUListElement | HTMLOListElement): void {\n mergeInlineStyle(list, {}, LIST_STYLE_KEYS);\n}\n\nfunction listMarkerType(list: HTMLUListElement | HTMLOListElement): string {\n return list.tagName === 'OL' ? 'decimal' : 'disc';\n}\n\nfunction applyExplicitListInline(\n list: HTMLUListElement | HTMLOListElement,\n paddingLeftPx: number,\n): void {\n mergeInlineStyle(\n list,\n {\n 'padding-left': `${paddingLeftPx}px`,\n margin: '0.5em 0',\n 'list-style-position': 'outside',\n 'list-style-type': listMarkerType(list),\n },\n LIST_STYLE_KEYS,\n );\n for (const li of Array.from(list.children)) {\n if (li.tagName !== 'LI') continue;\n mergeInlineStyle(li as HTMLLIElement, { margin: '0', padding: '0' }, LI_STYLE_KEYS);\n }\n}\n\n/** 读取当前列表缩进:无属性且无 padding-left 视为默认 null */\nexport function getListIndent(list: HTMLUListElement | HTMLOListElement): ListIndentValue {\n if (list.hasAttribute(LIST_INDENT_ATTR)) {\n const raw = list.getAttribute(LIST_INDENT_ATTR);\n if (raw == null || raw === 'default') return null;\n const n = parseInt(raw, 10);\n return Number.isFinite(n) ? clampListIndent(n) : null;\n }\n const fromStyle =\n parsePaddingLeftPx(list.style.paddingLeft) ??\n parsePaddingLeftPx(readStyleProp(list.getAttribute('style'), 'padding-left'));\n return fromStyle;\n}\n\nexport function clampListIndent(px: number): number {\n return Math.max(0, Math.min(LIST_INDENT_SLIDER_MAX, Math.round(px)));\n}\n\n/** 设置列表缩进;null 恢复为默认(移除显式标记与内联缩进) */\nexport function setListIndent(\n list: HTMLUListElement | HTMLOListElement,\n value: ListIndentValue,\n): void {\n if (value === null) {\n list.removeAttribute(LIST_INDENT_ATTR);\n stripManagedListStyles(list);\n return;\n }\n const px = clampListIndent(value);\n list.setAttribute(LIST_INDENT_ATTR, String(px));\n applyExplicitListInline(list, px);\n}\n\nexport function findListAtSelection(\n node: Node | null,\n root: HTMLElement,\n): HTMLUListElement | HTMLOListElement | null {\n const li = findListItem(node, root);\n return li ? findListRoot(li) : null;\n}\n\nfunction resolveExportPaddingPx(\n list: HTMLUListElement | HTMLOListElement,\n globalDefaultPx: number,\n): number {\n const explicit = getListIndent(list);\n if (explicit != null) return explicit;\n return globalDefaultPx;\n}\n\n/** 邮件设置中的列表默认缩进;未配置时返回内置 24px */\nexport function resolveGlobalListIndentPx(styles: GlobalStyles): number {\n const v = styles.listIndentDefaultPx;\n if (v === undefined) return LIST_INDENT_DEFAULT_PX;\n return clampListIndent(v);\n}\n\n/** 画布 CSS 变量值(px) */\nexport function globalListIndentCssVarValue(styles: GlobalStyles): string {\n return `${resolveGlobalListIndentPx(styles)}px`;\n}\n\n/** 编译后 HTML:统一 ul/ol 内联样式,剥离编辑态 data 属性 */\nexport function normalizeEmailListsInHtml(\n html: string,\n globalDefaultPx: number = LIST_INDENT_DEFAULT_PX,\n): string {\n const src = (html ?? '').trim();\n if (!src || typeof DOMParser === 'undefined') return html;\n\n const doc = new DOMParser().parseFromString(src, 'text/html');\n const lists = doc.querySelectorAll('ul, ol');\n if (!lists.length) return html;\n\n lists.forEach((node) => {\n const list = node as HTMLUListElement | HTMLOListElement;\n const px = resolveExportPaddingPx(list, globalDefaultPx);\n applyExplicitListInline(list, px);\n list.removeAttribute(LIST_INDENT_ATTR);\n });\n\n const serialized = doc.documentElement.outerHTML;\n const doctype = src.match(/<!DOCTYPE[^>]*>/i)?.[0];\n return doctype ? `${doctype}\\n${serialized}` : serialized;\n}\n","/**\n * 内容区 / 按钮等「布局宽度」解析:数字与无单位数字按 px;支持显式 `px` 与 `%`。\n */\n\nfunction coerceCssWidth(raw: unknown): string | undefined {\n if (raw == null || raw === '') return undefined;\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n const n = Math.round(raw);\n return n > 0 ? `${n}px` : undefined;\n }\n const s = String(raw).trim();\n if (!s) return undefined;\n if (/^\\d+(\\.\\d+)?%$/.test(s)) return s;\n if (/^\\d+(\\.\\d+)?px$/i.test(s)) return s.replace(/px$/i, 'px');\n if (/^\\d+(\\.\\d+)?$/.test(s)) return `${s}px`;\n return undefined;\n}\n\n/** 邮件 `meta.width` → CSS / mj-body 可用的宽度(非法则 600px) */\nexport function docContentWidthCss(raw: unknown): string {\n return coerceCssWidth(raw) ?? '600px';\n}\n\n/** 右栏输入解析存库:纯整数可存 number,其它存 string */\nexport function parseMetaWidthFromUserInput(input: string): number | string {\n const t = input.trim();\n if (!t) return 600;\n if (/^\\d+(\\.\\d+)?%$/.test(t)) return t;\n if (/^\\d+(\\.\\d+)?px$/i.test(t)) return t.replace(/PX$/i, 'px');\n if (/^\\d+$/.test(t)) return Number(t);\n if (/^\\d+\\.\\d+$/.test(t)) return `${t}px`;\n return t;\n}\n\nexport function metaWidthInputString(raw: unknown): string {\n if (raw == null) return '600';\n if (typeof raw === 'number' && Number.isFinite(raw)) return String(raw);\n return String(raw);\n}\n\n/** 按钮 / Section 等:可选宽度,空或 auto 表示不限制 */\nexport function blockButtonWidthCss(raw: unknown): string | undefined {\n if (raw == null) return undefined;\n const s = String(raw).trim();\n if (!s || s.toLowerCase() === 'auto') return undefined;\n return coerceCssWidth(s);\n}\n\n/** Section 右栏输入;空字符串表示清除宽度 */\nexport function parseSectionWidthFromUserInput(input: string): string | number | undefined {\n const t = input.trim();\n if (!t) return undefined;\n if (/^\\d+(\\.\\d+)?%$/.test(t)) return t;\n if (/^\\d+(\\.\\d+)?px$/i.test(t)) return t.replace(/PX$/i, 'px');\n if (/^\\d+$/.test(t)) return Number(t);\n if (/^\\d+\\.\\d+$/.test(t)) return `${t}px`;\n return t;\n}\n\nexport function sectionWidthInputString(raw: unknown): string {\n if (raw == null || raw === '') return '';\n if (typeof raw === 'number' && Number.isFinite(raw)) return String(raw);\n return String(raw);\n}\n","/** 极简 DOM 创建工具,避免引入 hyperscript 等额外依赖。 */\n\ntype Attrs = Record<string, string | number | boolean | EventListener | undefined | null>;\n\nexport function h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: (Node | string | null | undefined | false)[] = [],\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (v == null || v === false) continue;\n if (k === 'class') el.className = String(v);\n else if (k === 'style') el.setAttribute('style', String(v));\n else if (k === 'html') el.innerHTML = String(v);\n else if (k.startsWith('on') && typeof v === 'function') {\n el.addEventListener(k.slice(2).toLowerCase(), v as EventListener);\n } else if (typeof v === 'boolean') {\n if (v) el.setAttribute(k, '');\n } else {\n el.setAttribute(k, String(v));\n }\n }\n for (const child of children) {\n if (child == null || child === false) continue;\n el.appendChild(typeof child === 'string' ? document.createTextNode(child) : child);\n }\n return el;\n}\n\nexport function clear(el: HTMLElement) {\n while (el.firstChild) el.removeChild(el.firstChild);\n}\n\nexport function escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nexport function escapeAttr(s: string): string {\n return escapeHtml(s);\n}\n","/** 全局与各组件字重:固定五档,便于右栏平铺或步进滑块 */\nexport const FONT_WEIGHT_STEP_VALUES = ['300', '400', '500', '600', '700'] as const;\nexport type FontWeightStep = (typeof FONT_WEIGHT_STEP_VALUES)[number];\n\nexport const FONT_WEIGHT_STEP_OPTIONS: { label: string; value: string }[] = FONT_WEIGHT_STEP_VALUES.map(\n (v) => ({ label: v, value: v }),\n);\n\n/** 将任意历史写法映射到最近一档(normal→400,bold→700 等) */\nexport function normalizeFontWeightStep(raw: string | undefined | null): FontWeightStep {\n const s = String(raw ?? '400').trim().toLowerCase();\n if (s === '' || s === 'normal' || s === 'regular') return '400';\n if (s === 'bold' || s === 'bolder') return '700';\n if (s === 'lighter') return '300';\n const match = /^(\\d+)(\\.\\d+)?$/.exec(s);\n if (match) {\n const n = parseInt(match[1], 10);\n const steps = [300, 400, 500, 600, 700];\n let best: FontWeightStep = '400';\n let bestD = Infinity;\n for (const st of steps) {\n const d = Math.abs(n - st);\n if (d < bestD) {\n bestD = d;\n best = String(st) as FontWeightStep;\n }\n }\n return best;\n }\n return '400';\n}\n","import type { GlobalStyles } from '../types';\nimport { normalizeFontWeightStep } from './fontWeightSteps';\n\n/**\n * mj-column 编译结果外层会有 `font-size:0`(多列 inline-block 间距技巧),\n * mj-raw 内若未在祖先上重置字号,li/p 等会继承 0 导致「看不见」。\n * 在包裹 td 上对齐邮件全局正文样式即可规避。\n */\nexport interface MjRawCellTypography {\n fontSize: string;\n lineHeight: string;\n color: string;\n fontFamily: string;\n fontWeight: string;\n}\n\nexport function mjRawCellTypographyFromStyles(s: GlobalStyles): MjRawCellTypography {\n return {\n fontSize: (s.fontSize || '16px').trim(),\n lineHeight: (s.lineHeight || '1.25').trim(),\n color: (s.color || '#433f3f').trim(),\n fontFamily: (s.fontFamily || 'sans-serif').trim(),\n fontWeight: normalizeFontWeightStep(s.fontWeight),\n };\n}\n\n/** style=\"...\" 为双引号属性,避免值内双引号破坏解析 */\nfunction cssForDoubleQuotedAttr(value: string): string {\n return value.replace(/\"/g, \"'\").replace(/\\s+/g, ' ').trim();\n}\n\nfunction buildMjRawTdStyle(paddingCss: string, typo: MjRawCellTypography): string {\n const fontSize = cssForDoubleQuotedAttr(typo.fontSize);\n const lineHeight = cssForDoubleQuotedAttr(typo.lineHeight);\n const color = cssForDoubleQuotedAttr(typo.color);\n const fontFamily = cssForDoubleQuotedAttr(typo.fontFamily);\n const fontWeight = cssForDoubleQuotedAttr(typo.fontWeight);\n return `padding:${paddingCss};font-size:${fontSize};line-height:${lineHeight};color:${color};font-family:${fontFamily};font-weight:${fontWeight}`;\n}\n\n/**\n * mj-column 编译结果是表格布局,列内若用 mj-raw 直接输出 div/ul 等块级 HTML,\n * 会变成非法 table 子节点,浏览器/邮件里常表现为整块空白。\n * 用 presentation table + 单格 td 包住用户 HTML,与 mj-text 等组件结构一致。\n */\nexport function mjRawEmailTableWrap(\n paddingCss: string,\n cellInnerHtml: string,\n typo: MjRawCellTypography,\n): string {\n const tdStyle = buildMjRawTdStyle(paddingCss, typo);\n return `<mj-raw>\n<table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\">\n <tbody>\n <tr>\n <td style=\"${tdStyle}\">\n ${cellInnerHtml}\n </td>\n </tr>\n </tbody>\n</table>\n</mj-raw>`;\n}\n\n/**\n * 锁定片段插入 mj-column 时的规范化。\n *\n * mj-column 内只允许 mj-* 节点(或 mj-raw 包一层 HTML)。\n * 用户若在「编辑组件代码」里只保存了 `<ul>...</ul>` 等裸 HTML,直接下发会导致 MJML 编译失败、预览空白。\n */\nexport function wrapLockedMjmlForMjColumn(fragment: string, typo: MjRawCellTypography): string {\n const lead = fragment.trimStart();\n if (!lead) return '<mj-raw><!-- empty --></mj-raw>';\n if (/^<mj-/i.test(lead)) return fragment;\n const t = fragment.trim();\n // 无 props 上下文,内边距交给 0;用户可在片段内自行写 padding\n return mjRawEmailTableWrap('0', t, typo);\n}\n\n/** 旧版 HTML 块/锁定片段只有 mj-raw 包 div 或裸标签,编译进列后表格结构非法;统一包一层 presentation table。 */\nexport function normalizeHtmlBlockLockedMjmlForCompile(\n fragment: string,\n paddingCss: string,\n typo: MjRawCellTypography,\n): string {\n const raw = fragment.trim();\n const mj = raw.match(/^<mj-raw\\b[^>]*>([\\s\\S]*)<\\/mj-raw\\s*>$/i);\n if (!mj) return fragment;\n let inner = mj[1].trim();\n const divStrip = inner.match(/^\\s*<div\\b[^>]*style=\"[^\"]*\"[^>]*>([\\s\\S]*)<\\/div>\\s*$/i);\n if (divStrip) inner = divStrip[1].trim();\n if (/^\\s*<table\\b/i.test(inner)) return raw;\n return mjRawEmailTableWrap(paddingCss, inner, typo);\n}\n\n/** HTML 块内容是否误含 MJML 标签(应只写 HTML,MJML 标签在 mj-raw 内不会被编译)。 */\nexport function htmlContainsMjmlTags(html: string): boolean {\n return /<mj-[a-z]/i.test(String(html ?? ''));\n}\n\n/** 从 `<tag...>` 之后起,提取到与之配对的 `</tag>` 之前的完整内容(支持同名标签嵌套)。 */\nfunction extractHtmlUntilMatchingCloseTag(\n html: string,\n contentStart: number,\n tagName: string,\n): string | null {\n const openRe = new RegExp(`<${tagName}\\\\b`, 'gi');\n const closeRe = new RegExp(`</${tagName}\\\\s*>`, 'gi');\n let depth = 1;\n let i = contentStart;\n\n while (i < html.length) {\n openRe.lastIndex = i;\n closeRe.lastIndex = i;\n const nextOpen = openRe.exec(html);\n const nextClose = closeRe.exec(html);\n if (!nextClose) return null;\n\n if (nextOpen && nextOpen.index < nextClose.index) {\n depth++;\n i = nextOpen.index + nextOpen[0].length;\n continue;\n }\n\n depth--;\n if (depth === 0) return html.slice(contentStart, nextClose.index);\n i = nextClose.index + nextClose[0].length;\n }\n\n return null;\n}\n\n/** 提取最外层 `<table>...</table>` 内的 HTML(不含 table 标签本身)。 */\nfunction extractOutermostTableInner(html: string): string | null {\n const open = html.match(/^(\\s*)<table\\b[^>]*>/i);\n if (!open) return null;\n const contentStart = open[0].length;\n return extractHtmlUntilMatchingCloseTag(html, contentStart, 'table');\n}\n\n/** 从 presentation table 中提取最外层包裹 td 的完整内层 HTML(支持嵌套 table/td)。 */\nfunction innerFromPresentationTable(html: string): string | null {\n const trimmed = html.trim();\n if (!/^\\s*<table\\b/i.test(trimmed)) return null;\n\n const tableInner = extractOutermostTableInner(trimmed);\n if (tableInner == null) return null;\n\n const tdOpen = tableInner.match(/<td\\b[^>]*>/i);\n if (!tdOpen || tdOpen.index === undefined) return null;\n\n const contentStart = tdOpen.index + tdOpen[0].length;\n return extractHtmlUntilMatchingCloseTag(tableInner, contentStart, 'td');\n}\n\n/**\n * 从锁定 MJML 片段提取可在画布内渲染的 HTML;无法识别时返回 null(回退源码视图)。\n */\nexport function extractPreviewHtmlFromLockedMjml(lockedMjml: string): string | null {\n const raw = String(lockedMjml ?? '').trim();\n if (!raw) return '';\n\n const mjText = raw.match(/^<mj-text\\b[^>]*>([\\s\\S]*)<\\/mj-text\\s*>$/i);\n if (mjText) return mjText[1].trim();\n\n const mjButton = raw.match(/^<mj-button\\b[^>]*>([\\s\\S]*)<\\/mj-button\\s*>$/i);\n if (mjButton) {\n const label = mjButton[1].trim();\n if (!label) return '';\n return `<span style=\"display:inline-block;padding:12px 24px;background:#ff5a00;color:#fff;border-radius:4px;font-size:14px;\">${label}</span>`;\n }\n\n const mjRaw = raw.match(/^<mj-raw\\b[^>]*>([\\s\\S]*)<\\/mj-raw\\s*>$/i);\n if (mjRaw) {\n let body = mjRaw[1].trim();\n if (/^\\s*<table\\b/i.test(body)) {\n const tdInner = innerFromPresentationTable(body);\n if (tdInner != null) return tdInner;\n }\n return body;\n }\n\n if (!/^<mj-/i.test(raw)) return raw;\n\n return null;\n}\n\nexport interface BlockPaddingBox {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/** 锁定块画布预览用的默认内边距(与文本块一致:水平 0,由 section 承担版心 gutter)。 */\nexport function defaultPaddingForLockedBlock(\n _blockType: string,\n _lockedMjml: string,\n props: {\n paddingTop?: number;\n paddingRight?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n },\n): BlockPaddingBox {\n return {\n top: Number(props.paddingTop ?? 8),\n right: Number(props.paddingRight ?? 0),\n bottom: Number(props.paddingBottom ?? 8),\n left: Number(props.paddingLeft ?? 0),\n };\n}\n\n/** 锁定块在画布上的渲染结果:preview 为 WYSIWYG HTML,source 为无法解析时的源码回退。 */\nexport function resolveLockedMjmlCanvasContent(\n lockedMjml: string,\n padding: BlockPaddingBox,\n): { mode: 'preview'; html: string } | { mode: 'source'; source: string } {\n const previewInner = extractPreviewHtmlFromLockedMjml(lockedMjml);\n const pad = `${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px`;\n\n if (previewInner !== null) {\n if (!previewInner) {\n return {\n mode: 'preview',\n html: `<div style=\"padding:${pad};color:#9ca3af;font-size:13px;\">(无内容)</div>`,\n };\n }\n return {\n mode: 'preview',\n html: `<div style=\"padding:${pad};min-height:1em;\">${previewInner}</div>`,\n };\n }\n\n return { mode: 'source', source: lockedMjml };\n}\n\n/** @deprecated 使用 resolveLockedMjmlCanvasContent */\nexport function htmlFragmentForLockedHtmlBlockCanvas(\n lockedMjml: string,\n padding: BlockPaddingBox,\n): string {\n const resolved = resolveLockedMjmlCanvasContent(lockedMjml, padding);\n return resolved.mode === 'preview' ? resolved.html : resolved.source;\n}\n","import type { Registry } from '../registry/registry';\nimport type { Column, EmailDoc, RenderContext, Section, SectionLayout } from '../types';\nimport { getSectionDynamicVariantKey, sectionMjClassName } from '../utils/dynamicVariantKey';\nimport { blockButtonWidthCss, docContentWidthCss } from '../utils/contentWidth';\nimport { escapeAttr } from '../utils/dom';\nimport { normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport {\n mjRawCellTypographyFromStyles,\n normalizeHtmlBlockLockedMjmlForCompile,\n wrapLockedMjmlForMjColumn,\n} from '../utils/lockedMjml';\n\n/**\n * Schema → MJML 字符串。\n *\n * 不直接编译成 HTML——HTML 编译交给 `mjml-browser`,\n * 这一层只负责把数据模型翻译成 MJML 语义化标签。\n */\nexport function docToMjml(doc: EmailDoc, registry: Registry): string {\n const ctx: RenderContext = { doc, engine: 'mjml' };\n const attrs = doc.styles;\n\n const sections = doc.sections.map((s) => sectionToMjml(s, registry, ctx)).join('\\n');\n\n return `<mjml>\n <mj-head>\n <mj-title>${escapeAttr(doc.meta.subject || '')}</mj-title>\n ${doc.meta.preheader ? `<mj-preview>${escapeAttr(doc.meta.preheader)}</mj-preview>` : ''}\n <mj-attributes>\n <mj-all font-family=\"${escapeAttr(attrs.fontFamily)}\" />\n <mj-text font-size=\"${escapeAttr(attrs.fontSize)}\" font-weight=\"${escapeAttr(normalizeFontWeightStep(attrs.fontWeight))}\" color=\"${escapeAttr(attrs.color)}\" line-height=\"${escapeAttr(attrs.lineHeight ?? '1.25')}\" />\n <mj-class name=\"link\" color=\"${escapeAttr(attrs.linkColor)}\" />\n </mj-attributes>\n <mj-style>\n a { color: ${escapeAttr(attrs.linkColor)}; }\n${sectionWidthConstraintCss(doc)}\n${columnGapMobileCss(doc)}\n </mj-style>\n </mj-head>\n <mj-body background-color=\"${escapeAttr(attrs.backgroundColor)}\" width=\"${escapeAttr(docContentWidthCss(doc.meta.width))}\">\n${sections}\n </mj-body>\n</mjml>`;\n}\n\n/** 为设置了宽度的 Section 生成 max-width 规则(css-class 挂在 mj-section 上) */\nfunction sectionWidthConstraintCss(doc: EmailDoc): string {\n return doc.sections\n .map((s) => {\n const w = blockButtonWidthCss(s.attrs.width);\n if (!w) return '';\n const cls = sectionMjClassName(s.id);\n return ` .${cls} { max-width: ${w} !important; width: 100% !important; margin-left: auto !important; margin-right: auto !important; }`;\n })\n .filter(Boolean)\n .join('\\n');\n}\n\n/**\n * 列间距相关的小屏规则。\n *\n * 1) 水平间距(columnGap)用 mj-column 对称 padding 实现,小屏堆叠后 padding 不消失会导致\n * 相邻列内容纵向错位(首列右缩、次列左缩),需要在堆叠时清零。\n * 2) 堆叠纵向间距(columnStackedGap)只挂在非末列上,作为堆叠后相邻列之间的额外间距。\n *\n * 共同注意点:mj-column 的 padding 不落在带 css-class 的外层 div 上,编译结果是\n * `div[class] > table > tbody > tr > td{padding:...}`,所以规则必须命中这一层 td,\n * 用直接子代链避免波及块自身的 padding。\n * 断点取 MJML 默认堆叠断点 480px;!important 用于覆盖行内样式。\n * 仅对会小屏堆叠的列生效;mj-group(preserveColumnsOnMobile)不堆叠,不注入。\n */\nconst COLUMN_GAP_MOBILE_BREAKPOINT = 480;\n\nfunction columnGapClassName(sectionId: string): string {\n return `${sectionMjClassName(sectionId)}-cg`;\n}\n\nfunction columnStackedGapClassName(sectionId: string): string {\n return `${sectionMjClassName(sectionId)}-svg`;\n}\n\n/** 该 Section 的列是否会在小屏堆叠(未包 mj-group 的多列) */\nfunction stacksOnMobile(section: Section): boolean {\n return section.columns.length > 1 && section.attrs.preserveColumnsOnMobile !== true;\n}\n\nfunction columnGapMobileCss(doc: EmailDoc): string {\n const lines: string[] = [];\n\n for (const s of doc.sections) {\n if (!stacksOnMobile(s)) continue;\n const gap = Math.max(0, s.attrs.columnGap ?? 0);\n const stackedGap = Math.max(0, Math.round(s.attrs.columnStackedGap ?? 0));\n if (gap <= 0 && stackedGap <= 0) continue;\n\n if (gap > 0) {\n const cls = columnGapClassName(s.id);\n lines.push(\n ` .${cls},`,\n ` .${cls} > table > tbody > tr > td { padding-left: 0 !important; padding-right: 0 !important; }`,\n );\n }\n if (stackedGap > 0) {\n lines.push(\n ` .${columnStackedGapClassName(\n s.id,\n )} > table > tbody > tr > td { padding-bottom: ${stackedGap}px !important; }`,\n );\n }\n }\n\n if (!lines.length) return '';\n return ` @media only screen and (max-width:${COLUMN_GAP_MOBILE_BREAKPOINT}px) {\n${lines.join('\\n')}\n }`;\n}\n\nfunction sectionToMjml(section: Section, registry: Registry, ctx: RenderContext): string {\n const a = section.attrs;\n const padding = [a.paddingTop, a.paddingRight, a.paddingBottom, a.paddingLeft]\n .map((v) => `${v ?? 0}px`)\n .join(' ');\n const bg = a.backgroundColor ? ` background-color=\"${escapeAttr(a.backgroundColor)}\"` : '';\n const secW = blockButtonWidthCss(a.width);\n const dvKey = getSectionDynamicVariantKey(section);\n const secCls =\n secW || dvKey ? ` css-class=\"${escapeAttr(sectionMjClassName(section.id))}\"` : '';\n const widths = layoutWidths(section.layout);\n const gapPx = Math.max(0, section.attrs.columnGap ?? 0);\n /** 仅小屏堆叠时才有水平复位与纵向间距;与下方 grouped 判定保持一致 */\n const stacked = stacksOnMobile(section);\n const hCls = stacked && gapPx > 0 ? columnGapClassName(section.id) : '';\n const vCls =\n stacked && Math.max(0, Math.round(section.attrs.columnStackedGap ?? 0)) > 0\n ? columnStackedGapClassName(section.id)\n : '';\n const lastIndex = section.columns.length - 1;\n\n const columns = section.columns\n .map((col, i) =>\n columnToMjml(\n col,\n widths[i],\n i,\n section.columns.length,\n gapPx,\n [hCls, vCls && i < lastIndex ? vCls : ''].filter(Boolean).join(' '),\n registry,\n ctx,\n ),\n )\n .join('\\n');\n\n /** 多列 + 显式开启时包 mj-group,阻止小屏列堆叠(MJML 官方语义) */\n const multiCol = section.columns.length > 1;\n const grouped =\n multiCol && section.attrs.preserveColumnsOnMobile === true\n ? ` <mj-group>\\n${indent(columns, 2)}\\n </mj-group>`\n : columns;\n\n return ` <mj-section padding=\"${padding}\"${bg}${secCls}>\n${grouped}\n </mj-section>`;\n}\n\nfunction columnToMjml(\n column: Column,\n width: string,\n columnIndex: number,\n columnCount: number,\n columnGapPx: number,\n gapClassNames: string,\n registry: Registry,\n ctx: RenderContext,\n): string {\n const a = column.attrs;\n const va = a.verticalAlign ? ` vertical-align=\"${a.verticalAlign}\"` : '';\n const bg = a.backgroundColor ? ` background-color=\"${escapeAttr(a.backgroundColor)}\"` : '';\n\n let gapPad = '';\n if (columnCount > 1 && columnGapPx > 0) {\n const half = columnGapPx / 2;\n const pl = columnIndex > 0 ? `${half}px` : '0px';\n const pr = columnIndex < columnCount - 1 ? `${half}px` : '0px';\n gapPad = ` padding=\"0px ${pr} 0px ${pl}\"`;\n }\n const clsAttr = gapClassNames ? ` css-class=\"${escapeAttr(gapClassNames)}\"` : '';\n\n const rawTypo = mjRawCellTypographyFromStyles(ctx.doc.styles);\n const blocks = column.blocks\n .map((b) => {\n if (b.lockedMjml) {\n let frag = wrapLockedMjmlForMjColumn(b.lockedMjml, rawTypo);\n if (b.type === 'html') {\n const p = b.props as {\n paddingTop?: number;\n paddingRight?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n };\n const pad = `${Number(p.paddingTop ?? 8)}px ${Number(p.paddingRight ?? 0)}px ${Number(p.paddingBottom ?? 8)}px ${Number(p.paddingLeft ?? 0)}px`;\n frag = normalizeHtmlBlockLockedMjmlForCompile(frag, pad, rawTypo);\n }\n return indent(frag, 8);\n }\n const def = registry.require(b.type);\n return indent(def.toMjml(b.props, ctx), 8);\n })\n .join('\\n');\n\n return ` <mj-column width=\"${width}\"${va}${bg}${gapPad}${clsAttr}>\n${blocks || ' <!-- empty column -->'}\n </mj-column>`;\n}\n\nfunction layoutWidths(layout: SectionLayout): string[] {\n // 内容宽度 600,给到百分比即可,让 MJML 自己处理像素分配\n const parts = layout.split('-').map(Number);\n const total = parts.reduce((s, x) => s + x, 0);\n return parts.map((p) => `${((p / total) * 100).toFixed(2)}%`);\n}\n\nfunction indent(text: string, n: number): string {\n const pad = ' '.repeat(n);\n return text\n .split('\\n')\n .map((l) => (l ? pad + l : l))\n .join('\\n');\n}\n","import mjmlCompile from 'mjml-browser';\nimport type { EmailDoc, RenderEngine, Variable } from '../types';\nimport type { Registry } from '../registry/registry';\nimport { annotateDynamicVariantHtmlAttributes } from '../utils/dynamicVariantHtml';\nimport {\n normalizeEmailListsInHtml,\n resolveGlobalListIndentPx,\n} from '../utils/emailListStyles';\nimport { docToMjml } from './mjml';\n\nexport interface RenderResult {\n mjml: string;\n html: string;\n errors: { message: string }[];\n}\n\nexport interface RenderOptions {\n /** 渲染引擎,目前仅 'mjml';'table' 预留作将来直输 table HTML。 */\n engine?: RenderEngine;\n /**\n * 是否把 {{var}} 替换为变量的 sample 值。\n * 设计态预览默认不替换,保持占位符;仅当变量显式配置了 sample 且调用方传 true 时才替换。\n */\n withSampleVariables?: boolean;\n}\n\nexport function renderDoc(\n doc: EmailDoc,\n registry: Registry,\n opts: RenderOptions = {},\n): RenderResult {\n const engine: RenderEngine = opts.engine ?? 'mjml';\n\n if (engine !== 'mjml') {\n // 预留:将来可在此分支实现纯 table 输出。\n throw new Error(`渲染引擎暂未实现: ${engine}`);\n }\n\n const mjml = docToMjml(doc, registry);\n\n const compiled = mjmlCompile(mjml, {\n validationLevel: 'soft',\n keepComments: false,\n });\n\n let html = compiled.html;\n html = annotateDynamicVariantHtmlAttributes(html, doc);\n html = normalizeEmailListsInHtml(html, resolveGlobalListIndentPx(doc.styles));\n if (opts.withSampleVariables) {\n html = replaceVariables(html, doc.variables);\n }\n\n return {\n mjml,\n html,\n errors: (compiled.errors || []).map((e: any) => ({\n message: e.formattedMessage ?? e.message ?? String(e),\n })),\n };\n}\n\n/**\n * 用 sample 值替换 `{{var.name}}` 占位符。仅做最简单的字符串替换,\n * 不做任何沙箱式表达式求值(邮件场景里下游模板引擎会再处理一次)。\n */\nexport function replaceVariables(text: string, vars: Variable[]): string {\n if (!vars.length) return text;\n return text.replace(/\\{\\{\\s*([^}\\s]+)\\s*\\}\\}/g, (raw, key) => {\n const v = vars.find((x) => x.key === key);\n if (v && v.sample != null) return v.sample;\n return raw;\n });\n}\n","let _counter = 0;\n\n/**\n * 生成短 ID。无需密码学强度——仅用于文档内引用。\n * 使用 base36 + 自增计数,保证同 doc 内单调,便于 diff 调试。\n */\nexport function uid(prefix = 'id'): string {\n _counter += 1;\n const ts = Date.now().toString(36).slice(-4);\n const rand = Math.floor(Math.random() * 36 ** 3)\n .toString(36)\n .padStart(3, '0');\n return `${prefix}_${ts}${rand}${_counter.toString(36)}`;\n}\n","import type { Block, Column, EmailDoc, Section, SectionLayout, Selection } from '../types';\nimport { uid } from '../utils/id';\n\n/** 文档变更通知来源(右栏等可按来源决定是否保留焦点) */\nexport type DocChangedDetail = { source: 'mutate' | 'history' | 'replace' };\n\ntype Listener = (detail?: DocChangedDetail) => void;\ntype SelectionListener = () => void;\n\n/**\n * 极小的不可变 store + 发布订阅 + history。\n * 所有变更都通过 `update(fn)` 走结构化克隆,保证:\n * - 引用不可变(外部 memo/diff 友好)\n * - 变更原子(一个 update 一条 history)\n */\nexport class Store {\n private _doc: EmailDoc;\n private _selection: Selection | null = null;\n private _listeners: Set<Listener> = new Set();\n private _selectionListeners: Set<SelectionListener> = new Set();\n private _past: EmailDoc[] = [];\n private _future: EmailDoc[] = [];\n private _historyLimit = 100;\n\n constructor(initial: EmailDoc) {\n this._doc = initial;\n }\n\n get doc(): EmailDoc {\n return this._doc;\n }\n\n get selection(): Selection | null {\n return this._selection;\n }\n\n subscribe(fn: Listener): () => void {\n this._listeners.add(fn);\n return () => this._listeners.delete(fn);\n }\n\n subscribeSelection(fn: SelectionListener): () => void {\n this._selectionListeners.add(fn);\n return () => this._selectionListeners.delete(fn);\n }\n\n setSelection(sel: Selection | null) {\n this._selection = sel;\n this._selectionListeners.forEach((l) => l());\n }\n\n /**\n * 应用一次变更。`mutator` 收到一份可直接修改的 draft(结构化克隆得来)。\n * 修改完毕后用新对象替换当前 doc,并把旧 doc 入历史。\n */\n update(mutator: (draft: EmailDoc) => void, opts: { silent?: boolean } = {}) {\n const draft = structuredClone(this._doc);\n mutator(draft);\n this._past.push(this._doc);\n if (this._past.length > this._historyLimit) this._past.shift();\n this._future = [];\n this._doc = draft;\n if (!opts.silent) this._notify('mutate');\n }\n\n /** 替换整个文档(如外部 setValue),会清空 history。 */\n replace(doc: EmailDoc) {\n this._past = [];\n this._future = [];\n this._doc = doc;\n this._notify('replace');\n }\n\n undo(): boolean {\n const prev = this._past.pop();\n if (!prev) return false;\n this._future.push(this._doc);\n this._doc = prev;\n this._notify('history');\n return true;\n }\n\n redo(): boolean {\n const next = this._future.pop();\n if (!next) return false;\n this._past.push(this._doc);\n this._doc = next;\n this._notify('history');\n return true;\n }\n\n canUndo() {\n return this._past.length > 0;\n }\n\n canRedo() {\n return this._future.length > 0;\n }\n\n private _notify(source: DocChangedDetail['source']) {\n const detail: DocChangedDetail = { source };\n this._listeners.forEach((l) => l(detail));\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* 便捷的查询/变更助手 */\n/* -------------------------------------------------------------------------- */\n\nexport function findSection(doc: EmailDoc, sectionId: string): Section | undefined {\n return doc.sections.find((s) => s.id === sectionId);\n}\n\nexport function findBlockLocation(\n doc: EmailDoc,\n blockId: string,\n): { section: Section; columnIndex: number; block: Block } | undefined {\n for (const section of doc.sections) {\n for (let i = 0; i < section.columns.length; i += 1) {\n const col = section.columns[i];\n const blk = col.blocks.find((b) => b.id === blockId);\n if (blk) return { section, columnIndex: i, block: blk };\n }\n }\n return undefined;\n}\n\n/**\n * 若指定 Section 的每一列都没有 Block,则从文档中移除该 Section。\n * 在内容块被删除或拖走后调用,可与 `autoWrapSection` 搭配,避免单列 Section 在唯一块离场后仍残留空壳;\n * 多列 Section 始终保留,便于继续向各列拖入内容。\n * 仅处理刚变空的 Section,不会误删用户事先添加、尚未拖入内容的空布局。\n */\nexport function pruneSectionIfEmpty(draft: EmailDoc, sectionId: string) {\n const sec = draft.sections.find((s) => s.id === sectionId);\n if (!sec) return;\n if (sec.columns.length > 1) return;\n const isEmpty = sec.columns.every((col) => col.blocks.length === 0);\n if (!isEmpty) return;\n draft.sections = draft.sections.filter((s) => s.id !== sectionId);\n}\n\n/** @deprecated 请改用 {@link pruneSectionIfEmpty},避免误删多个空 Section */\nexport function pruneEmptySections(draft: EmailDoc) {\n draft.sections = draft.sections.filter((sec) =>\n sec.columns.some((col) => col.blocks.length > 0),\n );\n}\n\n/** 多列 Section 的列布局(左栏拖入默认 `1-1`,右栏可切换列数/比例) */\nexport const MULTI_COLUMN_LAYOUTS = ['1-1', '1-2', '2-1', '1-1-1'] as const;\nexport type MultiColumnLayout = (typeof MULTI_COLUMN_LAYOUTS)[number];\n\n/** @deprecated 使用 MULTI_COLUMN_LAYOUTS */\nexport const TWO_COLUMN_LAYOUTS = ['1-1', '1-2', '2-1'] as const;\nexport type TwoColumnLayout = (typeof TWO_COLUMN_LAYOUTS)[number];\n\nexport function isMultiColumnLayout(layout: SectionLayout): layout is MultiColumnLayout {\n return (\n layout === '1-1' || layout === '1-2' || layout === '2-1' || layout === '1-1-1'\n );\n}\n\n/** @deprecated 使用 isMultiColumnLayout */\nexport function isTwoColumnLayout(layout: SectionLayout): layout is TwoColumnLayout {\n return layout === '1-1' || layout === '1-2' || layout === '2-1';\n}\n\n/** 更新 layout;列数变化时增删列,被删列内块并入最后一列 */\nexport function setSectionLayout(section: Section, layout: SectionLayout): void {\n const nextCols = layout.split('-').length;\n const curCols = section.columns.length;\n if (nextCols === curCols) {\n section.layout = layout;\n return;\n }\n if (nextCols > curCols) {\n for (let i = curCols; i < nextCols; i++) {\n section.columns.push({ id: uid('col'), attrs: {}, blocks: [] });\n }\n } else {\n const removed = section.columns.splice(nextCols);\n const last = section.columns[nextCols - 1];\n if (last) {\n for (const col of removed) last.blocks.push(...col.blocks);\n }\n }\n section.layout = layout;\n}\n\nexport function createSection(layout: SectionLayout): Section {\n const colCount = layout.split('-').length;\n const columns: Column[] = Array.from({ length: colCount }, () => ({\n id: uid('col'),\n attrs: {},\n blocks: [],\n }));\n return {\n id: uid('sec'),\n type: 'section',\n layout,\n attrs: {\n /** 默认左右 16:版心内边距由节承担;上下 0 由内容块堆叠节奏(常见 8)控制 */\n paddingTop: 0,\n paddingRight: 16,\n paddingBottom: 0,\n paddingLeft: 16,\n },\n columns,\n };\n}\n","import type { Variable } from '../types';\n\nexport type VariableKind = 'text' | 'link' | 'image';\n\n/** 从 Mustache token 提取 key,如 `{{username}}` → `username` */\nexport function tokenToVariableKey(token: string): string {\n const t = String(token || '').trim();\n const m = t.match(/^\\{\\{\\s*([^}]+?)\\s*\\}\\}$/);\n return (m?.[1] || t.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '')).trim();\n}\n\nexport function variablePlaceholder(key: string): string {\n return `{{${key}}}`;\n}\n\n/** 无显式 sample 时保留 Mustache 占位符;仅当宿主传入 sample 才用于可选的示例替换。 */\nexport function defaultVariableSample(v: Pick<Variable, 'key' | 'label' | 'kind' | 'sample'>): string {\n if (v.sample != null && String(v.sample).trim() !== '') return String(v.sample);\n const key = v.key?.trim() || tokenToVariableKey(String(v.key));\n return variablePlaceholder(key);\n}\n\n/** 规范化 Variable(补 kind、sample) */\nexport function normalizeVariable(v: Variable): Variable {\n const key = v.key?.trim() || tokenToVariableKey(String(v.key));\n const kind = v.kind ?? 'text';\n return {\n ...v,\n key,\n kind,\n sample: defaultVariableSample({ ...v, key, kind }),\n };\n}\n\nexport function buildLinkVariableHtml(token: string, linkColor: string): string {\n const safeHref = token.replace(/\"/g, '&quot;');\n const safeText = token\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n return `<a href=\"${safeHref}\" style=\"color:${linkColor} !important;text-decoration:underline;\">${safeText}</a>`;\n}\n\nexport interface BodyVariableInsert {\n content: string;\n asHtml: boolean;\n}\n\n/** 插入变量 key(`{{key}}`) */\nexport function buildBodyVariableKeyInsert(v: Variable): BodyVariableInsert {\n const normalized = normalizeVariable(v);\n return { content: variablePlaceholder(normalized.key), asHtml: false };\n}\n\n/** 插入链接 / 图片等元素片段 */\nexport function buildBodyVariableElementInsert(\n v: Variable,\n options?: { linkColor?: string; token?: string },\n): BodyVariableInsert {\n const normalized = normalizeVariable(v);\n const token = options?.token?.trim() || variablePlaceholder(normalized.key);\n const linkColor = options?.linkColor?.trim() || '#ff5a00';\n\n if (normalized.kind === 'link') {\n return {\n content: buildLinkVariableHtml(token, linkColor),\n asHtml: true,\n };\n }\n if (normalized.kind === 'image') {\n const alt = tokenToVariableKey(token);\n return {\n content: `<img src=\"${token.replace(/\"/g, '&quot;')}\" alt=\"${alt.replace(/\"/g, '&quot;')}\" width=\"100\" style=\"max-width:100%;height:auto;display:block;border:0;\" />`,\n asHtml: true,\n };\n }\n return buildBodyVariableKeyInsert(normalized);\n}\n\n/** @deprecated 使用 buildBodyVariableKeyInsert / buildBodyVariableElementInsert */\nexport function buildBodyVariableInsert(\n v: Variable,\n options?: { linkColor?: string; token?: string },\n): BodyVariableInsert {\n const normalized = normalizeVariable(v);\n if (normalized.kind === 'link' || normalized.kind === 'image') {\n return buildBodyVariableElementInsert(normalized, options);\n }\n return buildBodyVariableKeyInsert(normalized);\n}\n","/**\n * 向富文本 HTML 末尾「行内」追加内容,避免落在 `</p>` 外产生换行。\n * 无块级标签时包一层 `<p style=\"margin:0;\">`。\n */\nexport function appendInlineToRichHtml(html: string, insert: string): string {\n const trimmed = String(html ?? '').trim();\n if (!insert) return trimmed;\n if (!trimmed) return `<p style=\"margin:0;\">${insert}</p>`;\n\n const blockClose = trimmed.match(/<\\/(p|div|h[1-6]|li)>\\s*$/i);\n if (blockClose && blockClose.index != null) {\n const idx = blockClose.index;\n return trimmed.slice(0, idx) + insert + trimmed.slice(idx);\n }\n return trimmed + insert;\n}\n","import type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { EmailDoc } from '../types';\nimport { DYNAMIC_VARIANT_HTML_ATTR } from './dynamicVariantKey';\nimport {\n dynamicVariantPlaceholder,\n getSectionDynamicVariantKey,\n isDynamicVariantSection,\n} from './dynamicVariantKey';\n\nexport {\n DYNAMIC_VARIANT_HTML_ATTR,\n dynamicVariantPlaceholder,\n getSectionDynamicVariantKey,\n isDynamicVariantSection,\n sectionMjClassName,\n} from './dynamicVariantKey';\n\n/** 仅编译某一 Section,返回邮件 body 内 HTML 片段 */\nexport function renderSectionBodyHtml(\n doc: EmailDoc,\n sectionId: string,\n registry: Registry,\n): string {\n const section = doc.sections.find((s) => s.id === sectionId);\n if (!section) return '';\n const mini: EmailDoc = { ...doc, sections: [section] };\n const { html } = renderDoc(mini, registry, { withSampleVariables: false });\n try {\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n return (parsed.body?.innerHTML || '').trim();\n } catch {\n return '';\n }\n}\n\nexport interface ExtractDynamicVariantSlotsResult {\n html: string;\n variants: Record<string, string>;\n}\n\nfunction replaceVariantMarkerInHtml(\n html: string,\n key: string,\n): { html: string; variantHtml: string } | null {\n try {\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n const el = parsed.querySelector(`[${DYNAMIC_VARIANT_HTML_ATTR}=\"${key}\"]`);\n if (!el) return null;\n const variantHtml = el.outerHTML || '';\n const token = dynamicVariantPlaceholder(key);\n el.replaceWith(parsed.createTextNode(token));\n const head = parsed.head?.innerHTML || '';\n const body = parsed.body?.innerHTML || '';\n return { html: `${head}${body}`, variantHtml };\n } catch {\n return null;\n }\n}\n\n/**\n * 将带 `dynamicVariantKey` 的 Section 从全文 HTML 中替换为占位符,并返回各 key 的编译 HTML。\n * 优先使用导出 HTML 上的 `data-dv=\"{key}\"` 标记。\n */\nexport function extractDynamicVariantSlots(\n html: string,\n doc: EmailDoc,\n registry: Registry,\n): ExtractDynamicVariantSlotsResult {\n const slots = doc.sections.filter(isDynamicVariantSection);\n if (!slots.length) return { html, variants: {} };\n\n let resultHtml = html;\n const variants: Record<string, string> = {};\n\n for (const section of slots) {\n const key = getSectionDynamicVariantKey(section);\n if (!key) continue;\n\n const fromMarker = replaceVariantMarkerInHtml(resultHtml, key);\n if (fromMarker) {\n variants[key] = fromMarker.variantHtml;\n resultHtml = fromMarker.html;\n continue;\n }\n\n const snippet = renderSectionBodyHtml(doc, section.id, registry);\n if (!snippet) continue;\n variants[key] = snippet;\n const token = dynamicVariantPlaceholder(key);\n const idx = resultHtml.indexOf(snippet);\n if (idx >= 0) {\n resultHtml = resultHtml.slice(0, idx) + token + resultHtml.slice(idx + snippet.length);\n }\n }\n\n return { html: resultHtml, variants };\n}\n","import type { SectionLayout } from '../types';\n\nconst LAYOUT_LABELS: Record<SectionLayout, string> = {\n '1': '一列',\n '1-1': '1:1',\n '1-2': '1:2',\n '2-1': '2:1',\n '1-1-1': '1:1:1',\n};\n\nexport function layoutHumanLabel(layout: SectionLayout): string {\n return LAYOUT_LABELS[layout] ?? layout;\n}\n","/**\n * 极轻量 HTML 格式化器(约 50 行)。\n *\n * 不追求 100% 通用,但对邮件 HTML(table 嵌套、inline style、无脚本)非常稳定:\n * - 按 `<` 切 token,识别开标签 / 闭标签 / 自闭合 / 注释 / DOCTYPE\n * - 维护 depth 控制缩进\n * - void 元素与 self-closing 不增加 depth\n * - <pre> / <textarea> 内的换行不二次处理(保留原样)\n */\nexport function prettyHtml(html: string, indent = ' '): string {\n if (!html) return '';\n const VOID = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n ]);\n const PRESERVE = new Set(['pre', 'textarea', 'script', 'style']);\n\n const tokens = html.match(/<!--[\\s\\S]*?-->|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|<![^>]*>|<\\/?[^<>]+>|[^<]+/g) ?? [];\n let depth = 0;\n let preserveStack: string[] = [];\n const out: string[] = [];\n const pad = (n: number) => indent.repeat(Math.max(0, n));\n\n for (const raw of tokens) {\n const tok = raw;\n const inPreserve = preserveStack.length > 0;\n\n if (tok.startsWith('<!--') || tok.startsWith('<![')) {\n if (inPreserve) out.push(tok);\n else out.push(pad(depth) + tok.trim());\n continue;\n }\n if (tok.startsWith('<!')) {\n out.push(tok.trim());\n continue;\n }\n\n if (tok.startsWith('</')) {\n const tag = (tok.match(/^<\\/([\\w-]+)/) ?? [])[1]?.toLowerCase();\n if (preserveStack[preserveStack.length - 1] === tag) {\n preserveStack.pop();\n out.push(tok);\n continue;\n }\n depth = Math.max(0, depth - 1);\n out.push(pad(depth) + tok.trim());\n continue;\n }\n\n if (tok.startsWith('<')) {\n const tag = (tok.match(/^<([\\w-]+)/) ?? [])[1]?.toLowerCase();\n const selfClosing = tok.endsWith('/>') || (tag && VOID.has(tag));\n if (inPreserve) {\n out.push(tok);\n if (tag && PRESERVE.has(tag) && !selfClosing) preserveStack.push(tag);\n continue;\n }\n out.push(pad(depth) + tok.trim());\n if (tag && !selfClosing) {\n if (PRESERVE.has(tag)) preserveStack.push(tag);\n else depth += 1;\n }\n continue;\n }\n\n // 文本\n if (inPreserve) {\n out.push(tok);\n } else {\n const txt = tok.replace(/\\s+/g, ' ').trim();\n if (txt) out.push(pad(depth) + txt);\n }\n }\n\n return out.join('\\n');\n}\n","export interface CodeEditorModalSize {\n width: string;\n height: string;\n}\n\nconst DEFAULT_MAX_WIDTH_RATIO = 0.96;\nconst DEFAULT_MAX_HEIGHT_RATIO = 0.88;\n\n/** 组件代码弹框默认固定尺寸 */\nexport function getCodeEditorModalDefaultSize(): CodeEditorModalSize {\n return {\n width: 'min(720px, 92vw)',\n height: 'min(560px, 85vh)',\n };\n}\n\n/** 代码编辑弹框最大化时的视口占比 */\nexport function getCodeEditorModalMaximizedSize(\n opts?: { maxWidthRatio?: number; maxHeightRatio?: number },\n): CodeEditorModalSize {\n const maxWidthRatio = opts?.maxWidthRatio ?? DEFAULT_MAX_WIDTH_RATIO;\n const maxHeightRatio = opts?.maxHeightRatio ?? DEFAULT_MAX_HEIGHT_RATIO;\n return {\n width: `${Math.floor(window.innerWidth * maxWidthRatio)}px`,\n height: `${Math.floor(window.innerHeight * maxHeightRatio)}px`,\n };\n}\n","import { h } from '../utils/dom';\nimport type { SimpleMailT } from '../i18n';\n\n/**\n * 极简 Modal:遮罩 + 居中卡片 + header/body/footer 三段。\n * - 自带 Esc / 点遮罩 关闭\n * - 不锁 body scroll(邮件编辑器场景内通常已经接管了高度)\n * - 不依赖框架,保持 vanilla\n */\nexport interface ModalOptions {\n title: string;\n /** 卡片宽度 / 高度。可传 'auto' / px / % */\n width?: string;\n height?: string;\n /** 自定义类名,便于覆盖样式(如 sm-modal--preview) */\n className?: string;\n /** 关闭回调;用户取消、Esc、点遮罩时触发 */\n onClose?: () => void;\n t?: SimpleMailT;\n}\n\nexport class Modal {\n el: HTMLElement;\n private mask: HTMLElement;\n private card: HTMLElement;\n private headerEl: HTMLElement;\n private bodyEl: HTMLElement;\n private footerEl: HTMLElement;\n private opts: ModalOptions;\n private headerToolNodes: HTMLElement[] = [];\n private keydownHandler?: (e: KeyboardEvent) => void;\n\n constructor(opts: ModalOptions) {\n this.opts = opts;\n\n this.mask = h('div', {\n class: 'sm-modal__mask',\n onclick: (e: Event) => {\n if (e.target === this.mask) this._handleClose();\n },\n });\n\n this.headerEl = h('header', { class: 'sm-modal__header' });\n this.bodyEl = h('div', { class: 'sm-modal__body' });\n this.footerEl = h('footer', { class: 'sm-modal__footer' });\n\n this.card = h(\n 'div',\n {\n class: `sm-modal__card ${opts.className ?? ''}`,\n style: [\n opts.width ? `width:${opts.width};` : '',\n opts.height ? `height:${opts.height};` : '',\n ].join(''),\n },\n [this.headerEl, this.bodyEl, this.footerEl],\n );\n\n this.mask.append(this.card);\n this.el = this.mask;\n\n this._renderHeader();\n }\n\n open(parent: HTMLElement = document.body) {\n parent.append(this.el);\n this.keydownHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this._handleClose();\n };\n document.addEventListener('keydown', this.keydownHandler);\n requestAnimationFrame(() => this.el.classList.add('is-open'));\n }\n\n close() {\n this._handleClose();\n }\n\n setTitle(title: string) {\n this.opts.title = title;\n this._renderHeader();\n }\n\n /** 动态调整卡片宽高(如 CodeMirror 弹框按内容适配) */\n setSize(width?: string, height?: string) {\n if (width !== undefined) {\n this.opts.width = width;\n this.card.style.width = width;\n }\n if (height !== undefined) {\n this.opts.height = height;\n this.card.style.height = height;\n }\n }\n\n /** body 容器直接给外部填充 */\n get body(): HTMLElement {\n return this.bodyEl;\n }\n\n /** footer 容器直接给外部填充按钮等 */\n get footer(): HTMLElement {\n return this.footerEl;\n }\n\n /** 在 header 右侧追加自定义工具按钮(setTitle 重绘 header 时保留) */\n appendHeaderTool(el: HTMLElement) {\n this.headerToolNodes.push(el);\n const tools = this.headerEl.querySelector('.sm-modal__header-tools');\n tools?.append(el);\n }\n\n get cardElement(): HTMLElement {\n return this.card;\n }\n\n private _renderHeader() {\n this.headerEl.innerHTML = '';\n const title = h('div', { class: 'sm-modal__title' }, [this.opts.title]);\n const tools = h('div', { class: 'sm-modal__header-tools' });\n for (const el of this.headerToolNodes) tools.append(el);\n const closeBtn = h(\n 'button',\n {\n class: 'sm-modal__close',\n type: 'button',\n title: this.opts.t?.('common.closeEsc') ?? '关闭 Esc',\n 'aria-label': this.opts.t?.('common.close') ?? '关闭',\n onclick: () => this._handleClose(),\n },\n [iconClose()],\n );\n this.headerEl.append(title, tools, closeBtn);\n }\n\n private _handleClose() {\n if (this.keydownHandler) document.removeEventListener('keydown', this.keydownHandler);\n this.el.classList.remove('is-open');\n setTimeout(() => this.el.remove(), 180);\n this.opts.onClose?.();\n }\n}\n\nfunction iconClose(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M5 5l10 10M15 5L5 15\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>';\n return el;\n}\n","import { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport { EditorState } from '@codemirror/state';\nimport type { Registry } from '../registry/registry';\nimport { findBlockLocation } from '../store/store';\nimport type { Store } from '../store/store';\nimport { h } from '../utils/dom';\nimport { prettyHtml } from '../utils/html';\nimport {\n getCodeEditorModalDefaultSize,\n getCodeEditorModalMaximizedSize,\n} from '../utils/modalSize';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface BlockCodeModalOptions {\n store: Store;\n registry: Registry;\n /** 须落在 MailEditor `.sm-root` 子树内,才能继承 `--sm-code-bg` 等变量 */\n mountParent: HTMLElement;\n t: SimpleMailT;\n}\n\nconst MAXIMIZED_PREF_KEY = 'sm-block-code-modal-maximized';\n\n/**\n * 画布内快速编辑单个 Block 的 MJML:与右栏「代码」Tab 行为一致(写入 lockedMjml)。\n */\nexport class BlockCodeModal {\n private opts: BlockCodeModalOptions;\n private modal: Modal;\n private editorHost: HTMLElement;\n private cm: EditorView | null = null;\n private blockId: string | null = null;\n private maximizeBtn: HTMLButtonElement;\n private maximized = false;\n\n constructor(opts: BlockCodeModalOptions) {\n this.opts = opts;\n const defaultSize = getCodeEditorModalDefaultSize();\n this.modal = new Modal({\n title: opts.t('blockCode.title'),\n className: 'sm-modal--block-code',\n width: defaultSize.width,\n height: defaultSize.height,\n onClose: () => this._destroyCm(),\n t: opts.t,\n });\n this.editorHost = h('div', { class: 'sm-export__editor' });\n this.modal.body.append(this.editorHost);\n\n this.maximizeBtn = h(\n 'button',\n {\n class: 'sm-modal__close',\n type: 'button',\n onclick: () => this._toggleMaximize(),\n },\n [iconMaximize()],\n ) as HTMLButtonElement;\n this.modal.appendHeaderTool(this.maximizeBtn);\n this._syncMaximizeButton();\n\n const beautifyBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this._beautify() },\n [opts.t('common.beautify')],\n );\n const saveBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => this._saveAndClose(),\n },\n [opts.t('common.save')],\n );\n this.modal.footer.append(beautifyBtn, saveBtn);\n }\n\n open(blockId: string, componentLabel: string) {\n const doc = this.opts.store.doc;\n const loc = findBlockLocation(doc, blockId);\n if (!loc) return;\n\n this._destroyCm();\n this.blockId = blockId;\n const block = loc.block;\n const def = this.opts.registry.get(block.type);\n const initial =\n block.lockedMjml ??\n (def ? def.toMjml(block.props as Record<string, unknown>, { doc, engine: 'mjml' }) : '');\n\n this.maximized = readMaximizedPref();\n this.modal.setTitle(this.opts.t('blockCode.titleWithName', { name: componentLabel }));\n this._applyModalSize();\n this.cm = new EditorView({\n parent: this.editorHost,\n state: EditorState.create({\n doc: initial,\n extensions: [basicSetup, cmHtml()],\n }),\n });\n this.modal.open(this.opts.mountParent);\n }\n\n destroy() {\n this._destroyCm();\n if (this.modal.el.parentElement) this.modal.close();\n }\n\n private _beautify() {\n if (!this.cm) return;\n const text = prettyHtml(this.cm.state.doc.toString());\n this.cm.dispatch({\n changes: { from: 0, to: this.cm.state.doc.length, insert: text },\n });\n }\n\n private _applyModalSize() {\n const size = this.maximized\n ? getCodeEditorModalMaximizedSize()\n : getCodeEditorModalDefaultSize();\n this.modal.setSize(size.width, size.height);\n this.modal.cardElement.classList.toggle('is-maximized', this.maximized);\n this._syncMaximizeButton();\n }\n\n private _toggleMaximize() {\n this.maximized = !this.maximized;\n writeMaximizedPref(this.maximized);\n this._applyModalSize();\n requestAnimationFrame(() => this.cm?.requestMeasure());\n }\n\n private _syncMaximizeButton() {\n this.maximizeBtn.title = this.maximized ? this.opts.t('common.restore') : this.opts.t('common.maximize');\n this.maximizeBtn.setAttribute('aria-pressed', this.maximized ? 'true' : 'false');\n this.maximizeBtn.replaceChildren(this.maximized ? iconRestore() : iconMaximize());\n }\n\n private _saveAndClose() {\n if (!this.cm || !this.blockId) return;\n const text = this.cm.state.doc.toString();\n const id = this.blockId;\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, id);\n if (l) l.block.lockedMjml = text;\n });\n this.modal.close();\n }\n\n private _destroyCm() {\n if (this.cm) {\n this.cm.destroy();\n this.cm = null;\n }\n this.blockId = null;\n this.modal.cardElement.classList.remove('is-maximized');\n }\n}\n\nfunction readMaximizedPref(): boolean {\n try {\n return localStorage.getItem(MAXIMIZED_PREF_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nfunction writeMaximizedPref(maximized: boolean) {\n try {\n localStorage.setItem(MAXIMIZED_PREF_KEY, maximized ? '1' : '0');\n } catch {\n /* ignore quota / private mode */\n }\n}\n\nfunction iconMaximize(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M4 10V4h6M10 10h6v6M10 4h6v6M4 10v6h6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>';\n return el;\n}\n\nfunction iconRestore(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M7 4H4v3M13 4h3v3M7 16H4v-3M13 16h3v-3\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>';\n return el;\n}\n","/**\n * contenteditable 富文本仍依赖 Document.execCommand / queryCommand* 系列 API。\n * 浏览器与 TypeScript lib.dom 虽已标记 deprecated,但目前无等价替代;集中封装便于 IDE 消警与日后迁移。\n */\nexport interface RichTextDocument extends Document {\n execCommand(commandId: string, showUI?: boolean, value?: string): boolean;\n queryCommandState(commandId: string): boolean;\n queryCommandValue(commandId: string): string;\n}\n\nfunction asRichTextDoc(doc: Document = document): RichTextDocument {\n return doc as RichTextDocument;\n}\n\nexport function richTextExecCommand(\n commandId: string,\n showUI = false,\n value?: string,\n doc: Document = document,\n): boolean {\n return asRichTextDoc(doc).execCommand(commandId, showUI, value);\n}\n\nexport function richTextQueryCommandState(commandId: string, doc: Document = document): boolean {\n return asRichTextDoc(doc).queryCommandState(commandId);\n}\n\nexport function richTextQueryCommandValue(commandId: string, doc: Document = document): string {\n return asRichTextDoc(doc).queryCommandValue(commandId);\n}\n","/** 是否仅为进入编辑时注入的占位 <br>(用户未改动) */\nexport function isRichHtmlEditorSeedOnly(html: string): boolean {\n const s = String(html ?? '').trim().toLowerCase();\n return s === '<br>' || s === '<br/>' || s === '<br />';\n}\n\n/** 是否包含换行(<br>) */\nexport function hasRichHtmlLineBreak(html: string): boolean {\n const tpl = document.createElement('template');\n tpl.innerHTML = String(html ?? '');\n return tpl.content.querySelector('br') != null;\n}\n\n/** 富文本纯文本(不 trim,保留空格;去掉零宽字符) */\nexport function getRichHtmlPlainText(html: string): string {\n const tpl = document.createElement('template');\n tpl.innerHTML = String(html ?? '');\n return (tpl.content.textContent ?? '').replace(/\\u200b/g, '');\n}\n\n/**\n * 富文本是否「完全无内容」。\n * 空格、&nbsp;、换行(<br>)均视为有效内容;仅空串或空标签壳子算空。\n */\nexport function isRichHtmlEffectivelyEmpty(html: string): boolean {\n const raw = String(html ?? '');\n if (!raw.trim()) return true;\n\n const tpl = document.createElement('template');\n tpl.innerHTML = raw;\n const root = tpl.content;\n\n if (root.querySelector('img')) return false;\n if (root.querySelector('br')) return false;\n\n const text = (root.textContent ?? '').replace(/\\u200b/g, '');\n return text.length === 0;\n}\n\n/** 提交前:完全无内容时统一为 '' */\nexport function normalizeRichHtmlForCommit(html: string): string {\n return isRichHtmlEffectivelyEmpty(html) ? '' : html;\n}\n","/**\n * 邮件编辑器品牌/主题色:写入 .sm-root 的 --sm-primary / --sm-primary-soft。\n */\n\n/** 合法则规范为 #RRGGBB(大写),否则 null */\nexport function normalizeAccentHex(input: string): string | null {\n const t = input.trim();\n if (!t) return null;\n const h = t.replace(/^#/, '');\n if (/^[0-9a-fA-F]{3}$/.test(h)) {\n return `#${(h[0] + h[0] + h[1] + h[1] + h[2] + h[2]).toUpperCase()}`;\n }\n if (/^[0-9a-fA-F]{6}$/.test(h)) {\n return `#${h.toUpperCase()}`;\n }\n return null;\n}\n\n/** 由 getComputedStyle 得到的 rgb(...) / rgba(...) 转 #rrggbb */\nexport function rgbCssToHex(rgb: string): string | null {\n const m = rgb.trim().match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (!m) return null;\n const h = (n: string) => Number(n).toString(16).padStart(2, '0');\n return `#${h(m[1])}${h(m[2])}${h(m[3])}`;\n}\n\n/**\n * 与浅色/深色界面配套的浅底强调色(选区、滑块 accent 等)。\n */\nexport function accentPrimarySoftRgba(primaryHex: string, isDarkChrome: boolean): string {\n const hex = normalizeAccentHex(primaryHex);\n if (!hex) return isDarkChrome ? 'rgba(129, 140, 248, 0.18)' : 'rgba(79, 70, 229, 0.12)';\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n const a = isDarkChrome ? 0.22 : 0.14;\n return `rgba(${r},${g},${b},${a})`;\n}\n","export type SimpleMailLocale = 'zh-CN' | 'en-US';\n\nexport type SimpleMailMessages = Record<string, string>;\n\nexport type SimpleMailMessagesInput = Partial<SimpleMailMessages>;\n\nexport type SimpleMailT = (key: string, params?: Record<string, string | number>) => string;\n\nexport interface SimpleMailI18nOptions {\n locale?: SimpleMailLocale;\n messages?: SimpleMailMessagesInput;\n}\n\nexport interface SimpleMailI18nContext {\n locale: SimpleMailLocale;\n messages: SimpleMailMessages;\n t: SimpleMailT;\n}\n\nexport const zhCNMessages: SimpleMailMessages = {\n 'common.cancel': '取消',\n 'common.close': '关闭',\n 'common.closeEsc': '关闭 Esc',\n 'common.save': '保存',\n 'common.beautify': '美化',\n 'common.maximize': '最大化',\n 'common.restore': '还原',\n 'common.delete': '删除',\n 'common.upload': '上传',\n 'common.add': '添加',\n 'common.insert': '插入',\n 'common.copy': '复制',\n 'common.image': '图片',\n 'common.noPermission': '无权限',\n 'common.noPermissionUpload': '无上传权限',\n 'common.noPermissionAdd': '无添加权限',\n 'common.noPermissionDelete': '无删除权限',\n 'common.left': '左',\n 'common.center': '居中',\n 'common.right': '右',\n 'common.inheritGlobal': '继承全局',\n 'common.dragSort': '拖拽排序',\n 'common.editText': '编辑文本',\n 'common.editCode': '编辑组件代码',\n 'common.clear': '清除',\n 'doc.defaultSubject': '一封新邮件',\n 'topbar.mode': '编辑模式',\n 'topbar.design': '设计',\n 'topbar.source': '源码',\n 'topbar.theme': '界面主题',\n 'topbar.light': '浅色',\n 'topbar.dark': '深色',\n 'topbar.system': '跟随系统',\n 'topbar.accentColor': '主题色',\n 'topbar.undoTitle': '撤销 ⌘Z',\n 'topbar.undo': '撤销',\n 'topbar.redoTitle': '重做 ⌘⇧Z',\n 'topbar.redo': '重做',\n 'topbar.clearCanvasTitle': '清空画布:移除画布上所有 Section 与组件',\n 'topbar.clearCanvas': '清空画布',\n 'topbar.resetContentTitle': '重置内容:恢复为预置邮件结构',\n 'topbar.resetContent': '重置内容',\n 'topbar.copyDesignTitle': '复制设计稿:将画布 JSON 写入剪贴板,可在另一封邮件中导入',\n 'topbar.copyDesign': '复制设计稿',\n 'topbar.importDesignTitle': '导入设计稿:从剪贴板或粘贴 JSON 覆盖当前画布',\n 'topbar.importDesign': '导入设计稿',\n 'topbar.preview': '预览',\n 'topbar.exportHtml': '导出 HTML',\n 'topbar.mailSettingsTitle': '邮件设置:主题、宽度与全局样式',\n 'topbar.mailSettings': '邮件设置',\n 'topbar.insertVariable': '插入变量',\n 'topbar.showLayoutBorders': '显示 Section / Block 边框',\n 'topbar.hideLayoutBorders': '隐藏 Section / Block 边框',\n 'topbar.fullscreen': '全屏',\n 'topbar.exitFullscreen': '退出全屏',\n 'leftPanel.layout': '布局',\n 'leftPanel.components': '组件',\n 'leftPanel.customTooltipSuffix': 'Navimow 定制组件,拖入列内使用',\n 'leftPanel.oneColumn': '一列',\n 'leftPanel.multiColumn': '多列',\n 'leftPanel.multiColumnTitle': '多列(右栏可调 2/3 列比例)',\n 'canvas.emptyHint': '从左侧拖入布局开始,或直接双击开始 ✦',\n 'canvas.addSection': '+ 添加 Section:',\n 'canvas.dynamicSectionLabel': '动态变量 {index} · {token}',\n 'canvas.sectionLabel': '区块 {index} · {layout}',\n 'canvas.sectionTitle': '{chip}。子组件铺满列内时:按 Esc 或 Alt+点击块可选中本节。',\n 'canvas.unknownBlock': '未知组件: {type}',\n 'canvas.emptyColumnHint': '拖入组件 · 双击插入文本',\n 'canvas.lockedCode': '已锁定为代码',\n 'rightPanel.docRoot.mail': '邮件',\n 'rightPanel.docRoot.layout': '版式',\n 'rightPanel.breadcrumb.selected': '当前选中',\n 'rightPanel.breadcrumb.selectTitle': '选中:{label}',\n 'rightPanel.layout.oneColumn': '一列',\n 'rightPanel.layout.columns': '多列',\n 'rightPanel.tabs.props': '属性',\n 'rightPanel.tabs.code': '代码',\n 'rightPanel.block.deleted': '该组件可能已被删除,请重新选中画布中的块。',\n 'rightPanel.block.locked': '该组件已被代码模式锁定。',\n 'rightPanel.block.restoreProps': '恢复为属性模式',\n 'rightPanel.block.unregistered': '未注册的组件: {type}',\n 'rightPanel.block.mjmlWarning': '检测到 MJML 标签(如 <mj-text>)。此处应只写 HTML,否则预览会显示源码。简单链接请用「文本」块。',\n 'rightPanel.doc.title': '邮件设置',\n 'rightPanel.doc.layoutTitle': '版式',\n 'rightPanel.doc.subject': '主题',\n 'rightPanel.doc.preheader': 'Preheader',\n 'rightPanel.doc.contentWidth': '内容宽度',\n 'rightPanel.doc.contentWidthPlaceholder': '如 600、600px、100%',\n 'rightPanel.doc.globalStyles': '全局样式',\n 'rightPanel.doc.pageBackground': '页面背景',\n 'rightPanel.doc.contentBackground': '内容背景',\n 'rightPanel.doc.fontFamily': '字体',\n 'rightPanel.doc.lineHeight': '行高',\n 'rightPanel.doc.lineHeightPlaceholder': '如 1.25 或 24px',\n 'rightPanel.doc.textColor': '正文颜色',\n 'rightPanel.doc.linkColor': '链接颜色',\n 'rightPanel.doc.fontSize': '字号',\n 'rightPanel.doc.fontSizeHelp': '滑块与数字均以 px 写入(如 16px)',\n 'rightPanel.doc.fontWeight': '字重',\n 'rightPanel.doc.listIndent': '列表默认缩进',\n 'rightPanel.doc.listIndentHelp': '未单独设置缩进的列表使用此值。',\n 'rightPanel.width.auto': '自适应',\n 'rightPanel.width.customHelp': '当前值为自定义写法,请直接编辑;清空后可选「自适应」再用滑块。',\n 'rightPanel.width.customPlaceholder': '如 480px、90%',\n 'rightPanel.inheritGlobal': '继承全局',\n 'rightPanel.spacing.suffix': '(上/右/下/左)',\n 'rightPanel.spacing.reset': '恢复默认',\n 'rightPanel.spacing.top': '上',\n 'rightPanel.spacing.right': '右',\n 'rightPanel.spacing.bottom': '下',\n 'rightPanel.spacing.left': '左',\n 'rightPanel.section.title': 'Section 设置',\n 'rightPanel.section.dynamicTitle': '动态变量 Section',\n 'rightPanel.section.dynamicKey': '动态变量名',\n 'rightPanel.section.dynamicKeyPlaceholder': '谨慎填写,需确认业务场景是否支持',\n 'rightPanel.section.dynamicKeyHelp': '本段内容将整体替换成该动态变量名',\n 'rightPanel.section.backgroundColor': '背景色',\n 'rightPanel.section.transparentPlaceholder': '留空=透明',\n 'rightPanel.section.width': '区域宽度',\n 'rightPanel.section.widthHelp': '留空=与邮件同宽;自适应等价于清空宽度',\n 'rightPanel.section.padding': '内边距',\n 'rightPanel.section.columnGap': '列间距 (px)',\n 'rightPanel.section.stackedGap': '堆叠纵向间距 (px)',\n 'rightPanel.section.stackedGapHelp': '小屏堆叠为单列后,相邻列之间的额外纵向间距;0 表示沿用块自身内边距。',\n 'rightPanel.section.preserveMobile': '小屏仍并排显示多列(可能字很窄)',\n 'rightPanel.section.preserveMobileHelp': '开启后 MJML 会生成 mj-group,移动端预览/导出与默认「小屏堆叠列」行为不同。',\n 'rightPanel.section.columnLayout': '列布局',\n 'rightPanel.social.labelPlaceholder': '标签文字(可选)',\n 'rightPanel.social.iconUrlPlaceholder': '图标 URL(可选)',\n 'rightPanel.social.add': '+ 添加社交链接',\n 'rightPanel.image.uploadTitle': '上传本地图片',\n 'rightPanel.image.upload': '上传',\n 'rightPanel.image.galleryTitle': '从图库选择',\n 'rightPanel.image.gallery': '图库',\n 'rightPanel.image.helpManual': '可手输 URL',\n 'rightPanel.image.helpUpload': '或使用「上传」',\n 'rightPanel.image.helpGallery': '或使用「图库」',\n 'rightPanel.image.helpSeparator': ';',\n 'rightPanel.image.helpEnd': '。',\n 'rightPanel.image.helpAssetsConfigured': '已传入 imageAssets:上传默认显示(提供 uploadImage 且未设 showUpload:false);图库需 showGallery:true,可使用内置 imageGallery 或自管 pickImageFromGallery。仍可手输 URL。',\n 'rightPanel.image.helpNoAssets': '在 MailEditor 的 imageAssets 中配置 uploadImage、内置 imageGallery 或 pickImageFromGallery 等;未配置时仅支持手输 URL。',\n 'rightPanel.color.unset': '未设置',\n 'rightPanel.fontSize.placeholder': '如 16px',\n 'rightPanel.code.title': '编辑组件 MJML 源码',\n 'rightPanel.code.restoreDefault': '恢复默认',\n 'rightPanel.code.saveLocked': '保存为锁定 MJML',\n 'rightPanel.code.help': '保存后该组件将以这段 MJML 直接输出,属性面板会被禁用,可点\"恢复默认\"取消锁定。',\n 'toolbar.fontDefault': '默认',\n 'toolbar.fontPingFang': '苹方/PingFang',\n 'toolbar.fontMicrosoftYaHei': '微软雅黑',\n 'toolbar.fontSimSun': '宋体',\n 'toolbar.bold': '加粗 ⌘B',\n 'toolbar.italic': '斜体 ⌘I',\n 'toolbar.underline': '下划线 ⌘U',\n 'toolbar.strikethrough': '删除线',\n 'toolbar.alignLeft': '左对齐',\n 'toolbar.alignCenter': '居中',\n 'toolbar.alignRight': '右对齐',\n 'toolbar.unorderedList': '无序列表',\n 'toolbar.orderedList': '有序列表',\n 'toolbar.listIndent': '列表缩进',\n 'toolbar.indent': '缩进',\n 'toolbar.fontFamily': '字体',\n 'toolbar.fontSize': '字号',\n 'toolbar.fontWeight': '字重',\n 'toolbar.textColor': '文字颜色',\n 'toolbar.textBackground': '文字背景色',\n 'toolbar.insertLink': '插入或编辑链接',\n 'toolbar.unlink': '取消链接',\n 'toolbar.clearFormat': '清除格式',\n 'toolbar.apply': '确定',\n 'variablePicker.title': '插入变量',\n 'variablePicker.pin': '固定面板',\n 'variablePicker.pinTitle': '固定面板,连续插入',\n 'variablePicker.unpinTitle': '取消固定',\n 'variablePicker.closeTitle': '关闭变量列表',\n 'variablePicker.empty': '暂无可用变量,请由宿主通过 setVariables 注入。',\n 'variablePicker.insertElement': '插入元素',\n 'variablePicker.copyTitle': '复制 {token}',\n 'gallery.title': '图库',\n 'gallery.searchPlaceholder': '搜索…',\n 'gallery.searchAria': '搜索图片',\n 'gallery.loadMore': '加载更多',\n 'gallery.empty': '暂无图片,可上传、添加链接或更换搜索条件',\n 'gallery.deleteTitle': '从图库删除',\n 'gallery.deleteConfirm': '确定从图库中删除这张图片?',\n 'gallery.deleteFailed': '删除失败',\n 'gallery.loadFailed': '加载失败',\n 'gallery.addUrlPlaceholder': '图片链接 https://…',\n 'gallery.addFailed': '添加失败',\n 'gallery.uploadFailed': '上传失败',\n 'source.compiledHtml': 'HTML(编译产物)',\n 'export.title': '导出 HTML',\n 'export.copyHtml': '复制 HTML',\n 'export.downloadHtml': '下载 .html',\n 'preview.title': '预览邮件',\n 'colorPicker.title': '选择颜色',\n 'colorPicker.custom': '自定义颜色',\n 'colorPicker.doubleClickConfirm': '{hex}(双击确认)',\n 'colorPicker.openTitle': '点击打开色板;预设色块可双击快速确认',\n 'importDoc.title': '导入设计稿',\n 'importDoc.hint1': '将覆盖当前画布上的所有 Section 与组件(全局样式会一并替换)。',\n 'importDoc.hint2': '若宿主管理邮件主题/宽度,这些字段可能保持不变。',\n 'importDoc.hint3': '粘贴由「复制设计稿」生成的 JSON,或裸 EmailDoc(version: \"1\")。',\n 'importDoc.placeholder': '在此粘贴设计稿 JSON…',\n 'importDoc.pasteFromClipboard': '从剪贴板填入',\n 'importDoc.apply': '应用并覆盖画布',\n 'importDoc.clipboardEmpty': '剪贴板为空或无法读取,请手动粘贴 JSON。',\n 'importDoc.clipboardFilled': '已从剪贴板填入,请确认后点击「应用并覆盖画布」。',\n 'importDoc.empty': '请先粘贴设计稿 JSON。',\n 'importDoc.invalid': 'JSON 无效或不是 simple-mail 设计稿格式。',\n 'blockCode.title': '编辑组件代码',\n 'blockCode.titleWithName': '编辑组件代码 · {name}',\n 'toast.copyDesignOk': '设计稿已复制到剪贴板',\n 'toast.copyDesignFailed': '复制失败,请检查浏览器剪贴板权限',\n 'toast.importDesignOk': '设计稿已导入',\n 'toast.noVariables': '暂无可用变量',\n 'toast.variableCopied': '已复制变量',\n 'toast.copiedToClipboard': '已复制到剪贴板',\n 'toast.copied': '已复制',\n 'blocks.text.name': '文本',\n 'blocks.html.name': 'HTML',\n 'blocks.image.name': '图片',\n 'blocks.social-group.name': '社交图标',\n 'blocks.hero.name': 'Hero 大图',\n 'blocks.button.name': '按钮',\n 'blocks.divider.name': '分隔线',\n 'blocks.spacer.name': '间距',\n 'blocks.logo.name': '公司 Logo',\n 'blocks.social.name': '社交链接',\n 'blocks.footer.name': '页脚',\n 'blocks.button.defaultText': '立即查看',\n 'blocks.text.defaultContent': '<p style=\"margin:0;\">在此处输入文本。<strong>双击</strong>进入编辑模式,<em>选中文字</em>会出现工具条;支持变量 {{user.name}}</p>',\n 'blocks.html.defaultHtml': '<p style=\"margin:0;\">在此写入任意 HTML,将经 <strong>mj-raw</strong> 原样输出到邮件。支持变量 {{user.name}}</p>',\n 'blocks.hero.defaultContent': '<p style=\"margin:0;font-size:28px;font-weight:700;line-height:1.25;\">主标题落在大图上</p><p style=\"margin:12px 0 0;font-size:16px;font-weight:400;opacity:0.95;line-height:1.5;\">支援变量与 <strong>双击编辑</strong>,与正文组件一致。</p>',\n 'blocks.footer.defaultCompanyName': '你的公司',\n 'blocks.footer.defaultAddress': '上海市某区某路某号',\n 'blocks.footer.defaultUnsubscribeText': '退订邮件',\n 'blocks.field.align': '对齐',\n 'blocks.field.textAlign': '文字水平对齐',\n 'blocks.field.verticalAlign': '文字垂直位置',\n 'blocks.field.color': '颜色',\n 'blocks.field.textColor': '文字颜色',\n 'blocks.field.backgroundColor': '背景色',\n 'blocks.field.backgroundUrl': '背景图',\n 'blocks.field.backgroundPlaceholderColor': '背景占位色',\n 'blocks.field.heightPx': '高度 (px)',\n 'blocks.field.areaHeightPx': '区域高度 (px)',\n 'blocks.field.width': '宽度',\n 'blocks.field.widthPx': '宽度 (px)',\n 'blocks.field.widthPercentOrPx': '宽度 (% 或 px)',\n 'blocks.field.thicknessPx': '粗细 (px)',\n 'blocks.field.padding': '内边距',\n 'blocks.field.margin': '外边距',\n 'blocks.field.topMargin': '上边距',\n 'blocks.field.bottomMargin': '下边距',\n 'blocks.field.text': '文字',\n 'blocks.field.link': '链接',\n 'blocks.field.href': '点击跳转',\n 'blocks.field.imageUrl': '图片地址',\n 'blocks.field.alt': '替代文本',\n 'blocks.field.fontSize': '字号',\n 'blocks.field.fontFamily': '字体',\n 'blocks.field.fontWeight': '字重',\n 'blocks.field.lineHeight': '行高',\n 'blocks.field.contentHtml': '内容(HTML,备用)',\n 'blocks.field.bodyHtml': '正文(HTML)',\n 'blocks.field.html': 'HTML',\n 'blocks.field.borderRadius': '圆角 (px)',\n 'blocks.field.buttonInnerPaddingV': '按钮内上下边距',\n 'blocks.field.buttonInnerPaddingH': '按钮内左右边距',\n 'blocks.field.logoImage': 'Logo 图片',\n 'blocks.field.websiteLink': '官网链接',\n 'blocks.field.socialLinks': '社交链接',\n 'blocks.field.labelFontSize': '标签字号 (px)',\n 'blocks.field.labelFontWeight': '标签字重',\n 'blocks.field.labelColor': '标签颜色',\n 'blocks.field.iconSize': '图标尺寸 (px)',\n 'blocks.field.iconRadius': '图标圆角 (px)',\n 'blocks.field.iconSpacing': '图标间距 (px)',\n 'blocks.field.companyName': '公司名称',\n 'blocks.field.address': '地址',\n 'blocks.field.unsubscribeText': '退订文案',\n 'blocks.field.unsubscribeLink': '退订链接',\n 'blocks.field.imageDescription': '图片描述',\n 'blocks.field.inheritGlobalPlaceholder': '继承全局',\n 'blocks.field.buttonTextPlaceholder': '按钮文字',\n 'blocks.field.textPlaceholder': '输入文本…',\n 'blocks.field.htmlPlaceholder': '输入 HTML…',\n 'blocks.field.heroPlaceholder': '编写覆盖在图片上的文案…',\n 'blocks.help.globalLineHeight': '留空则使用邮件设置里的全局行距',\n 'blocks.help.canvasEditRecommended': '建议直接在画布双击编辑;这里保留为高级编辑入口。',\n 'blocks.help.canvasEditRecommendedShort': '建议在画布内双击编辑;此处供高级修改。',\n 'blocks.help.htmlOnly': '只写 HTML(如 <a>、<table>),不要写 <mj-text> 等 MJML 标签;MJML 标签在 mj-raw 内不会被编译。简单链接建议用「文本」块。',\n 'blocks.help.imageFallbackColor': '图片加载失败时的底色',\n 'blocks.help.imageAutoHeight': '0 为自适应高度;填写固定值时画布与 MJML 会限制显示高度(预览可用 object-fit: cover)',\n 'blocks.help.buttonWidth': '支持纯数字(按 px)、带 px 或百分比',\n 'blocks.help.socialLinks': '每行:平台、链接、可选标签文字、自定义图标 URL、图标背景色。标签的字号/字重/颜色在下方统一设置。',\n 'blocks.help.bizSocialLinks': '平台:X、Rabbit、Facebook、TikTok、Instagram (ig)。可填标签、自定义图标 URL。MJML 侧 Rabbit/TikTok 使用 web 占位图标,需要品牌图时请填「图标 URL」。',\n 'blocks.help.iconRadius': '0 为方形直角;填较大值(如 999)或与尺寸一半相当时为圆形(默认圆形)。',\n 'blocks.help.iconSpacing': '每个图标周围的留白,横向即图标之间的间隔(MJML inner-padding)。',\n 'blocks.help.bizIconSpacing': '图标之间的间隔(MJML inner-padding)。',\n 'blocks.placeholder.buttonWidth': '留空=自适应,如 280px、100%',\n 'blocks.option.top': '靠上',\n 'blocks.option.middle': '居中',\n 'blocks.option.bottom': '靠下',\n};\n\nexport const enUSMessages: SimpleMailMessages = {\n 'common.cancel': 'Cancel',\n 'common.close': 'Close',\n 'common.closeEsc': 'Close Esc',\n 'common.save': 'Save',\n 'common.beautify': 'Format',\n 'common.maximize': 'Maximize',\n 'common.restore': 'Restore',\n 'common.delete': 'Delete',\n 'common.upload': 'Upload',\n 'common.add': 'Add',\n 'common.insert': 'Insert',\n 'common.copy': 'Copy',\n 'common.image': 'Image',\n 'common.noPermission': 'No permission',\n 'common.noPermissionUpload': 'No upload permission',\n 'common.noPermissionAdd': 'No add permission',\n 'common.noPermissionDelete': 'No delete permission',\n 'common.left': 'Left',\n 'common.center': 'Center',\n 'common.right': 'Right',\n 'common.inheritGlobal': 'Inherit global',\n 'common.dragSort': 'Drag to reorder',\n 'common.editText': 'Edit text',\n 'common.editCode': 'Edit block code',\n 'common.clear': 'Clear',\n 'doc.defaultSubject': 'New email',\n 'topbar.mode': 'Editor mode',\n 'topbar.design': 'Design',\n 'topbar.source': 'Source',\n 'topbar.theme': 'Interface theme',\n 'topbar.light': 'Light',\n 'topbar.dark': 'Dark',\n 'topbar.system': 'System',\n 'topbar.accentColor': 'Accent color',\n 'topbar.undoTitle': 'Undo ⌘Z',\n 'topbar.undo': 'Undo',\n 'topbar.redoTitle': 'Redo ⌘⇧Z',\n 'topbar.redo': 'Redo',\n 'topbar.clearCanvasTitle': 'Clear canvas: remove all sections and blocks',\n 'topbar.clearCanvas': 'Clear canvas',\n 'topbar.resetContentTitle': 'Reset content: restore the preset email layout',\n 'topbar.resetContent': 'Reset content',\n 'topbar.copyDesignTitle': 'Copy design: write the canvas JSON to the clipboard for reuse',\n 'topbar.copyDesign': 'Copy design',\n 'topbar.importDesignTitle': 'Import design: paste JSON or read from the clipboard to replace the canvas',\n 'topbar.importDesign': 'Import design',\n 'topbar.preview': 'Preview',\n 'topbar.exportHtml': 'Export HTML',\n 'topbar.mailSettingsTitle': 'Email settings: subject, width, and global styles',\n 'topbar.mailSettings': 'Email settings',\n 'topbar.insertVariable': 'Insert variable',\n 'topbar.showLayoutBorders': 'Show section/block borders',\n 'topbar.hideLayoutBorders': 'Hide section/block borders',\n 'topbar.fullscreen': 'Fullscreen',\n 'topbar.exitFullscreen': 'Exit fullscreen',\n 'leftPanel.layout': 'Layout',\n 'leftPanel.components': 'Components',\n 'leftPanel.customTooltipSuffix': 'Custom Navimow block. Drag it into a column.',\n 'leftPanel.oneColumn': 'One column',\n 'leftPanel.multiColumn': 'Columns',\n 'leftPanel.multiColumnTitle': 'Columns (adjust 2/3-column ratios in the right panel)',\n 'canvas.emptyHint': 'Drag a layout from the left, or double-click to start ✦',\n 'canvas.addSection': '+ Add section:',\n 'canvas.dynamicSectionLabel': 'Dynamic variable {index} · {token}',\n 'canvas.sectionLabel': 'Section {index} · {layout}',\n 'canvas.sectionTitle': '{chip}. When child blocks fill the column, press Esc or Alt-click a block to select this section.',\n 'canvas.unknownBlock': 'Unknown block: {type}',\n 'canvas.emptyColumnHint': 'Drag in a block · Double-click to insert text',\n 'canvas.lockedCode': 'Locked as code',\n 'rightPanel.docRoot.mail': 'Email',\n 'rightPanel.docRoot.layout': 'Layout',\n 'rightPanel.breadcrumb.selected': 'Current selection',\n 'rightPanel.breadcrumb.selectTitle': 'Select: {label}',\n 'rightPanel.layout.oneColumn': 'One column',\n 'rightPanel.layout.columns': 'Columns',\n 'rightPanel.tabs.props': 'Properties',\n 'rightPanel.tabs.code': 'Code',\n 'rightPanel.block.deleted': 'This block may have been deleted. Select a block on the canvas again.',\n 'rightPanel.block.locked': 'This block is locked in code mode.',\n 'rightPanel.block.restoreProps': 'Restore property mode',\n 'rightPanel.block.unregistered': 'Unregistered block: {type}',\n 'rightPanel.block.mjmlWarning': 'MJML tags were detected, such as <mj-text>. Write HTML only here, otherwise the preview will show source code. Use a Text block for simple links.',\n 'rightPanel.doc.title': 'Email settings',\n 'rightPanel.doc.layoutTitle': 'Layout',\n 'rightPanel.doc.subject': 'Subject',\n 'rightPanel.doc.preheader': 'Preheader',\n 'rightPanel.doc.contentWidth': 'Content width',\n 'rightPanel.doc.contentWidthPlaceholder': 'e.g. 600, 600px, or 100%',\n 'rightPanel.doc.globalStyles': 'Global styles',\n 'rightPanel.doc.pageBackground': 'Page background',\n 'rightPanel.doc.contentBackground': 'Content background',\n 'rightPanel.doc.fontFamily': 'Font family',\n 'rightPanel.doc.lineHeight': 'Line height',\n 'rightPanel.doc.lineHeightPlaceholder': 'e.g. 1.25 or 24px',\n 'rightPanel.doc.textColor': 'Body color',\n 'rightPanel.doc.linkColor': 'Link color',\n 'rightPanel.doc.fontSize': 'Font size',\n 'rightPanel.doc.fontSizeHelp': 'The slider and number input both write px values, such as 16px.',\n 'rightPanel.doc.fontWeight': 'Font weight',\n 'rightPanel.doc.listIndent': 'Default list indent',\n 'rightPanel.doc.listIndentHelp': 'Lists without their own indent use this value.',\n 'rightPanel.width.auto': 'Auto',\n 'rightPanel.width.customHelp': 'This value uses custom syntax. Edit it directly, or clear it to choose Auto and use the slider.',\n 'rightPanel.width.customPlaceholder': 'e.g. 480px or 90%',\n 'rightPanel.inheritGlobal': 'Inherit global',\n 'rightPanel.spacing.suffix': ' (top/right/bottom/left)',\n 'rightPanel.spacing.reset': 'Reset',\n 'rightPanel.spacing.top': 'Top',\n 'rightPanel.spacing.right': 'Right',\n 'rightPanel.spacing.bottom': 'Bottom',\n 'rightPanel.spacing.left': 'Left',\n 'rightPanel.section.title': 'Section settings',\n 'rightPanel.section.dynamicTitle': 'Dynamic variable section',\n 'rightPanel.section.dynamicKey': 'Dynamic variable name',\n 'rightPanel.section.dynamicKeyPlaceholder': 'Use with care. Confirm the business flow supports it.',\n 'rightPanel.section.dynamicKeyHelp': 'This whole section will be replaced by the dynamic variable name.',\n 'rightPanel.section.backgroundColor': 'Background color',\n 'rightPanel.section.transparentPlaceholder': 'Empty = transparent',\n 'rightPanel.section.width': 'Section width',\n 'rightPanel.section.widthHelp': 'Empty = email width. Auto is equivalent to clearing the width.',\n 'rightPanel.section.padding': 'Padding',\n 'rightPanel.section.columnGap': 'Column gap (px)',\n 'rightPanel.section.stackedGap': 'Stacked vertical gap (px)',\n 'rightPanel.section.stackedGapHelp': 'Extra vertical space between columns once they stack on small screens. 0 keeps each block own padding.',\n 'rightPanel.section.preserveMobile': 'Keep columns side by side on small screens',\n 'rightPanel.section.preserveMobileHelp': 'When enabled, MJML outputs mj-group. Mobile preview/export differs from the default stacked-column behavior.',\n 'rightPanel.section.columnLayout': 'Column layout',\n 'rightPanel.social.labelPlaceholder': 'Label text (optional)',\n 'rightPanel.social.iconUrlPlaceholder': 'Icon URL (optional)',\n 'rightPanel.social.add': '+ Add social link',\n 'rightPanel.image.uploadTitle': 'Upload local image',\n 'rightPanel.image.upload': 'Upload',\n 'rightPanel.image.galleryTitle': 'Choose from gallery',\n 'rightPanel.image.gallery': 'Gallery',\n 'rightPanel.image.helpManual': 'Enter a URL manually',\n 'rightPanel.image.helpUpload': 'or use Upload',\n 'rightPanel.image.helpGallery': 'or use Gallery',\n 'rightPanel.image.helpSeparator': '; ',\n 'rightPanel.image.helpEnd': '.',\n 'rightPanel.image.helpAssetsConfigured': 'imageAssets is configured: upload is shown by default when uploadImage exists and showUpload is not false; gallery requires showGallery:true and either imageGallery or pickImageFromGallery. Manual URLs are still supported.',\n 'rightPanel.image.helpNoAssets': 'Configure uploadImage, imageGallery, or pickImageFromGallery in MailEditor imageAssets. Without them, only manual URLs are supported.',\n 'rightPanel.color.unset': 'Not set',\n 'rightPanel.fontSize.placeholder': 'e.g. 16px',\n 'rightPanel.code.title': 'Edit block MJML source',\n 'rightPanel.code.restoreDefault': 'Restore default',\n 'rightPanel.code.saveLocked': 'Save as locked MJML',\n 'rightPanel.code.help': 'After saving, this block will output this MJML directly, and the properties panel will be disabled. Use \"Restore default\" to unlock it.',\n 'toolbar.fontDefault': 'Default',\n 'toolbar.fontPingFang': 'PingFang SC',\n 'toolbar.fontMicrosoftYaHei': 'Microsoft YaHei',\n 'toolbar.fontSimSun': 'SimSun',\n 'toolbar.bold': 'Bold ⌘B',\n 'toolbar.italic': 'Italic ⌘I',\n 'toolbar.underline': 'Underline ⌘U',\n 'toolbar.strikethrough': 'Strikethrough',\n 'toolbar.alignLeft': 'Align left',\n 'toolbar.alignCenter': 'Align center',\n 'toolbar.alignRight': 'Align right',\n 'toolbar.unorderedList': 'Bulleted list',\n 'toolbar.orderedList': 'Numbered list',\n 'toolbar.listIndent': 'List indent',\n 'toolbar.indent': 'Indent',\n 'toolbar.fontFamily': 'Font family',\n 'toolbar.fontSize': 'Font size',\n 'toolbar.fontWeight': 'Font weight',\n 'toolbar.textColor': 'Text color',\n 'toolbar.textBackground': 'Text background',\n 'toolbar.insertLink': 'Insert or edit link',\n 'toolbar.unlink': 'Remove link',\n 'toolbar.clearFormat': 'Clear formatting',\n 'toolbar.apply': 'Apply',\n 'variablePicker.title': 'Insert variable',\n 'variablePicker.pin': 'Pin panel',\n 'variablePicker.pinTitle': 'Pin panel for repeated inserts',\n 'variablePicker.unpinTitle': 'Unpin panel',\n 'variablePicker.closeTitle': 'Close variable list',\n 'variablePicker.empty': 'No variables available. Inject them from the host with setVariables.',\n 'variablePicker.insertElement': 'Insert element',\n 'variablePicker.copyTitle': 'Copy {token}',\n 'gallery.title': 'Gallery',\n 'gallery.searchPlaceholder': 'Search...',\n 'gallery.searchAria': 'Search images',\n 'gallery.loadMore': 'Load more',\n 'gallery.empty': 'No images. Upload one, add a link, or try another search.',\n 'gallery.deleteTitle': 'Delete from gallery',\n 'gallery.deleteConfirm': 'Delete this image from the gallery?',\n 'gallery.deleteFailed': 'Delete failed',\n 'gallery.loadFailed': 'Load failed',\n 'gallery.addUrlPlaceholder': 'Image URL https://...',\n 'gallery.addFailed': 'Add failed',\n 'gallery.uploadFailed': 'Upload failed',\n 'source.compiledHtml': 'HTML (compiled output)',\n 'export.title': 'Export HTML',\n 'export.copyHtml': 'Copy HTML',\n 'export.downloadHtml': 'Download .html',\n 'preview.title': 'Preview email',\n 'colorPicker.title': 'Choose color',\n 'colorPicker.custom': 'Custom color',\n 'colorPicker.doubleClickConfirm': '{hex} (double-click to confirm)',\n 'colorPicker.openTitle': 'Click to open the palette. Double-click a swatch to confirm.',\n 'importDoc.title': 'Import design',\n 'importDoc.hint1': 'This will replace all sections and blocks on the current canvas, including global styles.',\n 'importDoc.hint2': 'If the host manages subject or width, those fields may remain unchanged.',\n 'importDoc.hint3': 'Paste JSON generated by \"Copy design\", or a raw EmailDoc with version: \"1\".',\n 'importDoc.placeholder': 'Paste design JSON here...',\n 'importDoc.pasteFromClipboard': 'Paste from clipboard',\n 'importDoc.apply': 'Apply and replace canvas',\n 'importDoc.clipboardEmpty': 'Clipboard is empty or unreadable. Paste JSON manually.',\n 'importDoc.clipboardFilled': 'Filled from clipboard. Review it, then apply and replace the canvas.',\n 'importDoc.empty': 'Paste design JSON first.',\n 'importDoc.invalid': 'Invalid JSON or not a simple-mail design.',\n 'blockCode.title': 'Edit block code',\n 'blockCode.titleWithName': 'Edit block code · {name}',\n 'toast.copyDesignOk': 'Design copied to clipboard',\n 'toast.copyDesignFailed': 'Copy failed. Check browser clipboard permissions.',\n 'toast.importDesignOk': 'Design imported',\n 'toast.noVariables': 'No variables available',\n 'toast.variableCopied': 'Variable copied',\n 'toast.copiedToClipboard': 'Copied to clipboard',\n 'toast.copied': 'Copied',\n 'blocks.text.name': 'Text',\n 'blocks.html.name': 'HTML',\n 'blocks.image.name': 'Image',\n 'blocks.social-group.name': 'Social icons',\n 'blocks.hero.name': 'Hero image',\n 'blocks.button.name': 'Button',\n 'blocks.divider.name': 'Divider',\n 'blocks.spacer.name': 'Spacer',\n 'blocks.logo.name': 'Logo',\n 'blocks.social.name': 'Social card',\n 'blocks.footer.name': 'Footer',\n 'blocks.button.defaultText': 'View now',\n 'blocks.text.defaultContent': '<p style=\"margin:0;\">Enter text here. <strong>Double-click</strong> to edit, select text to show the toolbar, and use variables like {{user.name}}.</p>',\n 'blocks.html.defaultHtml': '<p style=\"margin:0;\">Write any HTML here. It will be output through <strong>mj-raw</strong>. Variables like {{user.name}} are supported.</p>',\n 'blocks.hero.defaultContent': '<p style=\"margin:0;font-size:28px;font-weight:700;line-height:1.25;\">Main headline on the hero image</p><p style=\"margin:12px 0 0;font-size:16px;font-weight:400;opacity:0.95;line-height:1.5;\">Supports variables and <strong>double-click editing</strong>, just like text blocks.</p>',\n 'blocks.footer.defaultCompanyName': 'Your company',\n 'blocks.footer.defaultAddress': '123 Example Street, Shanghai',\n 'blocks.footer.defaultUnsubscribeText': 'Unsubscribe',\n 'blocks.field.align': 'Alignment',\n 'blocks.field.textAlign': 'Text alignment',\n 'blocks.field.verticalAlign': 'Vertical text position',\n 'blocks.field.color': 'Color',\n 'blocks.field.textColor': 'Text color',\n 'blocks.field.backgroundColor': 'Background color',\n 'blocks.field.backgroundUrl': 'Background image',\n 'blocks.field.backgroundPlaceholderColor': 'Fallback background',\n 'blocks.field.heightPx': 'Height (px)',\n 'blocks.field.areaHeightPx': 'Area height (px)',\n 'blocks.field.width': 'Width',\n 'blocks.field.widthPx': 'Width (px)',\n 'blocks.field.widthPercentOrPx': 'Width (% or px)',\n 'blocks.field.thicknessPx': 'Thickness (px)',\n 'blocks.field.padding': 'Padding',\n 'blocks.field.margin': 'Margin',\n 'blocks.field.topMargin': 'Top margin',\n 'blocks.field.bottomMargin': 'Bottom margin',\n 'blocks.field.text': 'Text',\n 'blocks.field.link': 'Link',\n 'blocks.field.href': 'Click target',\n 'blocks.field.imageUrl': 'Image URL',\n 'blocks.field.alt': 'Alt text',\n 'blocks.field.fontSize': 'Font size',\n 'blocks.field.fontFamily': 'Font family',\n 'blocks.field.fontWeight': 'Font weight',\n 'blocks.field.lineHeight': 'Line height',\n 'blocks.field.contentHtml': 'Content (HTML, fallback)',\n 'blocks.field.bodyHtml': 'Body (HTML)',\n 'blocks.field.html': 'HTML',\n 'blocks.field.borderRadius': 'Radius (px)',\n 'blocks.field.buttonInnerPaddingV': 'Button vertical padding',\n 'blocks.field.buttonInnerPaddingH': 'Button horizontal padding',\n 'blocks.field.logoImage': 'Logo image',\n 'blocks.field.websiteLink': 'Website link',\n 'blocks.field.socialLinks': 'Social links',\n 'blocks.field.labelFontSize': 'Label font size (px)',\n 'blocks.field.labelFontWeight': 'Label font weight',\n 'blocks.field.labelColor': 'Label color',\n 'blocks.field.iconSize': 'Icon size (px)',\n 'blocks.field.iconRadius': 'Icon radius (px)',\n 'blocks.field.iconSpacing': 'Icon spacing (px)',\n 'blocks.field.companyName': 'Company name',\n 'blocks.field.address': 'Address',\n 'blocks.field.unsubscribeText': 'Unsubscribe text',\n 'blocks.field.unsubscribeLink': 'Unsubscribe link',\n 'blocks.field.imageDescription': 'Image description',\n 'blocks.field.inheritGlobalPlaceholder': 'Inherit global',\n 'blocks.field.buttonTextPlaceholder': 'Button text',\n 'blocks.field.textPlaceholder': 'Enter text...',\n 'blocks.field.htmlPlaceholder': 'Enter HTML...',\n 'blocks.field.heroPlaceholder': 'Write copy over the image...',\n 'blocks.help.globalLineHeight': 'Leave empty to use the global line height from email settings.',\n 'blocks.help.canvasEditRecommended': 'Double-click on the canvas to edit directly. This field remains as an advanced fallback.',\n 'blocks.help.canvasEditRecommendedShort': 'Double-click on the canvas to edit. Use this field for advanced edits.',\n 'blocks.help.htmlOnly': 'Write HTML only, such as <a> or <table>. Do not use MJML tags like <mj-text>; MJML tags inside mj-raw will not compile. Use a Text block for simple links.',\n 'blocks.help.imageFallbackColor': 'Background color used if the image fails to load.',\n 'blocks.help.imageAutoHeight': '0 means automatic height. Fixed values limit both canvas and MJML display height; preview uses object-fit: cover.',\n 'blocks.help.buttonWidth': 'Supports plain numbers as px, px values, or percentages.',\n 'blocks.help.socialLinks': 'Each row contains a network, link, optional label text, custom icon URL, and icon background color. Label font size, weight, and color are configured below.',\n 'blocks.help.bizSocialLinks': 'Networks: X, Rabbit, Facebook, TikTok, and Instagram (ig). Labels and custom icon URLs are optional. Rabbit/TikTok use the web placeholder icon in MJML unless you provide an icon URL.',\n 'blocks.help.iconRadius': '0 gives square corners. Large values such as 999, or about half the icon size, make it circular.',\n 'blocks.help.iconSpacing': 'Space around each icon; horizontally this is the gap between icons (MJML inner-padding).',\n 'blocks.help.bizIconSpacing': 'Gap between icons (MJML inner-padding).',\n 'blocks.placeholder.buttonWidth': 'Empty = auto, e.g. 280px or 100%',\n 'blocks.option.top': 'Top',\n 'blocks.option.middle': 'Middle',\n 'blocks.option.bottom': 'Bottom',\n};\n\nconst FALLBACK_LOCALE: SimpleMailLocale = 'zh-CN';\n\nexport function createI18nContext(options: SimpleMailI18nOptions = {}): SimpleMailI18nContext {\n const locale = options.locale ?? FALLBACK_LOCALE;\n const base = locale === 'en-US' ? enUSMessages : zhCNMessages;\n const messages: SimpleMailMessages = { ...zhCNMessages, ...base };\n for (const [key, value] of Object.entries(options.messages ?? {})) {\n if (typeof value === 'string') messages[key] = value;\n }\n const t: SimpleMailT = (key, params) => {\n let text = messages[key] ?? zhCNMessages[key] ?? key;\n if (params) {\n for (const [name, value] of Object.entries(params)) {\n text = text.replaceAll(`{${name}}`, String(value));\n }\n }\n return text;\n };\n return { locale, messages, t };\n}\n","import { normalizeAccentHex } from '../utils/accentColor';\nimport { h } from '../utils/dom';\nimport { createI18nContext, type SimpleMailT } from '../i18n';\n\n/** 邮件常用预设色 */\nexport const COLOR_PICKER_PALETTE = [\n '#FFFFFF',\n '#F5F6F8',\n '#E6E8EC',\n '#9AA0A6',\n '#6B7280',\n '#433F3F',\n '#1F2328',\n '#000000',\n '#DC2626',\n '#EA580C',\n '#FF5A00',\n '#CA8A04',\n '#16A34A',\n '#059669',\n '#2563EB',\n '#4F46E5',\n '#7C3AED',\n '#DB2777',\n '#FEE2E2',\n '#FFEDD5',\n '#FEF3C7',\n '#D1FAE5',\n '#EEF2FF',\n '#F3E8FF',\n] as const;\n\nexport interface ColorPickerPopoverOptions {\n anchor: HTMLElement;\n layerRoot: HTMLElement;\n value: string;\n placeholder?: string;\n /** 显示「清除」并允许提交空值 */\n allowClear?: boolean;\n t?: SimpleMailT;\n /** 每次改色立即 onCommit(富文本/顶栏) */\n liveCommit?: boolean;\n onPreview?: (hex: string) => void;\n onCommit: (hex: string) => void;\n onClear?: () => void;\n /** 打开前调用(富文本:在失焦前保存选区) */\n onBeforeOpen?: () => void;\n /** 为 false 时不自动 focus 十六进制输入,避免抢编辑区选区 */\n autoFocusHex?: boolean;\n onClosed?: () => void;\n}\n\nlet activeTeardown: (() => void) | null = null;\n\nexport function isColorPickerOpen(): boolean {\n return activeTeardown !== null;\n}\n\nexport function closeActiveColorPicker(): void {\n activeTeardown?.();\n activeTeardown = null;\n}\n\nfunction positionLayer(layer: HTMLElement, anchor: HTMLElement, layerRoot: HTMLElement) {\n const rect = anchor.getBoundingClientRect();\n const rootRect = layerRoot.getBoundingClientRect();\n layer.style.top = `${rect.bottom - rootRect.top + 4}px`;\n layer.style.left = `${Math.max(4, rect.left - rootRect.left)}px`;\n\n requestAnimationFrame(() => {\n const popRect = layer.getBoundingClientRect();\n if (popRect.right > rootRect.right - 8) {\n layer.style.left = `${Math.max(4, parseFloat(layer.style.left) - (popRect.right - rootRect.right + 8))}px`;\n }\n if (popRect.bottom > window.innerHeight - 8) {\n layer.style.top = `${rect.top - rootRect.top - popRect.height - 4}px`;\n }\n });\n}\n\n/** 点击色块网格缝隙等无焦点区域时,避免编辑区 blur 导致误提交 */\nfunction guardInlineEditFocus(layer: HTMLElement) {\n layer.addEventListener(\n 'mousedown',\n (e) => {\n const t = e.target as Element;\n if (t.closest('input, button, select, textarea, a, [contenteditable]')) return;\n e.preventDefault();\n },\n true,\n );\n}\n\nfunction syncNativeInput(native: HTMLInputElement, hex: string) {\n const n = normalizeAccentHex(hex);\n if (n) native.value = n;\n}\n\n/** 打开自定义色板(含关闭按钮);点击色卡触发,不再使用系统色板。 */\nexport function openColorPickerPopover(opts: ColorPickerPopoverOptions): void {\n closeActiveColorPicker();\n opts.onBeforeOpen?.();\n const t = opts.t ?? createI18nContext().t;\n\n const initialHex = normalizeAccentHex(opts.value);\n let draft = initialHex ?? '#4F46E5';\n let closed = false;\n\n const layer = h('div', {\n class: 'sm-color-picker-layer',\n 'data-sm-color-picker-layer': '',\n });\n const panel = h('div', {\n class: 'sm-color-picker',\n role: 'dialog',\n 'aria-label': t('colorPicker.title'),\n });\n\n const closeBtn = h(\n 'button',\n {\n class: 'sm-color-picker__close',\n type: 'button',\n title: t('common.close'),\n 'aria-label': t('common.close'),\n },\n ['×'],\n );\n\n const head = h('div', { class: 'sm-color-picker__head' }, [\n h('span', { class: 'sm-color-picker__title' }, [t('colorPicker.title')]),\n closeBtn,\n ]);\n\n const native = h('input', {\n class: 'sm-color-picker__native',\n type: 'color',\n 'aria-label': t('colorPicker.custom'),\n }) as HTMLInputElement;\n\n const hexInput = h('input', {\n class: 'sm-input sm-color-picker__hex',\n type: 'text',\n placeholder: opts.placeholder ?? '#RRGGBB',\n }) as HTMLInputElement;\n\n const applyDraft = (hex: string, commit: boolean) => {\n const n = normalizeAccentHex(hex);\n if (!n) return;\n draft = n;\n syncNativeInput(native, n);\n hexInput.value = n;\n opts.onPreview?.(n);\n if (commit || opts.liveCommit) opts.onCommit(n);\n };\n\n syncNativeInput(native, draft);\n hexInput.value = initialHex ?? '';\n\n const teardown = (commit: boolean) => {\n if (closed) return;\n closed = true;\n activeTeardown = null;\n document.removeEventListener('keydown', onKey, true);\n document.removeEventListener('mousedown', onDoc, true);\n layer.remove();\n if (commit && !opts.liveCommit) {\n const n = normalizeAccentHex(draft);\n if (n) opts.onCommit(n);\n }\n opts.onClosed?.();\n };\n\n const swatchGrid = h('div', { class: 'sm-color-picker__swatches' });\n for (const hex of COLOR_PICKER_PALETTE) {\n const btn = h('button', {\n class: 'sm-color-picker__swatch',\n type: 'button',\n title: t('colorPicker.doubleClickConfirm', { hex }),\n style: `background:${hex}`,\n 'aria-label': hex,\n });\n btn.addEventListener('click', () => applyDraft(hex, false));\n btn.addEventListener('dblclick', (e) => {\n e.preventDefault();\n applyDraft(hex, true);\n teardown(true);\n });\n swatchGrid.append(btn);\n }\n\n native.addEventListener('input', () => applyDraft(native.value, false));\n\n hexInput.addEventListener('input', () => {\n const n = normalizeAccentHex(hexInput.value);\n if (n) applyDraft(n, false);\n });\n hexInput.addEventListener('keydown', (e) => {\n const ke = e as KeyboardEvent;\n if (ke.key === 'Enter') {\n ke.preventDefault();\n const n = normalizeAccentHex(hexInput.value);\n if (n) {\n applyDraft(n, true);\n teardown(true);\n }\n }\n });\n\n const footKids: HTMLElement[] = [];\n if (opts.allowClear) {\n footKids.push(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--ghost sm-color-picker__clear',\n type: 'button',\n onclick: () => {\n opts.onClear?.();\n teardown(false);\n },\n },\n [t('common.clear')],\n ),\n );\n }\n\n panel.append(head, swatchGrid, native, hexInput);\n if (footKids.length) panel.append(h('div', { class: 'sm-color-picker__foot' }, footKids));\n\n layer.append(panel);\n guardInlineEditFocus(layer);\n opts.layerRoot.append(layer);\n positionLayer(layer, opts.anchor, opts.layerRoot);\n\n closeBtn.addEventListener('click', (e) => {\n e.preventDefault();\n teardown(true);\n });\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n if (initialHex) opts.onPreview?.(initialHex);\n teardown(false);\n }\n };\n\n const onDoc = (ev: MouseEvent) => {\n const t = ev.target as Node;\n if (layer.contains(t) || opts.anchor.contains(t)) return;\n teardown(true);\n };\n\n document.addEventListener('keydown', onKey, true);\n setTimeout(() => document.addEventListener('mousedown', onDoc, true), 0);\n\n activeTeardown = () => teardown(true);\n if (opts.autoFocusHex !== false) hexInput.focus();\n}\n\nexport interface BindColorPickerInputOptions\n extends Omit<ColorPickerPopoverOptions, 'anchor' | 'layerRoot' | 'value'> {\n layerRoot?: HTMLElement;\n getValue?: () => string;\n}\n\n/** 拦截色卡点击,改为打开自定义色板。 */\nexport function bindColorPickerInput(\n pick: HTMLInputElement,\n opts: BindColorPickerInputOptions,\n): void {\n const t = opts.t ?? createI18nContext().t;\n if (!pick.title) pick.title = t('colorPicker.openTitle');\n\n pick.addEventListener('mousedown', (e) => {\n e.preventDefault();\n opts.onBeforeOpen?.();\n });\n\n pick.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const layerRoot =\n opts.layerRoot ?? (pick.closest('.sm-root') as HTMLElement | null) ?? document.body;\n const value = opts.getValue?.() ?? pick.value;\n openColorPickerPopover({\n ...opts,\n anchor: pick,\n layerRoot,\n value,\n });\n });\n}\n","/**\n * 把任意 DOM 元素临时变成 contenteditable,并暴露提交/取消/选区事件。\n *\n * 设计要点:\n * - 不直接同步到 store。编辑过程中只在本地累积,提交(blur / Esc / 单行 Enter)时一次性回调,\n * 避免每次按键都触发画布全量重渲染导致光标丢失。\n * - mode=plain 时仅取 textContent,并在 paste/keydown 上拦截换行;\n * mode=rich 时保留 inline HTML,但会在提交时做一次清理(白名单标签 + inline style);\n * mode=html 时提交原始 innerHTML(用于 mj-raw 等),不挂富文本浮动条。\n * - 选区变化通过 `onSelectionChange` 实时回调,便于浮动工具条同步按钮状态/位置。\n */\nimport { normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport {\n findListAtSelection,\n getListIndent,\n LIST_INDENT_DEFAULT_PX,\n resolveGlobalListIndentPx,\n setListIndent as applyListIndentToElement,\n type ListIndentValue,\n} from '../utils/emailListStyles';\nimport type { GlobalStyles } from '../types';\nimport {\n applyListCommandForSelection,\n detectListFormats,\n findListItem,\n getListItemsInRange,\n getCaretTextOffsetAtRangeEnd,\n insertSelectionBoundaryMarkers,\n mergeListItemOnBackspace,\n mergeAdjacentSameTypeLists,\n mergeNextListItemOnDelete,\n removeSelectionBoundaryMarkers,\n restoreCaretAfterListMutation,\n restoreCaretToEndOfListInSelectionBounds,\n splitListItemOnEnter,\n} from '../utils/inlineListEditing';\nimport {\n richTextExecCommand,\n richTextQueryCommandState,\n richTextQueryCommandValue,\n} from '../utils/richTextCommand';\nimport {\n isRichHtmlEffectivelyEmpty,\n isRichHtmlEditorSeedOnly,\n hasRichHtmlLineBreak,\n getRichHtmlPlainText,\n} from '../utils/richHtmlEmpty';\nimport { isColorPickerOpen } from './ColorPickerPopover';\n\nexport interface InlineEditorOptions {\n el: HTMLElement;\n initialValue: string;\n mode: 'rich' | 'plain' | 'html';\n multiline: boolean;\n placeholder?: string;\n onCommit: (value: string) => void;\n onCancel: () => void;\n onSelectionChange?: (state: SelectionState | null) => void;\n /** 文档全局列表默认缩进(px),用于工具条展示继承值 */\n globalStyles?: GlobalStyles;\n}\n\nexport interface SelectionState {\n hasSelection: boolean;\n rect: DOMRect | null;\n /** queryCommandState 的若干常用值,用于工具条按钮高亮 */\n formats: {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n unorderedList: boolean;\n orderedList: boolean;\n align: 'left' | 'center' | 'right' | 'justify' | null;\n link: string | null;\n foreColor: string | null;\n fontSize: string | null;\n fontName: string | null;\n fontWeight: string | null;\n backColor: string | null;\n /** 光标是否在 ul/ol 内 */\n inList: boolean;\n /** null = 跟随邮件全局;非 null = 本列表显式 px */\n listIndentPx: ListIndentValue;\n /** 邮件全局列表默认缩进(px) */\n listIndentGlobalPx: number;\n /** 当前列表实际生效的缩进(px) */\n listIndentEffectivePx: number;\n };\n}\n\nexport class InlineEditor {\n private opts: InlineEditorOptions;\n private el: HTMLElement;\n private listeners: Array<() => void> = [];\n private committed = false;\n private originalContent: string;\n /** 防止 selectionchange 在我们 destroy 之后还回调 */\n private alive = true;\n /**\n * 上一次\"用户在编辑区内\"时的有效选区。\n * 当用户去工具条点 select / input 时焦点会离开 contenteditable,\n * execCommand 在那种状态下会哑火——必须先 focus 回来,再恢复选区,再执行命令。\n */\n private savedRange: Range | null = null;\n /** 富文本工具条控件会抢走焦点,此时 getSelection 已不在编辑区内;保留上一帧状态避免工具条整栏收起。 */\n private lastSelectionState: SelectionState | null = null;\n /** hiliteColor 在输入前不写 DOM;记录「待输入背景色 + 锚点」以便 bar 即时同步,移开光标后清除 */\n private pendingHiliteColor: string | null = null;\n private pendingHiliteAnchor: string | null = null;\n /** 进入编辑时空内容;用于忽略未改动就失焦时的占位 <br> */\n private initiallyEmpty = false;\n private edited = false;\n /** 是否曾有过文本(含空格);用于区分「仅换行」与「输入后清空残留的 <br>」 */\n private hadTextInSession = false;\n /** 工具条执行列表命令时,跳过 input 里的相邻列表合并(避免合并后再用旧偏移恢复光标) */\n private suppressListMerge = false;\n\n constructor(opts: InlineEditorOptions) {\n this.opts = opts;\n this.el = opts.el;\n this.originalContent = this.el.innerHTML;\n this._mount();\n }\n\n /** 立即提交并销毁。 */\n commit() {\n if (this.committed) return;\n this.committed = true;\n let value: string;\n if (this.opts.mode === 'plain') {\n value = (this.el.textContent ?? '').replace(/\\u200b/g, '');\n } else if (this.opts.mode === 'html') {\n value = this.el.innerHTML;\n } else {\n const sanitized = sanitizeRichHtml(this.el.innerHTML);\n const text = (this.el.textContent ?? '').replace(/\\u200b/g, '');\n if (text.length > 0) {\n value = sanitized;\n } else if (\n this.initiallyEmpty &&\n !this.edited &&\n isRichHtmlEditorSeedOnly(sanitized)\n ) {\n value = '';\n } else if (hasRichHtmlLineBreak(sanitized) && !this.hadTextInSession) {\n // 从未有过文本,仅换行(含单个 <br>)视为有效\n value = sanitized;\n } else {\n // 曾有过文本后清空,或无文本无换行\n value = '';\n }\n }\n\n this.opts.onCommit(value);\n this.destroy(false);\n }\n\n /** 放弃编辑、还原 DOM 并销毁。 */\n cancel() {\n if (this.committed) return;\n this.committed = true;\n this.el.innerHTML = this.originalContent;\n this.opts.onCancel();\n this.destroy(false);\n }\n\n destroy(restore = true) {\n if (!this.alive) return;\n this.alive = false;\n this.listeners.forEach((off) => off());\n this.listeners = [];\n this.el.removeAttribute('contenteditable');\n this.el.classList.remove('sm-inline-editing');\n if (restore && !this.committed) this.el.innerHTML = this.originalContent;\n }\n\n /**\n * 保存当前在编辑区内的选区。Toolbar 在 mousedown(capture)阶段调用:\n * 在浏览器把焦点切到 select/input 之前抢先存档。\n */\n saveSelection() {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n if (!this.el.contains(range.startContainer) || !this.el.contains(range.endContainer)) return;\n this.savedRange = range.cloneRange();\n }\n\n /** 直接对当前选区执行命令(供 Toolbar 调用)。 */\n exec(command: string, value?: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const sel = window.getSelection();\n let hiliteAnchor: string | null = null;\n if (command === 'hiliteColor' && sel?.rangeCount) {\n hiliteAnchor = selectionAnchorKey(sel.getRangeAt(0));\n }\n // 列表:Chrome 等在 styleWithCSS=true 下 insertOrderedList / insertUnorderedList 常失灵,需退回 HTML 列表标签\n const isListCmd = command === 'insertOrderedList' || command === 'insertUnorderedList';\n if (isListCmd && sel?.rangeCount) {\n const range = sel.getRangeAt(0);\n const itemsInRange = range.collapsed\n ? []\n : getListItemsInRange(range, this.el);\n const savedOffset = getCaretTextOffsetAtRangeEnd(this.el, range);\n const boundaryMarkers = insertSelectionBoundaryMarkers(range);\n this.suppressListMerge = true;\n try {\n const wantUl = command === 'insertUnorderedList';\n if (applyListCommandForSelection(this.el, range, wantUl, itemsInRange)) {\n restoreCaretAfterListMutation(this.el, boundaryMarkers.end, savedOffset);\n } else {\n richTextExecCommand('styleWithCSS', false, 'false');\n richTextExecCommand(command, false, value);\n if (!restoreCaretToEndOfListInSelectionBounds(this.el)) {\n restoreCaretAfterListMutation(this.el, boundaryMarkers.end, savedOffset);\n }\n }\n } finally {\n this.suppressListMerge = false;\n removeSelectionBoundaryMarkers(this.el);\n }\n this.saveSelection();\n this._emitSelection();\n return;\n } else {\n richTextExecCommand('styleWithCSS', false, isListCmd ? 'false' : 'true');\n richTextExecCommand(command, false, value);\n }\n if (command === 'hiliteColor') {\n this.pendingHiliteColor = value ?? null;\n this.pendingHiliteAnchor = hiliteAnchor;\n }\n // 命令执行后选区可能已经变化(例如插入链接会扩展),刷新存档\n this.saveSelection();\n this._emitSelection();\n }\n\n /** 设置当前列表缩进;null 表示恢复默认(不设值) */\n setListIndent(px: ListIndentValue) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const sel = window.getSelection();\n if (!sel?.rangeCount) return;\n const list = findListAtSelection(sel.anchorNode, this.el);\n if (!list) return;\n applyListIndentToElement(list, px);\n this.saveSelection();\n this._emitSelection();\n }\n\n /**\n * 设置或移除超链接:已有 &lt;a&gt; 则改 href;否则 createLink。\n * (仅用 createLink 在链接内需改 URL 时浏览器行为不一致。)\n */\n setLink(url: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const trimmed = url.trim();\n if (!trimmed) {\n richTextExecCommand('unlink');\n this.saveSelection();\n this._emitSelection();\n return;\n }\n const safe = /^https?:|^mailto:|^tel:|^\\{\\{/i.test(trimmed) ? trimmed : `https://${trimmed}`;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const anchor = findAncestorAnchor(sel.anchorNode, this.el);\n if (anchor) {\n anchor.setAttribute('href', safe);\n if (!anchor.getAttribute('rel')) anchor.setAttribute('rel', 'noopener');\n } else {\n richTextExecCommand('styleWithCSS', false, 'true');\n richTextExecCommand('createLink', false, safe);\n }\n this.saveSelection();\n this._emitSelection();\n }\n\n /** 在当前光标处插入纯文本(供\"插入变量\"使用)。 */\n insertText(text: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n richTextExecCommand('insertText', false, text);\n this.saveSelection();\n }\n\n /** 在当前光标处插入 HTML 片段(供链接类变量使用)。 */\n insertHtml(html: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n richTextExecCommand('insertHTML', false, html);\n this.saveSelection();\n }\n\n /** Toolbar 关闭某个面板/控件后调用,把选区还给编辑区,方便用户继续输入。 */\n refocus() {\n this._ensureFocus();\n this._restoreSelection();\n }\n\n /** 字号:走原生 fontSize 命令(styleWithCSS 下浏览器会写 span),与 foreColor 同类 */\n applyFontSize(px: string) {\n this.exec('fontSize', pxToLegacyFontSize(px));\n }\n\n /**\n * 字重:浏览器只有 bold 命令,没有 font-weight:500/600 的原生 API,需包 span。\n * 有选区包裹内容;折叠光标插入 typing span,后续输入沿用。\n */\n applyFontWeight(weight: string) {\n this.edited = true;\n this._ensureFocus();\n this._restoreSelection();\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n if (!this.el.contains(range.startContainer) || !this.el.contains(range.endContainer)) return;\n\n if (!range.collapsed) {\n const span = document.createElement('span');\n span.setAttribute('style', `font-weight:${weight};`);\n try {\n span.appendChild(range.extractContents());\n range.insertNode(span);\n const newRange = document.createRange();\n newRange.selectNodeContents(span);\n sel.removeAllRanges();\n sel.addRange(newRange);\n } catch {\n return;\n }\n } else {\n const span = document.createElement('span');\n span.setAttribute('style', `font-weight:${weight};`);\n span.appendChild(document.createTextNode('\\u200b'));\n range.insertNode(span);\n const caret = document.createRange();\n caret.setStart(span.firstChild!, 1);\n caret.collapse(true);\n sel.removeAllRanges();\n sel.addRange(caret);\n }\n\n this.saveSelection();\n this._emitSelection();\n }\n\n /** 内联编辑根节点(如 `.sm-text-content`)的盒模型矩形,供富文本条贴在正文区域外沿定位 */\n getAnchorRect(): DOMRect {\n return this.el.getBoundingClientRect();\n }\n\n private _restoreSelection() {\n if (!this.savedRange) return;\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(this.savedRange);\n }\n\n /* -------------------------------- 内部 ---------------------------------- */\n\n private _mount() {\n const { el, mode, multiline } = this.opts;\n el.setAttribute('contenteditable', 'true');\n el.classList.add('sm-inline-editing');\n el.classList.remove('is-empty');\n\n const initial = this.opts.initialValue ?? '';\n const initiallyEmpty =\n mode === 'plain' ? !initial.trim() : isRichHtmlEffectivelyEmpty(initial);\n this.initiallyEmpty = initiallyEmpty;\n this.edited = false;\n this.hadTextInSession =\n mode === 'plain'\n ? initial.replace(/\\u200b/g, '').length > 0\n : getRichHtmlPlainText(initial).length > 0;\n\n if (initiallyEmpty) {\n // 空 rich 块需一个 <br> 锚点,浏览器才能稳定接收输入/换行;不在编辑态显示 placeholder\n el.innerHTML = mode === 'plain' ? '' : '<br>';\n } else {\n el.innerHTML = mode === 'plain' ? escapeHtml(initial) : initial;\n }\n\n // 初始聚焦并把光标移到末尾,便于\"双击 → 直接输入\"\n requestAnimationFrame(() => {\n el.focus();\n placeCaretAtEnd(el);\n });\n\n let imeComposing = false;\n /** 部分浏览器在 compositionend 之后才派发 Enter keydown,需吞掉紧随其后的这一次 */\n let suppressNextEnter = false;\n\n const onCompositionStart = () => {\n imeComposing = true;\n };\n const onCompositionEnd = () => {\n imeComposing = false;\n suppressNextEnter = true;\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.cancel();\n return;\n }\n if (e.key === 'Enter') {\n // 拼音等 IME 用 Enter 上屏:不可 preventDefault / insertLineBreak\n if (e.isComposing || imeComposing || e.keyCode === 229) return;\n if (suppressNextEnter) {\n suppressNextEnter = false;\n return;\n }\n if (!multiline) {\n e.preventDefault();\n this.commit();\n return;\n }\n if (mode === 'rich') {\n if (e.shiftKey) {\n e.preventDefault();\n richTextExecCommand('insertLineBreak');\n this.saveSelection();\n this._emitSelection();\n return;\n }\n const sel = window.getSelection();\n if (sel?.rangeCount) {\n const range = sel.getRangeAt(0);\n const li = findListItem(range.startContainer, el);\n if (li && el.contains(li)) {\n e.preventDefault();\n splitListItemOnEnter(li, range);\n this.saveSelection();\n this._emitSelection();\n return;\n }\n }\n }\n // 非列表:回车默认会插入 <div>,强制 <br> 避免出现各种奇怪嵌套\n e.preventDefault();\n richTextExecCommand('insertLineBreak');\n return;\n }\n if (e.key === 'Backspace' && mode === 'rich' && multiline) {\n if (e.isComposing || imeComposing) return;\n const sel = window.getSelection();\n if (!sel?.rangeCount) return;\n const range = sel.getRangeAt(0);\n const li = findListItem(range.startContainer, el);\n if (li && el.contains(li) && mergeListItemOnBackspace(li, range)) {\n e.preventDefault();\n this.saveSelection();\n this._emitSelection();\n }\n return;\n }\n if (e.key === 'Delete' && mode === 'rich' && multiline) {\n if (e.isComposing || imeComposing) return;\n const sel = window.getSelection();\n if (!sel?.rangeCount) return;\n const range = sel.getRangeAt(0);\n const li = findListItem(range.startContainer, el);\n if (li && el.contains(li) && mergeNextListItemOnDelete(li, range)) {\n e.preventDefault();\n this.saveSelection();\n this._emitSelection();\n }\n }\n };\n const onBlur = (e: FocusEvent) => {\n // 给点钟摆余地,避免点击工具条按钮时立刻提交\n setTimeout(() => {\n if (!this.alive) return;\n const active = document.activeElement as HTMLElement | null;\n if (active && (active === el || el.contains(active))) return;\n if (isColorPickerOpen()) return;\n if (active?.closest?.('.sm-floating-toolbar, .sm-color-picker, .sm-color-picker-layer')) return;\n if (active?.closest?.('.sm-topbar, .sm-popover, .sm-panel--variable-picker')) return;\n // 从左栏拖入 / 画布内 Sortable 排序:mousedown 会先 blur,若在此时提交会触发画布重渲染并拆掉 drop 目标\n if (active?.closest?.('.sm-panel--left')) return;\n if (active?.closest?.('.sm-block__handle, .sm-section__handle')) return;\n const related = e.relatedTarget as HTMLElement | null;\n if (related?.closest?.('.sm-panel--left')) return;\n if (related?.closest?.('.sm-block-card')) return;\n if (related?.closest?.('.sm-block__handle, .sm-section__handle')) return;\n if (related?.closest?.('.sm-color-picker, .sm-color-picker-layer')) return;\n if (related?.closest?.('.sm-topbar, .sm-popover, .sm-panel--variable-picker')) return;\n if (document.querySelector('.sm-root .sm-drag, .sm-root .sm-chosen')) return;\n this.commit();\n }, 0);\n };\n const markEdited = () => {\n this.edited = true;\n };\n\n const syncTextPresence = () => {\n const t = (el.textContent ?? '').replace(/\\u200b/g, '');\n if (t.length > 0) this.hadTextInSession = true;\n };\n\n const onPaste = (e: ClipboardEvent) => {\n if (mode === 'rich' && multiline && !e.clipboardData?.getData('text/html')) {\n e.preventDefault();\n markEdited();\n const text = e.clipboardData?.getData('text/plain') ?? '';\n richTextExecCommand('insertHTML', false, plainTextToRichHtml(text));\n syncTextPresence();\n this.saveSelection();\n this._emitSelection();\n return;\n }\n if (mode !== 'plain') return;\n e.preventDefault();\n markEdited();\n const text = e.clipboardData?.getData('text/plain') ?? '';\n const safe = multiline ? text : text.replace(/\\r?\\n/g, ' ');\n richTextExecCommand('insertText', false, safe);\n };\n\n const onSelChange = () => {\n if (!this.alive) return;\n this._syncPendingHiliteAnchor();\n this.saveSelection();\n this._emitSelection();\n };\n\n const onInput = () => {\n markEdited();\n syncTextPresence();\n if (mode === 'rich' && multiline && !this.suppressListMerge) {\n mergeAdjacentSameTypeLists(el);\n }\n onSelChange();\n };\n\n const linkInsideEditing = (t: EventTarget | null): HTMLAnchorElement | null => {\n if (!(t instanceof Element)) return null;\n const a = t.closest('a');\n if (!a || !el.contains(a)) return null;\n const href = a.getAttribute('href');\n if (href == null || href === '' || href === '#') return null;\n return a;\n };\n\n /** Chrome:contenteditable 里的 <a href> 仍会在 click 时导航;mousedown 不拦截以保留拖选 */\n const stopLinkActivate = (e: MouseEvent) => {\n if (mode !== 'rich' && mode !== 'html') return;\n if (!linkInsideEditing(e.target)) return;\n e.preventDefault();\n };\n\n el.addEventListener('keydown', onKeyDown);\n el.addEventListener('compositionstart', onCompositionStart);\n el.addEventListener('compositionend', onCompositionEnd);\n el.addEventListener('blur', onBlur);\n el.addEventListener('paste', onPaste);\n document.addEventListener('selectionchange', onSelChange);\n el.addEventListener('input', onInput);\n el.addEventListener('mouseup', onSelChange);\n if (mode === 'rich' || mode === 'html') {\n el.addEventListener('click', stopLinkActivate, true);\n el.addEventListener('auxclick', stopLinkActivate, true);\n }\n\n this.listeners.push(\n () => el.removeEventListener('keydown', onKeyDown),\n () => el.removeEventListener('compositionstart', onCompositionStart),\n () => el.removeEventListener('compositionend', onCompositionEnd),\n () => el.removeEventListener('blur', onBlur),\n () => el.removeEventListener('paste', onPaste),\n () => document.removeEventListener('selectionchange', onSelChange),\n () => el.removeEventListener('input', onInput),\n () => el.removeEventListener('mouseup', onSelChange),\n ...(mode === 'rich' || mode === 'html'\n ? [\n () => el.removeEventListener('click', stopLinkActivate, true),\n () => el.removeEventListener('auxclick', stopLinkActivate, true),\n ]\n : []),\n );\n }\n\n private _ensureFocus() {\n if (document.activeElement !== this.el) {\n this.el.focus();\n }\n }\n\n private _syncPendingHiliteAnchor() {\n if (!this.pendingHiliteColor || !this.pendingHiliteAnchor) return;\n const sel = window.getSelection();\n if (!sel?.rangeCount) {\n this._clearPendingHilite();\n return;\n }\n if (selectionAnchorKey(sel.getRangeAt(0)) !== this.pendingHiliteAnchor) {\n this._clearPendingHilite();\n }\n }\n\n private _clearPendingHilite() {\n this.pendingHiliteColor = null;\n this.pendingHiliteAnchor = null;\n }\n\n private _emitSelection() {\n if (!this.opts.onSelectionChange) return;\n if (this.opts.mode === 'plain' || this.opts.mode === 'html') {\n this.opts.onSelectionChange(null); // plain / 原始 HTML 不挂富文本浮动条\n return;\n }\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) {\n this._emitSelectionOrKeepToolbar(null);\n return;\n }\n if (!this.el.contains(sel.anchorNode)) {\n this._emitSelectionOrKeepToolbar(null);\n return;\n }\n const range = sel.getRangeAt(0);\n const rect = sel.isCollapsed ? this._caretRect(range) : range.getBoundingClientRect();\n\n const align: SelectionState['formats']['align'] = richTextQueryCommandState('justifyCenter')\n ? 'center'\n : richTextQueryCommandState('justifyRight')\n ? 'right'\n : richTextQueryCommandState('justifyFull')\n ? 'justify'\n : 'left';\n\n const link = (() => {\n const a = findAncestorAnchor(sel.anchorNode, this.el);\n return a?.getAttribute('href') ?? null;\n })();\n\n const inline = resolveInlineFormatsAtSelection(this.el, sel);\n\n let foreColor = inline.foreColor ?? safeQueryValue('foreColor');\n let backColor = inline.backColor;\n if (\n !backColor &&\n range.collapsed &&\n this.pendingHiliteColor &&\n this.pendingHiliteAnchor === selectionAnchorKey(range)\n ) {\n backColor = this.pendingHiliteColor;\n }\n if (inline.backColor) this._clearPendingHilite();\n\n const listFormats = detectListFormats(sel.anchorNode, this.el);\n const activeList = findListAtSelection(sel.anchorNode, this.el);\n const listIndentPx = activeList ? getListIndent(activeList) : null;\n const listIndentGlobalPx = this.opts.globalStyles\n ? resolveGlobalListIndentPx(this.opts.globalStyles)\n : LIST_INDENT_DEFAULT_PX;\n const listIndentEffectivePx =\n listIndentPx != null ? listIndentPx : listIndentGlobalPx;\n\n const state: SelectionState = {\n hasSelection: true,\n rect,\n formats: {\n bold: richTextQueryCommandState('bold'),\n italic: richTextQueryCommandState('italic'),\n underline: richTextQueryCommandState('underline'),\n strikethrough: richTextQueryCommandState('strikeThrough'),\n unorderedList:\n listFormats.unorderedList || richTextQueryCommandState('insertUnorderedList'),\n orderedList: listFormats.orderedList || richTextQueryCommandState('insertOrderedList'),\n align,\n link,\n foreColor,\n fontSize: inline.fontSize,\n fontName: safeQueryValue('fontName'),\n fontWeight: inline.fontWeight,\n backColor,\n inList: !!activeList,\n listIndentPx,\n listIndentGlobalPx,\n listIndentEffectivePx,\n },\n };\n this.lastSelectionState = state;\n this.opts.onSelectionChange(state);\n }\n\n /** 焦点在浮动工具条上时沿用上一帧选区,避免点开链接框 / 颜色等控件后工具条消失。 */\n private _emitSelectionOrKeepToolbar(fallback: null) {\n if (\n fallback === null &&\n this.lastSelectionState &&\n isColorPickerOpen() ||\n document.activeElement?.closest?.(\n '.sm-floating-toolbar, .sm-color-picker, .sm-color-picker-layer',\n )\n ) {\n this.opts.onSelectionChange?.(this.lastSelectionState);\n return;\n }\n if (fallback === null) this.lastSelectionState = null;\n this.opts.onSelectionChange?.(fallback);\n }\n\n private _caretRect(range: Range): DOMRect | null {\n const rects = range.getClientRects();\n if (rects.length) return rects[0];\n // 折叠选区在空段落上时 rects 为空,造一个零宽 range 拿到位置\n const tmp = range.cloneRange();\n tmp.collapse(true);\n const span = document.createElement('span');\n span.appendChild(document.createTextNode('\\u200b'));\n tmp.insertNode(span);\n const r = span.getBoundingClientRect();\n span.remove();\n return r;\n }\n}\n\n/* ----------------------------- helpers ----------------------------- */\n\nfunction findAncestorAnchor(node: Node | null, root: HTMLElement): HTMLAnchorElement | null {\n while (node && node !== root) {\n if (node.nodeType === 1 && (node as HTMLElement).tagName === 'A') {\n return node as HTMLAnchorElement;\n }\n node = node.parentNode;\n }\n return null;\n}\n\nfunction placeCaretAtEnd(el: HTMLElement) {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nfunction safeQueryValue(cmd: string): string | null {\n try {\n const v = richTextQueryCommandValue(cmd);\n return v ? v : null;\n } catch {\n return null;\n }\n}\n\n/** 光标/选区处的字号、字重、文字色、背景色(queryCommandValue 对 span style 与链接内颜色不可靠) */\nfunction resolveInlineFormatsAtSelection(\n root: HTMLElement,\n sel: Selection,\n): {\n fontSize: string | null;\n fontWeight: string | null;\n foreColor: string | null;\n backColor: string | null;\n} {\n const host = selectionHostElement(sel, root);\n if (!host) return { fontSize: null, fontWeight: null, foreColor: null, backColor: null };\n\n let fontWeight: string | null = null;\n for (let el: HTMLElement | null = host; el && root.contains(el) && el !== root; el = el.parentElement) {\n if (el.style.fontWeight) fontWeight = el.style.fontWeight;\n }\n\n const foreColor = resolveForeColorAtSelection(root, host);\n const backColor = resolveBackColorAtSelection(root, host);\n // 用 computed px,避免读到 .sm-text-content 块级默认字号盖掉 <font>/span 上的真实字号\n const fontSize = window.getComputedStyle(host).fontSize;\n\n if (!fontWeight) {\n fontWeight = richTextQueryCommandState('bold')\n ? '700'\n : normalizeFontWeightStep(window.getComputedStyle(host).fontWeight);\n } else {\n fontWeight = normalizeFontWeightStep(fontWeight);\n }\n\n return { fontSize, fontWeight, foreColor, backColor };\n}\n\n/** 光标处文字色(foreColor / 链接局部 color;queryCommandValue 在 <a> 内常不准) */\nfunction resolveForeColorAtSelection(root: HTMLElement, host: HTMLElement): string | null {\n for (let el: HTMLElement | null = host; el && root.contains(el) && el !== root; el = el.parentElement) {\n const inline = el.style.color?.trim();\n if (inline) return inline;\n\n const fromAttr = readColorFromStyleAttr(el.getAttribute('style'));\n if (fromAttr) return fromAttr;\n }\n\n const computed = window.getComputedStyle(host).color;\n return computed || null;\n}\n\nfunction readColorFromStyleAttr(styleAttr: string | null): string | null {\n if (!styleAttr) return null;\n const m = styleAttr.match(/(?:^|;)\\s*color\\s*:\\s*([^;]+)/i);\n if (!m) return null;\n const c = m[1].trim();\n return c || null;\n}\n\n/** 光标处文字背景/高亮色(hiliteColor 的 queryCommandValue 在 Chrome 常为空,需读 DOM) */\nfunction resolveBackColorAtSelection(root: HTMLElement, host: HTMLElement): string | null {\n for (let el: HTMLElement | null = host; el && root.contains(el) && el !== root; el = el.parentElement) {\n const inline = el.style.backgroundColor?.trim();\n if (inline && !isTransparentColor(inline)) return inline;\n\n const fromAttr = readBackgroundFromStyleAttr(el.getAttribute('style'));\n if (fromAttr) return fromAttr;\n\n const computed = window.getComputedStyle(el).backgroundColor;\n if (computed && !isTransparentColor(computed)) return computed;\n }\n\n // 不用 queryCommandValue('hiliteColor'):它返回的是「下次输入用的颜色」,光标在无高亮处时仍会带上一次配置\n return null;\n}\n\nfunction readBackgroundFromStyleAttr(styleAttr: string | null): string | null {\n if (!styleAttr) return null;\n const m = styleAttr.match(/background(?:-color)?\\s*:\\s*([^;]+)/i);\n if (!m) return null;\n const c = m[1].trim();\n return c && !isTransparentColor(c) ? c : null;\n}\n\nfunction selectionHostElement(sel: Selection, root: HTMLElement): HTMLElement | null {\n const node = sel.anchorNode;\n if (!node || !root.contains(node)) return null;\n return node.nodeType === Node.TEXT_NODE ? node.parentElement : (node as HTMLElement);\n}\n\nfunction selectionAnchorKey(range: Range): string {\n return `${range.startContainer.nodeType}:${range.startOffset}:${range.endContainer.nodeType}:${range.endOffset}`;\n}\n\n/** execCommand fontSize 只认 1–7,与工具条 px 互转 */\nfunction pxToLegacyFontSize(px: string): string {\n const map: Record<string, string> = {\n '10px': '1',\n '12px': '2',\n '13px': '3',\n '14px': '3',\n '15px': '4',\n '16px': '4',\n '18px': '4',\n '20px': '5',\n '24px': '6',\n '28px': '6',\n '32px': '7',\n };\n const key = px.trim().toLowerCase();\n if (map[key]) return map[key];\n const num = parseFloat(key);\n if (Number.isNaN(num)) return '4';\n const steps: [number, string][] = [\n [10, '1'],\n [12, '2'],\n [14, '3'],\n [16, '4'],\n [20, '5'],\n [24, '6'],\n [32, '7'],\n ];\n let best = '4';\n let bestD = Infinity;\n for (const [size, legacy] of steps) {\n const d = Math.abs(size - num);\n if (d < bestD) {\n bestD = d;\n best = legacy;\n }\n }\n return best;\n}\n\nfunction isTransparentColor(c: string): boolean {\n const s = c.trim().toLowerCase();\n if (s === 'transparent' || s === 'inherit' || s === 'initial' || s === 'unset') return true;\n if (s === 'rgba(0, 0, 0, 0)' || s === 'rgba(0,0,0,0)') return true;\n const rgba = s.match(/^rgba?\\(\\s*(\\d+)[,\\s]+(\\d+)[,\\s]+(\\d+)(?:[,\\s/]+([\\d.]+))?\\s*\\)$/);\n if (rgba) {\n const a = rgba[4] !== undefined ? parseFloat(rgba[4]) : 1;\n return a === 0;\n }\n return false;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction plainTextToRichHtml(text: string): string {\n return escapeHtml(text).replace(/\\r\\n?/g, '\\n').replace(/\\n/g, '<br>');\n}\n\n/**\n * 邮件 HTML 必须只用一组保守的标签 + inline style。\n * 这里做一次轻量清理:\n * - 白名单标签:保留 a/b/strong/i/em/u/s/strike/span/br/p/div/ul/ol/li/h1-h6/font\n * - 标准化:<b> -> <strong>,<i> -> <em>,<font color> -> <span style=\"color:..\">\n * - 属性白名单:href / target / rel / style / class(保留邮件常见属性)\n */\nexport function sanitizeRichHtml(html: string): string {\n const tpl = document.createElement('template');\n tpl.innerHTML = html;\n walk(tpl.content);\n return tpl.innerHTML.replace(/\\u200b/g, '');\n\n function walk(root: Node) {\n const toRemove: Element[] = [];\n const all = (root as ParentNode).querySelectorAll('*');\n all.forEach((el) => {\n const tag = el.tagName.toLowerCase();\n if (tag === 'span' && el.getAttribute('data-sm-caret') === '1') {\n while (el.firstChild) el.parentNode?.insertBefore(el.firstChild, el);\n el.remove();\n return;\n }\n // <font color=\"...\" size=\"...\" face=\"...\"> → 转成 span style\n if (tag === 'font') {\n const span = document.createElement('span');\n const color = el.getAttribute('color');\n const size = el.getAttribute('size');\n const face = el.getAttribute('face');\n const styles: string[] = [el.getAttribute('style') ?? ''];\n if (color) styles.push(`color:${color}`);\n if (size) styles.push(`font-size:${fontSizeFromLegacy(size)}`);\n if (face) styles.push(`font-family:${face}`);\n const cleaned = styles.filter(Boolean).join(';');\n if (cleaned) span.setAttribute('style', cleaned);\n while (el.firstChild) span.appendChild(el.firstChild);\n el.parentNode?.replaceChild(span, el);\n return;\n }\n // 标签级白名单\n const allowed = [\n 'a',\n 'b',\n 'strong',\n 'i',\n 'em',\n 'u',\n 's',\n 'strike',\n 'span',\n 'br',\n 'p',\n 'div',\n 'ul',\n 'ol',\n 'li',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n ];\n if (!allowed.includes(tag)) {\n toRemove.push(el);\n return;\n }\n // 属性白名单\n const allowedAttrs = ['href', 'target', 'rel', 'style', 'class'];\n const listExtraAttrs = ['data-sm-list-indent'];\n [...el.attributes].forEach((attr) => {\n const name = attr.name.toLowerCase();\n const ok =\n allowedAttrs.includes(name) ||\n ((tag === 'ul' || tag === 'ol') && listExtraAttrs.includes(name));\n if (!ok) el.removeAttribute(attr.name);\n });\n // 链接安全\n if (tag === 'a') {\n const href = el.getAttribute('href') ?? '';\n if (/^javascript:/i.test(href)) el.setAttribute('href', '#');\n if (!el.getAttribute('rel')) el.setAttribute('rel', 'noopener');\n }\n if ((tag === 'p' || /^h[1-6]$/.test(tag)) && !hasMarginStyle(el)) {\n appendStyle(el, 'margin:0');\n }\n });\n toRemove.forEach((el) => {\n while (el.firstChild) el.parentNode?.insertBefore(el.firstChild, el);\n el.remove();\n });\n }\n}\n\nfunction hasMarginStyle(el: Element): boolean {\n const style = el.getAttribute('style') ?? '';\n return /(?:^|;)\\s*margin(?:-(?:top|right|bottom|left))?\\s*:/i.test(style);\n}\n\nfunction appendStyle(el: Element, style: string) {\n const raw = (el.getAttribute('style') ?? '').trim();\n el.setAttribute('style', raw ? `${raw.replace(/;+\\s*$/, '')};${style}` : style);\n}\n\nfunction fontSizeFromLegacy(size: string): string {\n // 旧 <font size=\"1..7\"> → px 近似\n const map: Record<string, string> = {\n '1': '10px',\n '2': '12px',\n '3': '14px',\n '4': '16px',\n '5': '20px',\n '6': '24px',\n '7': '32px',\n };\n return map[size] ?? size;\n}\n","import Sortable from 'sortablejs';\nimport type { Registry } from '../registry/registry';\nimport {\n createSection,\n findBlockLocation,\n findSection,\n pruneSectionIfEmpty,\n type Store,\n} from '../store/store';\nimport type {\n Block,\n Column,\n EditorUiOptions,\n EmailDoc,\n PaletteDropResult,\n RenderContext,\n Section,\n SectionAttrs,\n SectionLayout,\n} from '../types';\nimport { getSectionDynamicVariantKey } from '../utils/dynamicVariantSection';\nimport { blockButtonWidthCss, docContentWidthCss } from '../utils/contentWidth';\nimport { globalListIndentCssVarValue } from '../utils/emailListStyles';\nimport { normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport { clear, escapeHtml, h } from '../utils/dom';\nimport {\n defaultPaddingForLockedBlock,\n resolveLockedMjmlCanvasContent,\n} from '../utils/lockedMjml';\nimport { layoutHumanLabel } from '../utils/sectionLayout';\nimport { BlockCodeModal } from './BlockCodeModal';\nimport { InlineEditor, type SelectionState } from './InlineEditor';\nimport type { RichTextToolbar } from './RichTextToolbar';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface CanvasOptions {\n store: Store;\n registry: Registry;\n /** 富文本工具条由 Editor 主类创建,Canvas 只负责调用 attach/detach/update */\n toolbar: RichTextToolbar;\n /** 是否允许 Block 落到 sections 之间空白处时自动裹一列 Section */\n autoWrapSection: boolean;\n /**\n * 为 true 时:点击中栏灰色衬底、白底画布上未落到 Section/块的空白、空文档提示区等会提交内联编辑并清空选中。\n * 默认不绑定(由 MailEditor 的 clearSelectionOnCanvasMargin 控制)。\n */\n clearSelectionOnCanvasMargin?: boolean;\n /**\n * 画布内弹层(如「编辑组件代码」)挂接到此节点,以继承 `.sm-root` 上的主题 CSS 变量。\n * 应传入 MailEditor 根节点;若挂到 `document.body`,`var(--sm-code-bg)` 等会失效,弹框背景会变透明。\n */\n layerRoot: HTMLElement;\n /** 与 MailEditor.opts.ui 对齐 */\n ui?: EditorUiOptions;\n t: SimpleMailT;\n}\n\n/**\n * 画布。负责:\n * 1. 根据 doc 渲染轻量预览 DOM(非真实邮件 HTML)\n * 2. 选中态/悬浮态/工具条\n * 3. SortableJS 两级拖拽(仅 hover 显示的拖拽 handle 触发):\n * - 顶层(sections 组):Section 列表纵向排序,并接收左栏布局拖入\n * - 列内(blocks 组):Block 列表纵向排序,并接收左栏内容/自定义拖入\n * 4. 双击 Block 进入\"内联编辑\"——文本类直接富文本编辑,按钮文字单行编辑\n * 5. 设计画布内所有 <a href> 拦截默认行为,避免误跳转;真实跳转仅在「预览」iframe 中可用。\n *\n * 关键约束:所有数据变更走 store.update(),UI 通过 subscribe 全量重渲染。\n * 内联编辑是例外:编辑期间不再每次输入都 update,避免 contenteditable 因重渲染丢光标。\n */\nexport class Canvas {\n el: HTMLElement;\n private inner: HTMLElement;\n private addBar: HTMLElement;\n private opts: CanvasOptions;\n private sortableRefs: Sortable[] = [];\n /** 正在内联编辑的 block id;进入时画布不会被 store 触发的重渲染干扰它 */\n private editingBlockId: string | null = null;\n private inlineEditor: InlineEditor | null = null;\n /** 当 store 在编辑期间触发了 change(外部调用之类),延迟到编辑结束再重渲染 */\n private pendingRender = false;\n /** 设计模式下禁用画布内超链接导航(预览弹框 iframe 不在此 DOM 内,不受影响) */\n private linkNavSuppression = new AbortController();\n /** clearSelectionOnCanvasMargin:记录本次指针是否从编辑区内按下(区分拖选松手 vs 点空白退出) */\n private clearSelectionGestureTracking = new AbortController();\n private pointerGestureStartedInInlineEdit = false;\n private blockCodeModal: BlockCodeModal;\n\n constructor(opts: CanvasOptions) {\n this.opts = opts;\n this.el = h('div', { class: 'sm-canvas-wrap' });\n this.inner = h('div', { class: 'sm-canvas' });\n this.addBar = this._renderAddBar();\n this.el.append(this.inner, this.addBar);\n this.blockCodeModal = new BlockCodeModal({\n store: opts.store,\n registry: opts.registry,\n mountParent: opts.layerRoot,\n t: opts.t,\n });\n\n this._bindDesignModeLinkSuppression();\n if (opts.clearSelectionOnCanvasMargin) {\n this._bindClearSelectionGestureTracking();\n this._bindClearSelectionOnCanvasWhitespace();\n this._bindClearSelectionOnCanvasMargin();\n }\n\n this.inner.addEventListener('dblclick', (e: MouseEvent) => {\n this._onEmptyCanvasDblClick(e);\n });\n\n this._render();\n\n opts.store.subscribe((detail) => {\n // 编辑态下若走了文档级 undo/redo,必须丢弃未提交 DOM,否则失焦提交会与 store 脱节(整节消失等)\n if (this.editingBlockId && detail?.source === 'history') {\n this.abortInlineEdit();\n this._render();\n return;\n }\n if (this.editingBlockId) {\n this.pendingRender = true;\n return;\n }\n this._render();\n });\n opts.store.subscribeSelection(() => this._syncSelection());\n }\n\n setWidth(width: number) {\n this.inner.style.maxWidth = `${width}px`;\n }\n\n /** 暴露给 Editor,用于\"插入变量\"等外部交互直接写入到当前富文本光标处。 */\n get currentInlineEditor(): InlineEditor | null {\n return this.inlineEditor;\n }\n\n /** 强制提交并退出当前内联编辑(切换源码模式、destroy 前等场景) */\n commitInlineEdit() {\n this.inlineEditor?.commit();\n }\n\n get isInlineEditing(): boolean {\n return this.editingBlockId != null;\n }\n\n /**\n * 放弃未提交的内联编辑(不写入 store)。\n * 用于文档级撤销/重做:编辑期间画布不重绘,若直接 undo 会导致 DOM 与 doc 不一致。\n */\n abortInlineEdit() {\n if (!this.editingBlockId) return;\n const id = this.editingBlockId;\n this.editingBlockId = null;\n this.pendingRender = false;\n if (this.inlineEditor) {\n this.inlineEditor.destroy(false);\n this.inlineEditor = null;\n }\n this.opts.toolbar.detach();\n const blockEl = this.inner.querySelector(\n `.sm-block[data-id=\"${cssEscape(id)}\"]`,\n ) as HTMLElement | null;\n blockEl?.classList.remove('is-editing');\n }\n\n /** 强制重绘(内联编辑中会延迟到 commit 后) */\n refresh() {\n if (this.editingBlockId) {\n this.pendingRender = true;\n return;\n }\n this._render();\n }\n\n destroy() {\n this.linkNavSuppression.abort();\n this.clearSelectionGestureTracking.abort();\n this._exitEditing(false);\n this._destroySortables();\n this.blockCodeModal.destroy();\n }\n\n /**\n * clearSelectionOnCanvasMargin:mousedown 在编辑区内、mouseup 落在灰底/留白时,\n * 浏览器仍可能对 mouseup 目标派发 click;需与 Section padding 的拖选抑制同理。\n */\n private _bindClearSelectionGestureTracking() {\n const opts = { capture: true, signal: this.clearSelectionGestureTracking.signal } as const;\n document.addEventListener(\n 'mousedown',\n (e: MouseEvent) => {\n if (e.button !== 0) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n if (!this.editingBlockId) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n const editingEl = this.inner.querySelector('.sm-inline-editing');\n if (!editingEl) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n const t = e.target;\n if (!(t instanceof Node)) {\n this.pointerGestureStartedInInlineEdit = false;\n return;\n }\n const node = t.nodeType === Node.TEXT_NODE ? t.parentNode : t;\n this.pointerGestureStartedInInlineEdit = !!(node && editingEl.contains(node));\n },\n opts,\n );\n }\n\n /**\n * 点击画布白底上未落到 Section 内的区域(如 min-height 下方留白、空文档提示)时清空选中,\n * Section/Block 上的点击会在冒泡到此前被 stopPropagation,不会误清。\n */\n private _bindClearSelectionOnCanvasWhitespace() {\n this.inner.addEventListener('click', (e: MouseEvent) => {\n const t = e.target;\n if (!(t instanceof Node)) return;\n const el = t instanceof Element ? t : t.parentElement;\n if (!el) return;\n if (el === this.inner || el.closest('.sm-empty-doc')) {\n if (this._shouldSuppressClearSelectionFromTextDrag()) return;\n this.commitInlineEdit();\n this.opts.store.setSelection(null);\n }\n });\n }\n\n /** 点击中栏灰色衬底(非白底画布、非底部添加 Section 条)时取消选中 */\n private _bindClearSelectionOnCanvasMargin() {\n this.el.addEventListener('click', (e: MouseEvent) => {\n const t = e.target;\n if (!(t instanceof Node)) return;\n if (!this.el.contains(t)) return;\n if (this.inner.contains(t)) return;\n if (this.addBar.contains(t)) return;\n if (this._shouldSuppressClearSelectionFromTextDrag()) return;\n this.commitInlineEdit();\n this.opts.store.setSelection(null);\n });\n }\n\n /** 捕获阶段拦截 <a href>,防止 Chrome 等在画布预览 DOM 上触发跳转(含未进入内联编辑时点到按钮块链接) */\n private _bindDesignModeLinkSuppression() {\n const opts = { capture: true, signal: this.linkNavSuppression.signal } as const;\n const linkFromTarget = (target: EventTarget | null): HTMLAnchorElement | null => {\n if (!(target instanceof Element)) return null;\n const a = target.closest('a');\n if (!a || !this.inner.contains(a)) return null;\n if (!a.hasAttribute('href')) return null;\n return a;\n };\n this.inner.addEventListener(\n 'mousedown',\n (e: MouseEvent) => {\n const a = linkFromTarget(e.target);\n if (!a) return;\n // 内联编辑时保留 mousedown 默认行为,以便在链接文字上拖选\n if (a.closest('.sm-inline-editing')) return;\n e.preventDefault();\n },\n opts,\n );\n const stopNavigate = (e: MouseEvent) => {\n if (!linkFromTarget(e.target)) return;\n e.preventDefault();\n };\n this.inner.addEventListener('click', stopNavigate, opts);\n this.inner.addEventListener('auxclick', stopNavigate, opts);\n }\n\n /* -------------------------------- 渲染 ---------------------------------- */\n\n private _render() {\n this._destroySortables();\n clear(this.inner);\n\n const { doc } = this.opts.store;\n this.inner.style.maxWidth = docContentWidthCss(doc.meta.width);\n this.inner.style.background = doc.styles.contentBackgroundColor;\n this.inner.style.fontFamily = doc.styles.fontFamily;\n this.inner.style.fontSize = doc.styles.fontSize;\n this.inner.style.fontWeight = normalizeFontWeightStep(doc.styles.fontWeight);\n this.inner.style.color = doc.styles.color;\n this.inner.style.lineHeight = doc.styles.lineHeight ?? '1.25';\n this.inner.style.setProperty('--sm-editor-link-color', doc.styles.linkColor);\n this.inner.style.setProperty(\n '--sm-list-indent-default',\n globalListIndentCssVarValue(doc.styles),\n );\n\n if (!doc.sections.length) {\n this.inner.append(\n h('div', { class: 'sm-empty-doc' }, [\n this.opts.t('canvas.emptyHint'),\n ]),\n );\n } else {\n for (let si = 0; si < doc.sections.length; si++) {\n this.inner.append(this._renderSection(doc.sections[si], doc, si));\n }\n }\n\n // 顶层 Sortable:负责 Section 排序。\n // put 规则随 autoWrapSection 切换:\n // - autoWrapSection=true:同时接收 sections 与 blocks(block 落到这里时由 path B/C 自动套壳)\n // - autoWrapSection=false:仅接收 sections(block 落不下来,SortableJS 会显示禁止)\n // pull:false 始终:Section 不允许被拖到 column 里(保持四层模型)\n const topPut: string[] = this.opts.autoWrapSection ? ['sections', 'blocks'] : ['sections'];\n const top = Sortable.create(this.inner, {\n group: { name: 'sections', pull: false, put: topPut },\n animation: 150,\n handle: '.sm-section__handle',\n draggable: '> .sm-section-host',\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n onAdd: (e) => this._handleSectionAdd(e),\n onUpdate: (e) => this._handleSectionMove(e),\n });\n this.sortableRefs.push(top);\n\n this._syncSelection();\n }\n\n private _renderSection(section: Section, doc: EmailDoc, sectionIndex: number) {\n const a = section.attrs;\n const padding = `${a.paddingTop ?? 0}px ${a.paddingRight ?? 0}px ${\n a.paddingBottom ?? 0\n }px ${a.paddingLeft ?? 0}px`;\n\n const layoutShort =\n section.layout === '1' ? this.opts.t('rightPanel.layout.oneColumn') : layoutHumanLabel(section.layout);\n const dvKey =\n this.opts.ui?.enableDynamicVariantKey === true\n ? getSectionDynamicVariantKey(section)\n : undefined;\n const sectionChip = dvKey\n ? this.opts.t('canvas.dynamicSectionLabel', {\n index: sectionIndex + 1,\n token: `{{${dvKey}}}`,\n })\n : this.opts.t('canvas.sectionLabel', { index: sectionIndex + 1, layout: layoutShort });\n\n const sw = blockButtonWidthCss(a.width);\n const box =\n sw != null ? `max-width:${sw};width:100%;margin-left:auto;margin-right:auto;box-sizing:border-box;` : '';\n\n const host = h('div', {\n class: 'sm-section-host',\n 'data-id': section.id,\n });\n\n const wrap = h('div', {\n class: `sm-section${dvKey ? ' sm-section--dynamic-variant' : ''}`,\n title: this.opts.t('canvas.sectionTitle', { chip: sectionChip }),\n style: `padding:${padding};${a.backgroundColor ? `background:${a.backgroundColor};` : ''}${box}`,\n });\n\n const toolbar = h('div', { class: 'sm-section__toolbar' }, [\n h('span', { class: 'sm-section__toolbar-label', title: sectionChip }, [sectionChip]),\n h('div', { class: 'sm-section__toolbar-actions' }, [\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-section__handle',\n type: 'button',\n title: this.opts.t('common.dragSort'),\n },\n [iconDrag()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.copy'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._duplicateSection(section.id);\n },\n },\n [iconCopy()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-tool-btn--danger',\n type: 'button',\n title: this.opts.t('common.delete'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._removeSection(section.id);\n },\n },\n [iconTrash()],\n ),\n ]),\n ]);\n\n const cols = h('div', {\n class: 'sm-section__columns',\n style: layoutFlexStyle(section.layout, section.attrs.columnGap),\n });\n\n section.columns.forEach((col, i) => {\n cols.append(this._renderColumn(section, col, i, doc));\n });\n\n wrap.append(cols);\n\n host.append(wrap, toolbar);\n\n host.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).closest('.sm-block')) return;\n // 文本拖选时在 Section padding 等区域松开会冒泡 click,不应误切成 Section 选中\n if (!e.altKey && this._shouldSuppressSectionSelectFromTextInteraction()) return;\n e.stopPropagation();\n this.opts.store.setSelection({ kind: 'section', sectionId: section.id });\n });\n\n return host;\n }\n\n private _renderColumn(\n section: Section,\n column: Column,\n columnIndex: number,\n doc: EmailDoc,\n ): HTMLElement {\n const isEmpty = column.blocks.length === 0;\n const colEl = h('div', {\n class: `sm-column ${isEmpty ? 'is-empty' : ''}`,\n 'data-section-id': section.id,\n 'data-column-index': String(columnIndex),\n 'data-empty-hint': this.opts.t('canvas.emptyColumnHint'),\n style: `flex:${layoutFlexValue(section.layout, columnIndex)};${\n column.attrs.backgroundColor ? `background:${column.attrs.backgroundColor};` : ''\n }${column.attrs.verticalAlign ? `align-self:${vaToFlex(column.attrs.verticalAlign)};` : ''}`,\n });\n\n for (const block of column.blocks) {\n colEl.append(this._renderBlock(section, columnIndex, block, doc));\n }\n\n if (isEmpty) {\n colEl.addEventListener('dblclick', (e: MouseEvent) => {\n if ((e.target as HTMLElement).closest('.sm-block')) return;\n e.preventDefault();\n e.stopPropagation();\n this._insertEmptyTextAndEdit(section.id, columnIndex);\n });\n }\n\n // 列内 Sortable:负责块排序,并且:\n // - put: ['blocks'] 接受外来 block(同 group)\n // - pull: true(默认) 允许把内部 block 拖出到其他列 / 或顶层(自动裹一列)\n // - handle 限制为 .sm-block__handle:点选/编辑文本不会误触拖拽\n const sortable = Sortable.create(colEl, {\n group: { name: 'blocks', put: ['blocks'] },\n animation: 150,\n draggable: '.sm-block',\n handle: '.sm-block__handle',\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n onAdd: (e) => this._handleBlockAdd(e, section.id, columnIndex),\n onUpdate: (e) => this._handleBlockMove(e, section.id, columnIndex),\n onRemove: () => {\n /* DOM 调整由 store 重渲染负责;这里不处理。\n 源 column 把 block 拖出后,store 会被 onAdd 同步从源数组里移除该 block。 */\n },\n });\n this.sortableRefs.push(sortable);\n\n return colEl;\n }\n\n private _renderBlock(\n section: Section,\n columnIndex: number,\n block: Block,\n doc: EmailDoc,\n ): HTMLElement {\n const ctx: RenderContext = { doc, engine: 'mjml' };\n const def = this.opts.registry.get(block.type);\n let inner = '';\n if (block.lockedMjml) {\n const isHtmlLike = block.type === 'html' || def?.inlineEditable?.mode === 'html';\n const padding = defaultPaddingForLockedBlock(\n block.type,\n block.lockedMjml,\n block.props as {\n paddingTop?: number;\n paddingRight?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n },\n );\n const resolved = resolveLockedMjmlCanvasContent(block.lockedMjml, padding);\n if (resolved.mode === 'preview') {\n const wrapClass = isHtmlLike ? 'sm-html-content' : 'sm-locked-preview';\n inner = `<div class=\"${wrapClass}\">${resolved.html}</div>`;\n } else {\n inner = `<div style=\"padding:8px;color:#92400e;background:#fffbeb;border:1px dashed #f59e0b;font-family:monospace;font-size:11px;white-space:pre-wrap;\">${escapeHtml(\n resolved.source,\n )}</div>`;\n }\n } else if (def?.renderPreview) {\n inner = def.renderPreview(block.props as any, ctx);\n } else if (def) {\n inner = `<div style=\"padding:16px;color:#6b7280;background:#f9fafb;border:1px dashed #d1d5db;text-align:center;\">${escapeHtml(\n def.name,\n )}</div>`;\n } else {\n inner = `<div style=\"padding:8px;color:#dc2626;\">${escapeHtml(\n this.opts.t('canvas.unknownBlock', { type: block.type }),\n )}</div>`;\n }\n\n const displayName = def?.name ?? block.type;\n\n const el = h('div', {\n class: `sm-block ${block.lockedMjml ? 'is-locked' : ''}`,\n 'data-id': block.id,\n 'data-section-id': section.id,\n 'data-column-index': String(columnIndex),\n 'data-locked-label': this.opts.t('canvas.lockedCode'),\n });\n\n // 内容容器:renderPreview 输出放这里,便于精确定位 inlineEditable selector\n const content = h('div', { class: 'sm-block__content', html: inner });\n\n // 块工具条:hover 仅名称;选中 / 编辑中显示全部按钮;贴在块顶边之上不压内容\n const blockToolbar = h('div', { class: 'sm-block__toolbar' }, [\n h('span', { class: 'sm-block__toolbar-name', title: displayName }, [displayName]),\n h('div', { class: 'sm-block__toolbar-actions' }, [\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-block__handle',\n type: 'button',\n title: this.opts.t('common.dragSort'),\n onclick: (e: Event) => e.stopPropagation(),\n },\n [iconDrag()],\n ),\n def?.inlineEditable && !block.lockedMjml\n ? h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.editText'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._enterEditing(block);\n },\n },\n [iconEdit()],\n )\n : null,\n h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.editCode'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this.blockCodeModal.open(block.id, displayName);\n },\n },\n [iconCode()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn',\n type: 'button',\n title: this.opts.t('common.copy'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._duplicateBlock(block.id);\n },\n },\n [iconCopy()],\n ),\n h(\n 'button',\n {\n class: 'sm-tool-btn sm-tool-btn--danger',\n type: 'button',\n title: this.opts.t('common.delete'),\n onclick: (e: Event) => {\n e.stopPropagation();\n this._removeBlock(block.id);\n },\n },\n [iconTrash()],\n ),\n ]),\n ]);\n\n el.append(blockToolbar, content);\n\n el.addEventListener('click', (e) => {\n if (this.editingBlockId === block.id) return; // 编辑中不抢焦点\n /** Alt(mac Option):穿透选中父级 Section,解决单列内边距为 0 时块铺满无法点到 Section */\n if (e.altKey) {\n e.stopPropagation();\n this.opts.store.setSelection({ kind: 'section', sectionId: section.id });\n return;\n }\n e.stopPropagation();\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: section.id,\n columnIndex,\n blockId: block.id,\n });\n });\n\n if (block.lockedMjml) {\n el.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.blockCodeModal.open(block.id, displayName);\n });\n } else if (def?.inlineEditable) {\n el.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n this._enterEditing(block);\n });\n }\n\n return el;\n }\n\n private _renderAddBar(): HTMLElement {\n const layouts: { layout: SectionLayout; label: string }[] = [\n { layout: '1', label: this.opts.t('leftPanel.oneColumn') },\n { layout: '1-1', label: this.opts.t('leftPanel.multiColumn') },\n ];\n const bar = h('div', { class: 'sm-add-section-bar' }, [\n h('span', {}, [this.opts.t('canvas.addSection')]),\n ]);\n for (const l of layouts) {\n bar.append(\n h(\n 'button',\n {\n class: 'sm-add-section-bar__btn',\n type: 'button',\n onclick: () =>\n this.opts.store.update((d) => {\n d.sections.push(createSection(l.layout));\n }),\n },\n [l.label],\n ),\n );\n }\n return bar;\n }\n\n /* ----------------------------- 内联编辑 -------------------------------- */\n\n /** 空文档时:在画布白底区域双击,插入一列 Section + 空文本并进入编辑 */\n private _onEmptyCanvasDblClick(e: MouseEvent) {\n if (this.opts.store.doc.sections.length > 0) return;\n const t = e.target as HTMLElement | null;\n if (!t || !this.inner.contains(t)) return;\n e.preventDefault();\n e.stopPropagation();\n this._bootstrapEmptyDocWithText();\n }\n\n /** 无任何 Section 时:创建单栏布局并放入空正文块,再进入内联编辑 */\n private _bootstrapEmptyDocWithText() {\n const reg = this.opts.registry;\n if (!reg.get('text')?.inlineEditable) return;\n this.opts.store.update((d) => {\n if (d.sections.length > 0) return;\n const newBlock = reg.createBlock('text');\n (newBlock.props as { content: string }).content = '';\n const section = createSection('1');\n section.columns[0].blocks.push(newBlock);\n d.sections.push(section);\n });\n\n const doc = this.opts.store.doc;\n const firstBlock = doc.sections[0]?.columns[0]?.blocks[0];\n if (!firstBlock) return;\n\n requestAnimationFrame(() => {\n const loc = findBlockLocation(this.opts.store.doc, firstBlock.id);\n if (loc) this._enterEditing(loc.block);\n });\n }\n\n /** 空列双击:插入正文组件(content 为空)并直接进入编辑 */\n private _insertEmptyTextAndEdit(sectionId: string, columnIndex: number) {\n const reg = this.opts.registry;\n if (!reg.get('text')?.inlineEditable) return;\n const newBlock = reg.createBlock('text');\n (newBlock.props as { content: string }).content = '';\n\n this.opts.store.update((d) => {\n const sec = findSection(d, sectionId);\n if (!sec) return;\n const col = sec.columns[columnIndex];\n if (!col || col.blocks.length > 0) return;\n col.blocks.push(newBlock);\n });\n\n requestAnimationFrame(() => {\n const loc = findBlockLocation(this.opts.store.doc, newBlock.id);\n if (loc) this._enterEditing(loc.block);\n });\n }\n\n private _enterEditing(block: Block) {\n if (this.editingBlockId === block.id) return;\n this._exitEditing(true);\n\n const def = this.opts.registry.get(block.type);\n if (!def?.inlineEditable) return;\n\n const blockEl = this.inner.querySelector(\n `.sm-block[data-id=\"${cssEscape(block.id)}\"]`,\n ) as HTMLElement | null;\n const contentRoot = blockEl?.querySelector('.sm-block__content') as HTMLElement | null;\n if (!contentRoot) return;\n\n const target = (\n def.inlineEditable.selector\n ? contentRoot.querySelector(def.inlineEditable.selector)\n : contentRoot.firstElementChild\n ) as HTMLElement | null;\n if (!target) return;\n\n this.editingBlockId = block.id;\n blockEl?.classList.add('is-editing');\n\n const initial =\n def.inlineEditable.mode === 'plain'\n ? String((block.props as any)[def.inlineEditable.propKey] ?? '')\n : String((block.props as any)[def.inlineEditable.propKey] ?? '');\n\n this.inlineEditor = new InlineEditor({\n el: target,\n initialValue: initial,\n mode: def.inlineEditable.mode,\n multiline: !!def.inlineEditable.multiline,\n placeholder: def.inlineEditable.placeholder,\n globalStyles: this.opts.store.doc.styles,\n onCommit: (value) => {\n const propKey = def.inlineEditable!.propKey;\n const editingId = block.id;\n this._exitEditing(false);\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, editingId);\n if (loc) (loc.block.props as any)[propKey] = value;\n });\n },\n onCancel: () => this._exitEditing(true),\n onSelectionChange: (state: SelectionState | null) => {\n this.opts.toolbar.update(state);\n },\n });\n\n if (def.inlineEditable.mode === 'rich') {\n this.opts.toolbar.attach(this.inlineEditor);\n }\n\n // 选中该 block,便于属性面板同步\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: blockEl!.getAttribute('data-section-id')!,\n columnIndex: Number(blockEl!.getAttribute('data-column-index')),\n blockId: block.id,\n });\n }\n\n /** restoreUI=true:编辑器自身恢复原 DOM(取消场景);false:保留新内容(提交场景,等待 store 回写后重渲染) */\n private _exitEditing(restoreUI: boolean) {\n if (!this.editingBlockId) return;\n const id = this.editingBlockId;\n this.editingBlockId = null;\n if (this.inlineEditor) {\n this.inlineEditor.destroy(restoreUI);\n this.inlineEditor = null;\n }\n this.opts.toolbar.detach();\n const blockEl = this.inner.querySelector(\n `.sm-block[data-id=\"${cssEscape(id)}\"]`,\n ) as HTMLElement | null;\n blockEl?.classList.remove('is-editing');\n\n if (this.pendingRender) {\n this.pendingRender = false;\n this._render();\n }\n }\n\n /* -------------------------------- 拖拽 ---------------------------------- */\n\n /** 结构变更(拖入/排序)前提交内联编辑,避免编辑态 pendingRender 与 Sortable DOM 不同步 */\n private _commitEditingBeforeStructureChange() {\n if (this.editingBlockId) this.commitInlineEdit();\n }\n\n private _resolvePaletteDrop(blockType: string): PaletteDropResult {\n const def = this.opts.registry.get(blockType);\n if (def?.expandPaletteDrop) {\n const out = def.expandPaletteDrop((t) => this.opts.registry.createBlock(t));\n if (Array.isArray(out)) return { blocks: out };\n return out;\n }\n return { blocks: [this.opts.registry.createBlock(blockType)] };\n }\n\n private _applySectionAttrs(target: Section, partial?: Partial<SectionAttrs>) {\n if (!partial) return;\n const { meta, ...rest } = partial;\n Object.assign(target.attrs, rest);\n if (meta && typeof meta === 'object') {\n target.attrs.meta = { ...(target.attrs.meta ?? {}), ...meta };\n }\n }\n\n /** 未开启 `enableDynamicVariantKey` 时剥离 palette 上的动态变量节属性 */\n private _paletteSectionAttrsForDrop(\n sectionAttrs?: Partial<SectionAttrs>,\n ): Partial<SectionAttrs> | undefined {\n if (!sectionAttrs) return undefined;\n if (this.opts.ui?.enableDynamicVariantKey === true) return sectionAttrs;\n const { dynamicVariantKey: _dv, ...rest } = sectionAttrs;\n return Object.keys(rest).length ? rest : undefined;\n }\n\n /** 组合 palette 可一次创建原生多列 Section,并将 Block 放入指定列。 */\n private _createSectionFromPaletteDrop(drop: PaletteDropResult): Section {\n const section = createSection(drop.sectionLayout ?? '1');\n this._applySectionAttrs(section, this._paletteSectionAttrsForDrop(drop.sectionAttrs));\n if (drop.columnBlocks?.length) {\n drop.columnBlocks.forEach((blocks, columnIndex) => {\n section.columns[columnIndex]?.blocks.push(...blocks);\n });\n } else {\n section.columns[0]?.blocks.push(...drop.blocks);\n }\n return section;\n }\n\n private _paletteDropNeedsDedicatedSection(drop: PaletteDropResult): boolean {\n if (drop.sectionLayout && drop.sectionLayout !== '1') return true;\n if ((drop.columnBlocks?.length ?? 0) > 1) return true;\n const attrs = this._paletteSectionAttrsForDrop(drop.sectionAttrs);\n return !!attrs?.dynamicVariantKey;\n }\n\n private _firstBlockInSection(section: Section): { block: Block; columnIndex: number } | undefined {\n for (let columnIndex = 0; columnIndex < section.columns.length; columnIndex += 1) {\n const block = section.columns[columnIndex]?.blocks[0];\n if (block) return { block, columnIndex };\n }\n return undefined;\n }\n\n private _handleSectionAdd(e: Sortable.SortableEvent) {\n this._commitEditingBeforeStructureChange();\n const item = e.item;\n const layout = item.getAttribute('data-layout') as SectionLayout | null;\n const blockType = item.getAttribute('data-block-type');\n const fromBlockId = item.getAttribute('data-id');\n const sourceGroup = item.getAttribute('data-source-group');\n const newIndex = e.newIndex ?? 0;\n\n // 路径 A:左栏布局卡片\n if (layout) {\n item.parentElement?.removeChild(item);\n this.opts.store.update((d) => {\n d.sections.splice(newIndex, 0, createSection(layout));\n });\n return;\n }\n\n // 路径 B:左栏内容/自定义卡片拖到 sections 之间 → 自动裹一列 Section\n if (sourceGroup === 'blocks' && blockType) {\n item.parentElement?.removeChild(item);\n const drop = this._resolvePaletteDrop(blockType);\n const newSection = this._createSectionFromPaletteDrop(drop);\n this.opts.store.update((d) => {\n d.sections.splice(newIndex, 0, newSection);\n });\n const head = this._firstBlockInSection(newSection);\n if (head) {\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: newSection.id,\n columnIndex: head.columnIndex,\n blockId: head.block.id,\n });\n }\n return;\n }\n\n // 路径 C:从某个已有 column 把 block 拖到 sections 之间 → 自动裹一列 Section\n if (fromBlockId) {\n item.parentElement?.removeChild(item);\n const newSection = createSection('1');\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, fromBlockId);\n if (!loc) return;\n const fromCol = loc.section.columns[loc.columnIndex];\n const idx = fromCol.blocks.findIndex((b) => b.id === fromBlockId);\n if (idx < 0) return;\n const [moved] = fromCol.blocks.splice(idx, 1);\n newSection.columns[0].blocks.push(moved);\n // 注意:newIndex 是 SortableJS 把 item 放进 DOM 后看到的索引;\n // 由于来源 column 内的 block 不属于 inner 的直接子节点,\n // newIndex 在 inner 的可视位置上是准确的。\n d.sections.splice(newIndex, 0, newSection);\n pruneSectionIfEmpty(d, loc.section.id);\n });\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: newSection.id,\n columnIndex: 0,\n blockId: fromBlockId,\n });\n }\n }\n\n private _handleSectionMove(e: Sortable.SortableEvent) {\n this._commitEditingBeforeStructureChange();\n const oldIndex = e.oldIndex ?? 0;\n const newIndex = e.newIndex ?? 0;\n if (oldIndex === newIndex) return;\n this.opts.store.update((d) => {\n const [moved] = d.sections.splice(oldIndex, 1);\n d.sections.splice(newIndex, 0, moved);\n });\n }\n\n private _handleBlockAdd(e: Sortable.SortableEvent, sectionId: string, columnIndex: number) {\n this._commitEditingBeforeStructureChange();\n const item = e.item;\n const newIndex = e.newIndex ?? 0;\n const sourceGroup = item.getAttribute('data-source-group');\n const blockType = item.getAttribute('data-block-type');\n const fromBlockId = item.getAttribute('data-id');\n\n if (sourceGroup === 'blocks' && blockType) {\n item.parentElement?.removeChild(item);\n const drop = this._resolvePaletteDrop(blockType);\n if (this._paletteDropNeedsDedicatedSection(drop)) {\n const newSection = this._createSectionFromPaletteDrop(drop);\n this.opts.store.update((d) => {\n const secIdx = d.sections.findIndex((s) => s.id === sectionId);\n const insertAt = secIdx >= 0 ? secIdx + 1 : d.sections.length;\n d.sections.splice(insertAt, 0, newSection);\n });\n const head = this._firstBlockInSection(newSection);\n if (head) {\n this.opts.store.setSelection({\n kind: 'block',\n sectionId: newSection.id,\n columnIndex: head.columnIndex,\n blockId: head.block.id,\n });\n }\n return;\n }\n const blocks = drop.blocks;\n this.opts.store.update((d) => {\n const sec = d.sections.find((s) => s.id === sectionId);\n if (!sec) return;\n sec.columns[columnIndex]?.blocks.splice(newIndex, 0, ...blocks);\n });\n const head = blocks[0];\n if (head) {\n this.opts.store.setSelection({\n kind: 'block',\n sectionId,\n columnIndex,\n blockId: head.id,\n });\n }\n return;\n }\n\n if (fromBlockId) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, fromBlockId);\n if (!loc) return;\n const fromCol = loc.section.columns[loc.columnIndex];\n const idx = fromCol.blocks.findIndex((b) => b.id === fromBlockId);\n if (idx < 0) return;\n const [moved] = fromCol.blocks.splice(idx, 1);\n const targetSec = d.sections.find((s) => s.id === sectionId);\n targetSec?.columns[columnIndex]?.blocks.splice(newIndex, 0, moved);\n pruneSectionIfEmpty(d, loc.section.id);\n });\n }\n }\n\n private _handleBlockMove(e: Sortable.SortableEvent, sectionId: string, columnIndex: number) {\n this._commitEditingBeforeStructureChange();\n const oldIndex = e.oldIndex ?? 0;\n const newIndex = e.newIndex ?? 0;\n if (oldIndex === newIndex) return;\n this.opts.store.update((d) => {\n const sec = d.sections.find((s) => s.id === sectionId);\n const col = sec?.columns[columnIndex];\n if (!col) return;\n const [moved] = col.blocks.splice(oldIndex, 1);\n col.blocks.splice(newIndex, 0, moved);\n });\n }\n\n /* -------------------------------- 操作 ---------------------------------- */\n\n private _removeSection(id: string) {\n this.opts.store.update((d) => {\n d.sections = d.sections.filter((s) => s.id !== id);\n });\n this.opts.store.setSelection(null);\n }\n\n private _duplicateSection(id: string) {\n this.opts.store.update((d) => {\n const idx = d.sections.findIndex((s) => s.id === id);\n if (idx < 0) return;\n const clone = structuredClone(d.sections[idx]);\n clone.id = `${clone.id}_c${Date.now().toString(36)}`;\n clone.columns = clone.columns.map((c) => ({\n ...c,\n id: `${c.id}_c${Date.now().toString(36)}`,\n blocks: c.blocks.map((b) => ({ ...b, id: `${b.id}_c${Date.now().toString(36)}` })),\n }));\n d.sections.splice(idx + 1, 0, clone);\n });\n }\n\n private _removeBlock(id: string) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, id);\n if (!loc) return;\n const col = loc.section.columns[loc.columnIndex];\n col.blocks = col.blocks.filter((b) => b.id !== id);\n pruneSectionIfEmpty(d, loc.section.id);\n });\n this.opts.store.setSelection(null);\n }\n\n private _duplicateBlock(id: string) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, id);\n if (!loc) return;\n const col = loc.section.columns[loc.columnIndex];\n const idx = col.blocks.findIndex((b) => b.id === id);\n if (idx < 0) return;\n const clone = structuredClone(col.blocks[idx]);\n clone.id = `${clone.id}_c${Date.now().toString(36)}`;\n col.blocks.splice(idx + 1, 0, clone);\n });\n }\n\n /**\n * 内联编辑中从编辑区拖选文字,若 mouseup 落在 Section padding / 灰底 / 留白,\n * 浏览器仍可能对 mouseup 目标派发 click;选区仍在编辑区内时不应提交或改选中。\n */\n private _shouldSuppressClearSelectionFromTextDrag(): boolean {\n return (\n this.pointerGestureStartedInInlineEdit &&\n this._shouldSuppressSectionSelectFromTextInteraction()\n );\n }\n\n private _shouldSuppressSectionSelectFromTextInteraction(): boolean {\n if (!this.editingBlockId) return false;\n const editingEl = this.inner.querySelector('.sm-inline-editing');\n if (!editingEl) return false;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return false;\n const nodeInEditing = (n: Node | null): boolean => {\n if (!n) return false;\n const el = n.nodeType === Node.TEXT_NODE ? n.parentNode : n;\n return !!el && editingEl.contains(el);\n };\n return nodeInEditing(sel.anchorNode) || nodeInEditing(sel.focusNode);\n }\n\n private _syncSelection() {\n const sel = this.opts.store.selection;\n this.inner.querySelectorAll('.is-selected').forEach((el) => el.classList.remove('is-selected'));\n if (!sel) return;\n if (sel.kind === 'section') {\n this.inner\n .querySelector(`.sm-section-host[data-id=\"${cssEscape(sel.sectionId)}\"]`)\n ?.classList.add('is-selected');\n } else {\n this.inner\n .querySelector(`.sm-block[data-id=\"${cssEscape(sel.blockId)}\"]`)\n ?.classList.add('is-selected');\n }\n }\n\n private _destroySortables() {\n for (const s of this.sortableRefs) s.destroy();\n this.sortableRefs = [];\n }\n}\n\n/* ---------------------------------- utils --------------------------------- */\n\nfunction layoutFlexStyle(_layout: SectionLayout, columnGap?: number): string {\n const gap =\n columnGap != null && columnGap > 0 ? `gap:${Math.min(columnGap, 200)}px;` : '';\n return `display:flex;flex-wrap:nowrap;width:100%;${gap}`;\n}\n\nfunction layoutFlexValue(layout: SectionLayout, index: number): string {\n const parts = layout.split('-').map(Number);\n const total = parts.reduce((s, x) => s + x, 0);\n const ratio = parts[index] ?? 1;\n return `${ratio} 1 0;min-width:0;width:${((ratio / total) * 100).toFixed(2)}%`;\n}\n\nfunction vaToFlex(va: 'top' | 'middle' | 'bottom'): string {\n return va === 'top' ? 'flex-start' : va === 'bottom' ? 'flex-end' : 'center';\n}\n\nfunction cssEscape(s: string): string {\n if (typeof CSS !== 'undefined' && CSS.escape) return CSS.escape(s);\n return s.replace(/[^\\w-]/g, '\\\\$&');\n}\n\nfunction svg(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '12');\n el.setAttribute('height', '12');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML = inner;\n return el;\n}\nfunction iconDrag() {\n return svg(\n '<circle cx=\"7\" cy=\"5\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"13\" cy=\"5\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"7\" cy=\"10\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"13\" cy=\"10\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"7\" cy=\"15\" r=\"1.4\" fill=\"currentColor\"/><circle cx=\"13\" cy=\"15\" r=\"1.4\" fill=\"currentColor\"/>',\n );\n}\nfunction iconCopy() {\n return svg(\n '<rect x=\"6\" y=\"6\" width=\"10\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><path d=\"M4 12V5a1 1 0 011-1h7\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/>',\n );\n}\nfunction iconTrash() {\n return svg(\n '<path d=\"M5 6h10M8 6V4h4v2M6 6l1 10h6l1-10\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\" stroke-linejoin=\"round\"/>',\n );\n}\nfunction iconEdit() {\n return svg(\n '<path d=\"M4 14l8-8 2 2-8 8H4v-2z\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\" stroke-linejoin=\"round\"/>',\n );\n}\nfunction iconCode() {\n return svg(\n '<path d=\"M7 7l-3 3 3 3M13 7l3 3-3 3\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n );\n}\n","import { EditorState } from '@codemirror/state';\nimport { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { Store } from '../store/store';\nimport { prettyHtml } from '../utils/html';\nimport { h } from '../utils/dom';\nimport { richTextExecCommand } from '../utils/richTextCommand';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface ExportModalOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n /** 替换 {{var}} 为 sample 值 */\n withSampleVariables?: boolean;\n}\n\n/**\n * 导出 HTML 弹框:\n * - body 用 CodeMirror 只读展示当前文档编译产物\n * - footer:复制、美化、下载 三个动作\n */\nexport class ExportModal {\n private opts: ExportModalOptions;\n private modal: Modal;\n private cm: EditorView | null = null;\n private current: string = '';\n\n constructor(opts: ExportModalOptions) {\n this.opts = opts;\n this.modal = new Modal({\n title: opts.t('export.title'),\n className: 'sm-modal--export',\n width: 'min(960px, 96vw)',\n height: 'min(720px, 88vh)',\n onClose: () => this._destroyCm(),\n t: opts.t,\n });\n\n const editorHost = h('div', { class: 'sm-export__editor' });\n this.modal.body.append(editorHost);\n\n const copyBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this._copy() },\n [this.opts.t('export.copyHtml')],\n );\n const beautifyBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this._beautify() },\n [this.opts.t('common.beautify')],\n );\n const downloadBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => this._download(),\n },\n [this.opts.t('export.downloadHtml')],\n );\n this.modal.footer.append(copyBtn, beautifyBtn, downloadBtn);\n\n // 初始化 CodeMirror(在 open 时填充 doc)\n this.cm = new EditorView({\n parent: editorHost,\n state: EditorState.create({\n doc: '',\n extensions: [basicSetup, cmHtml(), EditorState.readOnly.of(true)],\n }),\n });\n }\n\n open(parent?: HTMLElement) {\n this._compile();\n this.modal.open(parent);\n }\n\n private _compile() {\n const result = renderDoc(this.opts.store.doc, this.opts.registry, {\n withSampleVariables: this.opts.withSampleVariables ?? false,\n });\n this.current = result.html;\n this._setText(result.html);\n }\n\n private _setText(text: string) {\n if (!this.cm) return;\n this.cm.dispatch({\n changes: { from: 0, to: this.cm.state.doc.length, insert: text },\n });\n }\n\n private async _copy() {\n try {\n await navigator.clipboard.writeText(this.current);\n this._toast(this.opts.t('toast.copiedToClipboard'));\n } catch {\n const ta = document.createElement('textarea');\n ta.value = this.current;\n document.body.appendChild(ta);\n ta.select();\n richTextExecCommand('copy');\n document.body.removeChild(ta);\n this._toast(this.opts.t('toast.copied'));\n }\n }\n\n private _beautify() {\n this.current = prettyHtml(this.current);\n this._setText(this.current);\n }\n\n private _download() {\n const blob = new Blob([this.current], { type: 'text/html;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `email-${Date.now()}.html`;\n a.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n\n private _toast(text: string) {\n const t = h('div', { class: 'sm-toast' }, [text]);\n this.modal.body.append(t);\n requestAnimationFrame(() => t.classList.add('is-visible'));\n setTimeout(() => {\n t.classList.remove('is-visible');\n setTimeout(() => t.remove(), 200);\n }, 1400);\n }\n\n private _destroyCm() {\n this.cm?.destroy();\n this.cm = null;\n }\n}\n","import Sortable from 'sortablejs';\nimport type { Registry } from '../registry/registry';\nimport type { BlockDefinition, SectionLayout } from '../types';\nimport { clear, h } from '../utils/dom';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface LeftPanelOptions {\n registry: Registry;\n t: SimpleMailT;\n /** 合并后的组件分组标题 */\n blockGroupTitle?: string;\n /** custom 类块默认 tooltip 后缀(无 paletteTooltip 时) */\n customPaletteTooltipSuffix?: string;\n /** 不显示在左栏的 block type(仍可在 Registry 中 createBlock) */\n hiddenPaletteBlockTypes?: string[];\n}\n\ninterface LayoutCard {\n layout: SectionLayout;\n nameKey: string;\n icon: string;\n titleKey?: string;\n}\n\nconst LAYOUT_CARDS: LayoutCard[] = [\n { layout: '1', nameKey: 'leftPanel.oneColumn', icon: layoutSvg([1]) },\n /** 默认 1:1;1:2 / 2:1 / 1:1:1 在选中 Section 后于右栏「列布局」切换 */\n {\n layout: '1-1',\n nameKey: 'leftPanel.multiColumn',\n icon: layoutSvg([1, 1]),\n titleKey: 'leftPanel.multiColumnTitle',\n },\n];\n\n/**\n * 左栏分两类:\n * - 布局(layout):决定 Section 结构,拖入到画布顶层(group: 'sections')\n * - 组件:内置与 custom 合并为一组,作为 Block 拖入 Column(group: 'blocks')\n *\n * 通过 SortableJS 的 group + clone + sort:false 实现。\n * 这两个组分开,画布顶层只接 'sections',列内只接 'blocks',\n * 严格两层拖拽,禁止跨级别——这是解决 GrapesJS 嵌套混乱的核心。\n */\nexport class LeftPanel {\n el: HTMLElement;\n private opts: LeftPanelOptions;\n\n constructor(opts: LeftPanelOptions) {\n this.opts = opts;\n this.el = h('aside', { class: 'sm-panel sm-panel--left' });\n this._render();\n }\n\n refresh() {\n this._render();\n }\n\n private _render() {\n clear(this.el);\n const hiddenPalette = new Set(this.opts.hiddenPaletteBlockTypes ?? []);\n const filterPalette = (defs: BlockDefinition[]) =>\n defs.filter((d) => !hiddenPalette.has(d.type));\n const paletteBlocks = [\n ...filterPalette(this.opts.registry.byCategory('content')),\n ...filterPalette(this.opts.registry.byCategory('custom')),\n ];\n\n const wrap = h('div', { class: 'sm-blocks' });\n\n wrap.append(this._renderLayoutGroup());\n if (paletteBlocks.length) {\n wrap.append(\n this._renderBlockGroup(\n this.opts.blockGroupTitle ?? this.opts.t('leftPanel.components'),\n paletteBlocks,\n ),\n );\n }\n\n this.el.append(wrap);\n }\n\n private _renderLayoutGroup(): HTMLElement {\n const grid = h('div', { class: 'sm-blocks__grid' });\n for (const c of LAYOUT_CARDS) {\n const name = this.opts.t(c.nameKey);\n grid.append(\n h(\n 'div',\n {\n class: 'sm-block-card',\n 'data-source-group': 'sections',\n 'data-layout': c.layout,\n title: c.titleKey ? this.opts.t(c.titleKey) : name,\n },\n [\n h('span', { class: 'sm-block-card__icon', html: c.icon }),\n h('span', { class: 'sm-block-card__name' }, [name]),\n ],\n ),\n );\n }\n Sortable.create(grid, {\n group: { name: 'sections', pull: 'clone', put: false },\n sort: false,\n animation: 120,\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n });\n return h('section', { class: 'sm-blocks__group' }, [\n h('div', { class: 'sm-panel__title' }, [this.opts.t('leftPanel.layout')]),\n grid,\n ]);\n }\n\n private _blockCardTitle(def: BlockDefinition): string {\n if (def.paletteTooltip?.trim()) return def.paletteTooltip.trim();\n if (def.category === 'custom') {\n const suffix =\n this.opts.customPaletteTooltipSuffix ?? this.opts.t('leftPanel.customTooltipSuffix');\n return `${def.name} — ${suffix}`;\n }\n return def.name;\n }\n\n private _renderBlockGroup(title: string, defs: BlockDefinition[]): HTMLElement {\n const grid = h('div', { class: 'sm-blocks__grid' });\n for (const def of defs) {\n const isCustom = def.category === 'custom';\n const children: HTMLElement[] = [];\n if (isCustom) {\n children.push(h('span', { class: 'sm-block-card__dot', 'aria-hidden': 'true' }));\n }\n children.push(\n h('span', { class: 'sm-block-card__icon', html: def.icon }),\n h('span', { class: 'sm-block-card__name' }, [def.name]),\n );\n grid.append(\n h(\n 'div',\n {\n class: 'sm-block-card',\n 'data-source-group': 'blocks',\n 'data-block-type': def.type,\n title: this._blockCardTitle(def),\n },\n children,\n ),\n );\n }\n Sortable.create(grid, {\n group: { name: 'blocks', pull: 'clone', put: false },\n sort: false,\n animation: 120,\n ghostClass: 'sm-ghost',\n chosenClass: 'sm-chosen',\n dragClass: 'sm-drag',\n });\n return h('section', { class: 'sm-blocks__group' }, [\n h('div', { class: 'sm-panel__title' }, [title]),\n grid,\n ]);\n }\n}\n\nfunction layoutSvg(parts: number[]): string {\n const total = parts.reduce((s, x) => s + x, 0);\n const w = 24;\n const gap = 1;\n const innerW = w - gap * (parts.length - 1);\n let x = 0;\n const rects = parts\n .map((p) => {\n const rw = (p / total) * innerW;\n const rect = `<rect x=\"${x}\" y=\"6\" width=\"${rw.toFixed(\n 2,\n )}\" height=\"12\" fill=\"currentColor\" opacity=\"0.8\" rx=\"1\"/>`;\n x += rw + gap;\n return rect;\n })\n .join('');\n return `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">${rects}</svg>`;\n}\n","import type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { Store } from '../store/store';\nimport { h } from '../utils/dom';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport type PreviewDevice = 'pc' | 'pad' | 'phone';\n\ninterface DeviceSpec {\n width: number;\n label: string;\n}\n\nconst DEVICES: Record<PreviewDevice, DeviceSpec> = {\n pc: { width: 800, label: 'PC' },\n pad: { width: 640, label: 'Pad' },\n phone: { width: 375, label: 'Phone' },\n};\n\nexport interface PreviewModalOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n}\n\n/**\n * 预览弹框:用 iframe 渲染真实 mjml 编译产物。\n * 通过 srcdoc 写入 HTML,避免跨域;默认保留 {{var}} 占位符,与画布编辑态一致。\n * 三个设备宽度切换:800 / 640 / 375,按邮件常见宽度档位。\n */\nexport class PreviewModal {\n private opts: PreviewModalOptions;\n private modal: Modal;\n private device: PreviewDevice = 'pc';\n private iframe: HTMLIFrameElement;\n private viewport: HTMLElement;\n private deviceBtns: Record<PreviewDevice, HTMLButtonElement> = {} as any;\n private iframeRo?: ResizeObserver;\n private layoutRaf: number | null = null;\n private onWinResize?: () => void;\n\n constructor(opts: PreviewModalOptions) {\n this.opts = opts;\n this.modal = new Modal({\n title: opts.t('preview.title'),\n className: 'sm-modal--preview',\n width: 'min(960px, calc(100vw - 32px))',\n /** 高度随 iframe 内容测量,见 _fitPreviewHeight;不超过屏高由 CSS max-height 约束 */\n onClose: () => this._teardownLayoutHooks(),\n t: opts.t,\n });\n\n this.iframe = h('iframe', {\n class: 'sm-preview__frame',\n sandbox: 'allow-same-origin',\n title: 'preview',\n }) as HTMLIFrameElement;\n this.iframe.addEventListener('load', () => {\n this._bindIframeResizeObserver();\n this._scheduleFitPreviewHeight();\n });\n\n this.viewport = h('div', { class: 'sm-preview__viewport' }, [this.iframe]);\n this.modal.body.classList.add('sm-modal__body--center');\n this.modal.body.append(this.viewport);\n\n // 设备切换工具条放在 header 右侧\n const switcher = h('div', { class: 'sm-segmented' });\n (['pc', 'pad', 'phone'] as PreviewDevice[]).forEach((d) => {\n const btn = h(\n 'button',\n {\n class: `sm-segmented__item ${d === this.device ? 'sm-segmented__item--active' : ''}`,\n type: 'button',\n onclick: () => this.setDevice(d),\n },\n [iconForDevice(d), DEVICES[d].label],\n ) as HTMLButtonElement;\n this.deviceBtns[d] = btn;\n switcher.append(btn);\n });\n this.modal.appendHeaderTool(switcher);\n }\n\n open(parent?: HTMLElement) {\n this._render();\n this.setDevice(this.device);\n this.modal.open(parent);\n this.onWinResize = () => this._scheduleFitPreviewHeight();\n window.addEventListener('resize', this.onWinResize);\n }\n\n setDevice(d: PreviewDevice) {\n this.device = d;\n const spec = DEVICES[d];\n this.viewport.style.setProperty('--sm-preview-w', `${spec.width}px`);\n for (const k of Object.keys(this.deviceBtns) as PreviewDevice[]) {\n this.deviceBtns[k].classList.toggle('sm-segmented__item--active', k === d);\n }\n requestAnimationFrame(() =>\n requestAnimationFrame(() => this._scheduleFitPreviewHeight()),\n );\n }\n\n private _render() {\n const result = renderDoc(this.opts.store.doc, this.opts.registry, {\n withSampleVariables: false,\n });\n // 用 srcdoc 而非 src=blob:,避免 about:srcdoc 偶发的相对资源问题\n this.iframe.srcdoc = result.html;\n }\n\n /** 标题栏 + body 上下 padding + 与视口的小间距 */\n private static readonly VIEWPORT_RESERVED_Y = 112;\n\n private _scheduleFitPreviewHeight() {\n if (this.layoutRaf != null) cancelAnimationFrame(this.layoutRaf);\n this.layoutRaf = requestAnimationFrame(() => {\n this.layoutRaf = null;\n this._fitPreviewHeight();\n });\n }\n\n private _fitPreviewHeight() {\n if (!this.iframe.isConnected) return;\n try {\n const doc = this.iframe.contentDocument;\n const root = doc?.documentElement;\n const body = doc?.body;\n if (!root || !body) return;\n const raw = Math.max(root.scrollHeight, body.scrollHeight);\n const maxPx = Math.max(\n 240,\n window.innerHeight - PreviewModal.VIEWPORT_RESERVED_Y,\n );\n const minPx = 200;\n const next = Math.min(Math.max(Math.ceil(raw), minPx), maxPx);\n this.viewport.style.height = `${next}px`;\n } catch {\n /* srcdoc 同域,极端情况下忽略 */\n }\n }\n\n private _bindIframeResizeObserver() {\n this.iframeRo?.disconnect();\n try {\n const doc = this.iframe.contentDocument;\n const body = doc?.body;\n if (!body || typeof ResizeObserver === 'undefined') return;\n this.iframeRo = new ResizeObserver(() => this._scheduleFitPreviewHeight());\n this.iframeRo.observe(body);\n const html = doc.documentElement;\n if (html) this.iframeRo.observe(html);\n } catch {\n /* ignore */\n }\n }\n\n private _teardownLayoutHooks() {\n if (this.onWinResize) {\n window.removeEventListener('resize', this.onWinResize);\n this.onWinResize = undefined;\n }\n this.iframeRo?.disconnect();\n this.iframeRo = undefined;\n if (this.layoutRaf != null) {\n cancelAnimationFrame(this.layoutRaf);\n this.layoutRaf = null;\n }\n }\n}\n\nfunction iconForDevice(d: PreviewDevice): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '14');\n el.setAttribute('height', '14');\n el.setAttribute('viewBox', '0 0 20 20');\n if (d === 'pc')\n el.innerHTML =\n '<rect x=\"2\" y=\"4\" width=\"16\" height=\"11\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><path d=\"M7 18h6\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>';\n else if (d === 'pad')\n el.innerHTML =\n '<rect x=\"4\" y=\"2\" width=\"12\" height=\"16\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"10\" cy=\"16\" r=\"0.6\" fill=\"currentColor\"/>';\n else\n el.innerHTML =\n '<rect x=\"6\" y=\"2\" width=\"8\" height=\"16\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"10\" cy=\"16\" r=\"0.6\" fill=\"currentColor\"/>';\n return el;\n}\n","import { bindColorPickerInput } from './ColorPickerPopover';\nimport { h } from '../utils/dom';\nimport { FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport { LIST_INDENT_PRESETS_PX, type ListIndentValue } from '../utils/emailListStyles';\nimport type { InlineEditor, SelectionState } from './InlineEditor';\nimport type { SimpleMailT } from '../i18n';\n\n/**\n * 富文本浮动工具条。\n *\n * 关键设计:\n * - 工具条挂在 editor root 上,跨 block 实例复用;切换编辑对象时调用 attach()。\n * - **mousedown 在工具条任意位置时(capture 阶段)先调用 editor.saveSelection()**:\n * 在浏览器把焦点切到 select/input 之前抢先把选区存到 InlineEditor,\n * 后续 exec 时会自动 focus 回 contenteditable + 恢复选区——这是\n * \"切字体/字号/颜色失灵\"问题的根本修复。\n * - 按钮全部 mousedown.preventDefault:不抢焦点;select/color/url 这些\n * 必须 takeFocus 的控件不能 preventDefault,但因为 mousedown 已经存档了选区,\n * onChange/onClick 时调 exec 即可。\n * - 定位:优先贴在当前内联编辑根节点(正文容器)**上沿外**,可覆盖上方块工具区;\n * 滚出中栏画布视口时钳制在 `.sm-canvas-wrap` 可见区域内(按需吸顶)。\n */\nexport interface RichTextToolbarOptions {\n /** 工具条的定位上下文:rect 是相对该容器计算的 */\n positionRoot: HTMLElement;\n /** 中栏画布滚动容器;省略时从 positionRoot 内查找 `.sm-canvas-wrap` */\n scrollRoot?: HTMLElement;\n t: SimpleMailT;\n}\n\nconst FONT_FAMILIES = [\n { labelKey: 'toolbar.fontDefault', label: 'Default', value: '' },\n { label: 'Inter', value: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' },\n { labelKey: 'toolbar.fontPingFang', label: 'PingFang SC', value: '\"PingFang SC\", \"Helvetica Neue\", Arial, sans-serif' },\n { labelKey: 'toolbar.fontMicrosoftYaHei', label: 'Microsoft YaHei', value: '\"Microsoft YaHei\", \"Segoe UI\", sans-serif' },\n { labelKey: 'toolbar.fontSimSun', label: 'SimSun', value: 'SimSun, \"Songti SC\", serif' },\n { label: 'Helvetica', value: '\"Helvetica Neue\", Arial, sans-serif' },\n { label: 'Arial', value: 'Arial, sans-serif' },\n { label: 'Georgia', value: 'Georgia, serif' },\n { label: 'Courier', value: '\"Courier New\", monospace' },\n];\n\nconst FONT_SIZES = ['12px', '13px', '14px', '15px', '16px', '18px', '20px', '24px', '28px', '32px'];\n\nexport class RichTextToolbar {\n el: HTMLElement;\n private opts: RichTextToolbarOptions;\n private editor: InlineEditor | null = null;\n private btns: Record<string, HTMLButtonElement> = {};\n private selectFontFamily!: HTMLSelectElement;\n private selectFontSize!: HTMLSelectElement;\n private selectFontWeight!: HTMLSelectElement;\n private inputColor!: HTMLInputElement;\n private inputBgColor!: HTMLInputElement;\n private inputLink!: HTMLInputElement;\n private linkPanel!: HTMLElement;\n /** 最近一次选区推断出的链接,供打开面板时预填 */\n private lastLinkHref: string | null = null;\n private listIndentGroup!: HTMLElement;\n private selectListIndent!: HTMLSelectElement;\n private syncingListIndentUi = false;\n private scrollListenersBound = false;\n private repositionRaf = 0;\n private readonly boundReposition = () => this._scheduleReposition();\n\n constructor(opts: RichTextToolbarOptions) {\n this.opts = opts;\n this.el = h('div', { class: 'sm-floating-toolbar', role: 'toolbar' });\n this._build();\n this.hide();\n opts.positionRoot.append(this.el);\n\n // 关键:用 capture 阶段在所有控件之前抢先 save selection\n this.el.addEventListener(\n 'mousedown',\n () => {\n this.editor?.saveSelection();\n },\n true,\n );\n }\n\n attach(editor: InlineEditor) {\n this.editor = editor;\n }\n\n detach() {\n this.editor = null;\n this.hide();\n }\n\n show() {\n this.el.classList.add('is-visible');\n this._bindScrollListeners();\n }\n\n hide() {\n this.el.classList.remove('is-visible');\n this.linkPanel.classList.remove('is-visible');\n this._unbindScrollListeners();\n if (this.repositionRaf) {\n cancelAnimationFrame(this.repositionRaf);\n this.repositionRaf = 0;\n }\n }\n\n /** 由 InlineEditor 推选区状态进来 */\n update(state: SelectionState | null) {\n if (!state || !this.editor) {\n this.hide();\n return;\n }\n this.show();\n\n const f = state.formats;\n this._setActive('bold', f.bold);\n this._setActive('italic', f.italic);\n this._setActive('underline', f.underline);\n this._setActive('strikethrough', f.strikethrough);\n this._setActive('ul', f.unorderedList);\n this._setActive('ol', f.orderedList);\n this._setActive('alignLeft', f.align === 'left');\n this._setActive('alignCenter', f.align === 'center');\n this._setActive('alignRight', f.align === 'right');\n\n const hasLink = !!f.link;\n this.lastLinkHref = f.link;\n this.btns.unlink.style.display = hasLink ? '' : 'none';\n\n if (f.foreColor) {\n const hex = colorToHexInput(f.foreColor);\n if (hex) this.inputColor.value = hex;\n }\n this.inputBgColor.value = f.backColor\n ? (colorToHexInput(f.backColor) ?? '#ffffff')\n : '#ffffff';\n if (f.fontName) this.selectFontFamily.value = matchFamily(f.fontName);\n this.selectFontSize.value = matchFontSize(f.fontSize);\n this.selectFontWeight.value = matchFontWeight(f.fontWeight);\n this._syncListIndentUi(f.inList, f.listIndentPx);\n\n this._scheduleReposition();\n }\n\n destroy() {\n this._unbindScrollListeners();\n if (this.repositionRaf) cancelAnimationFrame(this.repositionRaf);\n this.el.remove();\n }\n\n /* -------------------------------- 内部 ---------------------------------- */\n\n private _build() {\n const sep = () => h('div', { class: 'sm-floating-toolbar__sep' });\n const t = this.opts.t;\n\n // 这些按钮 mousedown.preventDefault 阻止抢焦点;点击时直接 exec\n const exec = (cmd: string, val?: string) => () => this.editor?.exec(cmd, val);\n\n this.btns.bold = this._btn('B', t('toolbar.bold'), exec('bold'), { fontWeight: '700' });\n this.btns.italic = this._btn('I', t('toolbar.italic'), exec('italic'), { fontStyle: 'italic' });\n this.btns.underline = this._btn('U', t('toolbar.underline'), exec('underline'), {\n textDecoration: 'underline',\n });\n this.btns.strikethrough = this._btn('S', t('toolbar.strikethrough'), exec('strikeThrough'), {\n textDecoration: 'line-through',\n });\n\n this.btns.alignLeft = this._iconBtn(\n svgIcon(\n '<path d=\"M3 5h14M3 9h10M3 13h14M3 17h10\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.alignLeft'),\n exec('justifyLeft'),\n );\n this.btns.alignCenter = this._iconBtn(\n svgIcon(\n '<path d=\"M3 5h14M5 9h10M3 13h14M5 17h10\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.alignCenter'),\n exec('justifyCenter'),\n );\n this.btns.alignRight = this._iconBtn(\n svgIcon(\n '<path d=\"M3 5h14M7 9h10M3 13h14M7 17h10\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.alignRight'),\n exec('justifyRight'),\n );\n\n this.btns.ul = this._iconBtn(\n svgIcon(\n '<circle cx=\"4\" cy=\"6\" r=\"1.2\" fill=\"currentColor\"/><circle cx=\"4\" cy=\"10\" r=\"1.2\" fill=\"currentColor\"/><circle cx=\"4\" cy=\"14\" r=\"1.2\" fill=\"currentColor\"/><path d=\"M8 6h9M8 10h9M8 14h9\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.unorderedList'),\n exec('insertUnorderedList'),\n );\n this.btns.ol = this._iconBtn(\n svgIcon(\n '<text x=\"2\" y=\"8\" font-size=\"6\" font-weight=\"600\" fill=\"currentColor\">1</text><text x=\"2\" y=\"14\" font-size=\"6\" font-weight=\"600\" fill=\"currentColor\">2</text><path d=\"M8 6h9M8 12h9\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.orderedList'),\n exec('insertOrderedList'),\n );\n\n this.selectListIndent = h('select', {\n class: 'sm-floating-toolbar__select sm-floating-toolbar__select--list-indent',\n title: t('toolbar.listIndent'),\n onchange: (e: Event) => {\n if (this.syncingListIndentUi) return;\n const raw = (e.target as HTMLSelectElement).value;\n if (raw === '') this.editor?.setListIndent(null);\n else this.editor?.setListIndent(Number(raw));\n },\n }) as HTMLSelectElement;\n {\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = t('toolbar.indent');\n this.selectListIndent.append(placeholder);\n for (const px of LIST_INDENT_PRESETS_PX) {\n const opt = document.createElement('option');\n opt.value = String(px);\n opt.textContent = String(px);\n this.selectListIndent.append(opt);\n }\n }\n this.listIndentGroup = this._group([this.selectListIndent]);\n this.listIndentGroup.style.display = 'none';\n\n // 字体:select 不能 preventDefault(否则下拉打不开);mousedown(capture) 已存档选区\n this.selectFontFamily = h('select', {\n class: 'sm-floating-toolbar__select',\n title: t('toolbar.fontFamily'),\n onchange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v) this.editor?.exec('fontName', v);\n else this.editor?.exec('removeFormat');\n },\n });\n for (const f of FONT_FAMILIES) {\n const opt = document.createElement('option');\n opt.value = f.value;\n opt.textContent = f.labelKey ? t(f.labelKey) : f.label;\n this.selectFontFamily.append(opt);\n }\n\n // 字号\n this.selectFontSize = h('select', {\n class: 'sm-floating-toolbar__select',\n title: t('toolbar.fontSize'),\n onchange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v) this.editor?.applyFontSize(v);\n },\n });\n {\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = t('toolbar.fontSize');\n this.selectFontSize.append(placeholder);\n }\n for (const px of FONT_SIZES) {\n const opt = document.createElement('option');\n opt.value = px;\n opt.textContent = px;\n this.selectFontSize.append(opt);\n }\n\n // 字重\n this.selectFontWeight = h('select', {\n class: 'sm-floating-toolbar__select',\n title: t('toolbar.fontWeight'),\n onchange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v) this.editor?.applyFontWeight(v);\n },\n });\n {\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = t('toolbar.fontWeight');\n this.selectFontWeight.append(placeholder);\n }\n for (const w of FONT_WEIGHT_STEP_OPTIONS) {\n const opt = document.createElement('option');\n opt.value = w.value;\n opt.textContent = w.label;\n this.selectFontWeight.append(opt);\n }\n\n // 文字颜色\n this.inputColor = h('input', {\n class: 'sm-floating-toolbar__color',\n type: 'color',\n title: t('toolbar.textColor'),\n value: '#433f3f',\n }) as HTMLInputElement;\n bindColorPickerInput(this.inputColor, {\n layerRoot: this.opts.positionRoot,\n liveCommit: true,\n autoFocusHex: false,\n t,\n onBeforeOpen: () => this.editor?.saveSelection(),\n onCommit: (hex) => this.editor?.exec('foreColor', hex),\n onClosed: () => this.editor?.refocus(),\n });\n\n // 文字背景色\n this.inputBgColor = h('input', {\n class: 'sm-floating-toolbar__color',\n type: 'color',\n title: t('toolbar.textBackground'),\n value: '#fff7e6',\n }) as HTMLInputElement;\n bindColorPickerInput(this.inputBgColor, {\n layerRoot: this.opts.positionRoot,\n liveCommit: true,\n autoFocusHex: false,\n t,\n onBeforeOpen: () => this.editor?.saveSelection(),\n onCommit: (hex) => this.editor?.exec('hiliteColor', hex),\n onClosed: () => this.editor?.refocus(),\n });\n\n // 链接:插入链接(无链接时显示)\n this.btns.link = this._iconBtn(\n svgIcon(\n '<path d=\"M9 11.5l1.5 1.5a3.5 3.5 0 005-5l-2-2a3.5 3.5 0 00-5 0M11 8.5L9.5 7a3.5 3.5 0 00-5 5l2 2a3.5 3.5 0 005 0\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n ),\n t('toolbar.insertLink'),\n () => this._toggleLinkPanel(),\n );\n\n // 取消链接(有链接时显示)\n this.btns.unlink = this._iconBtn(\n svgIcon(\n '<path d=\"M9 11.5l1.5 1.5a3.5 3.5 0 005-5l-2-2\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\"/><path d=\"M3 3l14 14\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.unlink'),\n exec('unlink'),\n );\n\n // 清除格式:图标改为 Tx,避免被误认为\"关闭工具条\"\n this.btns.clear = this._iconBtn(\n svgIcon(\n '<text x=\"2\" y=\"14\" font-size=\"11\" font-weight=\"700\" fill=\"currentColor\">T</text><text x=\"11\" y=\"9\" font-size=\"7\" font-weight=\"700\" fill=\"currentColor\">x</text><path d=\"M11 11l5 5M16 11l-5 5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>',\n ),\n t('toolbar.clearFormat'),\n exec('removeFormat'),\n );\n\n this.linkPanel = h('div', { class: 'sm-floating-toolbar__link-panel' });\n this.inputLink = h('input', {\n class: 'sm-input',\n type: 'url',\n placeholder: 'https://...',\n onkeydown: ((e: Event) => {\n const ke = e as KeyboardEvent;\n if (ke.key === 'Enter') {\n ke.preventDefault();\n this._applyLink();\n } else if (ke.key === 'Escape') {\n ke.preventDefault();\n this.linkPanel.classList.remove('is-visible');\n this.editor?.refocus();\n }\n }) as EventListener,\n }) as HTMLInputElement;\n const applyLinkBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onmousedown: (e: Event) => e.preventDefault(),\n onclick: () => this._applyLink(),\n },\n [t('toolbar.apply')],\n );\n this.linkPanel.append(this.inputLink, applyLinkBtn);\n\n this.el.append(\n this._group([this.btns.bold, this.btns.italic, this.btns.underline, this.btns.strikethrough]),\n sep(),\n this._group([this.selectFontFamily, this.selectFontSize, this.selectFontWeight]),\n sep(),\n this._group([this.inputColor, this.inputBgColor]),\n sep(),\n this._group([this.btns.alignLeft, this.btns.alignCenter, this.btns.alignRight]),\n sep(),\n this._group([this.btns.ul, this.btns.ol]),\n this.listIndentGroup,\n sep(),\n this._group([this.btns.link, this.btns.unlink, this.btns.clear]),\n this.linkPanel,\n );\n }\n\n private _toggleLinkPanel() {\n const opening = !this.linkPanel.classList.contains('is-visible');\n this.linkPanel.classList.toggle('is-visible');\n if (this.linkPanel.classList.contains('is-visible')) {\n if (opening) {\n this.inputLink.value = this.lastLinkHref ?? '';\n }\n requestAnimationFrame(() => this.inputLink.focus());\n } else {\n this.editor?.refocus();\n }\n }\n\n private _applyLink() {\n if (!this.editor) return;\n const url = this.inputLink.value.trim();\n this.editor.setLink(url);\n this.linkPanel.classList.remove('is-visible');\n this.inputLink.value = '';\n }\n\n private _getScrollRoot(): HTMLElement {\n return (\n this.opts.scrollRoot ??\n (this.opts.positionRoot.querySelector('.sm-canvas-wrap') as HTMLElement | null) ??\n this.opts.positionRoot\n );\n }\n\n private _scheduleReposition() {\n if (this.repositionRaf) cancelAnimationFrame(this.repositionRaf);\n const ed = this.editor;\n this.repositionRaf = requestAnimationFrame(() => {\n this.repositionRaf = 0;\n if (!this.editor || ed !== this.editor || !this.el.classList.contains('is-visible')) return;\n this._positionForAnchor(this.editor.getAnchorRect());\n });\n }\n\n private _bindScrollListeners() {\n if (this.scrollListenersBound) return;\n this.scrollListenersBound = true;\n const scrollRoot = this._getScrollRoot();\n scrollRoot.addEventListener('scroll', this.boundReposition, { passive: true });\n this.opts.positionRoot\n .querySelector('.sm-body')\n ?.addEventListener('scroll', this.boundReposition, { passive: true });\n window.addEventListener('resize', this.boundReposition, { passive: true });\n }\n\n private _unbindScrollListeners() {\n if (!this.scrollListenersBound) return;\n this.scrollListenersBound = false;\n const scrollRoot = this._getScrollRoot();\n scrollRoot.removeEventListener('scroll', this.boundReposition);\n this.opts.positionRoot\n .querySelector('.sm-body')\n ?.removeEventListener('scroll', this.boundReposition);\n window.removeEventListener('resize', this.boundReposition);\n }\n\n /**\n * 相对 `positionRoot` 定位:默认贴在**正文容器**上沿上方,可覆盖上方块工具区;\n * 上方空间不足时吸到中栏画布可见区顶部,此时才可能压进正文。\n */\n private _positionForAnchor(anchor: DOMRect) {\n const rootRect = this.opts.positionRoot.getBoundingClientRect();\n const viewRect = this._getScrollRoot().getBoundingClientRect();\n const gap = 6;\n const edge = 8;\n const bar = this.el.getBoundingClientRect();\n const tw = bar.width || this.el.offsetWidth;\n const th = bar.height || this.el.offsetHeight || 40;\n\n const viewTop = viewRect.top - rootRect.top + edge;\n const viewBottom = viewRect.bottom - rootRect.top - th - edge;\n const viewLeft = viewRect.left - rootRect.left + edge;\n const viewRight = viewRect.right - rootRect.left - tw - edge;\n\n const anchorTop = anchor.top - rootRect.top;\n let top = anchorTop - th - gap;\n top = Math.max(viewTop, Math.min(top, viewBottom));\n\n let left = anchor.left - rootRect.left + anchor.width / 2 - tw / 2;\n left = Math.max(viewLeft, Math.min(left, viewRight));\n\n this.el.style.top = `${top}px`;\n this.el.style.left = `${left}px`;\n }\n\n private _syncListIndentUi(inList: boolean, indent: ListIndentValue) {\n this.listIndentGroup.style.display = inList ? '' : 'none';\n if (!inList) return;\n\n this.syncingListIndentUi = true;\n if (indent === null) {\n this.selectListIndent.value = '';\n } else {\n const preset = LIST_INDENT_PRESETS_PX.find((px) => px === indent);\n const shown =\n preset ??\n LIST_INDENT_PRESETS_PX.reduce((best, px) =>\n Math.abs(px - indent) < Math.abs(best - indent) ? px : best,\n );\n this.selectListIndent.value = String(shown);\n }\n this.syncingListIndentUi = false;\n }\n\n private _setActive(key: string, on: boolean) {\n this.btns[key]?.classList.toggle('is-active', on);\n }\n\n private _btn(\n text: string,\n title: string,\n onClick: () => void,\n style: Partial<CSSStyleDeclaration> = {},\n ): HTMLButtonElement {\n const b = h(\n 'button',\n {\n class: 'sm-floating-toolbar__btn',\n type: 'button',\n title,\n onmousedown: (e: Event) => e.preventDefault(),\n onclick: onClick,\n },\n [text],\n ) as HTMLButtonElement;\n Object.assign(b.style, style);\n return b;\n }\n\n private _iconBtn(icon: SVGElement, title: string, onClick: () => void): HTMLButtonElement {\n return h(\n 'button',\n {\n class: 'sm-floating-toolbar__btn',\n type: 'button',\n title,\n onmousedown: (e: Event) => e.preventDefault(),\n onclick: onClick,\n },\n [icon],\n ) as HTMLButtonElement;\n }\n\n private _group(children: HTMLElement[]): HTMLElement {\n return h('div', { class: 'sm-floating-toolbar__group' }, children);\n }\n}\n\nfunction svgIcon(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '14');\n el.setAttribute('height', '14');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML = inner;\n return el;\n}\n\nfunction matchFamily(name: string): string {\n const lower = name.toLowerCase().replace(/['\"]/g, '').split(',')[0].trim();\n for (const f of FONT_FAMILIES) {\n if (!f.value) continue;\n if (f.value.toLowerCase().includes(lower)) return f.value;\n }\n return '';\n}\n\nfunction matchFontSize(raw: string | null): string {\n if (!raw) return '';\n const m = raw.trim().match(/^(\\d+(?:\\.\\d+)?)px$/i);\n if (!m) return '';\n const px = `${Math.round(parseFloat(m[1]))}px`;\n if (FONT_SIZES.includes(px)) return px;\n const num = parseFloat(px);\n let best = FONT_SIZES[0];\n let bestD = Infinity;\n for (const s of FONT_SIZES) {\n const d = Math.abs(parseFloat(s) - num);\n if (d < bestD) {\n bestD = d;\n best = s;\n }\n }\n return best;\n}\n\nfunction matchFontWeight(raw: string | null): string {\n if (!raw) return '';\n const step = normalizeFontWeightStep(raw);\n return FONT_WEIGHT_STEP_OPTIONS.some((w) => w.value === step) ? step : '';\n}\n\nfunction colorToHexInput(color: string): string | null {\n const s = color.trim();\n if (!s) return null;\n if (s.startsWith('#')) {\n if (/^#[0-9a-f]{3}$/i.test(s)) {\n const r = s[1];\n const g = s[2];\n const b = s[3];\n return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();\n }\n if (/^#[0-9a-f]{6}$/i.test(s)) return s.toLowerCase();\n return s;\n }\n const m = s.match(/^rgba?\\(\\s*(\\d+)[,\\s]+(\\d+)[,\\s]+(\\d+)/i);\n if (!m) return null;\n const toHex = (n: string) => Number(n).toString(16).padStart(2, '0');\n return `#${toHex(m[1])}${toHex(m[2])}${toHex(m[3])}`;\n}\n","/** 与 blocks 中社交图标预设背景一致;core 不可依赖 blocks,供属性面板展示默认背景色 */\nexport function defaultSocialIconBackground(network: string): string {\n const m: Record<string, string> = {\n wechat: '#1AAD19',\n weibo: '#E6162D',\n x: '#000000',\n linkedin: '#0A66C2',\n github: '#181717',\n facebook: '#1877F2',\n instagram: '#E4405F',\n ig: '#E4405F',\n youtube: '#FF0000',\n tiktok: '#000000',\n rabbit: '#FF2442',\n website: '#6b7280',\n web: '#6b7280',\n };\n return m[network] ?? '#6b7280';\n}\n","/**\n * 右侧「图片地址」类字段:宿主可选手输 URL、本地上传、内置图库弹层或完全自管图库回调。\n * 编辑器最终只把 URL 写入 props。\n */\n\nexport interface ImageFieldContext {\n /** 当前选中的 Block id */\n blockId: string;\n /** 对应 `block.props` 的字段名,如 `src`、`backgroundUrl` */\n propKey: string;\n /** 输入框当前值,便于宿主作为默认筛选或回填参考 */\n currentUrl: string;\n}\n\n/** 图库列表中的一条资源 */\nexport interface GalleryItem {\n id: string;\n /** 写入邮件字段的最终图片地址(建议 HTTPS 绝对 URL) */\n url: string;\n thumbnailUrl?: string;\n title?: string;\n}\n\nexport interface ImageGalleryListResult {\n items: GalleryItem[];\n hasMore: boolean;\n}\n\n/**\n * 资源动作权限的语义标识。宿主在 `ImageAssetPermissions.check` 中据此返回是否有权限:\n * - `'upload'`:右栏「上传」按钮、图库弹层「上传」按钮(对应创建/上传权限)\n * - `'addUrl'`:图库弹层「添加链接」按钮(对应创建权限)\n * - `'delete'`:图库弹层缩略图删除按钮(对应删除权限)\n */\nexport type AssetPermissionAction = 'upload' | 'addUrl' | 'delete';\n\n/**\n * 图片资源动作的权限管控配置。未配置 `check` 时视为全部有权限(不做管控)。\n */\nexport interface ImageAssetPermissions {\n /**\n * 权限校验:返回 `false` 表示该动作无权限。\n * 未配置时视为全部有权限。\n */\n check?: (action: AssetPermissionAction) => boolean;\n /**\n * 无权限时的表现:\n * - `'disable'`(默认):按钮置灰禁用,hover 提示无权限。\n * - `'hide'`:直接隐藏对应按钮。\n */\n noPermissionMode?: 'disable' | 'hide';\n /**\n * 无权限禁用时 hover 提示文案;未配置或为空时使用编辑器默认文案(`common.noPermission`)。\n */\n noPermissionTip?: string;\n}\n\n/** `resolveAssetPermission` 的结果。 */\nexport interface ResolvedAssetPermission {\n /** `true` 表示有权限 */\n allowed: boolean;\n /** 无权限时的表现(仅在 `allowed === false` 时有意义) */\n mode: 'disable' | 'hide';\n /** 无权限禁用时的 hover 提示文案(仅在 `allowed === false` 且 `mode === 'disable'` 时有意义) */\n tip: string;\n}\n\n/**\n * 解析某个动作的权限状态。未配置 `permissions` 或 `check` 时视为有权限。\n * @param defaultNoPermissionTip 编辑器默认的无权限提示文案(由调用方从 i18n 传入)\n */\nexport function resolveAssetPermission(\n permissions: ImageAssetPermissions | undefined,\n action: AssetPermissionAction,\n defaultNoPermissionTip: string,\n): ResolvedAssetPermission {\n if (!permissions?.check) return { allowed: true, mode: 'disable', tip: '' };\n const allowed = permissions.check(action);\n if (allowed) return { allowed: true, mode: 'disable', tip: '' };\n const mode: 'disable' | 'hide' = permissions.noPermissionMode === 'hide' ? 'hide' : 'disable';\n const tip = (permissions.noPermissionTip ?? '').trim() || defaultNoPermissionTip;\n return { allowed: false, mode, tip };\n}\n\n/**\n * 内置图库弹层的数据与扩展能力。实现 `listItems` 即可;上传、链接添加、删除等仅在提供对应方法时显示。\n */\nexport interface ImageGalleryAdapter {\n /** 搜索 + 分页;`query` 为搜索框当前文本,`page` 从 0 起 */\n listItems: (args: { query: string; page: number }) => Promise<ImageGalleryListResult>;\n /** 在弹层内「上传到图库」:成功后编辑器会重新拉取第 0 页 */\n uploadFile?: (file: File) => Promise<void | string>;\n /** 在弹层内「通过链接添加」:校验/落库后编辑器会重新拉取第 0 页 */\n addByUrl?: (url: string) => Promise<void>;\n /** 从图库删除一条;提供后每张缩略图右上角显示删除按钮 */\n deleteItem?: (id: string) => Promise<void>;\n}\n\nexport interface ImageAssetsHandlers {\n /**\n * 用户点击右侧「上传」并选择本地文件。宿主完成上传后返回 **绝对 HTTPS URL**。\n */\n uploadImage?: (file: File, ctx: ImageFieldContext) => Promise<string>;\n\n /**\n * 完全自管图库:与内置 `imageGallery` 可并存;\n * **同时配置时优先使用内置 `imageGallery` 弹层**。\n */\n pickImageFromGallery?: (ctx: ImageFieldContext) => Promise<string | null>;\n\n /**\n * 内置图库:实现 `listItems` 等后,将 `showGallery: true`,由本库渲染弹层;\n * 无需再写自有弹框 DOM。\n */\n imageGallery?: ImageGalleryAdapter;\n\n /**\n * 是否显示「上传」按钮。仅当配置了 `uploadImage` 时有效。\n * 默认 `true`;设为 `false` 可关闭(仍可手输 URL)。\n */\n showUpload?: boolean;\n\n /**\n * 是否显示「图库」按钮。在配置了 `pickImageFromGallery` 或 `imageGallery` 时有效。\n * 默认 `false`;需显式设为 `true` 才展示入口。\n */\n showGallery?: boolean;\n\n /**\n * 资源动作权限管控。配置后,「上传 / 添加链接 / 删除」按钮将按 `check` 结果禁用或隐藏。\n * 默认无权限时禁用并 hover 提示。右栏「上传」与图库弹层内按钮共用同一份配置。\n */\n permissions?: ImageAssetPermissions;\n}\n","import type { Registry } from '../registry/registry';\nimport type { Store } from '../store/store';\nimport { findBlockLocation, findSection } from '../store/store';\nimport { clear, h } from '../utils/dom';\nimport type { SectionLayout } from '../types';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface FocusBreadcrumbOptions {\n store: Store;\n registry: Registry;\n /** 文档级根节点文案(如「邮件」/「版式」) */\n docRootLabel: string;\n t: SimpleMailT;\n onFocusDocument: () => void;\n onFocusSection: (sectionId: string) => void;\n}\n\ninterface CrumbItem {\n label: string;\n current: boolean;\n onClick?: () => void;\n}\n\n/**\n * 右栏聚焦路径:邮件 > 一列 > 文本。\n * 点击父级等同 Esc 上浮(块 → Section → 文档级面板)。\n */\nexport class FocusBreadcrumb {\n el: HTMLElement;\n private opts: FocusBreadcrumbOptions;\n\n constructor(opts: FocusBreadcrumbOptions) {\n this.opts = opts;\n this.el = h('nav', {\n class: 'sm-focus-crumb',\n 'aria-label': opts.t('rightPanel.breadcrumb.selected'),\n });\n opts.store.subscribeSelection(() => this.sync());\n opts.store.subscribe(() => this.sync());\n this.sync();\n }\n\n setVisible(on: boolean) {\n this.el.hidden = !on;\n }\n\n sync() {\n clear(this.el);\n const items = this._buildItems();\n if (!items.length) {\n this.el.hidden = true;\n return;\n }\n this.el.hidden = false;\n\n items.forEach((item, i) => {\n if (i > 0) {\n this.el.append(h('span', { class: 'sm-focus-crumb__sep', 'aria-hidden': 'true' }, ['›']));\n }\n if (item.current || !item.onClick) {\n this.el.append(\n h(\n 'span',\n {\n class: `sm-focus-crumb__item sm-focus-crumb__item--current`,\n title: item.label,\n },\n [item.label],\n ),\n );\n } else {\n this.el.append(\n h(\n 'button',\n {\n type: 'button',\n class: 'sm-focus-crumb__item',\n title: this.opts.t('rightPanel.breadcrumb.selectTitle', { label: item.label }),\n onclick: () => item.onClick!(),\n },\n [item.label],\n ),\n );\n }\n });\n }\n\n private _buildItems(): CrumbItem[] {\n const { store, registry, docRootLabel, onFocusDocument, onFocusSection } = this.opts;\n const sel = store.selection;\n const doc = store.doc;\n\n if (!sel) {\n return [{ label: docRootLabel, current: true }];\n }\n\n if (sel.kind === 'section') {\n const sec = findSection(doc, sel.sectionId);\n if (!sec) return [{ label: docRootLabel, current: true }];\n return [\n { label: docRootLabel, current: false, onClick: onFocusDocument },\n { label: this._layoutLabel(sec.layout), current: true },\n ];\n }\n\n const sec = findSection(doc, sel.sectionId);\n const loc = findBlockLocation(doc, sel.blockId);\n if (!sec || !loc) {\n return [{ label: docRootLabel, current: true }];\n }\n\n const blockName = registry.get(loc.block.type)?.name ?? loc.block.type;\n return [\n {\n label: this._layoutLabel(sec.layout),\n current: false,\n onClick: () => onFocusSection(sel.sectionId),\n },\n { label: blockName, current: true },\n ];\n }\n\n private _layoutLabel(layout: SectionLayout): string {\n if (layout === '1') return this.opts.t('rightPanel.layout.oneColumn');\n if (layout === '1-1') return this.opts.t('rightPanel.layout.columns');\n return layout;\n }\n}\n","import { type SimpleMailT, createI18nContext } from '../i18n';\nimport { clear, h } from '../utils/dom';\nimport { Modal } from './Modal';\nimport {\n type AssetPermissionAction,\n type GalleryItem,\n type ImageAssetPermissions,\n type ImageGalleryAdapter,\n resolveAssetPermission,\n} from './imageAssets';\n\nexport interface OpenImageGalleryModalOptions {\n adapter: ImageGalleryAdapter;\n onPick: (url: string) => void;\n t?: SimpleMailT;\n /** 挂载父节点,默认 `document.body` */\n parent?: HTMLElement;\n onClose?: () => void;\n /**\n * 资源动作权限管控。未配置或未提供 `check` 时弹层内按钮不做管控;\n * 配置后「添加 / 上传 / 删除」按 `check` 结果禁用(默认)或隐藏,禁用时 hover 提示无权限。\n */\n permissions?: ImageAssetPermissions;\n}\n\n/**\n * 打开内置图库弹层:搜索、分页、选图插入;可选「链接添加」「上传到图库」「删除」由 adapter 决定。\n */\nexport function openImageGalleryModal(opts: OpenImageGalleryModalOptions): void {\n const { adapter, onPick, parent = document.body, onClose, permissions } = opts;\n const t = opts.t ?? createI18nContext().t;\n\n /** 默认无权限提示文案(i18n),按动作取对应文案 */\n const noPermissionTip = (action: AssetPermissionAction): string => {\n switch (action) {\n case 'upload':\n return t('common.noPermissionUpload');\n case 'addUrl':\n return t('common.noPermissionAdd');\n case 'delete':\n return t('common.noPermissionDelete');\n default:\n return t('common.noPermission');\n }\n };\n const perm = (action: AssetPermissionAction) =>\n resolveAssetPermission(permissions, action, noPermissionTip(action));\n\n const modal = new Modal({\n title: t('gallery.title'),\n width: 'min(760px, 94vw)',\n height: 'min(580px, 88vh)',\n className: 'sm-modal--gallery',\n onClose,\n t,\n });\n\n const wrap = h('div', { class: 'sm-gallery-modal' });\n\n let query = '';\n let page = 0;\n let hasMore = false;\n let loading = false;\n let selected: GalleryItem | null = null;\n\n const errEl = h('div', {\n class: 'sm-gallery-modal__error',\n style: 'display:none',\n role: 'alert',\n });\n\n const searchInp = h('input', {\n class: 'sm-input sm-gallery-modal__search',\n type: 'search',\n placeholder: t('gallery.searchPlaceholder'),\n 'aria-label': t('gallery.searchAria'),\n });\n\n let debounceId: ReturnType<typeof setTimeout> | null = null;\n searchInp.addEventListener('input', () => {\n if (debounceId) clearTimeout(debounceId);\n debounceId = setTimeout(() => {\n query = (searchInp as HTMLInputElement).value;\n void loadFirst();\n }, 320);\n });\n\n const gridEl = h('div', { class: 'sm-gallery-modal__grid' });\n\n const loadMoreBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-gallery-modal__loadmore',\n type: 'button',\n style: 'display:none',\n onclick: () => {\n if (!hasMore || loading) return;\n void loadPage(page + 1, true);\n },\n },\n [t('gallery.loadMore')],\n ) as HTMLButtonElement;\n\n const confirmBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n disabled: true,\n onclick: () => finishPick(),\n },\n [t('common.insert')],\n ) as HTMLButtonElement;\n\n function setError(msg: string | null) {\n if (msg) {\n errEl.textContent = msg;\n errEl.style.display = '';\n } else {\n errEl.textContent = '';\n errEl.style.display = 'none';\n }\n }\n\n function syncSelectionStyles() {\n const cells = gridEl.querySelectorAll('.sm-gallery-modal__cell');\n cells.forEach((c) => {\n const id = (c as HTMLElement).dataset.id;\n c.classList.toggle('is-selected', !!selected && id === selected.id);\n });\n }\n\n function renderCells(items: GalleryItem[], append: boolean) {\n if (!append) clear(gridEl);\n if (items.length === 0 && !append) {\n gridEl.append(h('div', { class: 'sm-gallery-modal__empty' }, [t('gallery.empty')]));\n loadMoreBtn.style.display = hasMore ? '' : 'none';\n return;\n }\n for (const it of items) {\n const thumb = it.thumbnailUrl || it.url;\n const cellWrap = h('div', { class: 'sm-gallery-modal__cell-wrap' });\n const cell = h(\n 'button',\n {\n type: 'button',\n class: 'sm-gallery-modal__cell',\n title: it.title || it.url,\n 'data-id': it.id,\n onclick: () => {\n selected = it;\n syncSelectionStyles();\n confirmBtn.disabled = false;\n },\n ondblclick: (e: Event) => {\n e.preventDefault();\n selected = it;\n finishPick();\n },\n },\n [],\n );\n const img = h('img', {\n class: 'sm-gallery-modal__thumb',\n alt: '',\n loading: 'lazy',\n decoding: 'async',\n }) as HTMLImageElement;\n img.src = thumb;\n img.onerror = () => {\n img.style.opacity = '0.72';\n };\n const cap = h('div', { class: 'sm-gallery-modal__caption' }, [\n it.title?.trim() ? it.title : t('common.image'),\n ]);\n cell.append(img, cap);\n cellWrap.append(cell);\n\n if (adapter.deleteItem) {\n const deletePerm = perm('delete');\n if (!deletePerm.allowed && deletePerm.mode === 'hide') {\n // 无删除权限且配置为隐藏:不渲染删除按钮\n } else {\n const delBtn = h(\n 'button',\n {\n type: 'button',\n class: 'sm-gallery-modal__cell-delete',\n title: deletePerm.allowed ? t('gallery.deleteTitle') : deletePerm.tip,\n disabled: !deletePerm.allowed,\n ...(deletePerm.allowed\n ? {\n onclick: async (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n if (!window.confirm(t('gallery.deleteConfirm'))) return;\n try {\n await adapter.deleteItem!(it.id);\n if (selected?.id === it.id) {\n selected = null;\n confirmBtn.disabled = true;\n }\n await loadFirst();\n } catch (err) {\n setError(err instanceof Error ? err.message : t('gallery.deleteFailed'));\n }\n },\n }\n : {}),\n },\n ['×'],\n );\n cellWrap.append(delBtn);\n }\n }\n\n gridEl.append(cellWrap);\n }\n loadMoreBtn.style.display = hasMore ? '' : 'none';\n }\n\n async function loadPage(p: number, append: boolean) {\n if (loading) return;\n loading = true;\n loadMoreBtn.disabled = true;\n setError(null);\n try {\n const res = await adapter.listItems({ query, page: p });\n hasMore = res.hasMore;\n page = p;\n renderCells(res.items, append);\n } catch (e) {\n setError(e instanceof Error ? e.message : t('gallery.loadFailed'));\n } finally {\n loading = false;\n loadMoreBtn.disabled = false;\n }\n }\n\n async function loadFirst() {\n page = 0;\n selected = null;\n confirmBtn.disabled = true;\n clear(gridEl);\n await loadPage(0, false);\n syncSelectionStyles();\n }\n\n function finishPick() {\n if (!selected?.url?.trim()) return;\n onPick(selected.url.trim());\n modal.close();\n }\n\n /** 搜索、链接、添加、上传同一行(窄屏可换行) */\n const toolbar = h('div', { class: 'sm-gallery-modal__toolbar' });\n const toolRow = h('div', { class: 'sm-gallery-modal__toolbar-row' });\n toolRow.append(searchInp);\n\n if (adapter.addByUrl) {\n const addPerm = perm('addUrl');\n if (!addPerm.allowed && addPerm.mode === 'hide') {\n // 无添加权限且配置为隐藏:不渲染添加链接输入框与按钮\n } else {\n const urlInp = h('input', {\n class: 'sm-input sm-gallery-modal__addurl-input',\n type: 'url',\n placeholder: t('gallery.addUrlPlaceholder'),\n disabled: !addPerm.allowed,\n }) as HTMLInputElement;\n const addBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-gallery-modal__toolbar-action',\n type: 'button',\n title: addPerm.allowed ? '' : addPerm.tip,\n disabled: !addPerm.allowed,\n ...(addPerm.allowed\n ? {\n onclick: async () => {\n const u = urlInp.value.trim();\n if (!u) return;\n try {\n await adapter.addByUrl!(u);\n urlInp.value = '';\n await loadFirst();\n } catch (e) {\n setError(e instanceof Error ? e.message : t('gallery.addFailed'));\n }\n },\n }\n : {}),\n },\n [t('common.add')],\n );\n toolRow.append(urlInp, addBtn);\n }\n }\n\n if (adapter.uploadFile) {\n const uploadPerm = perm('upload');\n if (!uploadPerm.allowed && uploadPerm.mode === 'hide') {\n // 无上传权限且配置为隐藏:不渲染上传按钮\n } else {\n const fileInp = h('input', {\n type: 'file',\n accept: 'image/*',\n class: 'sm-gallery-modal__file',\n });\n fileInp.addEventListener('change', async () => {\n const f = (fileInp as HTMLInputElement).files?.[0];\n (fileInp as HTMLInputElement).value = '';\n if (!f) return;\n try {\n await adapter.uploadFile!(f);\n await loadFirst();\n } catch (e) {\n setError(e instanceof Error ? e.message : t('gallery.uploadFailed'));\n }\n });\n const upBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-gallery-modal__toolbar-action',\n type: 'button',\n title: uploadPerm.allowed ? '' : uploadPerm.tip,\n disabled: !uploadPerm.allowed,\n ...(uploadPerm.allowed ? { onclick: () => fileInp.click() } : {}),\n },\n [t('common.upload')],\n );\n toolRow.append(upBtn, fileInp);\n }\n }\n\n toolbar.append(toolRow);\n\n const scrollArea = h('div', { class: 'sm-gallery-modal__scroll' }, [gridEl, loadMoreBtn]);\n\n wrap.append(toolbar, errEl, scrollArea);\n\n modal.body.append(wrap);\n modal.footer.append(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary',\n type: 'button',\n onclick: () => modal.close(),\n },\n [t('common.cancel')],\n ),\n confirmBtn,\n );\n\n modal.open(parent);\n void loadFirst();\n}\n","import type { Variable } from '../types';\nimport { variablePlaceholder } from '../variables';\nimport { h } from '../utils/dom';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface VariablePickerHandlers {\n onPickKey: (v: Variable) => void;\n onPickElement: (v: Variable) => void;\n onCopy: (token: string) => void;\n onClose: () => void;\n}\n\nexport interface VariablePickerHeadOptions {\n pinned: boolean;\n t: SimpleMailT;\n onClose: () => void;\n /** 切换固定状态,返回切换后的 pinned */\n onTogglePin: () => boolean;\n}\n\n/** 右栏变量列表头部(标题 + 固定 + 关闭) */\nexport function buildVariablePickerHead(options: VariablePickerHeadOptions): HTMLElement {\n let pinned = options.pinned;\n const t = options.t;\n const syncPinBtn = (btn: HTMLButtonElement) => {\n btn.classList.toggle('is-pinned', pinned);\n btn.setAttribute('aria-pressed', String(pinned));\n btn.title = pinned ? t('variablePicker.unpinTitle') : t('variablePicker.pinTitle');\n };\n const pinBtn = h(\n 'button',\n {\n class: 'sm-var-picker__pin',\n type: 'button',\n 'aria-label': t('variablePicker.pin'),\n onclick: () => {\n pinned = options.onTogglePin();\n syncPinBtn(pinBtn);\n },\n },\n [iconPin()],\n ) as HTMLButtonElement;\n syncPinBtn(pinBtn);\n\n const closeBtn = h(\n 'button',\n {\n class: 'sm-modal__close sm-var-picker__close',\n type: 'button',\n title: t('common.close'),\n 'aria-label': t('variablePicker.closeTitle'),\n onclick: () => options.onClose(),\n },\n [iconClose()],\n );\n\n return h('div', { class: 'sm-var-picker__head' }, [\n h('div', { class: 'sm-panel__title sm-var-picker__title' }, [t('variablePicker.title')]),\n h('div', { class: 'sm-var-picker__actions' }, [pinBtn, closeBtn]),\n ]);\n}\n\nfunction iconClose(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 20 20');\n el.innerHTML =\n '<path d=\"M5 5l10 10M15 5L5 15\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/>';\n return el;\n}\n\nfunction iconPin(): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '16');\n el.setAttribute('height', '16');\n el.setAttribute('viewBox', '0 0 1024 1024');\n el.innerHTML =\n '<path d=\"M393.846154 64.174932l117.454119 0.399843H512.499805l117.454119-0.399843-10.395939 10.395939c-18.89262 18.89262-28.488872 44.982429-26.28973 71.472081l20.292073 250.502148c2.998829 36.68567 18.092932 72.171808 42.483405 99.661069l34.186646 38.684889-122.252245-0.899648-55.478329-0.399844h-0.99961l-55.478329 0.399844-122.452167 0.799687 34.186646-38.684888c24.390472-27.589223 39.484576-62.9754 42.483405-99.66107l20.292074-250.402187c2.199141-26.589613-7.397111-52.679422-26.289731-71.472081l-10.395939-10.395939m281.889887-64.174932h-0.199922L512.399844 0.599766h-0.799688L348.36392 0h-0.199922c-20.891839 0-39.684498 13.494729-45.582194 33.58688-4.098399 13.994533-1.899258 30.887934 17.79305 47.581414l38.584927 38.584927c5.597813 5.597813 8.39672 13.294807 7.796955 21.091761L346.464662 391.247169c-1.899258 23.190941-11.195627 45.08239-26.589613 62.475596l-61.87583 69.872706c-8.696603 9.796173-13.894572 22.291292-14.394377 35.386177-0.299883 8.996486 1.599375 18.89262 8.596642 27.28934 6.897306 8.296759 17.293245 12.894963 27.989067 12.894963h0.299882l175.931277-1.199532 55.178446 422.834831 0.399844 3.098789 0.399844-3.098789 55.178446-422.834831 175.931277 1.199532h0.299882c10.795783 0 21.191722-4.598204 27.989067-12.894963 6.897306-8.39672 8.796564-18.292854 8.596642-27.28934-0.399844-13.094885-5.697774-25.590004-14.394377-35.386177l-61.87583-69.872706c-15.393987-17.393206-24.690355-39.284654-26.589613-62.475596l-20.292074-250.402187c-0.599766-7.796954 2.199141-15.593909 7.796955-21.091761l38.584927-38.584927c19.692308-16.693479 21.891449-33.58688 17.79305-47.581414-5.997657-19.992191-24.790316-33.58688-45.682155-33.58688z\" fill=\"currentColor\"/>';\n return el;\n}\n\n/** 右栏可滚动变量列表(交互与旧 popover 一致) */\nexport function buildVariablePickerBody(\n vars: Variable[],\n handlers: VariablePickerHandlers,\n t: SimpleMailT,\n): HTMLElement {\n const wrap = h('div', { class: 'sm-var-picker' });\n if (!vars.length) {\n wrap.append(\n h('div', { class: 'sm-empty-form' }, [t('variablePicker.empty')]),\n );\n return wrap;\n }\n for (const v of vars) {\n const token = variablePlaceholder(v.key);\n const row = h('div', { class: 'sm-popover__row' });\n const actions = h('div', { class: 'sm-popover__actions' });\n if (v.kind === 'link' || v.kind === 'image') {\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action',\n type: 'button',\n onclick: (e: Event) => {\n e.stopPropagation();\n handlers.onPickElement(v);\n },\n },\n [t('variablePicker.insertElement')],\n ),\n );\n }\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action sm-popover__action--copy',\n type: 'button',\n title: t('variablePicker.copyTitle', { token }),\n onclick: (e: Event) => {\n e.stopPropagation();\n handlers.onCopy(token);\n },\n },\n [t('common.copy')],\n ),\n );\n row.append(\n h(\n 'button',\n {\n class: 'sm-popover__item',\n type: 'button',\n onclick: () => handlers.onPickKey(v),\n },\n [\n h('span', { class: 'sm-popover__label' }, [v.label]),\n h('span', { class: 'sm-popover__key' }, [token]),\n ],\n ),\n actions,\n );\n wrap.append(row);\n }\n return wrap;\n}\n","import { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport { EditorState } from '@codemirror/state';\nimport type { Registry } from '../registry/registry';\nimport { htmlContainsMjmlTags } from '../utils/lockedMjml';\nimport {\n findBlockLocation,\n findSection,\n isMultiColumnLayout,\n setSectionLayout,\n type Store,\n type DocChangedDetail,\n} from '../store/store';\nimport type {\n Block,\n BlockSchemaField,\n EditorUiOptions,\n EmailDoc,\n Section,\n SectionLayout,\n Variable,\n} from '../types';\nimport { getSectionDynamicVariantKey } from '../utils/dynamicVariantSection';\nimport { defaultSocialIconBackground } from '../socialDefaults';\nimport { bindColorPickerInput } from './ColorPickerPopover';\nimport { normalizeAccentHex } from '../utils/accentColor';\nimport { clear, h } from '../utils/dom';\nimport { metaWidthInputString, parseMetaWidthFromUserInput, parseSectionWidthFromUserInput, sectionWidthInputString } from '../utils/contentWidth';\nimport {\n LIST_INDENT_PRESETS_PX,\n normalizeGlobalListIndentStorage,\n resolveGlobalListIndentPx,\n} from '../utils/emailListStyles';\nimport { FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '../utils/fontWeightSteps';\nimport { resolveAssetPermission, type ImageAssetsHandlers, type ImageFieldContext } from './imageAssets';\nimport { FocusBreadcrumb } from './FocusBreadcrumb';\nimport { openImageGalleryModal } from './ImageGalleryModal';\nimport {\n buildVariablePickerBody,\n buildVariablePickerHead,\n type VariablePickerHandlers,\n} from './VariablePickerPanel';\nimport type { SimpleMailT } from '../i18n';\n\n/** 与社交组 block 中每行元素结构一致(core 不依赖 blocks) */\ntype SocialLinkRow = {\n network: string;\n href: string;\n label?: string;\n iconSrc?: string;\n backgroundColor?: string;\n};\n\n/** 宽度滑块:解析右栏当前字符串 */\nfunction classifyLayoutWidth(raw: string): 'auto' | 'px' | '%' | 'custom' {\n const t = (raw ?? '').trim();\n if (!t || t.toLowerCase() === 'auto') return 'auto';\n if (/^\\d+(\\.\\d+)?%$/.test(t)) return '%';\n if (/^\\d+(\\.\\d+)?px$/i.test(t)) return 'px';\n if (/^\\d+(\\.\\d+)?$/.test(t)) return 'px';\n return 'custom';\n}\n\nfunction layoutWidthNumeric(raw: string, mode: 'px' | '%'): number {\n const t = (raw ?? '').trim();\n if (!t) return mode === '%' ? 100 : 280;\n const m = t.match(/^(\\d+(\\.\\d+)?)/);\n const n = m ? parseFloat(m[1]) : mode === '%' ? 100 : 280;\n if (mode === '%') return Math.min(100, Math.max(1, Math.round(n)));\n return Math.min(1200, Math.max(1, Math.round(n)));\n}\n\nexport interface RightPanelOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n /** 聚焦路径根节点文案(文档级),默认「邮件」 */\n docRootLabel?: string;\n /** 点击路径中的 Section 层级 */\n onFocusSection: (sectionId: string) => void;\n /** 点击路径中的文档级层级(等同 Esc 从 Section 上浮) */\n onFocusDocument: () => void;\n /**\n * 可选。配置后,schema 中 `type: 'image'` 的字段会显示「上传 / 图库」按钮并调用对应回调。\n */\n imageAssets?: ImageAssetsHandlers;\n /** 与 MailEditor.opts.ui 对齐 */\n ui?: EditorUiOptions;\n}\n\ntype RightTab = 'props' | 'code';\n\n/**\n * 右栏:选中 Section/Block 时显示对应配置;未选中显示文档级配置(标题/宽度/全局样式)。\n * Block 选中时多一个\"代码\"Tab,可编辑该 Block 的 MJML 片段(CodeMirror)。\n */\nexport class RightPanel {\n el: HTMLElement;\n private opts: RightPanelOptions;\n private headEl: HTMLElement;\n private contentEl: HTMLElement;\n private focusCrumb: FocusBreadcrumb;\n private currentTab: RightTab = 'props';\n private codeView: EditorView | null = null;\n private variablePickerOpen = false;\n private variablePickerPinned = false;\n private variablePickerHandlers: VariablePickerHandlers | null = null;\n\n private _preferSliderControls(): boolean {\n return this.opts.ui?.preferSliderControls === true;\n }\n\n private _hideMailMeta(): boolean {\n return this.opts.ui?.hideMailMeta === true;\n }\n\n constructor(opts: RightPanelOptions) {\n this.opts = opts;\n this.el = h('aside', { class: 'sm-panel sm-panel--right' });\n this.focusCrumb = new FocusBreadcrumb({\n store: opts.store,\n registry: opts.registry,\n docRootLabel: opts.docRootLabel ?? opts.t('rightPanel.docRoot.mail'),\n t: opts.t,\n onFocusDocument: () => opts.onFocusDocument(),\n onFocusSection: (id) => opts.onFocusSection(id),\n });\n this.headEl = h('div', { class: 'sm-panel__head' }, [this.focusCrumb.el]);\n this.contentEl = h('div', { class: 'sm-panel__body' });\n this.el.append(this.headEl, this.contentEl);\n this._syncHeadVisibility();\n this._render();\n opts.store.subscribe((detail?: DocChangedDetail) => {\n if (this.variablePickerOpen) return;\n if (detail?.source === 'history') {\n this._renderPreservingFieldFocus();\n return;\n }\n if (detail?.source === 'replace') {\n this._render();\n return;\n }\n // update() 每打一字符都会 notify;整栏 clear 会拆掉输入框导致失焦\n if (this._shouldSkipRenderBecauseFocused()) return;\n this._render();\n });\n opts.store.subscribeSelection(() => {\n if (this.variablePickerOpen) return;\n this.currentTab = 'props';\n this._syncHeadVisibility();\n this._render();\n });\n }\n\n /** 在右栏展示变量列表(顶替属性面板,不遮挡画布) */\n openVariablePicker(vars: Variable[], handlers: VariablePickerHandlers) {\n this.variablePickerOpen = true;\n this.variablePickerPinned = false;\n this.variablePickerHandlers = handlers;\n this._renderVariablePicker(vars);\n }\n\n closeVariablePicker() {\n if (!this.variablePickerOpen) return;\n this.variablePickerOpen = false;\n this.variablePickerPinned = false;\n this.variablePickerHandlers = null;\n this.el.classList.remove('sm-panel--variable-picker');\n clear(this.headEl);\n this.headEl.append(this.focusCrumb.el);\n this._syncHeadVisibility();\n this._render();\n }\n\n isVariablePickerOpen(): boolean {\n return this.variablePickerOpen;\n }\n\n isVariablePickerPinned(): boolean {\n return this.variablePickerPinned;\n }\n\n toggleVariablePickerPin(): boolean {\n this.variablePickerPinned = !this.variablePickerPinned;\n return this.variablePickerPinned;\n }\n\n /** 文档级(无选中)时不展示面包屑,避免与「邮件设置」标题重复 */\n private _syncHeadVisibility() {\n if (this.variablePickerOpen) return;\n const show = !!this.opts.store.selection;\n this.headEl.hidden = !show;\n }\n\n private _renderVariablePicker(vars: Variable[]) {\n const handlers = this.variablePickerHandlers;\n if (!handlers) return;\n this._destroyCodeView();\n clear(this.headEl);\n clear(this.contentEl);\n this.el.classList.add('sm-panel--variable-picker');\n this.headEl.hidden = false;\n this.headEl.append(\n buildVariablePickerHead({\n pinned: this.variablePickerPinned,\n t: this.opts.t,\n onClose: () => handlers.onClose(),\n onTogglePin: () => this.toggleVariablePickerPin(),\n }),\n );\n this.contentEl.append(buildVariablePickerBody(vars, handlers, this.opts.t));\n }\n\n /** 焦点在右栏可编辑控件上时不要整栏重渲染(避免输入/CodeMirror 失焦) */\n private _shouldSkipRenderBecauseFocused(): boolean {\n const ae = document.activeElement as HTMLElement | null;\n if (!ae || !this.el.contains(ae)) return false;\n if (ae.closest('.cm-editor')) return true;\n const tag = ae.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;\n return false;\n }\n\n /** undo/redo 后整栏重绘,但尽量回到同一输入框与光标位置 */\n private _renderPreservingFieldFocus() {\n if (this.variablePickerOpen) return;\n const ae = document.activeElement as HTMLElement | null;\n let token: string | null = null;\n let selStart = 0;\n let selEnd = 0;\n if (ae && this.el.contains(ae)) {\n token = ae.getAttribute('data-sm-focus');\n if (\n token &&\n (ae instanceof HTMLInputElement || ae instanceof HTMLTextAreaElement)\n ) {\n selStart = ae.selectionStart ?? 0;\n selEnd = ae.selectionEnd ?? 0;\n }\n }\n this._render();\n if (!token) return;\n const next = this._findFocusEl(token);\n next?.focus();\n if (next instanceof HTMLInputElement || next instanceof HTMLTextAreaElement) {\n const len = next.value.length;\n next.setSelectionRange(Math.min(selStart, len), Math.min(selEnd, len));\n }\n }\n\n private _findFocusEl(token: string): HTMLElement | null {\n for (const el of this.el.querySelectorAll('[data-sm-focus]')) {\n if ((el as HTMLElement).getAttribute('data-sm-focus') === token) return el as HTMLElement;\n }\n return null;\n }\n\n private _render() {\n if (this.variablePickerOpen) return;\n this._destroyCodeView();\n clear(this.contentEl);\n\n const sel = this.opts.store.selection;\n const doc = this.opts.store.doc;\n\n if (!sel) {\n this.contentEl.append(this._renderDocForm(doc));\n return;\n }\n\n if (sel.kind === 'section') {\n const section = findSection(doc, sel.sectionId);\n if (!section) return;\n this.contentEl.append(this._renderSectionForm(section));\n return;\n }\n\n // block\n const loc = findBlockLocation(doc, sel.blockId);\n if (!loc) {\n const tabs = h('div', { class: 'sm-tabs' }, [\n this._tabBtn('props', this.opts.t('rightPanel.tabs.props')),\n this._tabBtn('code', this.opts.t('rightPanel.tabs.code')),\n ]);\n this.contentEl.append(tabs);\n this.contentEl.append(\n h('div', { class: 'sm-empty-form' }, [this.opts.t('rightPanel.block.deleted')]),\n );\n return;\n }\n const def = this.opts.registry.get(loc.block.type);\n\n const tabs = h('div', { class: 'sm-tabs' }, [\n this._tabBtn('props', this.opts.t('rightPanel.tabs.props')),\n this._tabBtn('code', this.opts.t('rightPanel.tabs.code')),\n ]);\n this.contentEl.append(tabs);\n\n if (this.currentTab === 'props') {\n if (loc.block.lockedMjml) {\n this.contentEl.append(\n h('div', { class: 'sm-empty-form' }, [\n this.opts.t('rightPanel.block.locked'),\n h('div', { style: 'margin-top:8px;' }, [\n h(\n 'button',\n {\n class: 'sm-btn',\n type: 'button',\n onclick: () => {\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, loc.block.id);\n if (l) delete l.block.lockedMjml;\n });\n },\n },\n [this.opts.t('rightPanel.block.restoreProps')],\n ),\n ]),\n ]),\n );\n } else if (def) {\n this.contentEl.append(this._renderBlockForm(loc.block, def.schema));\n } else {\n this.contentEl.append(\n h('div', { class: 'sm-empty-form' }, [\n this.opts.t('rightPanel.block.unregistered', { type: loc.block.type }),\n ]),\n );\n }\n } else {\n this.contentEl.append(this._renderBlockCodeView(loc.block));\n }\n }\n\n private _tabBtn(tab: RightTab, label: string) {\n return h(\n 'button',\n {\n class: `sm-tabs__item ${this.currentTab === tab ? 'sm-tabs__item--active' : ''}`,\n type: 'button',\n onclick: () => {\n this.currentTab = tab;\n this._render();\n },\n },\n [label],\n );\n }\n\n /* ------------------------------ 文档级表单 ------------------------------- */\n\n private _renderDocForm(doc: EmailDoc): HTMLElement {\n const hideMeta = this._hideMailMeta();\n const rows: HTMLElement[] = [];\n if (!hideMeta) {\n rows.push(\n h('div', { class: 'sm-panel__title' }, [this.opts.t('rightPanel.doc.title')]),\n this._textField(this.opts.t('rightPanel.doc.subject'), doc.meta.subject, (v) =>\n this.opts.store.update((d) => {\n d.meta.subject = v;\n }),\n '',\n 'doc:meta.subject',\n ),\n this._textField(this.opts.t('rightPanel.doc.preheader'), doc.meta.preheader ?? '', (v) =>\n this.opts.store.update((d) => {\n d.meta.preheader = v;\n }),\n '',\n 'doc:meta.preheader',\n ),\n );\n } else {\n rows.push(h('div', { class: 'sm-panel__title' }, [this.opts.t('rightPanel.doc.layoutTitle')]));\n }\n rows.push(\n this._textField(\n this.opts.t('rightPanel.doc.contentWidth'),\n metaWidthInputString(doc.meta.width),\n (v) =>\n this.opts.store.update((d) => {\n d.meta.width = parseMetaWidthFromUserInput(v);\n }),\n this.opts.t('rightPanel.doc.contentWidthPlaceholder'),\n 'doc:meta.width',\n ),\n h('div', { class: 'sm-panel__title' }, [this.opts.t('rightPanel.doc.globalStyles')]),\n this._colorField(\n this.opts.t('rightPanel.doc.pageBackground'),\n doc.styles.backgroundColor,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.backgroundColor = v;\n }),\n 'doc:styles.backgroundColor',\n ),\n this._colorField(\n this.opts.t('rightPanel.doc.contentBackground'),\n doc.styles.contentBackgroundColor,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.contentBackgroundColor = v;\n }),\n 'doc:styles.contentBackgroundColor',\n ),\n this._textField(\n this.opts.t('rightPanel.doc.fontFamily'),\n doc.styles.fontFamily,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.fontFamily = v;\n }),\n '',\n 'doc:styles.fontFamily',\n ),\n this._docFontSizeField(\n doc.styles.fontSize,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.fontSize = v;\n }),\n 'doc:styles.fontSize',\n ),\n this._docFontWeightField(\n doc.styles.fontWeight ?? '400',\n (v) =>\n this.opts.store.update((d) => {\n d.styles.fontWeight = v;\n }),\n 'doc:styles.fontWeight',\n ),\n this._textField(\n this.opts.t('rightPanel.doc.lineHeight'),\n doc.styles.lineHeight ?? '1.25',\n (v) =>\n this.opts.store.update((d) => {\n d.styles.lineHeight = v;\n }),\n this.opts.t('rightPanel.doc.lineHeightPlaceholder'),\n 'doc:styles.lineHeight',\n ),\n this._colorField(\n this.opts.t('rightPanel.doc.textColor'),\n doc.styles.color,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.color = v;\n }),\n 'doc:styles.color',\n ),\n this._colorField(\n this.opts.t('rightPanel.doc.linkColor'),\n doc.styles.linkColor,\n (v) =>\n this.opts.store.update((d) => {\n d.styles.linkColor = v;\n }),\n 'doc:styles.linkColor',\n ),\n this._listIndentDefaultField(doc),\n );\n return h('form', { class: 'sm-form', onsubmit: (e: Event) => e.preventDefault() }, rows);\n }\n\n /* ------------------------------ Section 表单 ----------------------------- */\n\n private _renderSectionForm(section: Section): HTMLElement {\n const a = section.attrs;\n const dvUiEnabled = this.opts.ui?.enableDynamicVariantKey === true;\n const dvKey = dvUiEnabled ? getSectionDynamicVariantKey(section) : undefined;\n const dynamicVariantKeyField = dvUiEnabled\n ? (() => {\n const field = this._textField(\n this.opts.t('rightPanel.section.dynamicKey'),\n a.dynamicVariantKey ?? '',\n (v) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (!s) return;\n const trimmed = v.trim();\n s.attrs.dynamicVariantKey = trimmed || undefined;\n }),\n this.opts.t('rightPanel.section.dynamicKeyPlaceholder'),\n `section:${section.id}:attrs.dynamicVariantKey`,\n );\n field.append(\n h('div', { class: 'sm-field__help' }, [\n this.opts.t('rightPanel.section.dynamicKeyHelp'),\n ]),\n );\n return field;\n })()\n : null;\n return h('form', { class: 'sm-form', onsubmit: (e: Event) => e.preventDefault() }, [\n h('div', { class: 'sm-panel__title' }, [\n this.opts.t(dvKey ? 'rightPanel.section.dynamicTitle' : 'rightPanel.section.title'),\n ]),\n ...(dynamicVariantKeyField ? [dynamicVariantKeyField] : []),\n ...(isMultiColumnLayout(section.layout)\n ? [\n this._multiColumnLayoutField(\n section.layout,\n (layout) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) setSectionLayout(s, layout);\n }),\n `section:${section.id}:layout`,\n ),\n ]\n : []),\n this._colorField(\n this.opts.t('rightPanel.section.backgroundColor'),\n a.backgroundColor ?? '',\n (v) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.backgroundColor = v || undefined;\n }),\n `section:${section.id}:attrs.bg`,\n this.opts.t('rightPanel.section.transparentPlaceholder'),\n ),\n this._layoutWidthField(\n this.opts.t('rightPanel.section.width'),\n sectionWidthInputString(a.width),\n (v) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.width = parseSectionWidthFromUserInput(v);\n }),\n `section:${section.id}:attrs.width`,\n this.opts.t('rightPanel.section.widthHelp'),\n ),\n this._spacingField(\n this.opts.t('rightPanel.section.padding'),\n [a.paddingTop, a.paddingRight, a.paddingBottom, a.paddingLeft],\n (vals) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (!s) return;\n [s.attrs.paddingTop, s.attrs.paddingRight, s.attrs.paddingBottom, s.attrs.paddingLeft] =\n vals;\n }),\n `section:${section.id}:attrs.pad`,\n [0, 0, 0, 0],\n ),\n section.layout !== '1'\n ? this._numberField(\n this.opts.t('rightPanel.section.columnGap'),\n a.columnGap ?? 0,\n 0,\n 64,\n (v) => {\n const g = Math.max(0, Math.min(64, Math.round(v)));\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.columnGap = g > 0 ? g : undefined;\n });\n },\n 1,\n `section:${section.id}:attrs.columnGap`,\n )\n : null,\n section.layout !== '1' && !a.preserveColumnsOnMobile\n ? this._numberField(\n this.opts.t('rightPanel.section.stackedGap'),\n a.columnStackedGap ?? 0,\n 0,\n 64,\n (v) => {\n const g = Math.max(0, Math.min(64, Math.round(v)));\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.columnStackedGap = g > 0 ? g : undefined;\n });\n },\n 1,\n `section:${section.id}:attrs.stackedGap`,\n this.opts.t('rightPanel.section.stackedGapHelp'),\n )\n : null,\n section.layout !== '1'\n ? this._switchField(\n this.opts.t('rightPanel.section.preserveMobile'),\n !!a.preserveColumnsOnMobile,\n (checked) =>\n this.opts.store.update((d) => {\n const s = findSection(d, section.id);\n if (s) s.attrs.preserveColumnsOnMobile = checked || undefined;\n }),\n this.opts.t('rightPanel.section.preserveMobileHelp'),\n `section:${section.id}:attrs.preserveMobile`,\n )\n : null,\n ]);\n }\n\n /* ------------------------------- Block 表单 ----------------------------- */\n\n private _renderBlockForm(block: Block, schema: BlockSchemaField[]): HTMLElement {\n const form = h('form', { class: 'sm-form', onsubmit: (e: Event) => e.preventDefault() });\n for (const field of schema) {\n form.append(this._field(field, block));\n }\n return form;\n }\n\n private _updateBlock(blockId: string, key: string, value: unknown) {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, blockId);\n if (!loc) return;\n (loc.block.props as any)[key] = value;\n });\n }\n\n private _field(field: BlockSchemaField, block: Block): HTMLElement {\n const blockId = block.id;\n const fp = `block:${blockId}:${field.key}`;\n const def = this.opts.registry.get(block.type);\n const defaults = def?.defaultProps as Record<string, unknown> | undefined;\n const raw = (block.props as Record<string, unknown>)[field.key];\n const value: unknown =\n raw !== undefined && raw !== null ? raw : defaults?.[field.key];\n const onChange = (v: any) => this._updateBlock(blockId, field.key, v);\n\n switch (field.type) {\n case 'textarea':\n if (block.type === 'html' && field.key === 'html') {\n return this._textareaField(\n field.label,\n String(value ?? ''),\n onChange,\n field.help,\n fp,\n (v) =>\n htmlContainsMjmlTags(v)\n ? this.opts.t('rightPanel.block.mjmlWarning')\n : null,\n );\n }\n return this._textareaField(field.label, String(value ?? ''), onChange, field.help, fp);\n case 'number':\n return this._numberField(\n field.label,\n Number(value ?? 0),\n field.min ?? 0,\n field.max ?? 9999,\n onChange,\n field.step ?? 1,\n fp,\n );\n case 'color': {\n const rawColor = (block.props as Record<string, unknown>)[field.key];\n const stored =\n rawColor !== undefined && rawColor !== null ? String(rawColor).trim() : '';\n return this._colorField(\n field.label,\n stored,\n (v) => onChange(v.trim()),\n fp,\n field.placeholder ?? '',\n );\n }\n case 'select': {\n const isFw = field.key === 'fontWeight' || field.key === 'labelFontWeight';\n const opts = field.options?.length\n ? field.options\n : isFw\n ? FONT_WEIGHT_STEP_OPTIONS\n : [];\n if (isFw && field.inheritGlobal) {\n const stored =\n raw !== undefined && raw !== null ? String(raw).trim() : '';\n return this._fontWeightInheritField(\n field.label,\n stored,\n normalizeFontWeightStep(this.opts.store.doc.styles.fontWeight),\n (v) => onChange(v),\n fp,\n opts,\n field.help,\n );\n }\n const displayVal = isFw\n ? normalizeFontWeightStep(String(value ?? ''))\n : String(value ?? '');\n if (isFw || field.selectVariant === 'segmented') {\n const el = this._segmentedSelectField(field.label, displayVal, opts, onChange, fp);\n if (field.help) el.append(h('div', { class: 'sm-field__help' }, [field.help]));\n return el;\n }\n return this._selectField(field.label, displayVal, opts, onChange, fp);\n }\n case 'switch':\n return this._switchField(field.label, !!value, onChange, field.help, fp);\n case 'image':\n return this._imageField(\n field.label,\n String(value ?? ''),\n onChange,\n field.placeholder ?? 'https://',\n fp,\n { blockId, propKey: field.key },\n );\n case 'url':\n case 'text': {\n if (field.key === 'width' && this._preferSliderControls()) {\n return this._layoutWidthField(\n field.label,\n String(value ?? ''),\n (v) => onChange(v),\n fp,\n field.help,\n );\n }\n if (field.key === 'fontSize' && field.inheritGlobal) {\n const rawFs =\n raw !== undefined && raw !== null ? String(raw).trim() : '';\n return this._fontSizeSliderField(\n field.label,\n rawFs,\n (v) => onChange(v.trim()),\n fp,\n field.help,\n this.opts.store.doc.styles.fontSize,\n );\n }\n const row = this._textField(\n field.label,\n String(value ?? ''),\n onChange,\n field.placeholder ?? '',\n fp,\n );\n if (field.help) row.append(h('div', { class: 'sm-field__help' }, [field.help]));\n return row;\n }\n case 'spacing': {\n /** 与各 block 约定:四边分别存 paddingTop / paddingRight / paddingBottom / paddingLeft */\n const p = block.props as Record<string, unknown>;\n const quad = [\n Number(p.paddingTop ?? 0),\n Number(p.paddingRight ?? 0),\n Number(p.paddingBottom ?? 0),\n Number(p.paddingLeft ?? 0),\n ];\n const def = this.opts.registry.get(block.type);\n const dp = def?.defaultProps as Record<string, unknown> | undefined;\n const resetQuad: [number, number, number, number] = [\n Number(dp?.paddingTop ?? 0),\n Number(dp?.paddingRight ?? 0),\n Number(dp?.paddingBottom ?? 0),\n Number(dp?.paddingLeft ?? 0),\n ];\n return this._spacingField(field.label, quad, (vals) => {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, blockId);\n if (!loc) return;\n const pr = loc.block.props as Record<string, number>;\n [pr.paddingTop, pr.paddingRight, pr.paddingBottom, pr.paddingLeft] = vals;\n });\n }, `${fp}:pad`, resetQuad);\n }\n case 'socialLinkList': {\n const rows = Array.isArray(value)\n ? (value as SocialLinkRow[])\n : Array.isArray(defaults?.[field.key])\n ? (defaults[field.key] as SocialLinkRow[])\n : [];\n return this._socialLinkListField(\n field.label,\n rows,\n field.options ?? [],\n blockId,\n field.key,\n field.help,\n fp,\n );\n }\n default:\n return h('div');\n }\n }\n\n /**\n * 社交组:每行含平台、链接、可选标签/图标 URL/图标背景色。\n * 注意:右栏在输入框聚焦时会跳过整栏 _render(),故更新 elements 必须在 store.update 内\n * 读取当前 props 再合并,禁止依赖闭包里的 items 快照(否则改一行会覆盖其它行已编辑未重绘的数据)。\n */\n private _socialLinkListField(\n label: string,\n items: SocialLinkRow[],\n networkOptions: { label: string; value: string }[],\n blockId: string,\n elementsKey: string,\n help: string | undefined,\n focusPrefix: string,\n ): HTMLElement {\n const firstVal = networkOptions[0]?.value ?? 'weibo';\n const wrap = h('div', { class: 'sm-field' });\n wrap.append(h('label', { class: 'sm-field__label' }, [label]));\n\n const listEl = h('div', { class: 'sm-social-link-list' });\n\n const patchElements = (mutate: (rows: SocialLinkRow[]) => SocialLinkRow[]) => {\n this.opts.store.update((d) => {\n const loc = findBlockLocation(d, blockId);\n if (!loc) return;\n const props = loc.block.props as Record<string, unknown>;\n const raw = props[elementsKey];\n const cur: SocialLinkRow[] = Array.isArray(raw)\n ? (raw as SocialLinkRow[]).map((x) => ({ ...x }))\n : [];\n props[elementsKey] = mutate(cur);\n });\n };\n\n const syncItem = (index: number, patch: Partial<SocialLinkRow>) => {\n patchElements((rows) =>\n rows.map((x, i) => (i === index ? { ...x, ...patch } : x)),\n );\n };\n\n const removeAt = (index: number) => {\n patchElements((rows) => rows.filter((_, i) => i !== index));\n };\n\n for (let i = 0; i < items.length; i++) {\n const rowData = items[i];\n const rowWrap = h('div', { class: 'sm-social-link-list__row' });\n const mainRow = h('div', { class: 'sm-social-link-list__row-main' });\n const sel = h('select', {\n class: 'sm-select sm-social-link-list__network',\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:net` } : {}),\n onchange: (e: Event) =>\n syncItem(i, { network: (e.target as HTMLSelectElement).value }),\n });\n for (const o of networkOptions) {\n const opt = document.createElement('option');\n opt.value = o.value;\n opt.textContent = o.label;\n if (o.value === rowData.network) opt.selected = true;\n sel.append(opt);\n }\n if (!networkOptions.some((o) => o.value === rowData.network) && rowData.network) {\n const opt = document.createElement('option');\n opt.value = rowData.network;\n opt.textContent = rowData.network;\n opt.selected = true;\n sel.insertBefore(opt, sel.firstChild);\n }\n const inp = h('input', {\n class: 'sm-input sm-social-link-list__href',\n type: 'url',\n placeholder: 'https://',\n value: rowData.href,\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:href` } : {}),\n oninput: (e: Event) => syncItem(i, { href: (e.target as HTMLInputElement).value }),\n });\n const rm = h(\n 'button',\n {\n class: 'sm-social-link-list__remove',\n type: 'button',\n title: this.opts.t('common.delete'),\n onclick: () => removeAt(i),\n },\n ['×'],\n );\n mainRow.append(sel, inp, rm);\n rowWrap.append(mainRow);\n\n const extras = h('div', { class: 'sm-social-link-list__row-extras' });\n const bgResolved = defaultSocialIconBackground(rowData.network);\n const bgStored = rowData.backgroundColor?.trim();\n const bgDisplay =\n bgStored && bgStored.startsWith('#') ? bgStored : bgResolved;\n extras.append(\n h('input', {\n class: 'sm-input sm-social-link-list__label',\n type: 'text',\n placeholder: this.opts.t('rightPanel.social.labelPlaceholder'),\n value: rowData.label ?? '',\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:label` } : {}),\n oninput: (e: Event) => syncItem(i, { label: (e.target as HTMLInputElement).value }),\n }),\n h('input', {\n class: 'sm-input sm-social-link-list__iconsrc',\n type: 'url',\n placeholder: this.opts.t('rightPanel.social.iconUrlPlaceholder'),\n value: rowData.iconSrc ?? '',\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:icon` } : {}),\n oninput: (e: Event) => syncItem(i, { iconSrc: (e.target as HTMLInputElement).value }),\n }),\n );\n const bgPick = h('input', {\n class: 'sm-social-link-list__color sm-social-link-list__color--compact',\n type: 'color',\n value: bgDisplay.length >= 4 ? bgDisplay : bgResolved,\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:row:${i}:bg` } : {}),\n }) as HTMLInputElement;\n bindColorPickerInput(bgPick, {\n liveCommit: true,\n t: this.opts.t,\n onCommit: (hex) => syncItem(i, { backgroundColor: hex }),\n });\n extras.append(bgPick);\n rowWrap.append(extras);\n\n listEl.append(rowWrap);\n }\n\n const addBtn = h(\n 'button',\n {\n class: 'sm-btn sm-social-link-list__add',\n type: 'button',\n onclick: () =>\n patchElements((rows) => [\n ...rows,\n {\n network: firstVal,\n href: 'https://',\n label: '',\n iconSrc: '',\n },\n ]),\n },\n [this.opts.t('rightPanel.social.add')],\n );\n\n wrap.append(listEl, addBtn);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n /* --------------------------------- 控件 --------------------------------- */\n\n private _textField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n placeholder = '',\n focusToken?: string,\n ) {\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n h('input', {\n class: 'sm-input',\n type: 'text',\n value,\n placeholder,\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n oninput: (e: Event) => onChange((e.target as HTMLInputElement).value),\n }),\n ]);\n }\n\n /** `type: 'image'`:URL 输入 + 可选上传、图库(由 `imageAssets` 注入) */\n private _imageField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n placeholder: string,\n focusToken: string | undefined,\n ids: Pick<ImageFieldContext, 'blockId' | 'propKey'>,\n ): HTMLElement {\n const assets = this.opts.imageAssets;\n const showUploadBtn = !!assets?.uploadImage && assets.showUpload !== false;\n const showGalleryBtn =\n assets?.showGallery === true &&\n (!!assets.imageGallery || !!assets.pickImageFromGallery);\n const hasAssetCallbacks = !!(\n assets?.uploadImage ||\n assets?.pickImageFromGallery ||\n assets?.imageGallery\n );\n const hasAnyPickerBtn = showUploadBtn || showGalleryBtn;\n\n const row = h('div', { class: 'sm-image-field__row' });\n const urlInp = h('input', {\n class: 'sm-input sm-image-field__url',\n type: 'url',\n value,\n placeholder,\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n oninput: (e: Event) => onChange((e.target as HTMLInputElement).value),\n });\n const getCtx = (): ImageFieldContext => ({\n blockId: ids.blockId,\n propKey: ids.propKey,\n currentUrl: urlInp.value,\n });\n row.append(urlInp);\n\n const applyUrl = (url: string) => {\n const t = url.trim();\n if (!t) return;\n onChange(t);\n urlInp.value = t;\n };\n\n const runAsync = (p: Promise<string | null | void>, labelErr: string) => {\n p.catch((e) => {\n console.error(`[simple-mail] ${labelErr}`, e);\n });\n };\n\n if (showUploadBtn) {\n const fileInp = h('input', {\n type: 'file',\n accept: 'image/*',\n class: 'sm-image-field__file',\n onchange: (e: Event) => {\n const el = e.target as HTMLInputElement;\n const f = el.files?.[0];\n el.value = '';\n if (!f) return;\n runAsync(\n assets.uploadImage!(f, getCtx()).then((url) => applyUrl(String(url))),\n 'uploadImage',\n );\n },\n });\n const uploadPerm = resolveAssetPermission(\n assets?.permissions,\n 'upload',\n this.opts.t('common.noPermissionUpload'),\n );\n if (!uploadPerm.allowed && uploadPerm.mode === 'hide') {\n // 无权限且配置为隐藏:不渲染上传按钮(fileInp 同样不渲染)\n } else {\n row.append(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-image-field__btn',\n type: 'button',\n title: uploadPerm.allowed\n ? this.opts.t('rightPanel.image.uploadTitle')\n : uploadPerm.tip,\n disabled: !uploadPerm.allowed,\n ...(uploadPerm.allowed\n ? { onclick: () => fileInp.click() }\n : {}),\n },\n [this.opts.t('rightPanel.image.upload')],\n ),\n );\n row.append(fileInp);\n }\n }\n\n if (showGalleryBtn) {\n row.append(\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--secondary sm-image-field__btn',\n type: 'button',\n title: this.opts.t('rightPanel.image.galleryTitle'),\n onclick: () => {\n if (assets.imageGallery) {\n openImageGalleryModal({\n adapter: assets.imageGallery,\n permissions: assets?.permissions,\n onPick: (url) => applyUrl(url),\n t: this.opts.t,\n parent: this.el.closest('.sm-root') as HTMLElement | undefined,\n });\n return;\n }\n if (assets.pickImageFromGallery) {\n runAsync(\n assets.pickImageFromGallery(getCtx()).then((url) => {\n if (url != null && String(url).trim()) applyUrl(String(url));\n }),\n 'pickImageFromGallery',\n );\n }\n },\n },\n [this.opts.t('rightPanel.image.gallery')],\n ),\n );\n }\n\n let helpBody: string;\n if (hasAnyPickerBtn) {\n const bits: string[] = [this.opts.t('rightPanel.image.helpManual')];\n if (showUploadBtn) bits.push(this.opts.t('rightPanel.image.helpUpload'));\n if (showGalleryBtn) bits.push(this.opts.t('rightPanel.image.helpGallery'));\n helpBody = `${bits.join(this.opts.t('rightPanel.image.helpSeparator'))}${this.opts.t(\n 'rightPanel.image.helpEnd',\n )}`;\n } else if (hasAssetCallbacks) {\n helpBody = this.opts.t('rightPanel.image.helpAssetsConfigured');\n } else {\n helpBody = this.opts.t('rightPanel.image.helpNoAssets');\n }\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n row,\n h('div', { class: 'sm-field__help' }, [helpBody]),\n ]);\n }\n private _textareaField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n help?: string,\n focusToken?: string,\n warn?: (v: string) => string | null,\n ) {\n const warnEl = h('div', { class: 'sm-field__warn', style: 'display:none' });\n const ta = h('textarea', {\n class: 'sm-textarea',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n oninput: (e: Event) => {\n const v = (e.target as HTMLTextAreaElement).value;\n onChange(v);\n if (warn) {\n const msg = warn(v);\n warnEl.textContent = msg ?? '';\n warnEl.style.display = msg ? '' : 'none';\n }\n },\n });\n ta.value = value;\n if (warn) {\n const msg = warn(value);\n if (msg) {\n warnEl.textContent = msg;\n warnEl.style.display = '';\n }\n }\n return h(\n 'div',\n { class: 'sm-field' },\n [\n h('label', { class: 'sm-field__label' }, [label]),\n ta,\n warnEl,\n help ? h('div', { class: 'sm-field__help' }, [help]) : null,\n ],\n );\n }\n private _numberField(\n label: string,\n value: number,\n min: number,\n max: number,\n onChange: (v: number) => void,\n step = 1,\n focusToken?: string,\n help?: string,\n ): HTMLElement {\n const field = this._buildNumberField(label, value, min, max, onChange, step, focusToken);\n if (!help) return field;\n return h('div', { class: 'sm-field', style: 'flex-direction:column;align-items:flex-start;gap:6px;' }, [\n field,\n h('div', { class: 'sm-field__help' }, [help]),\n ]);\n }\n\n private _buildNumberField(\n label: string,\n value: number,\n min: number,\n max: number,\n onChange: (v: number) => void,\n step = 1,\n focusToken?: string,\n ) {\n const snap = (n: number) => {\n const c = Math.min(max, Math.max(min, n));\n if (!step || step <= 0) return c;\n const k = Math.round((c - min) / step);\n return Number((min + k * step).toPrecision(12));\n };\n\n if (!this._preferSliderControls()) {\n const inp = h('input', {\n class: 'sm-input',\n type: 'number',\n value: String(value),\n min,\n max,\n step,\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const commitPlain = () => {\n const t = inp.value.trim();\n const fb = snap(value);\n if (t === '') {\n inp.value = String(fb);\n onChange(fb);\n return;\n }\n const v = Number(t);\n const s = snap(Number.isNaN(v) ? fb : v);\n inp.value = String(s);\n onChange(s);\n };\n\n /** min>0 时中途输入会被 snap 打断(如想输入 16 会先变成 10),仅失焦/Enter 提交 */\n if (min > 0) {\n inp.addEventListener('blur', commitPlain);\n inp.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') inp.blur();\n });\n } else {\n inp.addEventListener('input', () => {\n const t = inp.value.trim();\n if (t === '') return;\n const v = Number(t);\n if (Number.isNaN(v)) return;\n onChange(snap(v));\n });\n inp.addEventListener('blur', commitPlain);\n inp.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') commitPlain();\n });\n }\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n inp,\n ]);\n }\n\n const v0 = snap(value);\n const range = h('input', {\n type: 'range',\n min,\n max,\n step,\n value: String(v0),\n }) as HTMLInputElement;\n\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min,\n max,\n step,\n value: String(v0),\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const syncFromSlider = (n: number) => {\n const s = snap(n);\n range.value = String(s);\n num.value = String(s);\n onChange(s);\n };\n\n range.addEventListener('input', () => {\n syncFromSlider(Number(range.value));\n });\n\n num.addEventListener('input', () => {\n const t = num.value.trim();\n if (t === '') return;\n const raw = Number(t);\n if (Number.isNaN(raw)) return;\n range.value = String(snap(raw));\n });\n\n num.addEventListener('blur', () => {\n const t = num.value.trim();\n const fb = snap(Number(range.value));\n if (t === '') {\n syncFromSlider(fb);\n return;\n }\n const raw = Number(t);\n if (Number.isNaN(raw)) {\n syncFromSlider(fb);\n return;\n }\n syncFromSlider(raw);\n });\n\n num.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n h('div', { class: 'sm-field__slider-row' }, [range, num]),\n ]);\n }\n private _colorField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n focusPrefix?: string,\n placeholder = '#ffffff',\n ) {\n const pickToken = focusPrefix ? `${focusPrefix}:pick` : undefined;\n const textToken = focusPrefix ? `${focusPrefix}:text` : undefined;\n const pick = h('input', {\n type: 'color',\n ...(pickToken ? { 'data-sm-focus': pickToken } : {}),\n }) as HTMLInputElement;\n const text = h('input', {\n class: 'sm-input',\n type: 'text',\n placeholder,\n ...(textToken ? { 'data-sm-focus': textToken } : {}),\n }) as HTMLInputElement;\n\n let lastValid = value.trim();\n\n const applyPickInherit = () => {\n pick.value = '#808080';\n pick.classList.add('sm-color-row__pick--inherit');\n pick.title = placeholder || this.opts.t('rightPanel.color.unset');\n };\n\n const applyStored = (stored: string) => {\n const trimmed = stored.trim();\n text.value = trimmed;\n const hex = normalizeAccentHex(trimmed);\n if (hex) {\n pick.value = hex;\n pick.classList.remove('sm-color-row__pick--inherit');\n pick.title = '';\n } else {\n applyPickInherit();\n }\n };\n\n applyStored(value);\n\n const previewPick = (hex: string) => {\n text.value = hex;\n pick.value = hex;\n pick.classList.remove('sm-color-row__pick--inherit');\n pick.title = '';\n lastValid = hex;\n };\n\n const commitPick = (hex: string) => {\n previewPick(hex);\n onChange(hex);\n };\n\n bindColorPickerInput(pick, {\n getValue: () => text.value.trim() || pick.value,\n placeholder,\n allowClear: true,\n t: this.opts.t,\n onPreview: previewPick,\n onCommit: commitPick,\n onClear: () => {\n applyStored('');\n lastValid = '';\n onChange('');\n },\n });\n\n text.addEventListener('input', () => {\n const raw = text.value;\n const hex = normalizeAccentHex(raw);\n if (hex) {\n pick.value = hex;\n pick.classList.remove('sm-color-row__pick--inherit');\n pick.title = '';\n lastValid = hex;\n } else if (!raw.trim()) {\n applyPickInherit();\n lastValid = '';\n }\n onChange(raw);\n });\n\n text.addEventListener('blur', () => {\n const raw = text.value.trim();\n if (!raw) {\n applyStored('');\n lastValid = '';\n onChange('');\n return;\n }\n const hex = normalizeAccentHex(raw);\n if (hex) {\n applyStored(hex);\n lastValid = hex;\n if (hex !== raw) onChange(hex);\n return;\n }\n applyStored(lastValid);\n onChange(lastValid);\n });\n\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n h('div', { class: 'sm-color-row' }, [pick, text]),\n ]);\n }\n private _selectField(\n label: string,\n value: string,\n options: { label: string; value: string }[],\n onChange: (v: string) => void,\n focusToken?: string,\n ) {\n const sel = h('select', {\n class: 'sm-select',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n onchange: (e: Event) => onChange((e.target as HTMLSelectElement).value),\n });\n for (const o of options) {\n const opt = document.createElement('option');\n opt.value = o.value;\n opt.textContent = o.label;\n if (o.value === value) opt.selected = true;\n sel.append(opt);\n }\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n sel,\n ]);\n }\n\n /** 邮件设置:列表默认缩进(平铺);未配置时初始为 24px */\n private _listIndentDefaultField(doc: EmailDoc): HTMLElement {\n const current = String(resolveGlobalListIndentPx(doc.styles));\n const options = LIST_INDENT_PRESETS_PX.map((px) => ({\n label: String(px),\n value: String(px),\n }));\n const help = h('div', { class: 'sm-field__help' }, [\n this.opts.t('rightPanel.doc.listIndentHelp'),\n ]);\n const field = this._segmentedSelectField(\n this.opts.t('rightPanel.doc.listIndent'),\n current,\n options,\n (v) =>\n this.opts.store.update((d) => {\n const stored = normalizeGlobalListIndentStorage(Number(v));\n if (stored === undefined) delete d.styles.listIndentDefaultPx;\n else d.styles.listIndentDefaultPx = stored;\n }),\n 'doc:styles.listIndentDefaultPx',\n true,\n );\n field.append(help);\n return field;\n }\n\n /** select 平铺:与顶栏 sm-segmented 视觉一致,占满右栏宽度 */\n private _segmentedSelectField(\n label: string,\n value: string,\n options: { label: string; value: string }[],\n onChange: (v: string) => void,\n focusToken?: string,\n wrap = false,\n ) {\n const group = h('div', {\n class: `sm-segmented sm-segmented--fill${wrap ? ' sm-segmented--wrap' : ''}`,\n role: 'group',\n 'aria-label': label,\n });\n for (const o of options) {\n const active = o.value === value;\n group.append(\n h(\n 'button',\n {\n type: 'button',\n class: `sm-segmented__item${active ? ' sm-segmented__item--active' : ''}`,\n 'aria-pressed': active ? 'true' : 'false',\n title: o.label,\n ...(focusToken ? { 'data-sm-focus': `${focusToken}:${o.value}` } : {}),\n onclick: () => onChange(o.value),\n },\n [o.label],\n ),\n );\n }\n return h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n group,\n ]);\n }\n private _switchField(\n label: string,\n value: boolean,\n onChange: (v: boolean) => void,\n help?: string,\n focusToken?: string,\n ): HTMLElement {\n const row = h('label', {\n class: 'sm-field',\n style: 'flex-direction:row;align-items:center;gap:8px;',\n }, [\n h('input', {\n type: 'checkbox',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n onchange: (e: Event) => onChange((e.target as HTMLInputElement).checked),\n ...(value ? { checked: true } : {}),\n } as any),\n h('span', { class: 'sm-field__label' }, [label]),\n ]);\n if (!help) return row;\n return h('div', { class: 'sm-field', style: 'flex-direction:column;align-items:flex-start;gap:6px;' }, [\n row,\n h('div', { class: 'sm-field__help' }, [help]),\n ]);\n }\n private _spacingField(\n label: string,\n [t, r, b, l]: (number | undefined)[],\n onChange: (vals: number[]) => void,\n focusPrefix?: string,\n resetQuad?: [number, number, number, number],\n ) {\n const titles = [\n this.opts.t('rightPanel.spacing.top'),\n this.opts.t('rightPanel.spacing.right'),\n this.opts.t('rightPanel.spacing.bottom'),\n this.opts.t('rightPanel.spacing.left'),\n ];\n const clampPad = (n: number) => Math.max(0, Math.min(200, Math.round(n)));\n\n /** 右栏聚焦时会跳过整栏重绘,闭包里的 t/r/b/l 会过时;用同一数组累积四边,避免改一边再改另一边时覆盖。 */\n const current: number[] = [\n clampPad(Number(t ?? 0)),\n clampPad(Number(r ?? 0)),\n clampPad(Number(b ?? 0)),\n clampPad(Number(l ?? 0)),\n ];\n const emit = () => onChange([...current]);\n\n const makePlain = (v: number | undefined, idx: number) => {\n const inp = h('input', {\n class: 'sm-input',\n type: 'number',\n min: 0,\n max: 200,\n value: String(v ?? 0),\n title: titles[idx],\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:${idx}` } : {}),\n }) as HTMLInputElement;\n inp.addEventListener('input', () => {\n const t = inp.value.trim();\n if (t === '') return;\n const raw = Number(t);\n if (Number.isNaN(raw)) return;\n current[idx] = clampPad(raw);\n emit();\n });\n inp.addEventListener('blur', () => {\n const t = inp.value.trim();\n if (t === '') {\n inp.value = String(current[idx]);\n return;\n }\n const raw = Number(t);\n const c = clampPad(Number.isNaN(raw) ? current[idx] : raw);\n inp.value = String(c);\n current[idx] = c;\n emit();\n });\n inp.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') inp.blur();\n });\n return inp;\n };\n\n const makeSliderRow = (v: number | undefined, idx: number) => {\n const cur = clampPad(v ?? 0);\n const range = h('input', {\n type: 'range',\n min: 0,\n max: 200,\n step: 1,\n value: String(cur),\n title: titles[idx],\n }) as HTMLInputElement;\n\n range.addEventListener('input', () => {\n const c = clampPad(Number(range.value));\n current[idx] = c;\n num.value = String(c);\n emit();\n });\n\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min: 0,\n max: 200,\n value: String(cur),\n title: titles[idx],\n ...(focusPrefix ? { 'data-sm-focus': `${focusPrefix}:${idx}` } : {}),\n }) as HTMLInputElement;\n\n num.addEventListener('input', () => {\n const t = num.value.trim();\n if (t === '') return;\n const rawN = Number(t);\n if (Number.isNaN(rawN)) return;\n const c = clampPad(rawN);\n range.value = String(c);\n current[idx] = c;\n emit();\n });\n\n num.addEventListener('blur', () => {\n const t = num.value.trim();\n if (t === '') {\n num.value = String(current[idx]);\n range.value = String(current[idx]);\n return;\n }\n const rawN = Number(t);\n const c = clampPad(Number.isNaN(rawN) ? current[idx] : rawN);\n num.value = String(c);\n range.value = String(c);\n current[idx] = c;\n emit();\n });\n\n num.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n return h('div', { class: 'sm-spacing-row' }, [\n h('span', { class: 'sm-spacing-row__axis' }, [titles[idx]]),\n range,\n num,\n ]);\n };\n\n return h('div', { class: 'sm-field' }, [\n h('div', { class: 'sm-spacing-field__label-row' }, [\n h('label', { class: 'sm-field__label' }, [`${label}${this.opts.t('rightPanel.spacing.suffix')}`]),\n resetQuad\n ? h(\n 'button',\n {\n type: 'button',\n class: 'sm-btn sm-btn--ghost sm-spacing-field__reset',\n onclick: () => {\n const next = resetQuad.map((n) => clampPad(Number(n)));\n for (let i = 0; i < 4; i++) current[i] = next[i];\n onChange([...current]);\n },\n },\n [this.opts.t('rightPanel.spacing.reset')],\n )\n : null,\n ]),\n this._preferSliderControls()\n ? h(\n 'div',\n { class: 'sm-spacing-rows' },\n [0, 1, 2, 3].map((idx) => makeSliderRow([t, r, b, l][idx], idx)),\n )\n : h(\n 'div',\n { class: 'sm-spacing-grid' },\n [0, 1, 2, 3].map((idx) => makePlain([t, r, b, l][idx], idx)),\n ),\n ]);\n }\n\n /** 「继承全局」开关行:开=跟随邮件全局,关=块级固定值 */\n private _globalInheritSwitch(\n inheritOn: boolean,\n globalDisplay: string,\n onToggle: (inherit: boolean) => void,\n focusToken?: string,\n ): { el: HTMLElement; setInherit: (on: boolean, display?: string) => void } {\n const input = h('input', {\n type: 'checkbox',\n class: 'sm-inherit-switch__input',\n role: 'switch',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n ...(inheritOn ? { checked: true } : {}),\n }) as HTMLInputElement;\n const valueEl = h('span', {\n class: 'sm-inherit-switch__value',\n hidden: !inheritOn,\n }, [globalDisplay]);\n const el = h('div', { class: 'sm-inherit-switch' }, [\n h('label', { class: 'sm-inherit-switch__label' }, [\n input,\n h('span', { class: 'sm-inherit-switch__text' }, [this.opts.t('rightPanel.inheritGlobal')]),\n ]),\n valueEl,\n ]);\n input.addEventListener('change', () => onToggle(input.checked));\n const setInherit = (on: boolean, display?: string) => {\n input.checked = on;\n if (display !== undefined) valueEl.textContent = display;\n valueEl.hidden = !on;\n };\n return { el, setInherit };\n }\n\n private _fontWeightInheritField(\n label: string,\n stored: string,\n globalWeight: string,\n onChange: (v: string) => void,\n focusToken: string,\n options: { label: string; value: string }[],\n help?: string,\n ): HTMLElement {\n let inheriting = !stored;\n const group = h('div', {\n class: 'sm-segmented sm-segmented--fill',\n role: 'group',\n 'aria-label': label,\n });\n\n const syncGroup = () => {\n group.classList.toggle('sm-segmented--disabled', inheriting);\n const display = inheriting ? '' : normalizeFontWeightStep(stored || globalWeight);\n clear(group);\n for (const o of options) {\n const active = !inheriting && o.value === display;\n group.append(\n h(\n 'button',\n {\n type: 'button',\n class: `sm-segmented__item${active ? ' sm-segmented__item--active' : ''}`,\n 'aria-pressed': active ? 'true' : 'false',\n title: o.label,\n ...(focusToken ? { 'data-sm-focus': `${focusToken}:${o.value}` } : {}),\n onclick: () => {\n inheriting = false;\n stored = o.value;\n inheritSwitch.setInherit(false);\n syncGroup();\n onChange(o.value);\n },\n },\n [o.label],\n ),\n );\n }\n };\n\n const inheritSwitch = this._globalInheritSwitch(\n inheriting,\n globalWeight,\n (on) => {\n if (on) {\n inheriting = true;\n stored = '';\n inheritSwitch.setInherit(true, globalWeight);\n syncGroup();\n onChange('');\n return;\n }\n inheriting = false;\n stored = globalWeight;\n inheritSwitch.setInherit(false);\n syncGroup();\n onChange(globalWeight);\n },\n `${focusToken}:inherit`,\n );\n\n syncGroup();\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n inheritSwitch.el,\n group,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _fontSizeInheritTextField(\n label: string,\n stored: string,\n onChange: (v: string) => void,\n focusToken: string,\n globalFontSize: string,\n help?: string,\n ): HTMLElement {\n const globalPx = this._snapFontSizeToPx(globalFontSize);\n let inheriting = !stored.trim();\n const input = h('input', {\n class: 'sm-input',\n type: 'text',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const syncInput = () => {\n input.disabled = inheriting;\n input.value = inheriting ? '' : stored;\n input.placeholder = inheriting ? '' : this.opts.t('rightPanel.fontSize.placeholder');\n input.classList.toggle('sm-input--inherit-disabled', inheriting);\n };\n\n const inheritSwitch = this._globalInheritSwitch(\n inheriting,\n `${globalPx}px`,\n (on) => {\n if (on) {\n inheriting = true;\n stored = '';\n inheritSwitch.setInherit(true, `${globalPx}px`);\n syncInput();\n onChange('');\n return;\n }\n inheriting = false;\n stored = `${globalPx}px`;\n inheritSwitch.setInherit(false);\n syncInput();\n onChange(stored);\n },\n `${focusToken}:inherit`,\n );\n\n syncInput();\n\n input.addEventListener('input', () => {\n if (inheriting) return;\n stored = input.value;\n onChange(stored);\n });\n\n input.addEventListener('blur', () => {\n if (inheriting) return;\n const t = input.value.trim();\n if (!t) {\n stored = `${globalPx}px`;\n input.value = stored;\n onChange(stored);\n }\n });\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n inheritSwitch.el,\n input,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _snapFontSizeToPx(value: string): number {\n const t = (value ?? '').trim();\n const m = t.match(/^(\\d+(\\.\\d+)?)/);\n if (m) return Math.min(48, Math.max(10, Math.round(parseFloat(m[1]))));\n return 16;\n }\n\n private _fontSizeSliderField(\n label: string,\n value: string,\n onChange: (v: string) => void,\n focusToken: string,\n help?: string,\n globalFontSize?: string,\n ) {\n const inheritGlobal = globalFontSize !== undefined;\n if (!this._preferSliderControls()) {\n if (inheritGlobal) {\n return this._fontSizeInheritTextField(\n label,\n value,\n onChange,\n focusToken,\n globalFontSize,\n help,\n );\n }\n return this._textField(label, value ?? '', onChange, '', focusToken);\n }\n\n const min = 10;\n const max = 48;\n const step = 1;\n const snap = (n: number) => Math.min(max, Math.max(min, Math.round(n)));\n const globalPx = snap(this._snapFontSizeToPx(globalFontSize ?? value ?? '16px'));\n let stored = value.trim();\n let inheriting = inheritGlobal && !stored;\n\n const sliderRow = h('div', { class: 'sm-field__slider-row' });\n const range = h('input', {\n type: 'range',\n min,\n max,\n step,\n }) as HTMLInputElement;\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min,\n max,\n step,\n 'data-sm-focus': focusToken,\n }) as HTMLInputElement;\n sliderRow.append(range, num);\n\n const syncSlider = () => {\n sliderRow.classList.toggle('sm-field__slider-row--inherit', inheriting);\n num.disabled = inheriting;\n if (inheriting) {\n range.value = String(globalPx);\n num.value = '';\n } else {\n const s = snap(this._snapFontSizeToPx(stored || `${globalPx}px`));\n range.value = String(s);\n num.value = String(s);\n }\n };\n\n let inheritSwitch: ReturnType<RightPanel['_globalInheritSwitch']> | null = null;\n if (inheritGlobal) {\n inheritSwitch = this._globalInheritSwitch(\n inheriting,\n `${globalPx}px`,\n (on) => {\n if (on) {\n inheriting = true;\n stored = '';\n inheritSwitch!.setInherit(true, `${globalPx}px`);\n syncSlider();\n onChange('');\n return;\n }\n inheriting = false;\n stored = `${globalPx}px`;\n inheritSwitch!.setInherit(false);\n syncSlider();\n onChange(stored);\n },\n `${focusToken}:inherit`,\n );\n }\n\n syncSlider();\n\n const leaveInherit = () => {\n if (!inheriting) return;\n inheriting = false;\n inheritSwitch?.setInherit(false);\n syncSlider();\n };\n\n range.addEventListener('input', () => {\n leaveInherit();\n const s = snap(Number(range.value));\n num.value = String(s);\n stored = `${s}px`;\n onChange(stored);\n });\n\n num.addEventListener('input', () => {\n if (inheriting) return;\n const rawN = Number(num.value);\n if (Number.isNaN(rawN)) return;\n range.value = String(snap(rawN));\n });\n\n num.addEventListener('blur', () => {\n if (inheriting) return;\n const t = num.value.trim();\n const fb = snap(Number(range.value));\n const s = snap(t === '' || Number.isNaN(Number(t)) ? fb : Number(t));\n stored = `${s}px`;\n num.value = String(s);\n range.value = String(s);\n onChange(stored);\n });\n\n num.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n ...(inheritSwitch ? [inheritSwitch.el] : []),\n sliderRow,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _docFontSizeField(value: string, onChange: (v: string) => void, focusToken: string) {\n return this._fontSizeSliderField(\n this.opts.t('rightPanel.doc.fontSize'),\n value,\n onChange,\n focusToken,\n this.opts.t('rightPanel.doc.fontSizeHelp'),\n );\n }\n\n private _layoutWidthField(\n label: string,\n raw: string,\n onChange: (v: string) => void,\n focusToken: string,\n help?: string,\n ) {\n if (!this._preferSliderControls()) {\n const tf = this._textField(label, raw, onChange, '', focusToken);\n if (help) tf.append(h('div', { class: 'sm-field__help' }, [help]));\n return tf;\n }\n\n const kind = classifyLayoutWidth(raw);\n if (kind === 'custom') {\n const wrap = h('div', { class: 'sm-field' });\n wrap.append(h('label', { class: 'sm-field__label' }, [label]));\n wrap.append(\n h('div', { class: 'sm-field__help' }, [\n this.opts.t('rightPanel.width.customHelp'),\n ]),\n );\n wrap.append(\n h('input', {\n class: 'sm-input',\n type: 'text',\n value: raw,\n placeholder: this.opts.t('rightPanel.width.customPlaceholder'),\n 'data-sm-focus': focusToken,\n oninput: (e: Event) => onChange((e.target as HTMLInputElement).value),\n }),\n );\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n const mode: 'auto' | 'px' | '%' = kind;\n const max = mode === '%' ? 100 : 1200;\n const min = 1;\n const displayN = mode === 'auto' ? 280 : layoutWidthNumeric(raw, mode === '%' ? '%' : 'px');\n\n const clampW = (n: number) => Math.max(min, Math.min(max, Math.round(n)));\n\n const range = h('input', {\n type: 'range',\n min,\n max,\n step: 1,\n value: String(displayN),\n disabled: mode === 'auto',\n }) as HTMLInputElement;\n\n const num = h('input', {\n class: 'sm-input',\n type: 'number',\n min,\n max,\n step: 1,\n value: String(displayN),\n disabled: mode === 'auto',\n ...(focusToken ? { 'data-sm-focus': focusToken } : {}),\n }) as HTMLInputElement;\n\n const emitW = (c: number) => {\n const v = clampW(c);\n range.value = String(v);\n num.value = String(v);\n onChange(mode === '%' ? `${v}%` : `${v}px`);\n };\n\n range.addEventListener('input', () => {\n if (mode === 'auto') return;\n emitW(Number(range.value));\n });\n\n num.addEventListener('input', () => {\n if (mode === 'auto') return;\n const t = num.value.trim();\n if (t === '') return;\n const rawN = Number(t);\n if (Number.isNaN(rawN)) return;\n range.value = String(clampW(rawN));\n });\n\n num.addEventListener('blur', () => {\n if (mode === 'auto') return;\n const t = num.value.trim();\n const fb = clampW(Number(range.value));\n if (t === '') {\n emitW(fb);\n return;\n }\n const rawN = Number(t);\n emitW(Number.isNaN(rawN) ? fb : rawN);\n });\n\n num.addEventListener('keydown', (e) => {\n if (mode === 'auto') return;\n if ((e as KeyboardEvent).key === 'Enter') num.blur();\n });\n\n const sliderRow = h(\n 'div',\n { class: `sm-width-field__slider-row ${mode === 'auto' ? 'is-disabled' : ''}` },\n [range, num],\n );\n\n const modesWrap = h('div', { class: 'sm-segmented sm-segmented--wrap sm-width-field__modes' });\n const addModeBtn = (m: 'auto' | 'px' | '%', text: string) => {\n modesWrap.append(\n h(\n 'button',\n {\n type: 'button',\n class: `sm-segmented__item ${mode === m ? 'sm-segmented__item--active' : ''}`,\n onclick: () => {\n if (m === 'auto') onChange('');\n else if (m === 'px') onChange(`${layoutWidthNumeric(raw, 'px')}px`);\n else onChange(`${layoutWidthNumeric(raw, '%')}%`);\n },\n },\n [text],\n ),\n );\n };\n addModeBtn('auto', this.opts.t('rightPanel.width.auto'));\n addModeBtn('px', 'px');\n addModeBtn('%', '%');\n\n const wrap = h('div', { class: 'sm-field' }, [\n h('label', { class: 'sm-field__label' }, [label]),\n modesWrap,\n sliderRow,\n ]);\n if (help) wrap.append(h('div', { class: 'sm-field__help' }, [help]));\n return wrap;\n }\n\n private _docFontWeightField(value: string, onChange: (v: string) => void, focusToken: string) {\n const cur = normalizeFontWeightStep(value);\n return this._segmentedSelectField(this.opts.t('rightPanel.doc.fontWeight'), cur, FONT_WEIGHT_STEP_OPTIONS, onChange, focusToken);\n }\n\n private _multiColumnLayoutField(\n layout: SectionLayout,\n onChange: (layout: SectionLayout) => void,\n focusToken: string,\n ) {\n return this._segmentedSelectField(\n this.opts.t('rightPanel.section.columnLayout'),\n layout,\n [\n { label: '1:1', value: '1-1' },\n { label: '1:2', value: '1-2' },\n { label: '2:1', value: '2-1' },\n { label: '1:1:1', value: '1-1-1' },\n ],\n (v) => onChange(v as SectionLayout),\n focusToken,\n );\n }\n\n private _renderBlockCodeView(block: Block): HTMLElement {\n const def = this.opts.registry.get(block.type);\n const initial =\n block.lockedMjml ??\n (def ? def.toMjml(block.props as any, { doc: this.opts.store.doc, engine: 'mjml' }) : '');\n\n const wrap = h('div', { class: 'sm-code-pane' });\n\n const header = h('div', { class: 'sm-code-pane__header' }, [\n h('div', { class: 'sm-code-pane__title' }, [this.opts.t('rightPanel.code.title')]),\n ]);\n\n const editorHost = h('div', { class: 'sm-code' });\n\n const view = new EditorView({\n parent: editorHost,\n state: EditorState.create({\n doc: initial,\n extensions: [basicSetup, cmHtml()],\n }),\n });\n this.codeView = view;\n\n const actions = h('div', { class: 'sm-code-pane__header' }, [\n h(\n 'button',\n {\n class: 'sm-btn',\n type: 'button',\n onclick: () => {\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, block.id);\n if (l) delete l.block.lockedMjml;\n });\n },\n },\n [this.opts.t('rightPanel.code.restoreDefault')],\n ),\n h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => {\n const text = view.state.doc.toString();\n this.opts.store.update((d) => {\n const l = findBlockLocation(d, block.id);\n if (l) l.block.lockedMjml = text;\n });\n },\n },\n [this.opts.t('rightPanel.code.saveLocked')],\n ),\n ]);\n\n wrap.append(\n header,\n editorHost,\n h('div', { class: 'sm-field__help' }, [this.opts.t('rightPanel.code.help')]),\n actions,\n );\n return wrap;\n }\n\n private _destroyCodeView() {\n if (this.codeView) {\n this.codeView.destroy();\n this.codeView = null;\n }\n }\n}\n","import { EditorState } from '@codemirror/state';\nimport { EditorView, basicSetup } from 'codemirror';\nimport { html as cmHtml } from '@codemirror/lang-html';\nimport type { Registry } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport type { Store } from '../store/store';\nimport { clear, h } from '../utils/dom';\nimport { richTextExecCommand } from '../utils/richTextCommand';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface SourceViewOptions {\n store: Store;\n registry: Registry;\n t: SimpleMailT;\n}\n\ntype SourceTab = 'mjml' | 'html';\n\n/**\n * 文档级源码视图:只读地展示当前文档编译出的 MJML 与 HTML。\n *\n * 本期不支持把源码直接回写到数据模型——MJML/HTML 反推 doc 风险大且不必要,\n * 用户若需要直接写源码,可在右栏对单个 Block 走\"组件级代码模式\"。\n */\nexport class SourceView {\n el: HTMLElement;\n private opts: SourceViewOptions;\n private currentTab: SourceTab = 'mjml';\n private body: HTMLElement;\n private cm: EditorView | null = null;\n\n constructor(opts: SourceViewOptions) {\n this.opts = opts;\n this.el = h('div', { class: 'sm-doc-source' });\n this.body = h('div', { class: 'sm-doc-source__body' });\n this._render();\n opts.store.subscribe(() => {\n if (this._isVisible()) this._renderEditor();\n });\n }\n\n /**\n * 设计态运行时 SourceView 不在 DOM,`store.subscribe` 里的 `_renderEditor()` 全部被跳过,\n * CodeMirror 里仍是构造函数那一刻的快照。**切到「源码」模式后必须手动调一次**,\n * 否则会看到空文档 / 旧文档,但「导出」「预览」「MJML→HTML」却一直是当前 doc ——这正是用户报告的错位。\n */\n refreshDoc() {\n this._renderEditor();\n }\n\n private _isVisible(): boolean {\n return this.el.isConnected && (this.el.offsetParent !== null || this.el.getClientRects().length > 0);\n }\n\n private _render() {\n clear(this.el);\n const bar = h('div', { class: 'sm-doc-source__bar' }, [\n this._tabBtn('mjml', 'MJML'),\n this._tabBtn('html', this.opts.t('source.compiledHtml')),\n h('div', { class: 'sm-topbar__spacer' }),\n h(\n 'button',\n {\n class: 'sm-btn',\n type: 'button',\n onclick: () => this._copy(),\n },\n [this.opts.t('common.copy')],\n ),\n ]);\n this.el.append(bar, this.body);\n this._renderEditor();\n }\n\n private _tabBtn(tab: SourceTab, label: string) {\n return h(\n 'button',\n {\n class: `sm-segmented__item ${tab === this.currentTab ? 'sm-segmented__item--active' : ''}`,\n type: 'button',\n onclick: () => {\n this.currentTab = tab;\n this._render();\n },\n },\n [label],\n );\n }\n\n private _renderEditor() {\n this._destroyCm();\n clear(this.body);\n const result = renderDoc(this.opts.store.doc, this.opts.registry, {\n withSampleVariables: false,\n });\n const text = this.currentTab === 'mjml' ? result.mjml : result.html;\n this.cm = new EditorView({\n parent: this.body,\n state: EditorState.create({\n doc: text,\n extensions: [basicSetup, cmHtml(), EditorState.readOnly.of(true)],\n }),\n });\n }\n\n private async _copy() {\n if (!this.cm) return;\n const text = this.cm.state.doc.toString();\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n const ta = document.createElement('textarea');\n ta.value = text;\n document.body.appendChild(ta);\n ta.select();\n richTextExecCommand('copy');\n document.body.removeChild(ta);\n }\n }\n\n private _destroyCm() {\n if (this.cm) {\n this.cm.destroy();\n this.cm = null;\n }\n }\n\n destroy() {\n this._destroyCm();\n }\n}\n","import type { Store } from '../store/store';\nimport { bindColorPickerInput } from './ColorPickerPopover';\nimport { normalizeAccentHex, rgbCssToHex } from '../utils/accentColor';\nimport { h, clear } from '../utils/dom';\nimport type { EditorTheme } from './theme';\nimport type { SimpleMailT } from '../i18n';\n\nexport type EditorMode = 'design' | 'source';\n\nexport interface TopbarOptions {\n store: Store;\n t: SimpleMailT;\n mode: EditorMode;\n theme: EditorTheme;\n /** 顶栏仅图标(tooltip 说明),适合窄屏嵌入 */\n compact?: boolean;\n /** 用于读取解析后的 `--sm-primary`,同步到原生 color 输入 */\n accentPickerRoot?: HTMLElement;\n /** 为 true 时在顶栏显示主题色拾取器(需同时提供 `onAccentChange`) */\n showAccentColorPicker?: boolean;\n onAccentChange?: (hex: string) => void;\n onThemeChange: (t: EditorTheme) => void;\n onModeChange: (m: EditorMode) => void;\n onUndo: () => void;\n onRedo: () => void;\n /** 清空画布选中并回到右栏「邮件设置 / 全局样式」 */\n onMailSettings: () => void;\n onInsertVariable: (anchor: HTMLElement) => void;\n onPreview: () => void;\n onExport: () => void;\n /** 切换编辑器根节点浏览器全屏(由 Editor 实现 Fullscreen API) */\n onFullscreenToggle?: () => void;\n /** 切换画布 Section / Block 布局虚线边框 */\n onLayoutBordersToggle?: () => void;\n /** 为 false 时不展示全屏按钮(也可用 `ui.hideTopbarFullscreen`) */\n showFullscreenButton?: boolean;\n /** 为 false 时不展示「邮件设置」按钮(也可用 `ui.hideTopbarMailSettings`) */\n showMailSettingsButton?: boolean;\n /** 为 false 时不渲染左侧产品标题 */\n showTitle?: boolean;\n /** 为 false 时不展示「清空画布」 */\n showClearCanvasButton?: boolean;\n onClearCanvas?: () => void;\n /** 为 false 时不展示「重置内容」 */\n showResetContentButton?: boolean;\n onResetContent?: () => void;\n /** 为 false 时不展示「复制设计稿」「导入设计稿」 */\n showDocClipboardButtons?: boolean;\n onCopyDocDesign?: () => void;\n onImportDocDesign?: () => void;\n /** 为 false 时不展示「插入变量」 */\n showInsertVariableButton?: boolean;\n}\n\nexport class Topbar {\n el: HTMLElement;\n private opts: TopbarOptions;\n private undoBtn!: HTMLButtonElement;\n private redoBtn!: HTMLButtonElement;\n private themeButtons!: Record<EditorTheme, HTMLButtonElement>;\n private modeButtons: Record<EditorMode, HTMLButtonElement> = {} as any;\n private accentInput?: HTMLInputElement;\n private fullscreenBtn?: HTMLButtonElement;\n private layoutBordersBtn?: HTMLButtonElement;\n private insertVariableBtn?: HTMLButtonElement;\n\n constructor(opts: TopbarOptions) {\n this.opts = opts;\n this.el = h('header', { class: 'sm-topbar' });\n this.setCompact(opts.compact === true);\n this._render();\n opts.store.subscribe(() => this._sync());\n this._sync();\n }\n\n /** 切换顶栏紧凑样式(仅图标布局,文案由 CSS 隐藏) */\n setCompact(compact: boolean) {\n this.el.classList.toggle('sm-topbar--compact', compact);\n }\n\n setMode(m: EditorMode) {\n this.opts.mode = m;\n for (const k of ['design', 'source'] as EditorMode[]) {\n this.modeButtons[k].classList.toggle('sm-segmented__item--active', k === m);\n }\n }\n\n syncTheme(t: EditorTheme) {\n this.opts.theme = t;\n for (const k of ['light', 'dark', 'system'] as const) {\n const on = k === t;\n this.themeButtons[k].classList.toggle('sm-segmented__item--active', on);\n this.themeButtons[k].setAttribute('aria-pressed', on ? 'true' : 'false');\n }\n }\n\n /** 根据 `.sm-root` 上计算后的 `--sm-primary` 更新拾取器显示(无拾取器或未挂 root 时忽略) */\n syncAccentPicker() {\n if (!this.accentInput || !this.opts.accentPickerRoot) return;\n const raw = getComputedStyle(this.opts.accentPickerRoot).getPropertyValue('--sm-primary').trim();\n const base = normalizeAccentHex(raw) || rgbCssToHex(raw);\n if (!base) return;\n const norm = normalizeAccentHex(base);\n if (!norm) return;\n const forInput = `#${norm.slice(1).toLowerCase()}`;\n if (this.accentInput.value.toLowerCase() !== forInput) this.accentInput.value = forInput;\n }\n\n /** 与 document fullscreen 状态同步图标与 aria(按钮不存在时忽略) */\n setFullscreenActive(active: boolean) {\n const btn = this.fullscreenBtn;\n if (!btn) return;\n btn.replaceChildren(active ? iconFullscreenExit() : iconFullscreenEnter());\n const title = active ? this.opts.t('topbar.exitFullscreen') : this.opts.t('topbar.fullscreen');\n btn.title = title;\n btn.setAttribute('aria-label', title);\n btn.setAttribute('aria-pressed', active ? 'true' : 'false');\n }\n\n /** 与画布布局边框开关同步按钮高亮(按钮不存在时忽略) */\n setLayoutBordersActive(active: boolean) {\n const btn = this.layoutBordersBtn;\n if (!btn) return;\n btn.setAttribute('aria-pressed', active ? 'true' : 'false');\n const title = active ? this.opts.t('topbar.hideLayoutBorders') : this.opts.t('topbar.showLayoutBorders');\n btn.title = title;\n btn.setAttribute('aria-label', title);\n }\n\n /** 变量列表在右栏打开(设计态)或浮层打开(源码态)时高亮顶栏按钮 */\n setInsertVariableActive(active: boolean) {\n const btn = this.insertVariableBtn;\n if (!btn) return;\n btn.setAttribute('aria-pressed', active ? 'true' : 'false');\n btn.classList.toggle('sm-topbar__insert-var--active', active);\n }\n\n private _render() {\n clear(this.el);\n const t = this.opts.t;\n\n const segmented = h('div', { class: 'sm-segmented sm-topbar__mode-seg', role: 'group', 'aria-label': t('topbar.mode') });\n const designBtn = modeSegBtn({\n active: this.opts.mode === 'design',\n title: t('topbar.design'),\n icon: iconDesign(),\n label: t('topbar.design'),\n onclick: () => this.opts.onModeChange('design'),\n });\n const sourceBtn = modeSegBtn({\n active: this.opts.mode === 'source',\n title: t('topbar.source'),\n icon: iconSource(),\n label: t('topbar.source'),\n onclick: () => this.opts.onModeChange('source'),\n });\n segmented.append(designBtn, sourceBtn);\n this.modeButtons = { design: designBtn, source: sourceBtn };\n\n const themeSeg = h('div', {\n class: 'sm-segmented sm-topbar__theme-seg',\n role: 'group',\n 'aria-label': t('topbar.theme'),\n });\n const themeBtn = (theme: EditorTheme, title: string, icon: SVGElement) =>\n h(\n 'button',\n {\n class: 'sm-segmented__item sm-topbar__theme-btn',\n type: 'button',\n title,\n 'aria-label': title,\n 'aria-pressed': theme === this.opts.theme ? 'true' : 'false',\n onclick: () => this.opts.onThemeChange(theme),\n },\n [icon],\n ) as HTMLButtonElement;\n this.themeButtons = {\n light: themeBtn('light', t('topbar.light'), iconSun()),\n dark: themeBtn('dark', t('topbar.dark'), iconMoon()),\n system: themeBtn('system', t('topbar.system'), iconThemeAuto()),\n };\n themeSeg.append(this.themeButtons.light, this.themeButtons.dark, this.themeButtons.system);\n\n const themeGroupKids: Node[] = [themeSeg];\n if (this.opts.showAccentColorPicker && this.opts.onAccentChange) {\n const inputEl = h('input', {\n type: 'color',\n class: 'sm-topbar__accent-input',\n 'aria-label': t('topbar.accentColor'),\n title: t('topbar.accentColor'),\n value: '#4f46e5',\n }) as HTMLInputElement;\n bindColorPickerInput(inputEl, {\n layerRoot: this.opts.accentPickerRoot,\n liveCommit: true,\n t,\n onCommit: (hex) => this.opts.onAccentChange!(hex),\n });\n this.accentInput = inputEl;\n themeGroupKids.push(h('div', { class: 'sm-topbar__accent' }, [inputEl]));\n } else {\n this.accentInput = undefined;\n }\n\n this.undoBtn = actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.undoTitle'),\n icon: iconUndo(),\n label: t('topbar.undo'),\n onclick: this.opts.onUndo,\n });\n this.redoBtn = actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.redoTitle'),\n icon: iconRedo(),\n label: t('topbar.redo'),\n onclick: this.opts.onRedo,\n });\n\n const contentActionKids: HTMLElement[] = [];\n if (this.opts.showClearCanvasButton !== false && typeof this.opts.onClearCanvas === 'function') {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.clearCanvasTitle'),\n icon: iconClearCanvas(),\n label: t('topbar.clearCanvas'),\n onclick: () => this.opts.onClearCanvas!(),\n }),\n );\n }\n if (\n this.opts.showResetContentButton !== false &&\n typeof this.opts.onResetContent === 'function'\n ) {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.resetContentTitle'),\n icon: iconResetContent(),\n label: t('topbar.resetContent'),\n onclick: () => this.opts.onResetContent!(),\n }),\n );\n }\n if (this.opts.showDocClipboardButtons !== false) {\n if (typeof this.opts.onCopyDocDesign === 'function') {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.copyDesignTitle'),\n icon: iconCopyDoc(),\n label: t('topbar.copyDesign'),\n onclick: () => this.opts.onCopyDocDesign!(),\n }),\n );\n }\n if (typeof this.opts.onImportDocDesign === 'function') {\n contentActionKids.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.importDesignTitle'),\n icon: iconImportDoc(),\n label: t('topbar.importDesign'),\n onclick: () => this.opts.onImportDocDesign!(),\n }),\n );\n }\n }\n const contentActionsGroup =\n contentActionKids.length > 0 && h('div', { class: 'sm-topbar__group' }, contentActionKids);\n\n const previewBtn = actionBtn({\n title: t('topbar.preview'),\n icon: iconEye(),\n label: t('topbar.preview'),\n onclick: this.opts.onPreview,\n });\n\n const exportBtn = actionBtn({\n class: 'sm-btn--primary',\n title: t('topbar.exportHtml'),\n icon: iconExport(),\n label: t('topbar.exportHtml'),\n onclick: this.opts.onExport,\n });\n\n const showMailSettings = this.opts.showMailSettingsButton !== false;\n const trailingGroup: HTMLElement[] = [];\n if (showMailSettings) {\n trailingGroup.push(\n actionBtn({\n class: 'sm-btn--ghost',\n title: t('topbar.mailSettingsTitle'),\n icon: iconSettings(),\n label: t('topbar.mailSettings'),\n onclick: () => this.opts.onMailSettings(),\n }),\n );\n }\n if (this.opts.showInsertVariableButton !== false) {\n trailingGroup.push(\n (this.insertVariableBtn = actionBtn({\n class: 'sm-topbar__insert-var',\n title: t('topbar.insertVariable'),\n icon: iconVariable(),\n label: t('topbar.insertVariable'),\n onclick: (e: Event) => this.opts.onInsertVariable(e.currentTarget as HTMLElement),\n })),\n );\n } else {\n this.insertVariableBtn = undefined;\n }\n trailingGroup.push(previewBtn, exportBtn);\n\n const canvasToolKids: HTMLElement[] = [];\n\n if (typeof this.opts.onLayoutBordersToggle === 'function') {\n canvasToolKids.push(\n (this.layoutBordersBtn = iconOnlyBtn({\n class: 'sm-btn--ghost sm-topbar__toggle-btn',\n title: t('topbar.showLayoutBorders'),\n icon: iconLayoutBorders(),\n pressed: false,\n onclick: () => this.opts.onLayoutBordersToggle!(),\n }) as HTMLButtonElement),\n );\n } else {\n this.layoutBordersBtn = undefined;\n }\n\n const showFs =\n this.opts.showFullscreenButton !== false &&\n typeof this.opts.onFullscreenToggle === 'function';\n if (showFs) {\n canvasToolKids.push(\n (this.fullscreenBtn = iconOnlyBtn({\n class: 'sm-btn--ghost sm-topbar__toggle-btn',\n title: t('topbar.fullscreen'),\n icon: iconFullscreenEnter(),\n pressed: false,\n onclick: () => this.opts.onFullscreenToggle!(),\n }) as HTMLButtonElement),\n );\n } else {\n this.fullscreenBtn = undefined;\n }\n\n const canvasToolsGroup =\n canvasToolKids.length > 0 && h('div', { class: 'sm-topbar__group' }, canvasToolKids);\n\n const headKids: HTMLElement[] = [];\n if (this.opts.showTitle !== false) {\n headKids.push(h('div', { class: 'sm-topbar__title' }, ['Simple Mail Editor']));\n }\n\n this.el.append(\n ...headKids,\n h('div', { class: 'sm-topbar__group' }, [segmented]),\n h('div', { class: 'sm-topbar__group sm-topbar__theme-group' }, themeGroupKids),\n h('div', { class: 'sm-topbar__group' }, [this.undoBtn, this.redoBtn]),\n ...(contentActionsGroup ? [contentActionsGroup] : []),\n ...(canvasToolsGroup ? [canvasToolsGroup] : []),\n h('div', { class: 'sm-topbar__spacer' }),\n h('div', { class: 'sm-topbar__group' }, trailingGroup),\n );\n\n this.setMode(this.opts.mode);\n this.syncTheme(this.opts.theme);\n }\n\n private _sync() {\n this.undoBtn.disabled = !this.opts.store.canUndo();\n this.redoBtn.disabled = !this.opts.store.canRedo();\n }\n}\n\nfunction topbarLabel(text: string): HTMLElement {\n return h('span', { class: 'sm-topbar__btn-label' }, [text]);\n}\n\nfunction actionBtn(opts: {\n class?: string;\n title: string;\n icon: SVGElement;\n label: string;\n onclick: (e: Event) => void;\n}): HTMLButtonElement {\n const extra = opts.class ? ` ${opts.class}` : '';\n return h(\n 'button',\n {\n class: `sm-btn sm-topbar__action-btn${extra}`,\n type: 'button',\n title: opts.title,\n 'aria-label': opts.title,\n onclick: opts.onclick,\n },\n [opts.icon, topbarLabel(opts.label)],\n ) as HTMLButtonElement;\n}\n\nfunction modeSegBtn(opts: {\n active: boolean;\n title: string;\n icon: SVGElement;\n label: string;\n onclick: () => void;\n}): HTMLButtonElement {\n const cls = opts.active\n ? 'sm-segmented__item sm-topbar__mode-btn sm-segmented__item--active'\n : 'sm-segmented__item sm-topbar__mode-btn';\n return h(\n 'button',\n {\n class: cls,\n type: 'button',\n title: opts.title,\n 'aria-label': opts.title,\n onclick: opts.onclick,\n },\n [opts.icon, topbarLabel(opts.label)],\n ) as HTMLButtonElement;\n}\n\nfunction iconOnlyBtn(opts: {\n class?: string;\n title: string;\n icon: SVGElement;\n pressed: boolean;\n onclick: () => void;\n}): HTMLButtonElement {\n const extra = opts.class ? ` ${opts.class}` : '';\n return h(\n 'button',\n {\n class: `sm-btn sm-btn--ghost sm-topbar__icon-btn${extra}`,\n type: 'button',\n title: opts.title,\n 'aria-label': opts.title,\n 'aria-pressed': opts.pressed ? 'true' : 'false',\n onclick: opts.onclick,\n },\n [opts.icon],\n ) as HTMLButtonElement;\n}\n\nconst ICON_UNDO_PATH =\n 'M596.16 284.064H258.56l101.376-101.44a31.968 31.968 0 1 0-45.248-45.216L178.56 273.504c-11.904 11.872-18.496 27.84-18.56 44.8a63.04 63.04 0 0 0 18.56 45.28l136.128 136.16a31.904 31.904 0 0 0 45.248 0 31.968 31.968 0 0 0 0-45.248l-106.752-106.496H596.16c114.88 0 208.32 93.312 208.32 208s-93.44 208-208.32 208h-223.36a32 32 0 0 0 0 64h223.36c150.144 0 272.32-122.016 272.32-272 0-149.984-122.176-272-272.32-272';\n\nfunction iconUndo(): SVGElement {\n return svgPathFill(ICON_UNDO_PATH);\n}\nfunction iconRedo(): SVGElement {\n return svgPathFill(ICON_UNDO_PATH, { flipX: true });\n}\nfunction iconEye(): SVGElement {\n return svgPathFill([\n 'M506.84131 829.259446C229.561713 829.259446 10.31738 575.193955 1.289673 564.876574c-7.738035-9.027708-7.738035-23.214106 0-33.531486 9.027708-10.31738 228.27204-264.382872 505.551637-264.382871 277.279597 0 496.523929 254.065491 505.551637 264.382871 7.738035 9.027708 7.738035 23.214106 0 33.531486-10.31738 10.31738-228.27204 264.382872-505.551637 264.382872z m-451.385391-281.148615c52.876574 55.455919 237.299748 229.561713 451.385391 229.561713s397.219144-174.105793 451.38539-229.561713c-52.876574-55.455919-237.299748-229.561713-451.38539-229.561713S108.332494 492.654912 55.455919 548.110831z',\n 'M497.813602 713.188917c-90.277078 0-163.788413-73.511335-163.788413-163.788413S407.536524 386.901763 497.813602 386.901763c90.277078 0 163.788413 73.511335 163.788413 163.788413s-73.511335 162.498741-163.788413 162.498741z m0-274.700252c-61.904282 0-112.201511 50.297229-112.201511 112.201511 0 61.904282 50.297229 112.201511 112.201511 112.201512s112.201511-50.297229 112.201511-112.201512c0-61.904282-50.297229-112.201511-112.201511-112.201511z',\n ]);\n}\nfunction iconDesign(): SVGElement {\n return svgPathFill(\n 'M947.96 199.329l-92.764 92.549L731.54 168.443l92.768-92.548c17.025-17.03 44.746-17.03 61.825 0l61.828 61.715c17.084 17.028 17.084 44.695 0 61.719z m-649.486 401.09l123.657 123.434-164.804 41.092 41.147-164.526z m525.834-277.653l-371.02 370.257-123.654-123.436L700.597 199.33l123.711 123.436zM154.843 196.272v673.501h673.503V383.884l87.856-87.854v617.673c0 24.287-19.641 43.93-43.927 43.93H110.917c-24.282 0-43.928-19.642-43.928-43.93V152.345c0-24.281 19.646-43.927 43.928-43.927h620.185l-87.855 87.854H154.843z',\n );\n}\nfunction iconSource(): SVGElement {\n return svgPathFill(\n 'M153.770667 517.558857l200.387047-197.241905L302.86019 268.190476 48.761905 518.290286l254.439619 243.614476 50.590476-52.833524-200.021333-191.512381zM658.285714 320.316952L709.583238 268.190476l254.098286 250.09981L709.241905 761.904762l-50.590476-52.833524 200.021333-191.512381L658.285714 320.316952z m-112.981333-86.186666L393.99619 785.554286l70.534096 19.358476 151.30819-551.399619-70.534095-19.358476z',\n );\n}\n/** 邮件设置齿轮(镂空路径用 evenodd) */\nfunction iconSettings(): SVGElement {\n return svgPathFill(\n 'M664.586139 993.077228c-18.756436 0-36.49901-7.60396-48.158416-20.277228-15.714851-17.235644-65.90099-62.352475-106.962376-62.352475-41.061386 0-91.754455 45.623762-106.455446 61.338614-11.659406 12.673267-29.40198 20.277228-47.651485 20.277227-8.617822 0-17.235644-1.520792-24.332673-5.069307l-1.520793-0.50693-125.211881-69.956436-1.013861-1.013861c-22.811881-15.714851-31.429703-47.144554-20.277228-72.491089 0 0 11.659406-26.360396 11.659406-50.69307 0-72.99802-59.310891-132.308911-132.308911-132.308911h-5.576237c-20.784158 0-38.019802-18.756436-43.59604-47.144554-0.506931-2.534653-10.645545-56.776238-10.645545-99.865347s10.138614-97.330693 10.645545-99.865346c5.576238-28.89505 22.811881-47.651485 44.10297-47.144555h4.562377c72.99802 0 132.308911-59.310891 132.30891-132.30891 0-23.825743-11.659406-50.693069-11.659405-50.69307-11.152475-25.346535-2.534653-56.269307 20.277227-72.491089l1.520792-1.013861 131.801981-72.491089 1.520792-1.520792c7.60396-3.041584 15.714851-4.562376 24.332673-4.562377 18.249505 0 35.992079 7.60396 48.158416 19.770297 15.714851 16.221782 64.887129 58.80396 104.934653 58.803961 39.540594 0 88.712871-41.568317 103.920792-57.790099 11.659406-12.166337 29.40198-19.263366 47.651485-19.263367 8.617822 0 17.235644 1.520792 24.839604 5.069307l1.520792 0.506931 127.239604 70.970297 1.013862 1.013861c22.811881 15.714851 31.429703 47.144554 20.277227 72.49109 0 0-11.659406 26.360396-11.659405 50.693069 0 72.99802 59.310891 132.308911 132.30891 132.308911h4.562377c21.291089-0.506931 38.526733 18.249505 44.10297 47.144554 0.506931 2.534653 10.645545 56.776238 10.645545 99.865347s-10.138614 97.330693-10.645545 99.865346c-5.576238 28.89505-22.811881 47.651485-44.10297 47.144555h-4.562377c-72.99802 0-132.308911 59.310891-132.30891 132.308911 0 23.825743 11.659406 50.693069 11.659405 50.693069 11.152475 25.346535 2.534653 56.269307-20.277227 72.491089l-1.520792 1.013861-129.774258 71.477228-1.520792 0.506931c-7.09703 3.548515-15.207921 5.069307-23.825742 5.069307z m-3.548515-60.831683c0.506931 0.506931 2.027723 1.013861 4.055445 1.013861l121.156436-66.914852c-3.041584-6.590099-16.221782-39.540594-16.221782-74.011881 0-102.906931 81.108911-187.057426 182.495049-192.126732 1.520792-8.110891 9.631683-53.227723 9.631683-87.69901 0-33.964356-8.110891-79.588119-9.631683-87.69901-101.386139-5.069307-182.49505-89.726733-182.495049-192.126733 0-34.471287 13.180198-67.421782 16.221782-74.011881l-119.128713-65.90099h-0.506931c-2.027723 0-4.055446 0.506931-4.562376 1.013861-2.027723 2.027723-19.263366 19.770297-44.10297 37.005941-36.49901 25.853465-71.477228 39.033663-102.906931 39.033663-31.936634 0-66.914851-13.180198-103.920792-39.540594-24.839604-17.742574-42.075248-35.485149-44.10297-37.512871-0.506931-0.506931-2.534653-1.013861-4.562376-1.013862h-0.506931L238.257426 158.669307c3.041584 7.09703 16.221782 39.540594 16.221782 74.011881 0 102.906931-81.108911 187.057426-182.49505 192.126733-1.520792 8.110891-9.631683 53.227723-9.631683 87.69901 0 33.964356 8.110891 79.588119 9.631683 87.69901 101.386139 5.069307 182.49505 89.726733 182.49505 192.126732 0 34.471287-13.687129 67.421782-16.221782 74.011881l116.594059 65.39406h0.506931c1.520792 0 3.548515-0.506931 4.055445-1.013862 2.027723-2.534653 19.770297-20.784158 44.609901-39.033663 37.512871-27.374257 72.99802-41.568317 105.948515-41.568317 32.950495 0 68.942574 14.194059 106.455446 42.075248 24.839604 18.756436 42.075248 37.512871 44.609901 40.047525z m-151.065347-243.833664c-97.330693 0-176.411881-79.081188-176.411881-176.411881 0-97.330693 79.081188-176.411881 176.411881-176.411881 97.330693 0 176.411881 79.081188 176.411881 176.411881 0 96.823762-79.588119 176.411881-176.411881 176.411881z m0-293.00594c-64.380198 0-116.594059 52.213861-116.594059 116.594059s52.213861 116.594059 116.594059 116.594059 116.594059-52.213861 116.59406-116.594059c-0.506931-64.380198-52.720792-116.594059-116.59406-116.594059z',\n { fillRule: 'evenodd' },\n );\n}\nfunction iconVariable(): SVGElement {\n return svgPathFill(\n 'M212.48 768v-157.866667c0-35.349333-28.373333-55.466667-63.36-55.466666A42.645333 42.645333 0 0 1 106.666667 512c0-23.445333 18.986667-42.666667 42.453333-42.666667 34.986667 0 63.36-20.117333 63.36-55.466666V256c0-85.333333 55.637333-128 125.610667-128h6.442666a39.466667 39.466667 0 0 1 0 78.933333h-6.442666c-23.317333 0-42.24 25.493333-42.24 49.066667v174.933333a85.290667 85.290667 0 0 1-58.026667 81.066667 85.290667 85.290667 0 0 1 58.026667 81.066667V768c0 23.573333 18.922667 49.066667 42.24 49.066667h6.442666a39.466667 39.466667 0 0 1 0 78.933333h-6.442666c-69.973333 0-125.610667-42.666667-125.610667-128z m599.04-157.866667V768c0 85.333333-55.850667 128-125.845333 128h-6.208a39.466667 39.466667 0 0 1 0-78.933333h6.208c23.338667 0 42.24-25.493333 42.24-49.066667v-174.933333a85.290667 85.290667 0 0 1 58.026666-81.066667 85.290667 85.290667 0 0 1-58.026666-81.066667V256c0-23.573333-18.901333-49.066667-42.24-49.066667h-6.208a39.466667 39.466667 0 0 1 0-78.933333h6.208c69.973333 0 125.866667 42.666667 125.866666 128v157.866667c0 35.349333 28.352 55.466667 63.36 55.466666 23.424 0 42.432 19.221333 42.432 42.666667s-18.986667 42.666667-42.453333 42.666667c-34.986667 0-63.36 20.117333-63.36 55.466666z',\n );\n}\nfunction iconExport(): SVGElement {\n return svg(\n '<path d=\"M10 4.5v8.5M7.2 11.2 10 14l2.8-2.8M5.5 15.5h9\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n );\n}\nfunction iconClearCanvas(): SVGElement {\n return svgPathFill(\n 'M744.5 695L641.9 592.4l44.5-51.3L789 650.5l102.6-109.4 51.3 51.3L833.5 695l109.4 102.6-51.3 44.5L789 739.5 686.4 842.1l-44.5-44.5L744.5 695zM64 182h896v65H64v-65z m0 191.5h896v65H64v-65zM577 630H64v-61.6h513V630zM64 824.9v-65h513v65H64z',\n );\n}\nfunction iconResetContent(): SVGElement {\n return svgPathFill(\n 'M864 512a352 352 0 0 0-600.96-248.96c-15.744 15.872-40.704 42.88-63.232 67.648H320a32 32 0 1 1 0 64H128a31.872 31.872 0 0 1-32-32v-192a32 32 0 1 1 64 0v108.672c20.544-22.528 42.688-46.4 57.856-61.504a416 416 0 1 1 0 588.288 32 32 0 1 1 45.248-45.248A352 352 0 0 0 864 512z',\n );\n}\nfunction iconCopyDoc(): SVGElement {\n return svg(\n '<rect x=\"6.5\" y=\"6.5\" width=\"9\" height=\"11\" rx=\"1.2\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><rect x=\"4.5\" y=\"3.5\" width=\"9\" height=\"11\" rx=\"1.2\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"var(--sm-surface, #fff)\"/>',\n );\n}\nfunction iconImportDoc(): SVGElement {\n return svg(\n '<path d=\"M10 4.5v6.5M7.2 9.2 10 12l2.8-2.8M5.5 14.5h9\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><rect x=\"4\" y=\"14\" width=\"12\" height=\"2.5\" rx=\".6\" fill=\"currentColor\"/>',\n );\n}\n/** 显示边框:圆角矩形描边(开启时由 toggle 样式点亮 currentColor) */\nfunction iconLayoutBorders(): SVGElement {\n return svgPathFill(\n 'M64 832V192a128 128 0 0 1 128-128h640a128 128 0 0 1 128 128v640a128 128 0 0 1-128 128H192a128 128 0 0 1-128-128z m64 0q0 26.496 18.752 45.248T192 896h640q26.496 0 45.248-18.752T896 832V192q0-26.496-18.752-45.248T832 128H192q-26.496 0-45.248 18.752T128 192v640z',\n );\n}\n/** 进入全屏:四角向外 */\nfunction iconFullscreenEnter(): SVGElement {\n return svg(\n '<path d=\"M6 4H4v2M14 4h2v2M6 16H4v-2M14 16h2v-2M4 6V4h2M16 6V4h-2M4 14v2h2M16 14v2h-2\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>',\n );\n}\n/** 退出全屏 / 缩小:四角向内 */\nfunction iconFullscreenExit(): SVGElement {\n return svgPathFill(\n 'M705.92 124.117333a38.826667 38.826667 0 1 0-77.568 0v232.704c0 21.461333 17.365333 38.826667 38.784 38.826667h232.746667a38.826667 38.826667 0 0 0 0-77.568h-193.962667V124.117333zM356.864 395.648a38.826667 38.826667 0 0 0 38.784-38.784V124.16a38.826667 38.826667 0 1 0-77.568 0v193.962667H124.117333a38.826667 38.826667 0 0 0 0 77.568h232.746667zM899.882667 705.92a38.826667 38.826667 0 0 0 0-77.568h-232.704a38.826667 38.826667 0 0 0-38.826667 38.784v232.746667a38.826667 38.826667 0 0 0 77.610667 0v-193.962667h193.92zM356.864 628.352a38.826667 38.826667 0 0 1 38.826667 38.826667v232.704a38.826667 38.826667 0 0 1-77.610667 0v-193.92H124.16a38.826667 38.826667 0 1 1 0-77.610667h232.746667z',\n );\n}\nfunction iconSun(): SVGElement {\n return svgTheme(\n '<circle cx=\"10\" cy=\"10\" r=\"3.2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M10 3.5V5M10 15v1.5M16.5 10H15M5 10H3.5M14.1 5.9 13 7M7 13 5.9 14.1M14.1 14.1 13 13M7 7 5.9 5.9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>',\n );\n}\nfunction iconMoon(): SVGElement {\n return svgPathFill(\n 'M524.490551 1023.43355c-140.102939 0-271.81403-54.547017-370.878782-153.611769S0 639.045939 0 498.943c0-115.183242 36.995772-223.867918 106.944903-314.336142a523.825343 523.825343 0 0 1 119.276826-112.266563A533.035909 533.035909 0 0 1 376.55863 1.11192a25.584905 25.584905 0 0 1 30.036679 36.228225c-33.004527 64.320451-48.35547 125.621883-48.355471 193.012523 0 239.832899 195.110485 434.943383 434.943384 434.943383 67.39064 0 128.692072-15.350943 193.012523-48.35547a25.584905 25.584905 0 0 1 36.228225 30.036678 534.468663 534.468663 0 0 1-71.228375 150.336902 523.825343 523.825343 0 0 1-112.266563 119.276826 509.395457 509.395457 0 0 1-314.336142 106.944903zM336.18565 69.884144C163.538712 143.82452 51.16981 309.819383 51.16981 498.943 51.16981 759.90903 263.524521 972.26374 524.490551 972.26374c189.123617 0 355.11848-112.420072 429.058855-285.01584A451.98293 451.98293 0 0 1 793.132052 716.414691c-129.868977 0-251.908974-50.555772-343.707612-142.354411S307.018859 360.170475 307.018859 230.301498c0-55.109885 9.619924-108.019469 29.166791-160.417354z',\n { scale: 0.86 },\n );\n}\n/** 显示器:表示跟随系统外观 */\nfunction iconThemeAuto(): SVGElement {\n return svgTheme(\n '<path d=\"M5 5.5h10c.8 0 1.5.7 1.5 1.5v6c0 .8-.7 1.5-1.5 1.5H5c-.8 0-1.5-.7-1.5-1.5v-6c0-.8.7-1.5 1.5-1.5z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"/><path d=\"M8 16h4M10 14.2V16\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>',\n );\n}\n/** 1024 系 fill 图标,颜色随 currentColor;flipX 用于 redo 镜像;scale 用于夜间图标略缩小 */\nfunction svgPathFill(\n d: string | string[],\n opts?: { viewBox?: string; flipX?: boolean; scale?: number; fillRule?: 'evenodd' | 'nonzero' },\n): SVGElement {\n const viewBox = opts?.viewBox ?? '0 0 1024 1024';\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '18');\n el.setAttribute('height', '18');\n el.setAttribute('viewBox', viewBox);\n el.setAttribute('aria-hidden', 'true');\n const host = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n const transforms: string[] = [];\n if (opts?.scale && opts.scale !== 1) {\n const s = opts.scale;\n transforms.push(`translate(512,512) scale(${s}) translate(-512,-512)`);\n }\n if (opts?.flipX) transforms.push('translate(1024,0) scale(-1,1)');\n if (transforms.length) host.setAttribute('transform', transforms.join(' '));\n const paths = Array.isArray(d) ? d : [d];\n for (const pd of paths) {\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path.setAttribute('d', pd);\n path.setAttribute('fill', 'currentColor');\n if (opts?.fillRule) path.setAttribute('fill-rule', opts.fillRule);\n host.append(path);\n }\n el.append(host);\n return el;\n}\n\nfunction svg(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '18');\n el.setAttribute('height', '18');\n el.setAttribute('viewBox', '0 0 20 20');\n el.setAttribute('aria-hidden', 'true');\n el.innerHTML = inner;\n return el;\n}\nfunction svgTheme(inner: string): SVGElement {\n const el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n el.setAttribute('width', '18');\n el.setAttribute('height', '18');\n el.setAttribute('viewBox', '0 0 20 20');\n el.setAttribute('aria-hidden', 'true');\n el.innerHTML = inner;\n return el;\n}\n","import type { EmailDoc, Section } from '../types';\nimport { uid } from './id';\n\n/** 剪贴板 / 文件 interchange 信封标识 */\nexport const DOC_CLIPBOARD_KIND = 'simple-mail/doc' as const;\nexport const DOC_CLIPBOARD_FORMAT_VERSION = 1 as const;\n\nexport interface DocClipboardEnvelope {\n kind: typeof DOC_CLIPBOARD_KIND;\n formatVersion: typeof DOC_CLIPBOARD_FORMAT_VERSION;\n doc: EmailDoc;\n}\n\nexport function serializeDocClipboard(doc: EmailDoc): string {\n const envelope: DocClipboardEnvelope = {\n kind: DOC_CLIPBOARD_KIND,\n formatVersion: DOC_CLIPBOARD_FORMAT_VERSION,\n doc,\n };\n return JSON.stringify(envelope);\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction isEmailDocShape(v: unknown): v is EmailDoc {\n if (!isRecord(v)) return false;\n if (v.version !== '1') return false;\n if (!isRecord(v.meta)) return false;\n if (!Array.isArray(v.sections)) return false;\n for (const sec of v.sections) {\n if (!isRecord(sec) || !Array.isArray(sec.columns)) return false;\n for (const col of sec.columns) {\n if (!isRecord(col) || !Array.isArray(col.blocks)) return false;\n }\n }\n return true;\n}\n\n/**\n * 解析剪贴板或手动粘贴的 JSON。支持信封格式与裸 `EmailDoc`(version: '1')。\n */\nexport function parseDocClipboard(raw: string): EmailDoc | null {\n const trimmed = (raw || '').trim();\n if (!trimmed) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n return null;\n }\n if (!isRecord(parsed)) return null;\n\n if (parsed.kind === DOC_CLIPBOARD_KIND) {\n if (parsed.formatVersion !== DOC_CLIPBOARD_FORMAT_VERSION) return null;\n const doc = parsed.doc;\n if (!isEmailDocShape(doc)) return null;\n return structuredClone(doc);\n }\n\n if (isEmailDocShape(parsed)) {\n return structuredClone(parsed);\n }\n\n return null;\n}\n\n/** 导入前重生成 section / column / block id,避免与当前文档冲突。 */\nexport function regenerateDocIds(doc: EmailDoc): EmailDoc {\n const next = structuredClone(doc);\n next.sections = next.sections.map((sec) => remapSectionIds(sec));\n return next;\n}\n\nfunction remapSectionIds(sec: Section): Section {\n return {\n ...sec,\n id: uid('sec'),\n columns: sec.columns.map((col) => ({\n ...col,\n id: uid('col'),\n blocks: col.blocks.map((blk) => ({\n ...blk,\n id: uid('blk'),\n })),\n })),\n };\n}\n","import type { EmailDoc } from '../types';\nimport { h, clear } from '../utils/dom';\nimport { parseDocClipboard } from '../utils/docClipboard';\nimport { richTextExecCommand } from '../utils/richTextCommand';\nimport { Modal } from './Modal';\nimport type { SimpleMailT } from '../i18n';\n\nexport interface ImportDocModalOptions {\n /** 读取剪贴板初始内容(失败时返回空字符串) */\n readClipboard?: () => Promise<string>;\n onApply: (doc: EmailDoc) => void;\n t: SimpleMailT;\n}\n\n/**\n * 导入设计稿:展示 JSON 文本区,支持从剪贴板填入后覆盖当前画布。\n */\nexport class ImportDocModal {\n private modal: Modal;\n private textarea: HTMLTextAreaElement;\n private hintEl: HTMLElement;\n private opts: ImportDocModalOptions;\n\n constructor(opts: ImportDocModalOptions) {\n this.opts = opts;\n const t = opts.t;\n this.modal = new Modal({\n title: t('importDoc.title'),\n className: 'sm-modal--import-doc',\n width: 'min(720px, 96vw)',\n height: 'auto',\n t,\n });\n\n this.hintEl = h('p', { class: 'sm-import-doc__hint' }, [\n t('importDoc.hint1'),\n t('importDoc.hint2'),\n t('importDoc.hint3'),\n ]);\n\n this.textarea = h('textarea', {\n class: 'sm-import-doc__input',\n spellcheck: 'false',\n placeholder: t('importDoc.placeholder'),\n rows: '14',\n }) as HTMLTextAreaElement;\n\n this.modal.body.append(this.hintEl, this.textarea);\n\n const cancelBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => this.modal.close() },\n [t('common.cancel')],\n );\n const pasteBtn = h(\n 'button',\n { class: 'sm-btn', type: 'button', onclick: () => void this._fillFromClipboard() },\n [t('importDoc.pasteFromClipboard')],\n );\n const applyBtn = h(\n 'button',\n {\n class: 'sm-btn sm-btn--primary',\n type: 'button',\n onclick: () => this._apply(),\n },\n [t('importDoc.apply')],\n );\n this.modal.footer.append(cancelBtn, pasteBtn, applyBtn);\n }\n\n async open(parent?: HTMLElement) {\n this.hintEl.classList.remove('sm-import-doc__hint--error');\n this.textarea.value = '';\n this.modal.open(parent);\n const initial = (await this.opts.readClipboard?.()) ?? '';\n if (initial.trim()) this.textarea.value = initial;\n }\n\n private async _fillFromClipboard() {\n const text = (await this.opts.readClipboard?.()) ?? '';\n if (!text.trim()) {\n this._setHint(this.opts.t('importDoc.clipboardEmpty'), true);\n return;\n }\n this.textarea.value = text;\n this._setHint(this.opts.t('importDoc.clipboardFilled'), false);\n }\n\n private _apply() {\n const raw = this.textarea.value.trim();\n if (!raw) {\n this._setHint(this.opts.t('importDoc.empty'), true);\n return;\n }\n const doc = parseDocClipboard(raw);\n if (!doc) {\n this._setHint(this.opts.t('importDoc.invalid'), true);\n return;\n }\n this.opts.onApply(doc);\n this.modal.close();\n }\n\n private _setHint(message: string, isError: boolean) {\n clear(this.hintEl);\n this.hintEl.classList.toggle('sm-import-doc__hint--error', isError);\n this.hintEl.append(message);\n }\n}\n\nexport async function readTextFromClipboard(): Promise<string> {\n try {\n return (await navigator.clipboard.readText()) || '';\n } catch {\n return '';\n }\n}\n\nexport async function writeTextToClipboard(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n const ta = document.createElement('textarea');\n ta.value = text;\n document.body.appendChild(ta);\n ta.select();\n const ok = richTextExecCommand('copy');\n document.body.removeChild(ta);\n return ok;\n }\n}\n","import { Registry, defineBlock } from '../registry/registry';\nimport { renderDoc } from '../renderer';\nimport { Store, createSection, findBlockLocation, pruneSectionIfEmpty } from '../store/store';\nimport type {\n Block,\n BlockDefinition,\n EditorUiOptions,\n EmailDoc,\n RenderEngine,\n Selection,\n Variable,\n} from '../types';\nimport {\n buildLinkVariableHtml,\n normalizeVariable,\n variablePlaceholder,\n} from '../variables';\nimport { clear, h } from '../utils/dom';\nimport { appendInlineToRichHtml } from '../utils/richHtmlInsert';\nimport { Canvas } from './Canvas';\nimport { ExportModal } from './ExportModal';\nimport { LeftPanel } from './LeftPanel';\nimport { PreviewModal } from './PreviewModal';\nimport { RichTextToolbar } from './RichTextToolbar';\nimport { RightPanel } from './RightPanel';\nimport { SourceView } from './SourceView';\nimport { Topbar, type EditorMode } from './Topbar';\nimport type { EditorTheme } from './theme';\nimport type { ImageAssetsHandlers } from './imageAssets';\nimport { accentPrimarySoftRgba, normalizeAccentHex } from '../utils/accentColor';\nimport {\n parseDocClipboard,\n regenerateDocIds,\n serializeDocClipboard,\n} from '../utils/docClipboard';\nimport { ImportDocModal, readTextFromClipboard, writeTextToClipboard } from './ImportDocModal';\nimport {\n createI18nContext,\n type SimpleMailI18nContext,\n type SimpleMailLocale,\n type SimpleMailMessagesInput,\n type SimpleMailT,\n} from '../i18n';\n\nimport './styles.css';\n\nexport interface EditorOptions {\n /** 挂载点 */\n container: HTMLElement;\n /** 初始文档;不传时使用空文档 */\n initialDoc?: Partial<EmailDoc>;\n /** 自定义组件定义(除内置组件之外) */\n blocks?: BlockDefinition<any>[];\n /** 渲染引擎,目前仅 'mjml'。预留 'table' 切换 */\n engine?: RenderEngine;\n /**\n * 把 Block 拖到 sections 之间的空白处时,是否自动包一个一列 Section。\n * - true(默认):宽容,运营即使没瞄准列也能落下,自动加壳\n * - false:严格,只允许拖到现有列内;落到顶层会被 SortableJS 显示为禁止\n */\n autoWrapSection?: boolean;\n /**\n * 为 true 时:点击中栏灰色衬底、画布内空白(未点到 Section/块)等会提交内联编辑并清空选中,\n * 右栏回到文档级面板(邮件设置 / 版式与全局样式;若 `ui.hideMailMeta` 则仅版式与全局样式)。\n * 默认 false;需要「点空白取消选中」的宿主再设为 true。\n */\n clearSelectionOnCanvasMargin?: boolean;\n /** 文档变更回调(防抖发出) */\n onChange?: (doc: EmailDoc) => void;\n /**\n * 品牌/主题色(#RRGGBB),映射为界面上的 --sm-primary / --sm-primary-soft(强调、选区、主按钮等)。\n * 不传则使用 styles 里与 light/dark/system 配套的默认紫/靛。\n */\n accentColor?: string;\n /** 为 true 时在顶栏显示主题色拾取(原生 color 控件);默认 false,仅通过 accentColor / setAccentColor 由宿主控制也可 */\n showAccentColorPicker?: boolean;\n /**\n * 编辑器外框主题。`system` 随 `prefers-color-scheme`;邮件画布仍默认白纸以便预览成品。\n * @default 'light'\n */\n theme?: EditorTheme;\n /**\n * 可选。为 `type: 'image'` 提供上传 / 图库;`showUpload` 默认 true(有 uploadImage 时),`showGallery` 默认 false。\n */\n imageAssets?: ImageAssetsHandlers;\n /** 右栏控件形态等可选 UI 偏好。 */\n ui?: EditorUiOptions;\n /** 编辑器 UI 语言。默认 zh-CN。 */\n locale?: SimpleMailLocale;\n /** 覆盖或补充 simple-mail 内置文案。 */\n messages?: SimpleMailMessagesInput;\n /**\n * 顶栏「重置内容」恢复的目标文档(与 `initialDoc` 独立;编辑已保存邮件时仍应指向业务预置模板)。\n * 未传时与构造时的 `initialDoc` 合并结果一致。\n */\n presetDoc?: Partial<EmailDoc>;\n}\n\n/**\n * 编辑器主类。所有外部能力都通过它暴露。\n *\n * 使用示例(vanilla):\n * const editor = new MailEditor({\n * container: document.getElementById('app')!,\n * blocks: [/* 自定义组件 *\\/],\n * // imageAssets: { uploadImage, pickImageFromGallery, showGallery: true } // 可选,见 README\n * });\n * editor.setVariables([{ key: 'user.name', label: '用户名', sample: '张三' }]);\n * editor.export(); // -> { mjml, html }\n */\nexport class MailEditor {\n readonly store: Store;\n readonly registry: Registry;\n private opts: EditorOptions;\n private root: HTMLElement;\n private theme: EditorTheme;\n private mode: EditorMode = 'design';\n private topbar!: Topbar;\n private leftPanel!: LeftPanel;\n private canvas!: Canvas;\n private rightPanel!: RightPanel;\n private sourceView!: SourceView;\n private toolbar!: RichTextToolbar;\n private body: HTMLElement;\n /** 浮层(变量列表、toast),避免挂到 grid 的 .sm-root 上被挤成窄条 */\n private overlayLayer!: HTMLElement;\n /** design 态右栏变量列表:未固定时点击外部收起 */\n private variablePickerOutsideClick: ((ev: MouseEvent) => void) | null = null;\n private changeTimer: number | null = null;\n /** 显式品牌色时覆盖 CSS 变量;未设置则由 styles 按 light/dark 使用默认紫/靛 */\n private accentColorOverride: string | undefined;\n /** 顶栏开关:是否在画布上始终显示 Section / Block 轻量虚线边框 */\n private showLayoutBorders = false;\n /** 「重置内容」时恢复的文档快照(与当前画布内容无关) */\n private presetContentDoc: EmailDoc;\n /** 宿主通过 setVariables 注入的列表;setValue 恢复文档后仍会写回,避免被 doc JSON 里的空数组覆盖 */\n private configuredVariables: Variable[] = [];\n private importDocModal: ImportDocModal | null = null;\n private topbarLayoutObserver: ResizeObserver | null = null;\n private topbarLayoutRaf = 0;\n private systemThemeMq: MediaQueryList | null = null;\n private i18n: SimpleMailI18nContext;\n private readonly _onSystemThemeMqChange = () => {\n if (this.accentColorOverride) this._applyAccentVars();\n };\n\n private readonly _onFullscreenChange = () => {\n const fs = smGetFullscreenElement() === this.root;\n this.topbar?.setFullscreenActive(fs);\n this._syncTopbarLayout();\n };\n\n /** design 态 Esc:块 → 父级 Section → 文档级面板(邮件设置或版式/全局样式,取决于 `ui.hideMailMeta`) */\n private _mailEscHandler = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n if (this.rightPanel.isVariablePickerOpen()) {\n e.preventDefault();\n this._closeVariablePicker();\n return;\n }\n if (this.mode !== 'design') return;\n if (!this.store.selection) return;\n if (document.querySelector('.sm-modal__mask.is-open')) return;\n const t = e.target as HTMLElement | null;\n if (t?.closest?.('.sm-modal__mask')) return;\n const ae = document.activeElement as HTMLElement | null;\n if (ae && (ae.tagName === 'INPUT' || ae.tagName === 'TEXTAREA' || ae.isContentEditable)) return;\n if (ae && ae !== document.body && !this.root.contains(ae)) return;\n e.preventDefault();\n const sel = this.store.selection;\n if (sel.kind === 'block') {\n this.canvas.commitInlineEdit();\n this.store.setSelection({ kind: 'section', sectionId: sel.sectionId });\n return;\n }\n this._focusMailSettings();\n };\n\n /**\n * 文档级撤销/重做(捕获阶段)。\n * - 画布内联 contenteditable:交给浏览器撤销文字,不走 store。\n * - 右栏 input / CodeMirror:控件自带撤销,不走 store。\n * - 其余区域:在 store 有历史时拦截并 undo/redo 整份文档。\n */\n private _mailUndoRedoHandler = (e: KeyboardEvent) => {\n const meta = e.metaKey || e.ctrlKey;\n if (!meta) return;\n const k = e.key.toLowerCase();\n if (k !== 'z') return;\n const t = e.target as Node | null;\n if (!t || !this.root.contains(t)) return;\n if (this._shouldDeferToLocalUndoRedo(t)) return;\n const undo = !e.shiftKey;\n const redo = e.shiftKey;\n if (undo && !this.store.canUndo()) return;\n if (redo && !this.store.canRedo()) return;\n e.preventDefault();\n if (undo) this._storeUndo();\n else this._storeRedo();\n };\n\n /** 内联编辑、右栏表单等应使用控件/浏览器本地撤销,而非文档 history */\n private _shouldDeferToLocalUndoRedo(target: Node): boolean {\n const el =\n target instanceof Element ? target : (target.parentElement as Element | null);\n if (!el) return false;\n if (el.closest('.sm-inline-editing')) return true;\n if (el.closest('.cm-editor')) return true;\n const panelField = el.closest('.sm-panel--right input, .sm-panel--right textarea, .sm-panel--right select');\n if (panelField) return true;\n return false;\n }\n\n private _storeUndo() {\n if (this.canvas.isInlineEditing) this.canvas.abortInlineEdit();\n this._blurRightPanelIfFocused();\n this.store.undo();\n }\n\n private _storeRedo() {\n if (this.canvas.isInlineEditing) this.canvas.abortInlineEdit();\n this._blurRightPanelIfFocused();\n this.store.redo();\n }\n\n constructor(opts: EditorOptions) {\n this.opts = opts;\n this.i18n = createI18nContext({ locale: opts.locale, messages: opts.messages });\n this.registry = new Registry();\n\n // 注册外部 blocks\n if (opts.blocks) {\n for (const def of opts.blocks) this.registry.register(def);\n }\n\n const initialDoc = createDefaultDoc(opts.initialDoc);\n applyLocalizedDefaultMeta(initialDoc, opts.initialDoc, this.i18n.t);\n const presetSource = opts.presetDoc ?? opts.initialDoc;\n const presetContentDoc = createDefaultDoc(presetSource);\n applyLocalizedDefaultMeta(presetContentDoc, presetSource, this.i18n.t);\n this.presetContentDoc = structuredClone(presetContentDoc);\n this.store = new Store(initialDoc);\n\n const initialAccent = normalizeAccentHex(this.opts.accentColor ?? '');\n if (\n this.opts.accentColor != null &&\n String(this.opts.accentColor).trim() !== '' &&\n !initialAccent\n ) {\n console.warn('[simple-mail] accentColor 无效,已忽略:', this.opts.accentColor);\n }\n this.accentColorOverride = initialAccent ?? undefined;\n\n this.theme = opts.theme ?? 'light';\n this.root = h('div', { class: 'sm-root' });\n this._applyThemeAttr();\n this.body = h('div', { class: 'sm-body' });\n opts.container.append(this.root);\n\n this._buildUI();\n this._bindKeyboard();\n this._bindFullscreen();\n this._bindTopbarLayoutWatch();\n\n this._applyAccentVars();\n this._refreshAccentMqBinding();\n this._syncTopbarAccentPicker();\n\n this.store.subscribe(() => this._onChange());\n }\n\n /* ------------------------------ Public API ------------------------------ */\n\n setValue(doc: EmailDoc) {\n this._blurRightPanelIfFocused();\n this.store.replace(doc);\n this._applyConfiguredVariables();\n }\n\n getValue(): EmailDoc {\n return this.store.doc;\n }\n\n /**\n * 清空画布:移除所有 Section/Block,保留 meta、styles、variables。\n * 会提交内联编辑并清空选中。\n */\n clearCanvas(): void {\n this.canvas.commitInlineEdit();\n this._blurRightPanelIfFocused();\n this.store.update((d) => {\n d.sections = [];\n });\n this.store.setSelection(null);\n }\n\n /**\n * 将画布恢复为 `presetDoc` 快照(未传时等同构造时的预置合并结果)。\n * 记入撤销栈(⌘Z 可恢复);与 `setValue` 不同,不会清空 history。\n */\n resetToPreset(): void {\n this.canvas.commitInlineEdit();\n this._blurRightPanelIfFocused();\n const preset = structuredClone(this.presetContentDoc);\n const configuredVars = this.configuredVariables.length\n ? this.configuredVariables.map((v) => ({ ...v }))\n : null;\n this.store.update((d) => {\n Object.assign(d, preset);\n if (configuredVars) d.variables = configuredVars;\n });\n this.store.setSelection(null);\n }\n\n /** 更新「重置内容」的目标(例如宿主异步加载默认模板后)。 */\n setPresetDoc(partial: Partial<EmailDoc>): void {\n const presetDoc = createDefaultDoc(partial);\n applyLocalizedDefaultMeta(presetDoc, partial, this.i18n.t);\n this.presetContentDoc = structuredClone(presetDoc);\n }\n\n setVariables(vars: Variable[]) {\n this.configuredVariables = vars.map(normalizeVariable);\n this._applyConfiguredVariables();\n }\n\n getVariables(): Variable[] {\n if (this.configuredVariables.length) return this.configuredVariables;\n return this.store.doc.variables;\n }\n\n private _applyConfiguredVariables() {\n if (!this.configuredVariables.length) return;\n const snapshot = this.configuredVariables.map((v) => ({ ...v }));\n this.store.update((d) => {\n d.variables = snapshot;\n });\n }\n\n /**\n * 插入变量 key(`{{key}}`)。\n * @returns 是否成功插入\n */\n insertVariableKey(v: Variable): boolean {\n const normalized = normalizeVariable(v);\n return this._insertAtFocus(variablePlaceholder(normalized.key), false);\n }\n\n /**\n * 插入链接 / 图片变量对应元素(`<a>` / image 块等)。\n * 非 link/image 时退化为 insertVariableKey。\n */\n insertVariableElement(v: Variable): boolean {\n const normalized = normalizeVariable(v);\n if (normalized.kind === 'image') {\n return this._insertImageVariable(normalized);\n }\n if (normalized.kind === 'link') {\n const token = variablePlaceholder(normalized.key);\n if (this._tryApplyLinkVariableToken(token)) return true;\n const html = buildLinkVariableHtml(\n token,\n this.store.doc.styles.linkColor || '#ff5a00',\n );\n return this._insertAtFocus(html, true);\n }\n return this.insertVariableKey(normalized);\n }\n\n /** 同 {@link insertVariableKey} */\n insertVariable(v: Variable): boolean {\n return this.insertVariableKey(v);\n }\n\n /** 当前界面主题(`system` 不解析为 light/dark)。 */\n getTheme(): EditorTheme {\n return this.theme;\n }\n\n /** 切换界面主题;写入 `data-sm-theme`,顶栏选择器同步。 */\n setTheme(t: EditorTheme) {\n if (this.theme === t) return;\n this.theme = t;\n this._applyThemeAttr();\n this._applyAccentVars();\n this._refreshAccentMqBinding();\n this.topbar?.syncTheme(t);\n this._syncTopbarAccentPicker();\n }\n\n /**\n * 品牌/主题色(#RRGGBB)。传 null、undefined 或空字符串则恢复为 light/dark/system 下的 CSS 默认色。\n */\n setAccentColor(hex: string | null | undefined) {\n if (hex == null || String(hex).trim() === '') {\n this.accentColorOverride = undefined;\n } else {\n const n = normalizeAccentHex(String(hex));\n if (!n) {\n console.warn('[simple-mail] setAccentColor 无效,已忽略:', hex);\n return;\n }\n this.accentColorOverride = n;\n }\n this._applyAccentVars();\n this._refreshAccentMqBinding();\n this._syncTopbarAccentPicker();\n }\n\n /** 当前由选项或 setAccentColor 显式设置的品牌色;未覆盖时为 undefined。 */\n getAccentColor(): string | undefined {\n return this.accentColorOverride;\n }\n\n /** 导出 MJML 与编译后的 HTML。withSampleVariables=true 时把 {{var}} 替换为 sample 值用于预览。 */\n export(opts: { withSampleVariables?: boolean } = {}) {\n return renderDoc(this.store.doc, this.registry, {\n engine: this.opts.engine ?? 'mjml',\n withSampleVariables: opts.withSampleVariables ?? false,\n });\n }\n\n /**\n * 将当前画布设计稿(EmailDoc JSON 信封)写入剪贴板,供另一实例「导入设计稿」使用。\n */\n async copyDocDesign(): Promise<boolean> {\n this.canvas.commitInlineEdit();\n const ok = await writeTextToClipboard(serializeDocClipboard(this.store.doc));\n this._showToast(ok ? this.i18n.t('toast.copyDesignOk') : this.i18n.t('toast.copyDesignFailed'));\n return ok;\n }\n\n /** 打开导入设计稿对话框(从剪贴板或手动粘贴 JSON,覆盖当前画布)。 */\n openImportDocDesign(): void {\n this.canvas.commitInlineEdit();\n this._ensureImportDocModal();\n void this.importDocModal!.open(this.root);\n }\n\n /**\n * 程序化导入设计稿(与对话框「应用」相同逻辑)。\n * @returns 是否成功解析并应用\n */\n importDocDesignFromJson(raw: string): boolean {\n const parsed = parseDocClipboard(raw);\n if (!parsed) return false;\n this._applyImportedDoc(parsed);\n return true;\n }\n\n registerBlock<P extends object>(def: BlockDefinition<P>) {\n this.registry.register(def);\n this.leftPanel?.refresh();\n }\n\n setSelection(sel: Selection | null) {\n this.store.setSelection(sel);\n }\n\n destroy() {\n this._closeVariablePicker();\n this._unbindFullscreen();\n this._unbindTopbarLayoutWatch();\n this._unbindSystemThemeMqForAccent();\n if (this.changeTimer) window.clearTimeout(this.changeTimer);\n if (smGetFullscreenElement() === this.root) void smExitFullscreen();\n document.removeEventListener('keydown', this._mailEscHandler, true);\n document.removeEventListener('keydown', this._mailUndoRedoHandler, true);\n this.canvas?.destroy?.();\n this.sourceView?.destroy?.();\n this.toolbar?.destroy?.();\n this.root.remove();\n }\n\n /* -------------------------------- 私有 ---------------------------------- */\n\n private _applyThemeAttr() {\n this.root.setAttribute('data-sm-theme', this.theme);\n }\n\n private _chromeIsEffectivelyDark(): boolean {\n if (this.theme === 'dark') return true;\n if (this.theme === 'light') return false;\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n private _applyAccentVars() {\n if (!this.accentColorOverride) {\n this.root.style.removeProperty('--sm-primary');\n this.root.style.removeProperty('--sm-primary-soft');\n return;\n }\n const dark = this._chromeIsEffectivelyDark();\n this.root.style.setProperty('--sm-primary', this.accentColorOverride);\n this.root.style.setProperty('--sm-primary-soft', accentPrimarySoftRgba(this.accentColorOverride, dark));\n }\n\n private _unbindSystemThemeMqForAccent() {\n if (this.systemThemeMq) {\n this.systemThemeMq.removeEventListener('change', this._onSystemThemeMqChange);\n this.systemThemeMq = null;\n }\n }\n\n /** `system` 主题且存在品牌色覆盖时,随系统深浅刷新 --sm-primary-soft */\n private _refreshAccentMqBinding() {\n this._unbindSystemThemeMqForAccent();\n if (this.theme === 'system' && this.accentColorOverride) {\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n mq.addEventListener('change', this._onSystemThemeMqChange);\n this.systemThemeMq = mq;\n }\n }\n\n private _syncTopbarAccentPicker() {\n this.topbar?.syncAccentPicker();\n }\n\n private _buildUI() {\n this.topbar = new Topbar({\n store: this.store,\n t: this.i18n.t,\n mode: this.mode,\n theme: this.theme,\n accentPickerRoot: this.root,\n showAccentColorPicker: this.opts.showAccentColorPicker === true,\n onAccentChange: (hx) => this.setAccentColor(hx),\n onThemeChange: (t) => this.setTheme(t),\n onModeChange: (m) => this._setMode(m),\n onUndo: () => {\n this._storeUndo();\n },\n onRedo: () => {\n this._storeRedo();\n },\n onMailSettings: () => this._focusMailSettings(),\n showMailSettingsButton: this.opts.ui?.hideTopbarMailSettings !== true,\n showTitle: this.opts.ui?.hideTopbarTitle !== true,\n showInsertVariableButton: this.opts.ui?.hideTopbarInsertVariable !== true,\n onInsertVariable: (anchor) => this._toggleVariablePanel(anchor),\n onPreview: () => this._showPreview(),\n onExport: () => this._showExport(),\n showFullscreenButton: this.opts.ui?.hideTopbarFullscreen !== true,\n onFullscreenToggle: () => void this._toggleFullscreen(),\n onLayoutBordersToggle: () => this._toggleLayoutBorders(),\n showClearCanvasButton: this.opts.ui?.hideTopbarClearCanvas !== true,\n onClearCanvas: () => this.clearCanvas(),\n showResetContentButton: this.opts.ui?.hideTopbarResetContent !== true,\n onResetContent: () => this.resetToPreset(),\n showDocClipboardButtons: this.opts.ui?.hideTopbarDocClipboard !== true,\n onCopyDocDesign: () => void this.copyDocDesign(),\n onImportDocDesign: () => this.openImportDocDesign(),\n compact: !topbarPrefersLabels(this.opts.ui, this._topbarLayoutContext()),\n });\n\n this.toolbar = new RichTextToolbar({ positionRoot: this.root, t: this.i18n.t });\n const ui = this.opts.ui;\n this.leftPanel = new LeftPanel({\n registry: this.registry,\n t: this.i18n.t,\n blockGroupTitle:\n ui?.paletteBlockGroupTitle ?? ui?.blockCategoryLabels?.content,\n customPaletteTooltipSuffix: ui?.customPaletteTooltipSuffix,\n hiddenPaletteBlockTypes: ui?.hiddenPaletteBlockTypes,\n });\n const autoWrap = this.opts.autoWrapSection !== false;\n this.root.classList.toggle('sm-allow-auto-wrap', autoWrap);\n this.canvas = new Canvas({\n store: this.store,\n registry: this.registry,\n toolbar: this.toolbar,\n autoWrapSection: autoWrap,\n clearSelectionOnCanvasMargin: this.opts.clearSelectionOnCanvasMargin === true,\n layerRoot: this.root,\n ui: this.opts.ui,\n t: this.i18n.t,\n });\n this.rightPanel = new RightPanel({\n store: this.store,\n registry: this.registry,\n docRootLabel: this.opts.ui?.hideMailMeta\n ? this.i18n.t('rightPanel.docRoot.layout')\n : this.i18n.t('rightPanel.docRoot.mail'),\n onFocusSection: (sectionId) => {\n this.canvas.commitInlineEdit();\n this.store.setSelection({ kind: 'section', sectionId });\n },\n onFocusDocument: () => this._focusMailSettings(),\n imageAssets: this.opts.imageAssets,\n ui: this.opts.ui,\n t: this.i18n.t,\n });\n this.sourceView = new SourceView({\n store: this.store,\n registry: this.registry,\n t: this.i18n.t,\n });\n\n this.body.append(this.leftPanel.el, this.canvas.el, this.rightPanel.el);\n this.overlayLayer = h('div', { class: 'sm-overlay-layer' });\n this.root.append(this.topbar.el, this.body, this.overlayLayer);\n }\n\n /** 撤销/替换文档前先失焦右栏,否则 RightPanel 会因「保留焦点」跳过重绘而仍显示旧值 */\n private _blurRightPanelIfFocused() {\n const ae = document.activeElement as HTMLElement | null;\n if (ae && this.rightPanel.el.contains(ae)) ae.blur();\n }\n\n /** 提交内联编辑并清空选中,右栏回到文档级面板 */\n private _focusMailSettings() {\n this._closeVariablePicker();\n this.canvas.commitInlineEdit();\n this.store.setSelection(null);\n }\n\n private _setMode(m: EditorMode) {\n if (this.mode === m) return;\n this._closeVariablePicker();\n this._dismissVariablePopover();\n if (m !== 'design') this.canvas.commitInlineEdit();\n this.mode = m;\n this.topbar.setMode(m);\n clear(this.body);\n if (m === 'design') {\n this.body.classList.remove('sm-body--source');\n this.body.style.removeProperty('grid-template-columns');\n this.body.append(this.leftPanel.el, this.canvas.el, this.rightPanel.el);\n } else {\n this.body.classList.add('sm-body--source');\n this.body.style.removeProperty('grid-template-columns');\n this.body.append(this.sourceView.el);\n // 见 SourceView.refreshDoc:设计态源码面板未挂载时不更新,否则会一直显示构造函数时的旧快照\n queueMicrotask(() => this.sourceView.refreshDoc());\n }\n }\n\n private _bindKeyboard() {\n this.root.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' || e.key === 'Backspace') {\n const tag = (e.target as HTMLElement).tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || (e.target as HTMLElement).isContentEditable) {\n return;\n }\n const sel = this.store.selection;\n if (!sel) return;\n e.preventDefault();\n if (sel.kind === 'section') {\n this.store.update((d) => {\n d.sections = d.sections.filter((s) => s.id !== sel.sectionId);\n });\n this.store.setSelection(null);\n } else {\n this.store.update((d) => {\n const sec = d.sections.find((s) => s.id === sel.sectionId);\n if (!sec) return;\n const col = sec.columns[sel.columnIndex];\n if (!col) return;\n col.blocks = col.blocks.filter((b) => b.id !== sel.blockId);\n pruneSectionIfEmpty(d, sel.sectionId);\n });\n this.store.setSelection(null);\n }\n }\n });\n document.addEventListener('keydown', this._mailUndoRedoHandler, true);\n document.addEventListener('keydown', this._mailEscHandler, true);\n this.root.tabIndex = 0;\n }\n\n private _onChange() {\n if (!this.opts.onChange) return;\n if (this.changeTimer) window.clearTimeout(this.changeTimer);\n this.changeTimer = window.setTimeout(() => {\n this.opts.onChange?.(this.store.doc);\n this.changeTimer = null;\n }, 60) as unknown as number;\n }\n\n private _unbindVariablePickerOutsideClick() {\n if (!this.variablePickerOutsideClick) return;\n document.removeEventListener('click', this.variablePickerOutsideClick, true);\n this.variablePickerOutsideClick = null;\n }\n\n private _bindVariablePickerOutsideClick(anchor: HTMLElement) {\n this._unbindVariablePickerOutsideClick();\n const handler = (ev: MouseEvent) => {\n if (!this.rightPanel.isVariablePickerOpen() || this.rightPanel.isVariablePickerPinned()) return;\n const target = ev.target as Node;\n if (this.rightPanel.el.contains(target)) return;\n if (anchor.contains(target) || target === anchor) return;\n this._closeVariablePicker();\n };\n this.variablePickerOutsideClick = handler;\n setTimeout(() => {\n if (this.variablePickerOutsideClick === handler) {\n document.addEventListener('click', handler, true);\n }\n }, 0);\n }\n\n private _closeVariablePicker() {\n this._unbindVariablePickerOutsideClick();\n if (!this.rightPanel.isVariablePickerOpen()) return;\n this.rightPanel.closeVariablePicker();\n this.topbar.setInsertVariableActive(false);\n }\n\n private _toggleVariablePanel(anchor: HTMLElement) {\n this.canvas.currentInlineEditor?.saveSelection();\n\n const vars = this.getVariables();\n if (!vars.length) {\n this._showToast(this.i18n.t('toast.noVariables'));\n return;\n }\n\n if (this.mode === 'design') {\n if (this.rightPanel.isVariablePickerOpen()) {\n this._closeVariablePicker();\n return;\n }\n this._dismissVariablePopover();\n this._blurRightPanelIfFocused();\n this.rightPanel.openVariablePicker(vars, {\n onPickKey: (v) => {\n this.insertVariableKey(v);\n if (!this.rightPanel.isVariablePickerPinned()) this._closeVariablePicker();\n },\n onPickElement: (v) => {\n this.insertVariableElement(v);\n if (!this.rightPanel.isVariablePickerPinned()) this._closeVariablePicker();\n },\n onCopy: (token) => {\n void copyVariableToken(token).then((ok) => {\n if (!ok) return;\n this._showToast(this.i18n.t('toast.variableCopied'));\n });\n },\n onClose: () => this._closeVariablePicker(),\n });\n this._bindVariablePickerOutsideClick(anchor);\n this.topbar.setInsertVariableActive(true);\n return;\n }\n\n this._toggleVariablePopover(anchor, vars);\n }\n\n private _dismissVariablePopover() {\n this.overlayLayer.querySelector('.sm-popover')?.remove();\n }\n\n /** 源码模式无右栏时仍用浮层选择变量 */\n private _toggleVariablePopover(anchor: HTMLElement, vars: Variable[]) {\n const existing = this.overlayLayer.querySelector('.sm-popover');\n if (existing) {\n existing.remove();\n this.topbar.setInsertVariableActive(false);\n return;\n }\n\n const pop = h('div', { class: 'sm-popover sm-popover--variables' });\n let onDocClick: ((ev: MouseEvent) => void) | null = null;\n const dismissPopover = () => {\n pop.remove();\n if (onDocClick) document.removeEventListener('click', onDocClick, true);\n this.topbar.setInsertVariableActive(false);\n };\n\n for (const v of vars) {\n const token = variablePlaceholder(v.key);\n const row = h('div', { class: 'sm-popover__row' });\n const actions = h('div', { class: 'sm-popover__actions' });\n if (v.kind === 'link' || v.kind === 'image') {\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action',\n type: 'button',\n onclick: (e: Event) => {\n e.stopPropagation();\n this.insertVariableElement(v);\n dismissPopover();\n },\n },\n [this.i18n.t('variablePicker.insertElement')],\n ),\n );\n }\n actions.append(\n h(\n 'button',\n {\n class: 'sm-popover__action sm-popover__action--copy',\n type: 'button',\n title: this.i18n.t('variablePicker.copyTitle', { token }),\n onclick: (e: Event) => {\n e.stopPropagation();\n void copyVariableToken(token).then((ok) => {\n if (!ok) return;\n dismissPopover();\n this._showToast(this.i18n.t('toast.variableCopied'));\n });\n },\n },\n [this.i18n.t('common.copy')],\n ),\n );\n row.append(\n h(\n 'button',\n {\n class: 'sm-popover__item',\n type: 'button',\n onclick: () => {\n this.insertVariableKey(v);\n dismissPopover();\n },\n },\n [\n h('span', { class: 'sm-popover__label' }, [v.label]),\n h('span', { class: 'sm-popover__key' }, [token]),\n ],\n ),\n actions,\n );\n pop.append(row);\n }\n\n this.overlayLayer.append(pop);\n positionAnchoredLayer(pop, anchor, this.root);\n\n onDocClick = (ev: MouseEvent) => {\n if (!pop.contains(ev.target as Node) && ev.target !== anchor) {\n dismissPopover();\n }\n };\n setTimeout(() => {\n if (onDocClick) document.addEventListener('click', onDocClick, true);\n }, 0);\n this.topbar.setInsertVariableActive(true);\n }\n\n private _showToast(text: string) {\n const t = h('div', { class: 'sm-toast' }, [text]);\n this.overlayLayer.append(t);\n requestAnimationFrame(() => t.classList.add('is-visible'));\n setTimeout(() => {\n t.classList.remove('is-visible');\n setTimeout(() => t.remove(), 200);\n }, 1400);\n }\n\n private _insertImageVariable(v: Variable): boolean {\n const token = variablePlaceholder(v.key);\n const block = this.registry.createBlock('image');\n const props = block.props as { src: string; alt: string };\n props.src = token;\n props.alt = v.label?.trim() || v.key;\n const sel = this.store.selection;\n this.store.update((d) => {\n this._insertBlockRelativeToSelection(d, sel, block);\n });\n return true;\n }\n\n /**\n * 按当前选中插入块:block → 其后;section → 该 section 首列末尾;无选中 → 文档最后一节首列末尾。\n */\n private _insertBlockRelativeToSelection(\n d: EmailDoc,\n sel: Selection | null,\n block: Block,\n ): void {\n if (sel?.kind === 'block') {\n const sec = d.sections.find((s) => s.id === sel.sectionId);\n const col = sec?.columns[sel.columnIndex];\n if (col) {\n const idx = col.blocks.findIndex((b) => b.id === sel.blockId);\n col.blocks.splice(idx >= 0 ? idx + 1 : col.blocks.length, 0, block);\n return;\n }\n }\n if (sel?.kind === 'section') {\n const sec = d.sections.find((s) => s.id === sel.sectionId);\n sec?.columns[0]?.blocks.push(block);\n return;\n }\n let section = d.sections[d.sections.length - 1];\n if (!section) {\n section = createSection('1');\n d.sections.push(section);\n }\n section.columns[0]?.blocks.push(block);\n }\n\n /** 链接变量:写入图片/按钮等块的 `href`(MJML 可点击),而非 alt 或右栏纯文本。 */\n private _tryApplyLinkVariableToken(token: string): boolean {\n const active = document.activeElement as HTMLInputElement | HTMLTextAreaElement | null;\n if (\n active &&\n (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA') &&\n this.root.contains(active)\n ) {\n const focusToken = active.getAttribute('data-sm-focus');\n if (focusToken?.startsWith('block:')) {\n const parts = focusToken.split(':');\n const blockId = parts[1];\n const propKey = parts[2];\n if (blockId && propKey && this._setBlockUrlProp(blockId, propKey, token)) {\n active.value = token;\n active.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n }\n }\n\n const sel = this.store.selection;\n if (sel?.kind !== 'block') return false;\n const loc = findBlockLocation(this.store.doc, sel.blockId);\n if (!loc) return false;\n const urlKey = this._schemaUrlPropKey(this.registry.get(loc.block.type));\n if (!urlKey) return false;\n this.store.update((d) => {\n const l = findBlockLocation(d, sel.blockId);\n if (l) (l.block.props as Record<string, unknown>)[urlKey] = token;\n });\n return true;\n }\n\n private _schemaUrlPropKey(def: BlockDefinition | undefined): string | undefined {\n return def?.schema.find((f) => f.type === 'url')?.key;\n }\n\n private _setBlockUrlProp(blockId: string, propKey: string, token: string): boolean {\n const loc = findBlockLocation(this.store.doc, blockId);\n if (!loc) return false;\n const field = this.registry.get(loc.block.type)?.schema.find((f) => f.key === propKey);\n if (field?.type !== 'url') return false;\n this.store.update((d) => {\n const l = findBlockLocation(d, blockId);\n if (l) (l.block.props as Record<string, unknown>)[propKey] = token;\n });\n return true;\n }\n\n /** 在焦点处插入文本或 HTML;失败时返回 false */\n private _insertAtFocus(content: string, asHtml: boolean): boolean {\n const inline = this.canvas.currentInlineEditor;\n if (inline) {\n if (asHtml) inline.insertHtml(content);\n else inline.insertText(content);\n return true;\n }\n\n const active = document.activeElement as HTMLInputElement | HTMLTextAreaElement | null;\n if (\n active &&\n (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA') &&\n this.root.contains(active)\n ) {\n if (asHtml) {\n const focusToken = active.getAttribute('data-sm-focus');\n if (focusToken?.startsWith('block:')) {\n const parts = focusToken.split(':');\n const blockId = parts[1];\n const propKey = parts[2];\n if (blockId && propKey) {\n const m = content.match(/\\{\\{[^}]+\\}\\}/);\n const token = m?.[0] ?? content;\n if (this._setBlockUrlProp(blockId, propKey, token)) {\n active.value = token;\n active.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n }\n }\n /* 链接 HTML 不写入 alt 等右栏文本框,落到下方新建文本块 */\n } else {\n const start = active.selectionStart ?? active.value.length;\n const end = active.selectionEnd ?? active.value.length;\n active.value = active.value.slice(0, start) + content + active.value.slice(end);\n active.dispatchEvent(new Event('input', { bubbles: true }));\n return true;\n }\n }\n\n const sel = this.store.selection;\n if (sel?.kind === 'block') {\n let updated = false;\n this.store.update((d) => {\n for (const s of d.sections) {\n for (const c of s.columns) {\n const b = c.blocks.find((x) => x.id === sel.blockId);\n if (!b) continue;\n const def = this.registry.get(b.type);\n const key = def?.inlineEditable?.propKey;\n if (!key) continue;\n const cur = String((b.props as Record<string, unknown>)[key] ?? '');\n const richInline = def.inlineEditable!.mode !== 'plain';\n (b.props as Record<string, unknown>)[key] = richInline\n ? appendInlineToRichHtml(cur, content)\n : cur + content;\n updated = true;\n }\n }\n });\n if (updated) return true;\n }\n\n const block = this.registry.createBlock('text');\n const wrapped = appendInlineToRichHtml('', content);\n (block.props as { content: string }).content = wrapped;\n this.store.update((d) => {\n this._insertBlockRelativeToSelection(d, sel, block);\n });\n return true;\n }\n\n private _ensureImportDocModal() {\n if (this.importDocModal) return;\n this.importDocModal = new ImportDocModal({\n readClipboard: readTextFromClipboard,\n onApply: (doc) => this._applyImportedDoc(doc),\n t: this.i18n.t,\n });\n }\n\n private _applyImportedDoc(source: EmailDoc) {\n const current = this.store.doc;\n let next = regenerateDocIds(source);\n if (this.opts.ui?.hideMailMeta) {\n next = {\n ...next,\n meta: { ...current.meta },\n };\n }\n this.setValue(next);\n this.store.setSelection(null);\n this._showToast(this.i18n.t('toast.importDesignOk'));\n }\n\n private _showExport() {\n // 切回设计模式时如果还在内联编辑,先把内容提交进 store\n this.canvas.commitInlineEdit();\n const modal = new ExportModal({\n store: this.store,\n registry: this.registry,\n t: this.i18n.t,\n withSampleVariables: false,\n });\n modal.open(this.root);\n }\n\n private _showPreview() {\n this.canvas.commitInlineEdit();\n const modal = new PreviewModal({\n store: this.store,\n registry: this.registry,\n t: this.i18n.t,\n });\n modal.open(this.root);\n }\n\n private _topbarLayoutContext(): TopbarLayoutContext {\n return {\n fullscreenOnRoot: smGetFullscreenElement() === this.root,\n rootWidth: this.root.clientWidth,\n };\n }\n\n private _syncTopbarLayout() {\n const bar = this.topbar;\n if (!bar) return;\n const ctx = this._topbarLayoutContext();\n if (!topbarPrefersLabels(this.opts.ui, ctx)) {\n bar.setCompact(true);\n return;\n }\n // 在同一帧内展开并测量溢出,避免先展示文案、下一帧再收起的闪烁\n bar.setCompact(false);\n const el = bar.el;\n if (el.scrollWidth > el.clientWidth + 2) bar.setCompact(true);\n }\n\n private _bindTopbarLayoutWatch() {\n if (this.opts.ui?.topbarCompact !== true) return;\n this._syncTopbarLayout();\n this.topbarLayoutObserver = new ResizeObserver(() => {\n if (this.topbarLayoutRaf) cancelAnimationFrame(this.topbarLayoutRaf);\n this.topbarLayoutRaf = requestAnimationFrame(() => {\n this.topbarLayoutRaf = 0;\n this._syncTopbarLayout();\n });\n });\n this.topbarLayoutObserver.observe(this.root);\n }\n\n private _unbindTopbarLayoutWatch() {\n this.topbarLayoutObserver?.disconnect();\n this.topbarLayoutObserver = null;\n if (this.topbarLayoutRaf) {\n cancelAnimationFrame(this.topbarLayoutRaf);\n this.topbarLayoutRaf = 0;\n }\n }\n\n private _bindFullscreen() {\n if (this.opts.ui?.hideTopbarFullscreen === true) return;\n document.addEventListener('fullscreenchange', this._onFullscreenChange);\n document.addEventListener('webkitfullscreenchange', this._onFullscreenChange);\n this._onFullscreenChange();\n }\n\n private _unbindFullscreen() {\n document.removeEventListener('fullscreenchange', this._onFullscreenChange);\n document.removeEventListener('webkitfullscreenchange', this._onFullscreenChange);\n }\n\n private async _toggleFullscreen() {\n try {\n if (smGetFullscreenElement() === this.root) await smExitFullscreen();\n else await smRequestFullscreen(this.root);\n } catch (err) {\n console.warn('[simple-mail] 全屏不可用:', err);\n }\n }\n\n private _toggleLayoutBorders() {\n this.showLayoutBorders = !this.showLayoutBorders;\n this.root.classList.toggle('sm-show-layout-borders', this.showLayoutBorders);\n this.topbar.setLayoutBordersActive(this.showLayoutBorders);\n }\n}\n\n/** 在 .sm-root 坐标系下定位浮层,靠右的锚点右对齐,并限制在根节点内 */\nfunction positionAnchoredLayer(layer: HTMLElement, anchor: HTMLElement, root: HTMLElement) {\n const rect = anchor.getBoundingClientRect();\n const rootRect = root.getBoundingClientRect();\n const gap = 4;\n const margin = 8;\n layer.style.top = `${rect.bottom - rootRect.top + gap}px`;\n const w = layer.offsetWidth;\n let left = rect.left - rootRect.left;\n const anchorMid = rect.left + rect.width * 0.5;\n const rootMid = rootRect.left + rootRect.width * 0.5;\n if (anchorMid >= rootMid) {\n left = rect.right - rootRect.left - w;\n }\n left = Math.max(margin, Math.min(left, rootRect.width - w - margin));\n layer.style.left = `${left}px`;\n}\n\nexport const DEFAULT_TOPBAR_COMPACT_MIN_WIDTH = 1200;\n\nexport interface TopbarLayoutContext {\n fullscreenOnRoot: boolean;\n rootWidth: number;\n}\n\n/** 顶栏是否应展示按钮文案(紧凑模式下的策略;非 compact 配置恒为 true) */\nexport function topbarPrefersLabels(\n ui: EditorUiOptions | undefined,\n ctx: TopbarLayoutContext,\n): boolean {\n if (ui?.topbarCompact !== true) return true;\n const labels = ui.topbarLabels ?? 'auto';\n if (labels === 'always') return true;\n if (labels === 'never') return false;\n const minW = ui.topbarCompactMinWidth ?? DEFAULT_TOPBAR_COMPACT_MIN_WIDTH;\n return ctx.fullscreenOnRoot || ctx.rootWidth >= minW;\n}\n\nasync function copyVariableToken(token: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(token);\n return true;\n } catch {\n // fallback\n }\n try {\n const ta = document.createElement('textarea');\n ta.value = token;\n ta.setAttribute('readonly', 'true');\n ta.style.position = 'fixed';\n ta.style.left = '-9999px';\n document.body.appendChild(ta);\n ta.select();\n const ok = document.execCommand('copy');\n document.body.removeChild(ta);\n return ok;\n } catch {\n return false;\n }\n}\n\nfunction smGetFullscreenElement(): Element | null {\n const d = document as Document & { webkitFullscreenElement?: Element | null };\n return document.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n}\n\nasync function smRequestFullscreen(el: HTMLElement): Promise<void> {\n const anyEl = el as HTMLElement & { webkitRequestFullscreen?: () => Promise<void> | void };\n if (typeof anyEl.requestFullscreen === 'function') await anyEl.requestFullscreen();\n else if (typeof anyEl.webkitRequestFullscreen === 'function') await anyEl.webkitRequestFullscreen();\n}\n\nasync function smExitFullscreen(): Promise<void> {\n const d = document as Document & { webkitExitFullscreen?: () => Promise<void> | void };\n if (typeof document.exitFullscreen === 'function') await document.exitFullscreen();\n else if (typeof d.webkitExitFullscreen === 'function') await d.webkitExitFullscreen();\n}\n\n/* ----------------------------- 默认空文档 ------------------------------- */\n\nfunction applyLocalizedDefaultMeta(\n doc: EmailDoc,\n source: Partial<EmailDoc> | undefined,\n t: SimpleMailT,\n): void {\n if (source?.meta?.subject == null) doc.meta.subject = t('doc.defaultSubject');\n}\n\nfunction createDefaultDoc(partial?: Partial<EmailDoc>): EmailDoc {\n const mergedStyles = {\n backgroundColor: '#ffffff',\n contentBackgroundColor: '#ffffff',\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"PingFang SC\", \"Microsoft YaHei\", sans-serif',\n fontSize: '16px',\n fontWeight: '400',\n color: '#433f3f',\n linkColor: '#ff5a00',\n lineHeight: '1.25',\n ...(partial?.styles ?? {}),\n };\n return {\n version: '1',\n meta: {\n subject: '一封新邮件',\n preheader: '',\n width: 600,\n ...(partial?.meta ?? {}),\n },\n variables: partial?.variables ?? [],\n styles: {\n ...mergedStyles,\n fontWeight: mergedStyles.fontWeight ?? '400',\n lineHeight: mergedStyles.lineHeight ?? '1.25',\n },\n sections: partial?.sections ?? [],\n };\n}\n\nexport { defineBlock };\n"],"names":["Registry","__publicField","def","type","category","d","cryptoRandomId","ts","rand","defineBlock","DYNAMIC_VARIANT_HTML_ATTR","getSectionDynamicVariantKey","section","isDynamicVariantSection","dynamicVariantPlaceholder","key","sectionMjClassName","sectionId","serializeParsedHtml","doc","head","_a","body","_b","annotateDynamicVariantHtmlAttributes","html","slots","parsed","cls","candidates","target","el","LIST_GAP_ATTR","findListItem","node","root","findListRoot","li","parent","isIgnorableListSeparator","clone","br","findPreviousListOfSameType","list","findNextListOfSameType","mergeListInto","source","next","mergeAdjacentSameTypeLists","merged","prev","isLiEffectivelyEmpty","isCaretAtLiStart","range","probe","fragmentHasSubstantiveText","frag","box","isCaretAtLiEnd","after","placeCaretInElement","atStart","sel","placeCaretAtEndOfElement","visibleTextLength","text","getCaretTextOffset","container","setCaretByTextOffset","offset","walker","remaining","textNode","data","len","count","nodeOffset","i","getElementVisibleTextLength","CARET_MARKER_ATTR","RANGE_START_MARKER_ATTR","insertBoundaryMarker","attr","marker","insertSelectionBoundaryMarkers","startRange","endRange","removeSelectionBoundaryMarkers","m","getCaretTextOffsetAtRangeEnd","atEnd","restoreCaretMarker","normalizeSelectionSpan","start","end","listInSelectionSpan","anchor","far","afterAnchor","beforeFar","lastListInDocumentOrder","lists","best","placeCaretAtEndOfList","items","c","lastLi","restoreCaretToEndOfListInSelectionBounds","matched","restoreCaretAfterListMutation","fallbackOffset","ensureLiHasPlaceholder","exitListFromEmptyItem","index","afterItems","p","newList","item","splitListItemOnEnter","newLi","tailRange","tailProbe","fragment","mergeListItemOnBackspace","prevInList","prevList","prevLi","junctionOffset","prevLiEl","mergeNextListItemOnDelete","nextInList","nextLi","nextList","nextLiEl","rangeIntersectsNode","nodeRange","sortByDocumentOrder","nodes","a","b","pos","getListItemsInRange","copyListElementAttributes","from","to","indentAttr","style","appendListWithItems","tag","appendUnwrappedItems","replaceListWithSegments","before","middle","middleMode","origTag","applyListTypeToWholeList","wantUl","inUl","convertListTag","applyListCommandForSelection","affectedItems","byList","group","selected","allItems","selectedSet","toggleOff","indices","firstIdx","lastIdx","unwrapList","child","detectListFormats","LIST_INDENT_ATTR","LIST_INDENT_DEFAULT_PX","LIST_INDENT_SLIDER_MAX","LIST_INDENT_PRESETS_PX","normalizeGlobalListIndentStorage","px","n","clampListIndent","LIST_STYLE_KEYS","LI_STYLE_KEYS","parsePaddingLeftPx","raw","s","readStyleProp","styleAttr","prop","re","mergeInlineStyle","patch","managedKeys","map","part","idx","val","k","v","stripManagedListStyles","listMarkerType","applyExplicitListInline","paddingLeftPx","getListIndent","setListIndent","value","findListAtSelection","resolveExportPaddingPx","globalDefaultPx","explicit","resolveGlobalListIndentPx","styles","globalListIndentCssVarValue","normalizeEmailListsInHtml","src","serialized","doctype","coerceCssWidth","docContentWidthCss","parseMetaWidthFromUserInput","input","metaWidthInputString","blockButtonWidthCss","parseSectionWidthFromUserInput","sectionWidthInputString","h","attrs","children","clear","escapeHtml","escapeAttr","FONT_WEIGHT_STEP_VALUES","FONT_WEIGHT_STEP_OPTIONS","normalizeFontWeightStep","match","steps","bestD","st","mjRawCellTypographyFromStyles","cssForDoubleQuotedAttr","buildMjRawTdStyle","paddingCss","typo","fontSize","lineHeight","color","fontFamily","fontWeight","mjRawEmailTableWrap","cellInnerHtml","wrapLockedMjmlForMjColumn","lead","t","normalizeHtmlBlockLockedMjmlForCompile","mj","inner","divStrip","htmlContainsMjmlTags","extractHtmlUntilMatchingCloseTag","contentStart","tagName","openRe","closeRe","depth","nextOpen","nextClose","extractOutermostTableInner","open","innerFromPresentationTable","trimmed","tableInner","tdOpen","extractPreviewHtmlFromLockedMjml","lockedMjml","mjText","mjButton","label","mjRaw","tdInner","defaultPaddingForLockedBlock","_blockType","_lockedMjml","props","resolveLockedMjmlCanvasContent","padding","previewInner","pad","docToMjml","registry","ctx","sections","sectionToMjml","sectionWidthConstraintCss","columnGapMobileCss","w","COLUMN_GAP_MOBILE_BREAKPOINT","columnGapClassName","columnStackedGapClassName","stacksOnMobile","lines","gap","stackedGap","bg","secW","dvKey","secCls","widths","layoutWidths","gapPx","stacked","hCls","vCls","lastIndex","columns","col","columnToMjml","grouped","indent","column","width","columnIndex","columnCount","columnGapPx","gapClassNames","va","gapPad","half","pl","clsAttr","rawTypo","blocks","layout","parts","total","x","l","renderDoc","opts","engine","mjml","compiled","mjmlCompile","replaceVariables","e","vars","_counter","uid","prefix","Store","initial","fn","mutator","draft","detail","findSection","findBlockLocation","blockId","blk","pruneSectionIfEmpty","sec","pruneEmptySections","MULTI_COLUMN_LAYOUTS","TWO_COLUMN_LAYOUTS","isMultiColumnLayout","isTwoColumnLayout","setSectionLayout","nextCols","curCols","removed","last","createSection","colCount","tokenToVariableKey","token","variablePlaceholder","defaultVariableSample","normalizeVariable","kind","buildLinkVariableHtml","linkColor","safeHref","safeText","buildBodyVariableKeyInsert","normalized","buildBodyVariableElementInsert","options","alt","buildBodyVariableInsert","appendInlineToRichHtml","insert","blockClose","renderSectionBodyHtml","mini","replaceVariantMarkerInHtml","variantHtml","extractDynamicVariantSlots","resultHtml","variants","fromMarker","snippet","LAYOUT_LABELS","layoutHumanLabel","prettyHtml","VOID","PRESERVE","tokens","preserveStack","out","tok","inPreserve","selfClosing","txt","DEFAULT_MAX_WIDTH_RATIO","DEFAULT_MAX_HEIGHT_RATIO","getCodeEditorModalDefaultSize","getCodeEditorModalMaximizedSize","maxWidthRatio","maxHeightRatio","Modal","title","height","tools","closeBtn","_d","_c","iconClose","MAXIMIZED_PREF_KEY","BlockCodeModal","defaultSize","iconMaximize","beautifyBtn","saveBtn","componentLabel","loc","block","readMaximizedPref","EditorView","EditorState","basicSetup","cmHtml","size","writeMaximizedPref","iconRestore","id","maximized","asRichTextDoc","richTextExecCommand","commandId","showUI","richTextQueryCommandState","richTextQueryCommandValue","isRichHtmlEditorSeedOnly","hasRichHtmlLineBreak","tpl","getRichHtmlPlainText","isRichHtmlEffectivelyEmpty","normalizeRichHtmlForCommit","normalizeAccentHex","rgbCssToHex","rgb","accentPrimarySoftRgba","primaryHex","isDarkChrome","hex","r","g","zhCNMessages","enUSMessages","FALLBACK_LOCALE","createI18nContext","locale","messages","params","name","COLOR_PICKER_PALETTE","activeTeardown","isColorPickerOpen","closeActiveColorPicker","positionLayer","layer","layerRoot","rect","rootRect","popRect","guardInlineEditFocus","syncNativeInput","native","openColorPickerPopover","initialHex","closed","panel","hexInput","applyDraft","commit","teardown","onKey","onDoc","swatchGrid","btn","ke","footKids","ev","bindColorPickerInput","pick","InlineEditor","sanitized","sanitizeRichHtml","restore","off","command","hiliteAnchor","selectionAnchorKey","isListCmd","itemsInRange","savedOffset","boundaryMarkers","applyListIndentToElement","url","safe","findAncestorAnchor","pxToLegacyFontSize","weight","span","caret","newRange","mode","multiline","initiallyEmpty","placeCaretAtEnd","imeComposing","suppressNextEnter","onCompositionStart","onCompositionEnd","onKeyDown","onBlur","active","related","_e","_f","_g","_h","_i","markEdited","syncTextPresence","onPaste","plainTextToRichHtml","onSelChange","onInput","linkInsideEditing","href","stopLinkActivate","align","link","inline","resolveInlineFormatsAtSelection","foreColor","safeQueryValue","backColor","listFormats","activeList","listIndentPx","listIndentGlobalPx","listIndentEffectivePx","state","fallback","rects","tmp","cmd","host","selectionHostElement","resolveForeColorAtSelection","resolveBackColorAtSelection","fromAttr","readColorFromStyleAttr","isTransparentColor","readBackgroundFromStyleAttr","computed","num","legacy","rgba","walk","toRemove","face","fontSizeFromLegacy","cleaned","allowedAttrs","listExtraAttrs","hasMarginStyle","appendStyle","Canvas","blockEl","cssEscape","editingEl","linkFromTarget","stopNavigate","si","topPut","top","Sortable","sectionIndex","layoutShort","sectionChip","sw","wrap","toolbar","iconDrag","iconCopy","iconTrash","cols","layoutFlexStyle","isEmpty","colEl","layoutFlexValue","vaToFlex","sortable","isHtmlLike","resolved","displayName","content","blockToolbar","iconEdit","iconCode","layouts","bar","reg","newBlock","firstBlock","contentRoot","propKey","editingId","restoreUI","blockType","partial","meta","rest","sectionAttrs","_dv","drop","fromBlockId","sourceGroup","newIndex","newSection","fromCol","moved","oldIndex","secIdx","insertAt","targetSec","nodeInEditing","_layout","columnGap","ratio","svg","ExportModal","editorHost","copyBtn","downloadBtn","result","ta","blob","LAYOUT_CARDS","layoutSvg","LeftPanel","hiddenPalette","filterPalette","defs","paletteBlocks","grid","suffix","isCustom","innerW","rw","DEVICES","_PreviewModal","switcher","iconForDevice","spec","maxPx","PreviewModal","FONT_FAMILIES","FONT_SIZES","RichTextToolbar","editor","f","hasLink","colorToHexInput","matchFamily","matchFontSize","matchFontWeight","sep","exec","svgIcon","placeholder","opt","applyLinkBtn","opening","ed","viewRect","edge","tw","th","viewTop","viewBottom","viewLeft","viewRight","left","inList","shown","on","onClick","icon","lower","step","toHex","defaultSocialIconBackground","network","resolveAssetPermission","permissions","action","defaultNoPermissionTip","tip","FocusBreadcrumb","store","docRootLabel","onFocusDocument","onFocusSection","blockName","openImageGalleryModal","adapter","onPick","onClose","noPermissionTip","perm","modal","query","page","hasMore","loading","errEl","searchInp","debounceId","loadFirst","gridEl","loadMoreBtn","loadPage","confirmBtn","finishPick","setError","msg","syncSelectionStyles","renderCells","append","it","thumb","cellWrap","cell","img","cap","deletePerm","delBtn","err","res","toolRow","addPerm","urlInp","addBtn","u","uploadPerm","fileInp","upBtn","scrollArea","buildVariablePickerHead","pinned","syncPinBtn","pinBtn","iconPin","buildVariablePickerBody","handlers","row","actions","classifyLayoutWidth","layoutWidthNumeric","RightPanel","show","ae","selStart","selEnd","tabs","tab","hideMeta","rows","dvUiEnabled","dynamicVariantKeyField","field","vals","checked","schema","form","fp","defaults","onChange","rawColor","stored","isFw","displayVal","rawFs","quad","dp","resetQuad","pr","networkOptions","elementsKey","help","focusPrefix","firstVal","listEl","patchElements","mutate","cur","syncItem","removeAt","_","rowData","rowWrap","mainRow","o","inp","rm","extras","bgResolved","bgStored","bgDisplay","bgPick","focusToken","ids","assets","showUploadBtn","showGalleryBtn","hasAssetCallbacks","hasAnyPickerBtn","getCtx","applyUrl","runAsync","labelErr","helpBody","bits","warn","warnEl","min","max","snap","commitPlain","fb","v0","syncFromSlider","pickToken","textToken","lastValid","applyPickInherit","applyStored","previewPick","commitPick","current","titles","clampPad","emit","makePlain","makeSliderRow","rawN","inheritOn","globalDisplay","onToggle","valueEl","display","globalWeight","inheriting","syncGroup","inheritSwitch","globalFontSize","globalPx","syncInput","inheritGlobal","sliderRow","syncSlider","leaveInherit","tf","displayN","clampW","emitW","modesWrap","addModeBtn","header","view","SourceView","Topbar","compact","base","norm","forInput","iconFullscreenExit","iconFullscreenEnter","segmented","designBtn","modeSegBtn","iconDesign","sourceBtn","iconSource","themeSeg","themeBtn","theme","iconSun","iconMoon","iconThemeAuto","themeGroupKids","inputEl","actionBtn","iconUndo","iconRedo","contentActionKids","iconClearCanvas","iconResetContent","iconCopyDoc","iconImportDoc","contentActionsGroup","previewBtn","iconEye","exportBtn","iconExport","showMailSettings","trailingGroup","iconSettings","iconVariable","canvasToolKids","iconOnlyBtn","iconLayoutBorders","canvasToolsGroup","headKids","topbarLabel","extra","ICON_UNDO_PATH","svgPathFill","svgTheme","viewBox","transforms","paths","pd","path","DOC_CLIPBOARD_KIND","DOC_CLIPBOARD_FORMAT_VERSION","serializeDocClipboard","isRecord","isEmailDocShape","parseDocClipboard","regenerateDocIds","remapSectionIds","ImportDocModal","cancelBtn","pasteBtn","applyBtn","message","isError","readTextFromClipboard","writeTextToClipboard","ok","MailEditor","fs","smGetFullscreenElement","undo","redo","initialDoc","createDefaultDoc","applyLocalizedDefaultMeta","presetSource","presetContentDoc","initialAccent","preset","configuredVars","presetDoc","snapshot","smExitFullscreen","dark","mq","hx","topbarPrefersLabels","ui","autoWrap","handler","copyVariableToken","existing","pop","onDocClick","dismissPopover","positionAnchoredLayer","urlKey","asHtml","updated","richInline","wrapped","smRequestFullscreen","margin","anchorMid","rootMid","DEFAULT_TOPBAR_COMPACT_MIN_WIDTH","labels","minW","anyEl","mergedStyles"],"mappings":";;;;;;;;AAMO,MAAMA,GAAS;AAAA,EAAf;AACG,IAAAC,EAAA,iCAAU,IAAA;AAAA;AAAA,EAElB,SAA2BC,GAAyB;AAClD,WAAI,KAAK,IAAI,IAAIA,EAAI,IAAI,KACvB,QAAQ,KAAK,kCAAkCA,EAAI,IAAI,YAAY,GAErE,KAAK,IAAI,IAAIA,EAAI,MAAMA,CAA2B,GAC3C;AAAA,EACT;AAAA,EAEA,IAAIC,GAA2C;AAC7C,WAAO,KAAK,IAAI,IAAIA,CAAI;AAAA,EAC1B;AAAA;AAAA,EAGA,QAAQA,GAA+B;AACrC,UAAMD,IAAM,KAAK,IAAI,IAAIC,CAAI;AAC7B,QAAI,CAACD,EAAK,OAAM,IAAI,MAAM,kCAAkCC,CAAI,EAAE;AAClE,WAAOD;AAAA,EACT;AAAA,EAEA,OAA0B;AACxB,WAAO,CAAC,GAAG,KAAK,IAAI,QAAQ;AAAA,EAC9B;AAAA,EAEA,WAAWE,GAA0D;AACnE,WAAO,KAAK,OAAO,OAAO,CAACC,MAAMA,EAAE,aAAaD,CAAQ;AAAA,EAC1D;AAAA;AAAA,EAGA,YAAYD,GAAqB;AAC/B,UAAMD,IAAM,KAAK,QAAQC,CAAI;AAC7B,WAAO;AAAA,MACL,IAAIG,GAAA;AAAA,MACJ,MAAAH;AAAA,MACA,OAAO,gBAAgBD,EAAI,YAAY;AAAA,IAAA;AAAA,EAE3C;AACF;AAEA,SAASI,KAAiB;AACxB,QAAMC,IAAK,KAAK,IAAA,EAAM,SAAS,EAAE,EAAE,MAAM,EAAE,GACrCC,IAAO,KAAK,MAAM,KAAK,WAAW,MAAM,CAAC,EAC5C,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AAClB,SAAO,OAAOD,CAAE,GAAGC,CAAI;AACzB;AAGO,SAASC,GAA8BP,GAA6C;AACzF,SAAOA;AACT;ACrDO,MAAMQ,KAA4B;AAGlC,SAASC,GAA4BC,GAAsC;AAEhF,SADY,OAAOA,EAAQ,MAAM,qBAAqB,EAAE,EAAE,KAAA,KAC5C;AAChB;AAEO,SAASC,GAAwBD,GAA2B;AACjE,SAAO,CAAC,CAACD,GAA4BC,CAAO;AAC9C;AAEO,SAASE,GAA0BC,GAAqB;AAC7D,SAAO,KAAK,OAAOA,CAAG,EAAE,MAAM;AAChC;AAEO,SAASC,GAAmBC,GAA2B;AAC5D,SAAO,UAAUA,EAAU,QAAQ,mBAAmB,GAAG,CAAC;AAC5D;ACfA,SAASC,GAAoBC,GAAuB;;AAClD,QAAMC,MAAOC,IAAAF,EAAI,SAAJ,gBAAAE,EAAU,cAAa,IAC9BC,MAAOC,IAAAJ,EAAI,SAAJ,gBAAAI,EAAU,cAAa;AACpC,SAAO,GAAGH,CAAI,GAAGE,CAAI;AACvB;AAKO,SAASE,GAAqCC,GAAcN,GAAuB;AACxF,QAAMO,IAAQP,EAAI,SAAS,OAAON,EAAuB;AACzD,MAAI,CAACa,EAAM,OAAQ,QAAOD;AAC1B,MAAI;AACF,UAAME,IAAS,IAAI,UAAA,EAAY,gBAAgBF,GAAM,WAAW;AAChE,eAAWb,KAAWc,GAAO;AAC3B,YAAMX,IAAMJ,GAA4BC,CAAO;AAC/C,UAAI,CAACG,EAAK;AACV,YAAMa,IAAMZ,GAAmBJ,EAAQ,EAAE;AAEzC,UADee,EAAO,cAAc,IAAIjB,EAAyB,KAAKK,CAAG,IAAI,EACjE;AACZ,YAAMc,IAAaF,EAAO,iBAAiB,YAAYC,CAAG,gBAAgBA,CAAG,IAAI;AACjF,UAAIE,IAAyB;AAC7B,iBAAWC,KAAMF;AAEf,aADWE,EAAG,aAAa,OAAO,KAAK,IAChC,MAAM,KAAK,EAAE,SAASH,CAAG,GAAG;AACjC,UAAAE,IAASC;AACT;AAAA,QACF;AAEF,MAAI,CAACD,KAAUD,EAAW,WAAQC,IAASD,EAAW,CAAC,IACnDC,KAAQA,EAAO,aAAapB,IAA2BK,CAAG;AAAA,IAChE;AACA,WAAOG,GAAoBS,CAAM;AAAA,EACnC,QAAQ;AACN,WAAOF;AAAA,EACT;AACF;ACzCO,MAAMO,KAAgB;AAEtB,SAASC,GAAaC,GAAmBC,GAAyC;AACvF,SAAOD,KAAQA,MAASC,KAAM;AAC5B,QAAID,EAAK,aAAa,KAAK,gBAAiBA,EAAqB,YAAY;AAC3E,aAAOA;AAET,IAAAA,IAAOA,EAAK;AAAA,EACd;AACA,SAAO;AACT;AAEO,SAASE,EACdC,GAC4C;AAC5C,QAAMC,IAASD,EAAG;AAClB,SAAKC,MACDA,EAAO,YAAY,QAAQA,EAAO,YAAY,QACzCA,IAFW;AAKtB;AAKO,SAASC,GAAyBR,GAAsB;AAE7D,MADIA,EAAG,aAAaC,EAAa,KAC7BD,EAAG,YAAY,OAAOA,EAAG,YAAY,MAAO,QAAO;AACvD,QAAMS,IAAQT,EAAG,UAAU,EAAI;AAC/B,SAAAS,EAAM,iBAAiB,IAAI,EAAE,QAAQ,CAACC,MAAOA,EAAG,QAAQ,IAChDD,EAAM,eAAe,IAAI,QAAQ,WAAW,EAAE,EAAE,WAAW;AACrE;AAEA,SAASE,GAA2BC,GAAuC;AACzE,MAAIT,IAAuBS,EAAK;AAChC,SAAOT,KAAM;AACX,QAAIA,EAAK,YAAYS,EAAK,QAAS,QAAOT;AAC1C,QAAI,CAACK,GAAyBL,CAAI,EAAG,QAAO;AAC5C,IAAAA,IAAOA,EAAK;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAASU,GAAuBD,GAAuC;AACrE,MAAIT,IAAuBS,EAAK;AAChC,SAAOT,KAAM;AACX,QAAIA,EAAK,YAAYS,EAAK,QAAS,QAAOT;AAC1C,QAAI,CAACK,GAAyBL,CAAI,EAAG,QAAO;AAC5C,IAAAA,IAAOA,EAAK;AAAA,EACd;AACA,SAAO;AACT;AAGA,SAASW,GAAcf,GAAqBgB,GAA2B;AACrE,MAAIZ,IAAuBJ,EAAO;AAClC,SAAOI,KAAQA,MAASY,KAAQ;AAC9B,UAAMC,IAAOb,EAAK;AAClB,QAAIK,GAAyBL,CAAI,EAAG,CAAAA,EAAK,OAAA;AAAA,QACpC;AACL,IAAAA,IAAOa;AAAA,EACT;AACA,SAAOD,EAAO,aAAY,CAAAhB,EAAO,YAAYgB,EAAO,UAAU;AAC9D,EAAAA,EAAO,OAAA;AACT;AAGO,SAASE,GAA2Bb,GAA4B;AACrE,MAAIc,IAAS;AACb,aAAWN,KAAQ,MAAM,KAAKR,EAAK,iBAAiB,QAAQ,CAAC,GAAG;AAC9D,QAAI,CAACA,EAAK,SAASQ,CAAI,EAAG;AAC1B,UAAMO,IAAOR,GAA2BC,CAAmB;AAC3D,IAAIO,KAAQf,EAAK,SAASe,CAAI,MAC5BL,GAAcK,GAAMP,CAAmB,GACvCM,IAAS;AAAA,EAEb;AACA,SAAOA;AACT;AAEO,SAASE,GAAqBd,GAA4B;AAC/D,QAAMG,IAAQH,EAAG,UAAU,EAAI;AAC/B,SAAAG,EAAM,iBAAiB,IAAI,EAAE,QAAQ,CAACC,MAAOA,EAAG,QAAQ,IAChDD,EAAM,eAAe,IAAI,QAAQ,WAAW,EAAE,EAAE,WAAW;AACrE;AAEO,SAASY,GAAiBf,GAAmBgB,GAAuB;AACzE,QAAMC,IAAQ,SAAS,YAAA;AACvB,SAAAA,EAAM,mBAAmBjB,CAAE,GAC3BiB,EAAM,OAAOD,EAAM,gBAAgBA,EAAM,WAAW,GAC7CC,EAAM,WAAW,QAAQ,WAAW,EAAE,EAAE,WAAW;AAC5D;AAEA,SAASC,GAA2BC,GAAiC;AACnE,QAAMC,IAAM,SAAS,cAAc,KAAK;AACxC,SAAAA,EAAI,YAAYD,CAAI,GACpBC,EAAI,iBAAiB,IAAI,EAAE,QAAQ,CAAChB,MAAOA,EAAG,QAAQ,IAC9CgB,EAAI,eAAe,IAAI,QAAQ,WAAW,EAAE,EAAE,OAAO,SAAS;AACxE;AAGO,SAASC,GAAerB,GAAmBgB,GAAuB;AACvE,QAAMM,IAAQ,SAAS,YAAA;AACvB,MAAI;AACF,IAAAA,EAAM,SAASN,EAAM,cAAcA,EAAM,SAAS,GAC9ChB,EAAG,YAAWsB,EAAM,YAAYtB,EAAG,SAAS,IAC3CsB,EAAM,OAAOtB,GAAI,CAAC;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO,CAACkB,GAA2BI,EAAM,eAAe;AAC1D;AAEO,SAASC,GAAoB7B,GAAiB8B,GAAwB;AAC3E,QAAMR,IAAQ,SAAS,YAAA;AACvB,EAAAA,EAAM,mBAAmBtB,CAAE,GAC3BsB,EAAM,SAASQ,CAAO;AACtB,QAAMC,IAAM,OAAO,aAAA;AACnB,EAAKA,MACLA,EAAI,gBAAA,GACJA,EAAI,SAAST,CAAK;AACpB;AAEO,SAASU,GAAyBhC,GAAuB;AAC9D,EAAA6B,GAAoB7B,GAAI,EAAK;AAC/B;AAEA,SAASiC,GAAkBC,GAAsB;AAC/C,SAAOA,EAAK,QAAQ,WAAW,EAAE,EAAE;AACrC;AAGO,SAASC,GAAmBC,GAAwBd,GAAsB;AAC/E,QAAMC,IAAQ,SAAS,YAAA;AACvB,SAAAA,EAAM,mBAAmBa,CAAS,GAClCb,EAAM,OAAOD,EAAM,gBAAgBA,EAAM,WAAW,GAC7CW,GAAkBV,EAAM,UAAU;AAC3C;AAGO,SAASc,EAAqBD,GAAwBE,GAAsB;AACjF,QAAMvC,IAAS,KAAK,IAAI,GAAGuC,CAAM,GAC3BC,IAAS,SAAS,iBAAiBH,GAAW,WAAW,SAAS;AACxE,MAAII,IAAYzC,GACZ0C,IAAwB;AAE5B,SAAQA,IAAWF,EAAO,cAA4B;AACpD,UAAMG,IAAOD,EAAS,QAAQ,IACxBE,IAAMV,GAAkBS,CAAI;AAClC,QAAIF,KAAaG,GAAK;AACpB,UAAIC,IAAQ,GACRC,IAAaH,EAAK;AACtB,eAASI,IAAI,GAAGA,IAAIJ,EAAK,QAAQI;AAC/B,YAAIJ,EAAKI,CAAC,MAAM,KAChB;AAAA,cAAIF,MAAUJ,GAAW;AACvB,YAAAK,IAAaC;AACb;AAAA,UACF;AACA,UAAAF;AAAA;AAEF,YAAMtB,IAAQ,SAAS,YAAA;AACvB,MAAAA,EAAM,SAASmB,GAAUI,CAAU,GACnCvB,EAAM,SAAS,EAAI;AACnB,YAAMS,IAAM,OAAO,aAAA;AACnB,MAAAA,KAAA,QAAAA,EAAK,mBACLA,KAAA,QAAAA,EAAK,SAAST;AACd;AAAA,IACF;AACA,IAAAkB,KAAaG;AAAA,EACf;AAEA,EAAAX,GAAyBI,CAAS;AACpC;AAEO,SAASW,GAA4B/C,GAAyB;AACnE,SAAOiC,GAAkBjC,EAAG,eAAe,EAAE;AAC/C;AAEA,MAAMgD,KAAoB,iBACpBC,KAA0B;AAEhC,SAASC,GAAqB5B,GAAc6B,GAAsC;AAChF,MAAI,CAAC7B,EAAM,UAAW,QAAO;AAC7B,QAAM8B,IAAS,SAAS,cAAc,MAAM;AAC5C,EAAAA,EAAO,aAAaD,GAAM,GAAG,GAC7BC,EAAO,YAAY,SAAS,eAAe,GAAQ,CAAC;AACpD,MAAI;AACF,WAAA9B,EAAM,WAAW8B,CAAM,GAChBA;AAAA,EACT,QAAQ;AACN,WAAAA,EAAO,OAAA,GACA;AAAA,EACT;AACF;AAQO,SAASC,GAA+B/B,GAG7C;AACA,QAAMgC,IAAahC,EAAM,WAAA;AACzB,EAAAgC,EAAW,SAAS,EAAI;AACxB,QAAMC,IAAWjC,EAAM,WAAA;AACvB,SAAAiC,EAAS,SAAS,EAAK,GAChB;AAAA,IACL,OAAOL,GAAqBI,GAAYL,EAAuB;AAAA,IAC/D,KAAKC,GAAqBK,GAAUP,EAAiB;AAAA,EAAA;AAEzD;AASO,SAASQ,GAA+BpD,GAAyB;AACtE,EAAAA,EACG;AAAA,IACC,QAAQ6C,EAAuB,eAAeD,EAAiB;AAAA,EAAA,EAEhE,QAAQ,CAACS,MAAMA,EAAE,QAAQ;AAC9B;AAGO,SAASC,GACdtB,GACAd,GACQ;AACR,QAAMqC,IAAQrC,EAAM,WAAA;AACpB,SAAAqC,EAAM,SAAS,EAAK,GACbxB,GAAmBC,GAAWuB,CAAK;AAC5C;AAGO,SAASC,GAAmBxD,GAA4B;AAC7D,QAAMgD,IAAShD,EAAK,cAAc,QAAQ4C,EAAiB,OAAO;AAClE,MAAI,EAAEI,aAAkB,oBAAoB,CAAChD,EAAK,SAASgD,CAAM,EAAG,QAAO;AAE3E,QAAM9B,IAAQ,SAAS,YAAA;AACvB,EAAAA,EAAM,eAAe8B,CAAM,GAC3B9B,EAAM,SAAS,EAAI,GACnB8B,EAAO,OAAA;AAEP,QAAMrB,IAAM,OAAO,aAAA;AACnB,SAAKA,KACLA,EAAI,gBAAA,GACJA,EAAI,SAAST,CAAK,GACX,MAHU;AAInB;AAEA,SAASuC,GAAuBC,GAAaC,GAAwC;AACnF,SAAID,EAAM,wBAAwBC,CAAG,IAAI,KAAK,8BACrC,EAAE,QAAQD,GAAO,KAAKC,EAAA,IAExB,EAAE,QAAQA,GAAK,KAAKD,EAAA;AAC7B;AAEA,SAASE,GAAoBpD,GAAekD,GAAaC,GAAoB;AAC3E,MAAInD,EAAK,SAASkD,CAAK,KAAKlD,EAAK,SAASmD,CAAG,EAAG,QAAO;AAEvD,QAAM,EAAE,QAAAE,GAAQ,KAAAC,EAAA,IAAQL,GAAuBC,GAAOC,CAAG,GACnDI,KACHvD,EAAK,wBAAwBqD,CAAM,IAAI,KAAK,iCAAiC,GAC1EG,KACHxD,EAAK,wBAAwBsD,CAAG,IAAI,KAAK,iCAAiC;AAC7E,SAAOC,KAAeC;AACxB;AAEA,SAASC,GAAwBC,GAA0C;AACzE,MAAIC,IAA2B;AAC/B,aAAW3D,KAAQ0D;AACjB,KACE,CAACC,KACAA,EAAK,wBAAwB3D,CAAI,IAAI,KAAK,iCAE3C2D,IAAO3D;AAGX,SAAO2D;AACT;AAEA,SAASC,GAAsB5D,GAA4B;AACzD,QAAM6D,IAAQ,MAAM,KAAK7D,EAAK,QAAQ,EAAE;AAAA,IACtC,CAAC8D,MAA0BA,EAAE,YAAY;AAAA,EAAA,GAErCC,IAASF,EAAMA,EAAM,SAAS,CAAC;AACrC,SAAKE,KACL3C,GAAyB2C,CAAM,GACxB,MAFa;AAGtB;AAMO,SAASC,GAAyCxE,GAA4B;AACnF,QAAM0D,IAAQ1D,EAAK,cAAc,QAAQ6C,EAAuB,OAAO,GACjEc,IAAM3D,EAAK,cAAc,QAAQ4C,EAAiB,OAAO;AAC/D,MACE,EAAEc,aAAiB,oBACnB,EAAEC,aAAe,oBACjB,CAAC3D,EAAK,SAAS0D,CAAK,KACpB,CAAC1D,EAAK,SAAS2D,CAAG;AAElB,WAAO;AAGT,QAAMc,IAAyB,CAAA;AAC/B,aAAW1E,KAAQC,EAAK,iBAAiB,QAAQ,GAAG;AAClD,QAAI,EAAED,aAAgB,gBAAgB,CAACC,EAAK,SAASD,CAAI,EAAG;AAC5D,UAAMS,IAAOT;AACb,IAAI6D,GAAoBpD,GAAMkD,GAAOC,CAAG,KAAGc,EAAQ,KAAKjE,CAAI;AAAA,EAC9D;AAEA,EAAAkD,EAAM,OAAA,GACNC,EAAI,OAAA;AAEJ,QAAMhE,IAASsE,GAAwBQ,CAAO;AAC9C,SAAK9E,IACEyE,GAAsBzE,CAAM,IADf;AAEtB;AAGO,SAAS+E,GACd1E,GACAgD,GACA2B,GACM;AACN,EAAInB,GAAmBxD,CAAI,KAC3BiC,EAAqBjC,GAAM2E,CAAc;AAC3C;AAEA,SAASC,GAAuB1E,GAAyB;AACvD,EAAIc,GAAqBd,CAAE,MACzBA,EAAG,cAAc,IACjBA,EAAG,YAAY,SAAS,cAAc,IAAI,CAAC;AAE/C;AAGO,SAAS2E,GAAsB3E,GAAyB;AAC7D,QAAMM,IAAOP,EAAaC,CAAE;AAC5B,MAAI,CAACM,EAAM;AAEX,QAAM6D,IAAQ,MAAM,KAAK7D,EAAK,QAAQ,EAAE;AAAA,IACtC,CAAC8D,MAA0BA,EAAE,YAAY;AAAA,EAAA,GAErCQ,IAAQT,EAAM,QAAQnE,CAAE;AAC9B,MAAI4E,MAAU,GAAI;AAElB,QAAMC,IAAaV,EAAM,MAAMS,IAAQ,CAAC;AACxC,EAAA5E,EAAG,OAAA;AAEH,QAAM8E,IAAI,SAAS,cAAc,GAAG;AAIpC,MAHAA,EAAE,aAAanF,IAAe,GAAG,GACjCmF,EAAE,YAAY,SAAS,cAAc,IAAI,CAAC,GAEtCxE,EAAK,SAAS,WAAW;AAC3B,IAAAA,EAAK,YAAYwE,CAAC;AAAA,WACTD,EAAW,WAAW;AAC/B,IAAAvE,EAAK,MAAMwE,CAAC;AAAA,WACHF,MAAU;AACnB,IAAAtE,EAAK,OAAOwE,CAAC;AAAA,OACR;AACL,UAAMC,IAAU,SAAS,cAAczE,EAAK,QAAQ,aAAa;AAGjE,IAAAuE,EAAW,QAAQ,CAACG,MAASD,EAAQ,YAAYC,CAAI,CAAC,GACtD1E,EAAK,MAAMwE,CAAC,GACZA,EAAE,MAAMC,CAAO;AAAA,EACjB;AAEA,EAAAxD,GAAoBuD,GAAG,EAAI;AAC7B;AAGO,SAASG,GAAqBjF,GAAmBgB,GAAoB;AAC1E,QAAMV,IAAOP,EAAaC,CAAE;AAC5B,MAAI,CAACM,EAAM;AAEX,MAAIQ,GAAqBd,CAAE,GAAG;AAC5B,IAAA2E,GAAsB3E,CAAE;AACxB;AAAA,EACF;AAEA,MAAIe,GAAiBf,GAAIgB,CAAK,GAAG;AAC/B,UAAMkE,IAAQ,SAAS,cAAc,IAAI;AACzCA,IAAAA,EAAM,YAAY,SAAS,cAAc,IAAI,CAAC,GAC9C5E,EAAK,aAAa4E,GAAOlF,CAAE,GAC3BuB,GAAoB2D,GAAO,EAAI;AAC/B;AAAA,EACF;AAEA,MAAI7D,GAAerB,GAAIgB,CAAK,GAAG;AAC7B,UAAMkE,IAAQ,SAAS,cAAc,IAAI;AACzCA,IAAAA,EAAM,YAAY,SAAS,cAAc,IAAI,CAAC,GAC1ClF,EAAG,cAAaM,EAAK,aAAa4E,GAAOlF,EAAG,WAAW,IACtDM,EAAK,YAAY4E,CAAK,GAC3B3D,GAAoB2D,GAAO,EAAI;AAC/B;AAAA,EACF;AAEA,QAAMC,IAAY,SAAS,YAAA;AAC3B,EAAAA,EAAU,SAASnE,EAAM,gBAAgBA,EAAM,WAAW,GACtDhB,EAAG,YAAWmF,EAAU,YAAYnF,EAAG,SAAS,IAC/CmF,EAAU,OAAOnF,GAAI,CAAC;AAE3B,QAAMoF,IAAY,SAAS,YAAA;AAI3B,MAHAA,EAAU,SAASpE,EAAM,gBAAgBA,EAAM,WAAW,GACtDhB,EAAG,YAAWoF,EAAU,YAAYpF,EAAG,SAAS,IAC/CoF,EAAU,OAAOpF,GAAI,CAAC,GACvB,CAACkB,GAA2BkE,EAAU,cAAA,CAAe,GAAG;AAC1D,UAAMF,IAAQ,SAAS,cAAc,IAAI;AACzCA,IAAAA,EAAM,YAAY,SAAS,cAAc,IAAI,CAAC,GAC1ClF,EAAG,cAAaM,EAAK,aAAa4E,GAAOlF,EAAG,WAAW,IACtDM,EAAK,YAAY4E,CAAK,GAC3B3D,GAAoB2D,GAAO,EAAI;AAC/B;AAAA,EACF;AAEA,QAAMA,IAAQ,SAAS,cAAc,IAAI,GACnCG,IAAWF,EAAU,gBAAA;AAC3B,EAAAD,EAAM,YAAYG,CAAQ,GAC1BX,GAAuB1E,CAAE,GAErBA,EAAG,cAAaM,EAAK,aAAa4E,GAAOlF,EAAG,WAAW,IACtDM,EAAK,YAAY4E,CAAK,GAE3B3D,GAAoB2D,GAAO,EAAI;AACjC;AAGO,SAASI,GAAyBtF,GAAmBgB,GAAuB;AACjF,MAAI,CAACA,EAAM,aAAa,CAACD,GAAiBf,GAAIgB,CAAK,EAAG,QAAO;AAE7D,QAAMV,IAAOP,EAAaC,CAAE;AAC5B,MAAI,CAACM,EAAM,QAAO;AAElB,MAAIQ,GAAqBd,CAAE,GAAG;AAC5B,UAAMuF,IAAavF,EAAG;AACtB,QAAI,CAACuF,KAAcA,EAAW,YAAY,MAAM;AAC9C,YAAMC,IAAWnF,GAA2BC,CAAI;AAChD,UAAIkF,GAAU;AACZ,QAAAxF,EAAG,OAAA,GACHQ,GAAcgF,GAAUlF,CAAI;AAC5B,cAAM+D,IAASmB,EAAS;AACxB,eAAInB,aAAkB,iBAAe3C,GAAyB2C,CAAM,GAC7D;AAAA,MACT;AAAA,IACF;AACA,WAAAM,GAAsB3E,CAAE,GACjB;AAAA,EACT;AAEA,QAAMuF,IAAavF,EAAG;AACtB,MAAIuF,KAAcA,EAAW,YAAY,MAAM;AAC7C,UAAME,IAASF,GACTG,IAAiBjD,GAA4BgD,CAAM;AACzD,WAAOzF,EAAG,aAAY,CAAAyF,EAAO,YAAYzF,EAAG,UAAU;AACtD,WAAAA,EAAG,OAAA,GACH+B,EAAqB0D,GAAQC,CAAc,GACpC;AAAA,EACT;AAEA,QAAMF,IAAWnF,GAA2BC,CAAI;AAChD,MAAIkF,GAAU;AACZ,UAAMC,IAASD,EAAS;AACxB,QAAIC,KAAUA,EAAO,YAAY,MAAM;AACrC,YAAME,IAAWF,GACXC,IAAiBjD,GAA4BkD,CAAQ;AAC3D,aAAO3F,EAAG,aAAY,CAAA2F,EAAS,YAAY3F,EAAG,UAAU;AACxD,aAAAA,EAAG,OAAA,GACCM,EAAK,SAAS,WAAW,KAAGE,GAAcgF,GAAUlF,CAAI,GAC5DyB,EAAqB4D,GAAUD,CAAc,GACtC;AAAA,IACT;AAAA,EACF;AAEA,QAAMZ,IAAI,SAAS,cAAc,GAAG;AACpC,SAAO9E,EAAG,aAAY,CAAA8E,EAAE,YAAY9E,EAAG,UAAU;AACjD,SAAK8E,EAAE,qBAAmB,YAAY,SAAS,cAAc,IAAI,CAAC,GAClE9E,EAAG,OAAA,GAECM,EAAK,SAAS,WAAW,IAC3BA,EAAK,YAAYwE,CAAC,IAElBxE,EAAK,OAAOwE,CAAC,GAEfpD,GAAyBoD,CAAC,GACnB;AACT;AAGO,SAASc,GAA0B5F,GAAmBgB,GAAuB;AAClF,MAAI,CAACA,EAAM,aAAa,CAACK,GAAerB,GAAIgB,CAAK,EAAG,QAAO;AAE3D,QAAMV,IAAOP,EAAaC,CAAE;AAC5B,MAAI,CAACM,EAAM,QAAO;AAElB,QAAMuF,IAAa7F,EAAG;AACtB,MAAI6F,KAAcA,EAAW,YAAY,MAAM;AAC7C,UAAMC,IAASD,GACTH,IAAiBjD,GAA4BzC,CAAE;AAErD,QAAIc,GAAqBgF,CAAM;AAC7BA,aAAAA,EAAO,OAAA,GACP/D,EAAqB/B,GAAI0F,CAAc,GAChC;AAGT,WAAOI,EAAO,aAAY,CAAA9F,EAAG,YAAY8F,EAAO,UAAU;AAC1DA,WAAAA,EAAO,OAAA,GACP/D,EAAqB/B,GAAI0F,CAAc,GAChC;AAAA,EACT;AAEA,QAAMK,IAAWxF,GAAuBD,CAAI;AAC5C,MAAI,CAACyF,EAAU,QAAO;AAEtB,QAAMD,IAASC,EAAS;AACxB,MAAI,CAACD,KAAUA,EAAO,YAAY,KAAM,QAAO;AAE/C,QAAME,IAAWF,GACXJ,IAAiBjD,GAA4BzC,CAAE;AAErD,MAAIc,GAAqBkF,CAAQ;AAC/B,WAAAA,EAAS,OAAA,GACLD,EAAS,SAAS,WAAW,KAAGvF,GAAcF,GAAMyF,CAAQ,GAChEhE,EAAqB/B,GAAI0F,CAAc,GAChC;AAGT,SAAOM,EAAS,aAAY,CAAAhG,EAAG,YAAYgG,EAAS,UAAU;AAC9D,SAAAA,EAAS,OAAA,GACLD,EAAS,SAAS,WAAW,KAAGvF,GAAcF,GAAMyF,CAAQ,GAChEhE,EAAqB/B,GAAI0F,CAAc,GAChC;AACT;AAEA,SAASO,GAAoBjF,GAAcnB,GAAqB;AAC9D,MAAI;AACF,UAAMqG,IAAY,SAAS,YAAA;AAC3B,WAAAA,EAAU,mBAAmBrG,CAAI,GAE/BmB,EAAM,sBAAsB,MAAM,cAAckF,CAAS,IAAI,MAC7DlF,EAAM,sBAAsB,MAAM,cAAckF,CAAS,IAAI;AAAA,EAEjE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,GAAoCC,GAAiB;AAC5D,SAAO,CAAC,GAAGA,CAAK,EAAE,KAAK,CAACC,GAAGC,MAAM;AAC/B,UAAMC,IAAMF,EAAE,wBAAwBC,CAAC;AACvC,WAAIC,IAAM,KAAK,8BAAoC,KAC/CA,IAAM,KAAK,8BAAoC,IAC5C;AAAA,EACT,CAAC;AACH;AAGO,SAASC,GACdxF,GACAlB,GACiB;AACjB,QAAMqE,IAAyB,CAAA;AAC/B,aAAWtE,KAAQC,EAAK,iBAAiB,IAAI;AAC3C,IAAMD,aAAgB,iBACjBE,EAAaF,CAAI,KACjBoG,GAAoBjF,GAAOnB,CAAI,KACpCsE,EAAM,KAAKtE,CAAI;AAEjB,SAAOsG,GAAoBhC,CAAK;AAClC;AAEA,SAASsC,GAA0BC,GAAmBC,GAAuB;AAC3E,QAAMC,IAAaF,EAAK,aAAa,qBAAqB;AAC1D,EAAIE,KAAc,QAAMD,EAAG,aAAa,uBAAuBC,CAAU;AACzE,QAAMC,IAAQH,EAAK,aAAa,OAAO;AACvC,EAAIG,KAAOF,EAAG,aAAa,SAASE,CAAK;AAC3C;AAEA,SAASC,GACP3F,GACA4F,GACAtG,GACA0D,GACM;AACN,MAAI,CAACA,EAAM,OAAQ;AACnB,QAAMzE,IAAK,SAAS,cAAcqH,CAAG;AACrC,EAAAN,GAA0BhG,GAAQf,CAAE,GACpCyE,EAAM,QAAQ,CAACnE,MAAON,EAAG,YAAYM,CAAE,CAAC,GACxCmB,EAAK,YAAYzB,CAAE;AACrB;AAEA,SAASsH,GAAqB7F,GAAwBgD,GAA8B;AAClF,aAAWnE,KAAMmE,GAAO;AACtB,UAAMW,IAAI,SAAS,cAAc,GAAG;AACpC,WAAO9E,EAAG,aAAY,CAAA8E,EAAE,YAAY9E,EAAG,UAAU;AACjD,IAAK8E,EAAE,qBAAmB,YAAY,SAAS,cAAc,IAAI,CAAC,GAClE3D,EAAK,YAAY2D,CAAC;AAAA,EACpB;AACF;AAOA,SAASmC,GACP3G,GACA4G,GACAC,GACA7F,GACA8F,GACM;AACN,QAAMnH,IAASK,EAAK;AACpB,MAAI,CAACL,EAAQ;AAEb,QAAMoH,IAAU/G,EAAK,QAAQ,YAAA,GACvBa,IAAO,SAAS,uBAAA;AAEtB,EAAA2F,GAAoB3F,GAAMkG,GAAS/G,GAAM4G,CAAM,GAE3CE,MAAe,WACjBJ,GAAqB7F,GAAMgG,CAAM,IAEjCL,GAAoB3F,GAAMiG,EAAW,KAAK9G,GAAM6G,CAAM,GAGxDL,GAAoB3F,GAAMkG,GAAS/G,GAAMgB,CAAK,GAE9CrB,EAAO,aAAakB,GAAMb,CAAI,GAC9BA,EAAK,OAAA;AACP;AAEA,SAASgH,GAAyBhH,GAAmBiH,GAAuB;AAC1E,QAAMC,IAAOlH,EAAK,YAAY;AAE9B,EADkBiH,MAAWC,OACHlH,CAAI,IACzBmH,GAAenH,GAAMiH,IAAS,OAAO,IAAI;AAChD;AAQO,SAASG,GACd5H,GACAkB,GACAuG,GAEAI,GACS;AACT,MAAI3G,EAAM,WAAW;AACnB,UAAMhB,IAAKJ,GAAaoB,EAAM,gBAAgBlB,CAAI,GAC5CQ,IAAON,IAAKD,EAAaC,CAAE,IAAI;AACrC,WAAKM,KACLgH,GAAyBhH,GAAMiH,CAAM,GAC9B,MAFW;AAAA,EAGpB;AAEA,QAAMpD,IAAQwD,KAAiBnB,GAAoBxF,GAAOlB,CAAI;AAC9D,MAAI,CAACqE,EAAM,OAAQ,QAAO;AAE1B,QAAMyD,wBAAa,IAAA;AACnB,aAAW5H,KAAMmE,GAAO;AACtB,UAAM7D,IAAOP,EAAaC,CAAE;AAC5B,QAAI,CAACM,EAAM;AACX,UAAMuH,IAAQD,EAAO,IAAItH,CAAI,KAAK,CAAA;AAClC,IAAAuH,EAAM,KAAK7H,CAAE,GACb4H,EAAO,IAAItH,GAAMuH,CAAK;AAAA,EACxB;AAEA,QAAM7D,IAAQmC,GAAoB,CAAC,GAAGyB,EAAO,KAAA,CAAM,CAAC,EAAE,QAAA;AAEtD,aAAWtH,KAAQ0D,GAAO;AACxB,UAAM8D,IAAW3B,GAAoByB,EAAO,IAAItH,CAAI,KAAK,EAAE,GACrDyH,IAAW,MAAM,KAAKzH,EAAK,QAAQ,EAAE;AAAA,MACzC,CAAC8D,MAA0BA,EAAE,YAAY;AAAA,IAAA,GAErC4D,IAAc,IAAI,IAAIF,CAAQ;AAKpC,QAHEA,EAAS,WAAWC,EAAS,UAC7BA,EAAS,MAAM,CAAC/H,MAAOgI,EAAY,IAAIhI,CAAE,CAAC,GAE3B;AACf,MAAAsH,GAAyBhH,GAAMiH,CAAM;AACrC;AAAA,IACF;AAEA,UAAMC,IAAOlH,EAAK,YAAY,MACxB2H,IAAYV,MAAWC,GAEvBU,IAAUJ,EACb,IAAI,CAAC9H,MAAO+H,EAAS,QAAQ/H,CAAE,CAAC,EAChC,OAAO,CAACwC,MAAMA,KAAK,CAAC,EACpB,KAAK,CAAC6D,GAAGC,MAAMD,IAAIC,CAAC;AACvB,QAAI,CAAC4B,EAAQ,OAAQ;AAErB,UAAMC,IAAWD,EAAQ,CAAC,GACpBE,IAAUF,EAAQA,EAAQ,SAAS,CAAC,GACpChB,IAASa,EAAS,MAAM,GAAGI,CAAQ,GACnChB,IAASY,EAAS,MAAMI,GAAUC,IAAU,CAAC,GAC7C9G,IAAQyG,EAAS,MAAMK,IAAU,CAAC;AAExC,IAAIH,IACFhB,GAAwB3G,GAAM4G,GAAQC,GAAQ7F,GAAO,QAAQ,IAE7D2F,GAAwB3G,GAAM4G,GAAQC,GAAQ7F,GAAO;AAAA,MACnD,KAAKiG,IAAS,OAAO;AAAA,IAAA,CACtB;AAAA,EAEL;AACA,SAAO;AACT;AAGO,SAASc,GAAW/H,GAAiD;AAC1E,QAAML,IAASK,EAAK;AACpB,MAAI,CAACL,EAAQ;AACb,QAAMoF,IAAW,SAAS,uBAAA;AAC1B,aAAWiD,KAAS,MAAM,KAAKhI,EAAK,QAAQ,GAAG;AAC7C,QAAIgI,EAAM,YAAY,KAAM;AAC5B,UAAMxD,IAAI,SAAS,cAAc,GAAG;AACpC,WAAOwD,EAAM,aAAY,CAAAxD,EAAE,YAAYwD,EAAM,UAAU;AACvD,IAAKxD,EAAE,qBAAmB,YAAY,SAAS,cAAc,IAAI,CAAC,GAClEO,EAAS,YAAYP,CAAC;AAAA,EACxB;AACA,EAAA7E,EAAO,aAAaoF,GAAU/E,CAAI,GAClCA,EAAK,OAAA;AACP;AAGO,SAASmH,GACdnH,GACAyG,GACqC;AACrC,MAAIzG,EAAK,QAAQ,YAAA,MAAkByG,EAAK,QAAOzG;AAC/C,QAAMI,IAAO,SAAS,cAAcqG,CAAG;AACvC,SAAOzG,EAAK,aAAY,CAAAI,EAAK,YAAYJ,EAAK,UAAU;AACxD,QAAMsG,IAAatG,EAAK,aAAa,qBAAqB;AAC1D,EAAIsG,KAAc,QAAMlG,EAAK,aAAa,uBAAuBkG,CAAU;AAC3E,QAAMC,IAAQvG,EAAK,aAAa,OAAO;AACvC,SAAIuG,KAAOnG,EAAK,aAAa,SAASmG,CAAK,GAC3CvG,EAAK,YAAYI,CAAI,GACdA;AACT;AAEO,SAAS6H,GAAkB1I,GAAmBC,GAGnD;AACA,QAAME,IAAKJ,GAAaC,GAAMC,CAAI,GAC5BQ,IAAON,IAAKD,EAAaC,CAAE,IAAI;AACrC,SAAO;AAAA,IACL,gBAAeM,KAAA,gBAAAA,EAAM,aAAY;AAAA,IACjC,cAAaA,KAAA,gBAAAA,EAAM,aAAY;AAAA,EAAA;AAEnC;ACjwBO,MAAMkI,KAAmB,uBAGnBC,KAAyB,IAEzBC,KAAyB,IAEzBC,KAAyB,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE;AAGjD,SAASC,GAAiCC,GAAgC;AAC/E,QAAMC,IAAIC,GAAgBF,CAAE;AAC5B,SAAOC,MAAML,KAAyB,SAAYK;AACpD;AAKA,MAAME,KAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEMC,KAAgB,CAAC,UAAU,SAAS;AAE1C,SAASC,GAAmBC,GAA+C;AACzE,QAAMC,KAAKD,KAAO,IAAI,KAAA;AACtB,MAAI,CAACC,EAAG,QAAO;AACf,QAAMjG,IAAIiG,EAAE,MAAM,2BAA2B;AAC7C,MAAI,CAACjG,EAAG,QAAO;AACf,QAAM,IAAI,OAAOA,EAAE,CAAC,CAAC;AACrB,SAAO,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,CAAC,IAAI;AAC3D;AAEA,SAASkG,GAAcC,GAA0BC,GAAsB;;AACrE,MAAI,CAACD,EAAW,QAAO;AACvB,QAAME,IAAK,IAAI,OAAO,cAAcD,CAAI,oBAAoB,GAAG,GACzDpG,IAAImG,EAAU,MAAME,CAAE;AAC5B,WAAOxK,IAAAmE,KAAA,gBAAAA,EAAI,OAAJ,gBAAAnE,EAAQ,WAAU;AAC3B;AAEA,SAASyK,GACP/J,GACAgK,GACAC,GACM;AACN,QAAMC,wBAAU,IAAA,GACV/I,IAAOnB,EAAG,aAAa,OAAO,KAAK;AACzC,aAAWmK,KAAQhJ,EAAK,MAAM,GAAG,GAAG;AAClC,UAAMiJ,IAAMD,EAAK,QAAQ,GAAG;AAC5B,QAAIC,IAAM,EAAG;AACb,UAAMpL,IAAMmL,EAAK,MAAM,GAAGC,CAAG,EAAE,KAAA,EAAO,YAAA,GAChCC,IAAMF,EAAK,MAAMC,IAAM,CAAC,EAAE,KAAA;AAChC,IAAIpL,KAAOqL,KAAKH,EAAI,IAAIlL,GAAKqL,CAAG;AAAA,EAClC;AACA,aAAWrL,KAAOiL,EAAa,CAAAC,EAAI,OAAOlL,CAAG;AAC7C,aAAW,CAACA,GAAKqL,CAAG,KAAK,OAAO,QAAQL,CAAK;AAC3C,IAAIK,KAAO,QAAQA,MAAQ,KAAIH,EAAI,OAAOlL,CAAG,IACxCkL,EAAI,IAAIlL,GAAKqL,CAAG;AAEvB,QAAMrJ,IAAO,CAAC,GAAGkJ,EAAI,SAAS,EAAE,IAAI,CAAC,CAACI,GAAGC,CAAC,MAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAAE,KAAK,GAAG;AACrE,EAAIvJ,IAAMhB,EAAG,aAAa,SAASgB,CAAI,IAClChB,EAAG,gBAAgB,OAAO;AACjC;AAEA,SAASwK,GAAuB5J,GAAiD;AAC/E,EAAAmJ,GAAiBnJ,GAAM,CAAA,GAAI0I,EAAe;AAC5C;AAEA,SAASmB,GAAe7J,GAAmD;AACzE,SAAOA,EAAK,YAAY,OAAO,YAAY;AAC7C;AAEA,SAAS8J,GACP9J,GACA+J,GACM;AACN,EAAAZ;AAAA,IACEnJ;AAAA,IACA;AAAA,MACE,gBAAgB,GAAG+J,CAAa;AAAA,MAChC,QAAQ;AAAA,MACR,uBAAuB;AAAA,MACvB,mBAAmBF,GAAe7J,CAAI;AAAA,IAAA;AAAA,IAExC0I;AAAA,EAAA;AAEF,aAAWhJ,KAAM,MAAM,KAAKM,EAAK,QAAQ;AACvC,IAAIN,EAAG,YAAY,QACnByJ,GAAiBzJ,GAAqB,EAAE,QAAQ,KAAK,SAAS,IAAA,GAAOiJ,EAAa;AAEtF;AAGO,SAASqB,GAAchK,GAA4D;AACxF,MAAIA,EAAK,aAAakI,EAAgB,GAAG;AACvC,UAAMW,IAAM7I,EAAK,aAAakI,EAAgB;AAC9C,QAAIW,KAAO,QAAQA,MAAQ,UAAW,QAAO;AAC7C,UAAM,IAAI,SAASA,GAAK,EAAE;AAC1B,WAAO,OAAO,SAAS,CAAC,IAAIJ,GAAgB,CAAC,IAAI;AAAA,EACnD;AAIA,SAFEG,GAAmB5I,EAAK,MAAM,WAAW,KACzC4I,GAAmBG,GAAc/I,EAAK,aAAa,OAAO,GAAG,cAAc,CAAC;AAEhF;AAEO,SAASyI,GAAgBF,GAAoB;AAClD,SAAO,KAAK,IAAI,GAAG,KAAK,IAAIH,IAAwB,KAAK,MAAMG,CAAE,CAAC,CAAC;AACrE;AAGO,SAAS0B,GACdjK,GACAkK,GACM;AACN,MAAIA,MAAU,MAAM;AAClB,IAAAlK,EAAK,gBAAgBkI,EAAgB,GACrC0B,GAAuB5J,CAAI;AAC3B;AAAA,EACF;AACA,QAAMuI,IAAKE,GAAgByB,CAAK;AAChC,EAAAlK,EAAK,aAAakI,IAAkB,OAAOK,CAAE,CAAC,GAC9CuB,GAAwB9J,GAAMuI,CAAE;AAClC;AAEO,SAAS4B,GACd5K,GACAC,GAC4C;AAC5C,QAAME,IAAKJ,GAAaC,GAAMC,CAAI;AAClC,SAAOE,IAAKD,EAAaC,CAAE,IAAI;AACjC;AAEA,SAAS0K,GACPpK,GACAqK,GACQ;AACR,QAAMC,IAAWN,GAAchK,CAAI;AACnC,SAAIsK,KACGD;AACT;AAGO,SAASE,GAA0BC,GAA8B;AACtE,QAAMb,IAAIa,EAAO;AACjB,SAAIb,MAAM,SAAkBxB,KACrBM,GAAgBkB,CAAC;AAC1B;AAGO,SAASc,GAA4BD,GAA8B;AACxE,SAAO,GAAGD,GAA0BC,CAAM,CAAC;AAC7C;AAGO,SAASE,GACd5L,GACAuL,IAA0BlC,IAClB;;AACR,QAAMwC,KAAO7L,KAAQ,IAAI,KAAA;AACzB,MAAI,CAAC6L,KAAO,OAAO,YAAc,IAAa,QAAO7L;AAErD,QAAMN,IAAM,IAAI,UAAA,EAAY,gBAAgBmM,GAAK,WAAW,GACtDjH,IAAQlF,EAAI,iBAAiB,QAAQ;AAC3C,MAAI,CAACkF,EAAM,OAAQ,QAAO5E;AAE1B,EAAA4E,EAAM,QAAQ,CAACnE,MAAS;AACtB,UAAMS,IAAOT,GACPgJ,IAAK6B,GAAuBpK,GAAMqK,CAAe;AACvD,IAAAP,GAAwB9J,GAAMuI,CAAE,GAChCvI,EAAK,gBAAgBkI,EAAgB;AAAA,EACvC,CAAC;AAED,QAAM0C,IAAapM,EAAI,gBAAgB,WACjCqM,KAAUnM,IAAAiM,EAAI,MAAM,kBAAkB,MAA5B,gBAAAjM,EAAgC;AAChD,SAAOmM,IAAU,GAAGA,CAAO;AAAA,EAAKD,CAAU,KAAKA;AACjD;ACvLA,SAASE,GAAejC,GAAkC;AACxD,MAAIA,KAAO,QAAQA,MAAQ,GAAI;AAC/B,MAAI,OAAOA,KAAQ,YAAY,OAAO,SAASA,CAAG,GAAG;AACnD,UAAML,IAAI,KAAK,MAAMK,CAAG;AACxB,WAAOL,IAAI,IAAI,GAAGA,CAAC,OAAO;AAAA,EAC5B;AACA,QAAMM,IAAI,OAAOD,CAAG,EAAE,KAAA;AACtB,MAAKC,GACL;AAAA,QAAI,iBAAiB,KAAKA,CAAC,EAAG,QAAOA;AACrC,QAAI,mBAAmB,KAAKA,CAAC,UAAUA,EAAE,QAAQ,QAAQ,IAAI;AAC7D,QAAI,gBAAgB,KAAKA,CAAC,EAAG,QAAO,GAAGA,CAAC;AAAA;AAE1C;AAGO,SAASiC,GAAmBlC,GAAsB;AACvD,SAAOiC,GAAejC,CAAG,KAAK;AAChC;AAGO,SAASmC,GAA4BC,GAAgC;AAC1E,QAAM,IAAIA,EAAM,KAAA;AAChB,SAAK,IACD,iBAAiB,KAAK,CAAC,IAAU,IACjC,mBAAmB,KAAK,CAAC,IAAU,EAAE,QAAQ,QAAQ,IAAI,IACzD,QAAQ,KAAK,CAAC,IAAU,OAAO,CAAC,IAChC,aAAa,KAAK,CAAC,IAAU,GAAG,CAAC,OAC9B,IALQ;AAMjB;AAEO,SAASC,GAAqBrC,GAAsB;AACzD,SAAIA,KAAO,OAAa,SACpB,OAAOA,KAAQ,YAAY,OAAO,SAASA,CAAG,GAAU,OAAOA,CAAG;AAExE;AAGO,SAASsC,GAAoBtC,GAAkC;AACpE,MAAIA,KAAO,KAAM;AACjB,QAAMC,IAAI,OAAOD,CAAG,EAAE,KAAA;AACtB,MAAI,GAACC,KAAKA,EAAE,YAAA,MAAkB;AAC9B,WAAOgC,GAAehC,CAAC;AACzB;AAGO,SAASsC,GAA+BH,GAA4C;AACzF,QAAM,IAAIA,EAAM,KAAA;AAChB,MAAK;AACL,WAAI,iBAAiB,KAAK,CAAC,IAAU,IACjC,mBAAmB,KAAK,CAAC,IAAU,EAAE,QAAQ,QAAQ,IAAI,IACzD,QAAQ,KAAK,CAAC,IAAU,OAAO,CAAC,IAChC,aAAa,KAAK,CAAC,IAAU,GAAG,CAAC,OAC9B;AACT;AAEO,SAASI,GAAwBxC,GAAsB;AAC5D,SAAIA,KAAO,QAAQA,MAAQ,KAAW,MAClC,OAAOA,KAAQ,YAAY,OAAO,SAASA,CAAG,GAAU,OAAOA,CAAG;AAExE;AC3DO,SAASyC,EACd7E,GACA8E,IAAe,CAAA,GACfC,IAAyD,CAAA,GAC/B;AAC1B,QAAMpM,IAAK,SAAS,cAAcqH,CAAG;AACrC,aAAW,CAACiD,GAAGC,CAAC,KAAK,OAAO,QAAQ4B,CAAK;AACvC,IAAI5B,KAAK,QAAQA,MAAM,OACnBD,MAAM,UAAStK,EAAG,YAAY,OAAOuK,CAAC,IACjCD,MAAM,UAAStK,EAAG,aAAa,SAAS,OAAOuK,CAAC,CAAC,IACjDD,MAAM,SAAQtK,EAAG,YAAY,OAAOuK,CAAC,IACrCD,EAAE,WAAW,IAAI,KAAK,OAAOC,KAAM,aAC1CvK,EAAG,iBAAiBsK,EAAE,MAAM,CAAC,EAAE,YAAA,GAAeC,CAAkB,IACvD,OAAOA,KAAM,YAClBA,KAAGvK,EAAG,aAAasK,GAAG,EAAE,IAE5BtK,EAAG,aAAasK,GAAG,OAAOC,CAAC,CAAC;AAGhC,aAAW3B,KAASwD;AAClB,IAAIxD,KAAS,QAAQA,MAAU,MAC/B5I,EAAG,YAAY,OAAO4I,KAAU,WAAW,SAAS,eAAeA,CAAK,IAAIA,CAAK;AAEnF,SAAO5I;AACT;AAEO,SAASqM,EAAMrM,GAAiB;AACrC,SAAOA,EAAG,aAAY,CAAAA,EAAG,YAAYA,EAAG,UAAU;AACpD;AAEO,SAASsM,GAAW5C,GAAmB;AAC5C,SAAOA,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;AAEO,SAAS6C,EAAW7C,GAAmB;AAC5C,SAAO4C,GAAW5C,CAAC;AACrB;AC5CO,MAAM8C,KAA0B,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK,GAG5DC,KAA+DD,GAAwB;AAAA,EAClG,CAACjC,OAAO,EAAE,OAAOA,GAAG,OAAOA,EAAA;AAC7B;AAGO,SAASmC,EAAwBjD,GAAgD;AACtF,QAAMC,IAAI,OAAOD,KAAO,KAAK,EAAE,KAAA,EAAO,YAAA;AACtC,MAAIC,MAAM,MAAMA,MAAM,YAAYA,MAAM,UAAW,QAAO;AAC1D,MAAIA,MAAM,UAAUA,MAAM,SAAU,QAAO;AAC3C,MAAIA,MAAM,UAAW,QAAO;AAC5B,QAAMiD,IAAQ,kBAAkB,KAAKjD,CAAC;AACtC,MAAIiD,GAAO;AACT,UAAM,IAAI,SAASA,EAAM,CAAC,GAAG,EAAE,GACzBC,IAAQ,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG;AACtC,QAAIrI,IAAuB,OACvBsI,IAAQ;AACZ,eAAWC,KAAMF,GAAO;AACtB,YAAMtO,IAAI,KAAK,IAAI,IAAIwO,CAAE;AACzB,MAAIxO,IAAIuO,MACNA,IAAQvO,GACRiG,IAAO,OAAOuI,CAAE;AAAA,IAEpB;AACA,WAAOvI;AAAA,EACT;AACA,SAAO;AACT;ACdO,SAASwI,GAA8BrD,GAAsC;AAClF,SAAO;AAAA,IACL,WAAWA,EAAE,YAAY,QAAQ,KAAA;AAAA,IACjC,aAAaA,EAAE,cAAc,QAAQ,KAAA;AAAA,IACrC,QAAQA,EAAE,SAAS,WAAW,KAAA;AAAA,IAC9B,aAAaA,EAAE,cAAc,cAAc,KAAA;AAAA,IAC3C,YAAYgD,EAAwBhD,EAAE,UAAU;AAAA,EAAA;AAEpD;AAGA,SAASsD,GAAuBlC,GAAuB;AACrD,SAAOA,EAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAA;AACvD;AAEA,SAASmC,GAAkBC,GAAoBC,GAAmC;AAChF,QAAMC,IAAWJ,GAAuBG,EAAK,QAAQ,GAC/CE,IAAaL,GAAuBG,EAAK,UAAU,GACnDG,IAAQN,GAAuBG,EAAK,KAAK,GACzCI,IAAaP,GAAuBG,EAAK,UAAU,GACnDK,IAAaR,GAAuBG,EAAK,UAAU;AACzD,SAAO,WAAWD,CAAU,cAAcE,CAAQ,gBAAgBC,CAAU,UAAUC,CAAK,gBAAgBC,CAAU,gBAAgBC,CAAU;AACjJ;AAOO,SAASC,GACdP,GACAQ,GACAP,GACQ;AAER,SAAO;AAAA;AAAA;AAAA;AAAA,mBADSF,GAAkBC,GAAYC,CAAI,CAK1B;AAAA,UAChBO,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAMvB;AAQO,SAASC,GAA0BhI,GAAkBwH,GAAmC;AAC7F,QAAMS,IAAOjI,EAAS,UAAA;AACtB,MAAI,CAACiI,EAAM,QAAO;AAClB,MAAI,SAAS,KAAKA,CAAI,EAAG,QAAOjI;AAChC,QAAMkI,IAAIlI,EAAS,KAAA;AAEnB,SAAO8H,GAAoB,KAAKI,GAAGV,CAAI;AACzC;AAGO,SAASW,GACdnI,GACAuH,GACAC,GACQ;AACR,QAAM1D,IAAM9D,EAAS,KAAA,GACfoI,IAAKtE,EAAI,MAAM,0CAA0C;AAC/D,MAAI,CAACsE,EAAI,QAAOpI;AAChB,MAAIqI,IAAQD,EAAG,CAAC,EAAE,KAAA;AAClB,QAAME,IAAWD,EAAM,MAAM,yDAAyD;AAEtF,SADIC,MAAUD,IAAQC,EAAS,CAAC,EAAE,KAAA,IAC9B,gBAAgB,KAAKD,CAAK,IAAUvE,IACjCgE,GAAoBP,GAAYc,GAAOb,CAAI;AACpD;AAGO,SAASe,GAAqBxO,GAAuB;AAC1D,SAAO,aAAa,KAAK,OAAOA,KAAQ,EAAE,CAAC;AAC7C;AAGA,SAASyO,GACPzO,GACA0O,GACAC,GACe;AACf,QAAMC,IAAS,IAAI,OAAO,IAAID,CAAO,OAAO,IAAI,GAC1CE,IAAU,IAAI,OAAO,KAAKF,CAAO,SAAS,IAAI;AACpD,MAAIG,IAAQ,GACR1L,IAAIsL;AAER,SAAOtL,IAAIpD,EAAK,UAAQ;AACtB,IAAA4O,EAAO,YAAYxL,GACnByL,EAAQ,YAAYzL;AACpB,UAAM2L,IAAWH,EAAO,KAAK5O,CAAI,GAC3BgP,IAAYH,EAAQ,KAAK7O,CAAI;AACnC,QAAI,CAACgP,EAAW,QAAO;AAEvB,QAAID,KAAYA,EAAS,QAAQC,EAAU,OAAO;AAChD,MAAAF,KACA1L,IAAI2L,EAAS,QAAQA,EAAS,CAAC,EAAE;AACjC;AAAA,IACF;AAGA,QADAD,KACIA,MAAU,EAAG,QAAO9O,EAAK,MAAM0O,GAAcM,EAAU,KAAK;AAChE,IAAA5L,IAAI4L,EAAU,QAAQA,EAAU,CAAC,EAAE;AAAA,EACrC;AAEA,SAAO;AACT;AAGA,SAASC,GAA2BjP,GAA6B;AAC/D,QAAMkP,IAAOlP,EAAK,MAAM,uBAAuB;AAC/C,MAAI,CAACkP,EAAM,QAAO;AAClB,QAAMR,IAAeQ,EAAK,CAAC,EAAE;AAC7B,SAAOT,GAAiCzO,GAAM0O,GAAc,OAAO;AACrE;AAGA,SAASS,GAA2BnP,GAA6B;AAC/D,QAAMoP,IAAUpP,EAAK,KAAA;AACrB,MAAI,CAAC,gBAAgB,KAAKoP,CAAO,EAAG,QAAO;AAE3C,QAAMC,IAAaJ,GAA2BG,CAAO;AACrD,MAAIC,KAAc,KAAM,QAAO;AAE/B,QAAMC,IAASD,EAAW,MAAM,cAAc;AAC9C,MAAI,CAACC,KAAUA,EAAO,UAAU,OAAW,QAAO;AAElD,QAAMZ,IAAeY,EAAO,QAAQA,EAAO,CAAC,EAAE;AAC9C,SAAOb,GAAiCY,GAAYX,GAAc,IAAI;AACxE;AAKO,SAASa,GAAiCC,GAAmC;AAClF,QAAMzF,IAAM,OAAOyF,KAAc,EAAE,EAAE,KAAA;AACrC,MAAI,CAACzF,EAAK,QAAO;AAEjB,QAAM0F,IAAS1F,EAAI,MAAM,4CAA4C;AACrE,MAAI0F,EAAQ,QAAOA,EAAO,CAAC,EAAE,KAAA;AAE7B,QAAMC,IAAW3F,EAAI,MAAM,gDAAgD;AAC3E,MAAI2F,GAAU;AACZ,UAAMC,IAAQD,EAAS,CAAC,EAAE,KAAA;AAC1B,WAAKC,IACE,wHAAwHA,CAAK,YADjH;AAAA,EAErB;AAEA,QAAMC,IAAQ7F,EAAI,MAAM,0CAA0C;AAClE,MAAI6F,GAAO;AACT,QAAI/P,IAAO+P,EAAM,CAAC,EAAE,KAAA;AACpB,QAAI,gBAAgB,KAAK/P,CAAI,GAAG;AAC9B,YAAMgQ,IAAUV,GAA2BtP,CAAI;AAC/C,UAAIgQ,KAAW,KAAM,QAAOA;AAAA,IAC9B;AACA,WAAOhQ;AAAA,EACT;AAEA,SAAK,SAAS,KAAKkK,CAAG,IAEf,OAFyBA;AAGlC;AAUO,SAAS+F,GACdC,GACAC,GACAC,GAMiB;AACjB,SAAO;AAAA,IACL,KAAK,OAAOA,EAAM,cAAc,CAAC;AAAA,IACjC,OAAO,OAAOA,EAAM,gBAAgB,CAAC;AAAA,IACrC,QAAQ,OAAOA,EAAM,iBAAiB,CAAC;AAAA,IACvC,MAAM,OAAOA,EAAM,eAAe,CAAC;AAAA,EAAA;AAEvC;AAGO,SAASC,GACdV,GACAW,GACwE;AACxE,QAAMC,IAAeb,GAAiCC,CAAU,GAC1Da,IAAM,GAAGF,EAAQ,GAAG,MAAMA,EAAQ,KAAK,MAAMA,EAAQ,MAAM,MAAMA,EAAQ,IAAI;AAEnF,SAAIC,MAAiB,OACdA,IAME;AAAA,IACL,MAAM;AAAA,IACN,MAAM,uBAAuBC,CAAG,qBAAqBD,CAAY;AAAA,EAAA,IAP1D;AAAA,IACL,MAAM;AAAA,IACN,MAAM,uBAAuBC,CAAG;AAAA,EAAA,IAS/B,EAAE,MAAM,UAAU,QAAQb,EAAA;AACnC;ACzNO,SAASc,GAAU5Q,GAAe6Q,GAA4B;AACnE,QAAMC,IAAqB,EAAE,KAAA9Q,GAAK,QAAQ,OAAA,GACpC+M,IAAQ/M,EAAI,QAEZ+Q,IAAW/Q,EAAI,SAAS,IAAI,CAAC,MAAMgR,GAAc,GAAGH,GAAUC,CAAG,CAAC,EAAE,KAAK;AAAA,CAAI;AAEnF,SAAO;AAAA;AAAA,gBAEO3D,EAAWnN,EAAI,KAAK,WAAW,EAAE,CAAC;AAAA,MAC5CA,EAAI,KAAK,YAAY,eAAemN,EAAWnN,EAAI,KAAK,SAAS,CAAC,kBAAkB,EAAE;AAAA;AAAA,6BAE/DmN,EAAWJ,EAAM,UAAU,CAAC;AAAA,4BAC7BI,EAAWJ,EAAM,QAAQ,CAAC,kBAAkBI,EAAWG,EAAwBP,EAAM,UAAU,CAAC,CAAC,YAAYI,EAAWJ,EAAM,KAAK,CAAC,kBAAkBI,EAAWJ,EAAM,cAAc,MAAM,CAAC;AAAA,qCACnLI,EAAWJ,EAAM,SAAS,CAAC;AAAA;AAAA;AAAA,mBAG7CI,EAAWJ,EAAM,SAAS,CAAC;AAAA,EAC5CkE,GAA0BjR,CAAG,CAAC;AAAA,EAC9BkR,GAAmBlR,CAAG,CAAC;AAAA;AAAA;AAAA,+BAGMmN,EAAWJ,EAAM,eAAe,CAAC,YAAYI,EAAWZ,GAAmBvM,EAAI,KAAK,KAAK,CAAC,CAAC;AAAA,EACxH+Q,CAAQ;AAAA;AAAA;AAGV;AAGA,SAASE,GAA0BjR,GAAuB;AACxD,SAAOA,EAAI,SACR,IAAI,CAACsK,MAAM;AACV,UAAM6G,IAAIxE,GAAoBrC,EAAE,MAAM,KAAK;AAC3C,WAAK6G,IAEE,UADKtR,GAAmByK,EAAE,EAAE,CACf,iBAAiB6G,CAAC,wGAFvB;AAAA,EAGjB,CAAC,EACA,OAAO,OAAO,EACd,KAAK;AAAA,CAAI;AACd;AAeA,MAAMC,KAA+B;AAErC,SAASC,GAAmBvR,GAA2B;AACrD,SAAO,GAAGD,GAAmBC,CAAS,CAAC;AACzC;AAEA,SAASwR,GAA0BxR,GAA2B;AAC5D,SAAO,GAAGD,GAAmBC,CAAS,CAAC;AACzC;AAGA,SAASyR,GAAe9R,GAA2B;AACjD,SAAOA,EAAQ,QAAQ,SAAS,KAAKA,EAAQ,MAAM,4BAA4B;AACjF;AAEA,SAASyR,GAAmBlR,GAAuB;AACjD,QAAMwR,IAAkB,CAAA;AAExB,aAAWlH,KAAKtK,EAAI,UAAU;AAC5B,QAAI,CAACuR,GAAejH,CAAC,EAAG;AACxB,UAAMmH,IAAM,KAAK,IAAI,GAAGnH,EAAE,MAAM,aAAa,CAAC,GACxCoH,IAAa,KAAK,IAAI,GAAG,KAAK,MAAMpH,EAAE,MAAM,oBAAoB,CAAC,CAAC;AACxE,QAAI,EAAAmH,KAAO,KAAKC,KAAc,IAE9B;AAAA,UAAID,IAAM,GAAG;AACX,cAAMhR,IAAM4Q,GAAmB/G,EAAE,EAAE;AACnC,QAAAkH,EAAM;AAAA,UACJ,YAAY/Q,CAAG;AAAA,UACf,YAAYA,CAAG;AAAA,QAAA;AAAA,MAEnB;AACA,MAAIiR,IAAa,KACfF,EAAM;AAAA,QACJ,YAAYF;AAAA,UACVhH,EAAE;AAAA,QAAA,CACH,gDAAgDoH,CAAU;AAAA,MAAA;AAAA;AAAA,EAGjE;AAEA,SAAKF,EAAM,SACJ,2CAA2CJ,EAA4B;AAAA,EAC9EI,EAAM,KAAK;AAAA,CAAI,CAAC;AAAA,WAFU;AAI5B;AAEA,SAASR,GAAcvR,GAAkBoR,GAAoBC,GAA4B;AACvF,QAAMvJ,IAAI9H,EAAQ,OACZgR,IAAU,CAAClJ,EAAE,YAAYA,EAAE,cAAcA,EAAE,eAAeA,EAAE,WAAW,EAC1E,IAAI,CAAC4D,MAAM,GAAGA,KAAK,CAAC,IAAI,EACxB,KAAK,GAAG,GACLwG,IAAKpK,EAAE,kBAAkB,sBAAsB4F,EAAW5F,EAAE,eAAe,CAAC,MAAM,IAClFqK,IAAOjF,GAAoBpF,EAAE,KAAK,GAClCsK,IAAQrS,GAA4BC,CAAO,GAC3CqS,IACJF,KAAQC,IAAQ,eAAe1E,EAAWtN,GAAmBJ,EAAQ,EAAE,CAAC,CAAC,MAAM,IAC3EsS,IAASC,GAAavS,EAAQ,MAAM,GACpCwS,IAAQ,KAAK,IAAI,GAAGxS,EAAQ,MAAM,aAAa,CAAC,GAEhDyS,IAAUX,GAAe9R,CAAO,GAChC0S,IAAOD,KAAWD,IAAQ,IAAIZ,GAAmB5R,EAAQ,EAAE,IAAI,IAC/D2S,IACJF,KAAW,KAAK,IAAI,GAAG,KAAK,MAAMzS,EAAQ,MAAM,oBAAoB,CAAC,CAAC,IAAI,IACtE6R,GAA0B7R,EAAQ,EAAE,IACpC,IACA4S,IAAY5S,EAAQ,QAAQ,SAAS,GAErC6S,IAAU7S,EAAQ,QACrB;AAAA,IAAI,CAAC8S,GAAK7O,MACT8O;AAAA,MACED;AAAA,MACAR,EAAOrO,CAAC;AAAA,MACRA;AAAA,MACAjE,EAAQ,QAAQ;AAAA,MAChBwS;AAAA,MACA,CAACE,GAAMC,KAAQ1O,IAAI2O,IAAYD,IAAO,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAClEvB;AAAA,MACAC;AAAA,IAAA;AAAA,EACF,EAED,KAAK;AAAA,CAAI,GAIN2B,IADWhT,EAAQ,QAAQ,SAAS,KAE5BA,EAAQ,MAAM,4BAA4B,KAClD;AAAA,EAAqBiT,GAAOJ,GAAS,CAAC,CAAC;AAAA,qBACvCA;AAEN,SAAO,4BAA4B7B,CAAO,IAAIkB,CAAE,GAAGG,CAAM;AAAA,EACzDW,CAAO;AAAA;AAET;AAEA,SAASD,GACPG,GACAC,GACAC,GACAC,GACAC,GACAC,GACAnC,GACAC,GACQ;AACR,QAAM,IAAI6B,EAAO,OACXM,IAAK,EAAE,gBAAgB,oBAAoB,EAAE,aAAa,MAAM,IAChEtB,IAAK,EAAE,kBAAkB,sBAAsBxE,EAAW,EAAE,eAAe,CAAC,MAAM;AAExF,MAAI+F,IAAS;AACb,MAAIJ,IAAc,KAAKC,IAAc,GAAG;AACtC,UAAMI,IAAOJ,IAAc,GACrBK,IAAKP,IAAc,IAAI,GAAGM,CAAI,OAAO;AAE3C,IAAAD,IAAS,iBADEL,IAAcC,IAAc,IAAI,GAAGK,CAAI,OAAO,KAC7B,QAAQC,CAAE;AAAA,EACxC;AACA,QAAMC,IAAUL,IAAgB,eAAe7F,EAAW6F,CAAa,CAAC,MAAM,IAExEM,IAAU3F,GAA8BmD,EAAI,IAAI,MAAM,GACtDyC,IAASZ,EAAO,OACnB,IAAI,CAACnL,MAAM;AACV,QAAIA,EAAE,YAAY;AAChB,UAAInF,IAAOkM,GAA0B/G,EAAE,YAAY8L,CAAO;AAC1D,UAAI9L,EAAE,SAAS,QAAQ;AACrB,cAAMxB,IAAIwB,EAAE,OAMNmJ,IAAM,GAAG,OAAO3K,EAAE,cAAc,CAAC,CAAC,MAAM,OAAOA,EAAE,gBAAgB,CAAC,CAAC,MAAM,OAAOA,EAAE,iBAAiB,CAAC,CAAC,MAAM,OAAOA,EAAE,eAAe,CAAC,CAAC;AAC3I,QAAA3D,IAAOqM,GAAuCrM,GAAMsO,GAAK2C,CAAO;AAAA,MAClE;AACA,aAAOZ,GAAOrQ,GAAM,CAAC;AAAA,IACvB;AACA,UAAMtD,IAAM8R,EAAS,QAAQrJ,EAAE,IAAI;AACnC,WAAOkL,GAAO3T,EAAI,OAAOyI,EAAE,OAAOsJ,CAAG,GAAG,CAAC;AAAA,EAC3C,CAAC,EACA,KAAK;AAAA,CAAI;AAEZ,SAAO,2BAA2B8B,CAAK,IAAIK,CAAE,GAAGtB,CAAE,GAAGuB,CAAM,GAAGG,CAAO;AAAA,EACrEE,KAAU,+BAA+B;AAAA;AAE3C;AAEA,SAASvB,GAAawB,GAAiC;AAErD,QAAMC,IAAQD,EAAO,MAAM,GAAG,EAAE,IAAI,MAAM,GACpCE,IAAQD,EAAM,OAAO,CAACnJ,GAAGqJ,MAAMrJ,IAAIqJ,GAAG,CAAC;AAC7C,SAAOF,EAAM,IAAI,CAACzN,MAAM,IAAKA,IAAI0N,IAAS,KAAK,QAAQ,CAAC,CAAC,GAAG;AAC9D;AAEA,SAAShB,GAAO5P,GAAckH,GAAmB;AAC/C,QAAM2G,IAAM,IAAI,OAAO3G,CAAC;AACxB,SAAOlH,EACJ,MAAM;AAAA,CAAI,EACV,IAAI,CAAC8Q,MAAOA,KAAIjD,IAAMiD,CAAM,EAC5B,KAAK;AAAA,CAAI;AACd;AC1MO,SAASC,GACd7T,GACA6Q,GACAiD,IAAsB,CAAA,GACR;AACd,QAAMC,IAAuBD,EAAK,UAAU;AAE5C,MAAIC,MAAW;AAEb,UAAM,IAAI,MAAM,aAAaA,CAAM,EAAE;AAGvC,QAAMC,IAAOpD,GAAU5Q,GAAK6Q,CAAQ,GAE9BoD,IAAWC,GAAYF,GAAM;AAAA,IACjC,iBAAiB;AAAA,IACjB,cAAc;AAAA,EAAA,CACf;AAED,MAAI1T,IAAO2T,EAAS;AACpB,SAAA3T,IAAOD,GAAqCC,GAAMN,CAAG,GACrDM,IAAO4L,GAA0B5L,GAAMyL,GAA0B/L,EAAI,MAAM,CAAC,GACxE8T,EAAK,wBACPxT,IAAO6T,GAAiB7T,GAAMN,EAAI,SAAS,IAGtC;AAAA,IACL,MAAAgU;AAAA,IACA,MAAA1T;AAAA,IACA,SAAS2T,EAAS,UAAU,CAAA,GAAI,IAAI,CAACG,OAAY;AAAA,MAC/C,SAASA,EAAE,oBAAoBA,EAAE,WAAW,OAAOA,CAAC;AAAA,IAAA,EACpD;AAAA,EAAA;AAEN;AAMO,SAASD,GAAiBrR,GAAcuR,GAA0B;AACvE,SAAKA,EAAK,SACHvR,EAAK,QAAQ,4BAA4B,CAACuH,GAAKzK,MAAQ;AAC5D,UAAMuL,IAAIkJ,EAAK,KAAK,CAACV,MAAMA,EAAE,QAAQ/T,CAAG;AACxC,WAAIuL,KAAKA,EAAE,UAAU,OAAaA,EAAE,SAC7Bd;AAAA,EACT,CAAC,IALwBvH;AAM3B;ACxEA,IAAIwR,KAAW;AAMR,SAASC,GAAIC,IAAS,MAAc;AACzC,EAAAF,MAAY;AACZ,QAAMlV,IAAK,KAAK,IAAA,EAAM,SAAS,EAAE,EAAE,MAAM,EAAE,GACrCC,IAAO,KAAK,MAAM,KAAK,WAAW,MAAM,CAAC,EAC5C,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AAClB,SAAO,GAAGmV,CAAM,IAAIpV,CAAE,GAAGC,CAAI,GAAGiV,GAAS,SAAS,EAAE,CAAC;AACvD;ACEO,MAAMG,GAAM;AAAA,EASjB,YAAYC,GAAmB;AARvB,IAAA5V,EAAA;AACA,IAAAA,EAAA,oBAA+B;AAC/B,IAAAA,EAAA,wCAAgC,IAAA;AAChC,IAAAA,EAAA,iDAAkD,IAAA;AAClD,IAAAA,EAAA,eAAoB,CAAA;AACpB,IAAAA,EAAA,iBAAsB,CAAA;AACtB,IAAAA,EAAA,uBAAgB;AAGtB,SAAK,OAAO4V;AAAA,EACd;AAAA,EAEA,IAAI,MAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,YAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAUC,GAA0B;AAClC,gBAAK,WAAW,IAAIA,CAAE,GACf,MAAM,KAAK,WAAW,OAAOA,CAAE;AAAA,EACxC;AAAA,EAEA,mBAAmBA,GAAmC;AACpD,gBAAK,oBAAoB,IAAIA,CAAE,GACxB,MAAM,KAAK,oBAAoB,OAAOA,CAAE;AAAA,EACjD;AAAA,EAEA,aAAahS,GAAuB;AAClC,SAAK,aAAaA,GAClB,KAAK,oBAAoB,QAAQ,CAACiR,MAAMA,GAAG;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAOgB,GAAoCd,IAA6B,IAAI;AAC1E,UAAMe,IAAQ,gBAAgB,KAAK,IAAI;AACvC,IAAAD,EAAQC,CAAK,GACb,KAAK,MAAM,KAAK,KAAK,IAAI,GACrB,KAAK,MAAM,SAAS,KAAK,iBAAe,KAAK,MAAM,MAAA,GACvD,KAAK,UAAU,CAAA,GACf,KAAK,OAAOA,GACPf,EAAK,UAAQ,KAAK,QAAQ,QAAQ;AAAA,EACzC;AAAA;AAAA,EAGA,QAAQ9T,GAAe;AACrB,SAAK,QAAQ,CAAA,GACb,KAAK,UAAU,CAAA,GACf,KAAK,OAAOA,GACZ,KAAK,QAAQ,SAAS;AAAA,EACxB;AAAA,EAEA,OAAgB;AACd,UAAM+B,IAAO,KAAK,MAAM,IAAA;AACxB,WAAKA,KACL,KAAK,QAAQ,KAAK,KAAK,IAAI,GAC3B,KAAK,OAAOA,GACZ,KAAK,QAAQ,SAAS,GACf,MAJW;AAAA,EAKpB;AAAA,EAEA,OAAgB;AACd,UAAMH,IAAO,KAAK,QAAQ,IAAA;AAC1B,WAAKA,KACL,KAAK,MAAM,KAAK,KAAK,IAAI,GACzB,KAAK,OAAOA,GACZ,KAAK,QAAQ,SAAS,GACf,MAJW;AAAA,EAKpB;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,MAAM,SAAS;AAAA,EAC7B;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,QAAQ,SAAS;AAAA,EAC/B;AAAA,EAEQ,QAAQD,GAAoC;AAClD,UAAMmT,IAA2B,EAAE,QAAAnT,EAAA;AACnC,SAAK,WAAW,QAAQ,CAACiS,MAAMA,EAAEkB,CAAM,CAAC;AAAA,EAC1C;AACF;AAMO,SAASC,EAAY/U,GAAeF,GAAwC;AACjF,SAAOE,EAAI,SAAS,KAAK,CAACsK,MAAMA,EAAE,OAAOxK,CAAS;AACpD;AAEO,SAASkV,EACdhV,GACAiV,GACqE;AACrE,aAAWxV,KAAWO,EAAI;AACxB,aAAS0D,IAAI,GAAGA,IAAIjE,EAAQ,QAAQ,QAAQiE,KAAK,GAAG;AAElD,YAAMwR,IADMzV,EAAQ,QAAQiE,CAAC,EACb,OAAO,KAAK,CAAC8D,MAAMA,EAAE,OAAOyN,CAAO;AACnD,UAAIC,EAAK,QAAO,EAAE,SAAAzV,GAAS,aAAaiE,GAAG,OAAOwR,EAAA;AAAA,IACpD;AAGJ;AAQO,SAASC,GAAoBN,GAAiB/U,GAAmB;AACtE,QAAMsV,IAAMP,EAAM,SAAS,KAAK,CAACvK,MAAMA,EAAE,OAAOxK,CAAS;AAIzD,EAHI,CAACsV,KACDA,EAAI,QAAQ,SAAS,KAErB,CADYA,EAAI,QAAQ,MAAM,CAAC7C,MAAQA,EAAI,OAAO,WAAW,CAAC,MAElEsC,EAAM,WAAWA,EAAM,SAAS,OAAO,CAACvK,MAAMA,EAAE,OAAOxK,CAAS;AAClE;AAGO,SAASuV,GAAmBR,GAAiB;AAClD,EAAAA,EAAM,WAAWA,EAAM,SAAS;AAAA,IAAO,CAACO,MACtCA,EAAI,QAAQ,KAAK,CAAC7C,MAAQA,EAAI,OAAO,SAAS,CAAC;AAAA,EAAA;AAEnD;AAGO,MAAM+C,KAAuB,CAAC,OAAO,OAAO,OAAO,OAAO,GAIpDC,KAAqB,CAAC,OAAO,OAAO,KAAK;AAG/C,SAASC,GAAoBhC,GAAoD;AACtF,SACEA,MAAW,SAASA,MAAW,SAASA,MAAW,SAASA,MAAW;AAE3E;AAGO,SAASiC,GAAkBjC,GAAkD;AAClF,SAAOA,MAAW,SAASA,MAAW,SAASA,MAAW;AAC5D;AAGO,SAASkC,GAAiBjW,GAAkB+T,GAA6B;AAC9E,QAAMmC,IAAWnC,EAAO,MAAM,GAAG,EAAE,QAC7BoC,IAAUnW,EAAQ,QAAQ;AAChC,MAAIkW,MAAaC,GAAS;AACxB,IAAAnW,EAAQ,SAAS+T;AACjB;AAAA,EACF;AACA,MAAImC,IAAWC;AACb,aAASlS,IAAIkS,GAASlS,IAAIiS,GAAUjS;AAClC,MAAAjE,EAAQ,QAAQ,KAAK,EAAE,IAAI8U,GAAI,KAAK,GAAG,OAAO,CAAA,GAAI,QAAQ,CAAA,GAAI;AAAA,OAE3D;AACL,UAAMsB,IAAUpW,EAAQ,QAAQ,OAAOkW,CAAQ,GACzCG,IAAOrW,EAAQ,QAAQkW,IAAW,CAAC;AACzC,QAAIG;AACF,iBAAWvD,KAAOsD,EAAS,CAAAC,EAAK,OAAO,KAAK,GAAGvD,EAAI,MAAM;AAAA,EAE7D;AACA,EAAA9S,EAAQ,SAAS+T;AACnB;AAEO,SAASuC,GAAcvC,GAAgC;AAC5D,QAAMwC,IAAWxC,EAAO,MAAM,GAAG,EAAE,QAC7BlB,IAAoB,MAAM,KAAK,EAAE,QAAQ0D,EAAA,GAAY,OAAO;AAAA,IAChE,IAAIzB,GAAI,KAAK;AAAA,IACb,OAAO,CAAA;AAAA,IACP,QAAQ,CAAA;AAAA,EAAC,EACT;AACF,SAAO;AAAA,IACL,IAAIA,GAAI,KAAK;AAAA,IACb,MAAM;AAAA,IACN,QAAAf;AAAA,IACA,OAAO;AAAA;AAAA,MAEL,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,eAAe;AAAA,MACf,aAAa;AAAA,IAAA;AAAA,IAEf,SAAAlB;AAAA,EAAA;AAEJ;AC7MO,SAAS2D,GAAmBC,GAAuB;AACxD,QAAM,IAAI,OAAOA,KAAS,EAAE,EAAE,KAAA,GACxB7R,IAAI,EAAE,MAAM,0BAA0B;AAC5C,WAAQA,KAAA,gBAAAA,EAAI,OAAM,EAAE,QAAQ,YAAY,EAAE,EAAE,QAAQ,YAAY,EAAE,GAAG,KAAA;AACvE;AAEO,SAAS8R,EAAoBvW,GAAqB;AACvD,SAAO,KAAKA,CAAG;AACjB;AAGO,SAASwW,GAAsBjL,GAAgE;;AACpG,MAAIA,EAAE,UAAU,QAAQ,OAAOA,EAAE,MAAM,EAAE,KAAA,MAAW,GAAI,QAAO,OAAOA,EAAE,MAAM;AAC9E,QAAMvL,MAAMM,IAAAiL,EAAE,QAAF,gBAAAjL,EAAO,WAAU+V,GAAmB,OAAO9K,EAAE,GAAG,CAAC;AAC7D,SAAOgL,EAAoBvW,CAAG;AAChC;AAGO,SAASyW,GAAkBlL,GAAuB;;AACvD,QAAMvL,MAAMM,IAAAiL,EAAE,QAAF,gBAAAjL,EAAO,WAAU+V,GAAmB,OAAO9K,EAAE,GAAG,CAAC,GACvDmL,IAAOnL,EAAE,QAAQ;AACvB,SAAO;AAAA,IACL,GAAGA;AAAA,IACH,KAAAvL;AAAA,IACA,MAAA0W;AAAA,IACA,QAAQF,GAAsB,EAAE,GAAGjL,GAAG,KAAAvL,EAAU,CAAC;AAAA,EAAA;AAErD;AAEO,SAAS2W,GAAsBL,GAAeM,GAA2B;AAC9E,QAAMC,IAAWP,EAAM,QAAQ,MAAM,QAAQ,GACvCQ,IAAWR,EACd,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM;AACvB,SAAO,YAAYO,CAAQ,kBAAkBD,CAAS,2CAA2CE,CAAQ;AAC3G;AAQO,SAASC,GAA2BxL,GAAiC;AAC1E,QAAMyL,IAAaP,GAAkBlL,CAAC;AACtC,SAAO,EAAE,SAASgL,EAAoBS,EAAW,GAAG,GAAG,QAAQ,GAAA;AACjE;AAGO,SAASC,GACd1L,GACA2L,GACoB;;AACpB,QAAMF,IAAaP,GAAkBlL,CAAC,GAChC+K,MAAQhW,IAAA4W,KAAA,gBAAAA,EAAS,UAAT,gBAAA5W,EAAgB,WAAUiW,EAAoBS,EAAW,GAAG,GACpEJ,MAAYpW,IAAA0W,KAAA,gBAAAA,EAAS,cAAT,gBAAA1W,EAAoB,WAAU;AAEhD,MAAIwW,EAAW,SAAS;AACtB,WAAO;AAAA,MACL,SAASL,GAAsBL,GAAOM,CAAS;AAAA,MAC/C,QAAQ;AAAA,IAAA;AAGZ,MAAII,EAAW,SAAS,SAAS;AAC/B,UAAMG,IAAMd,GAAmBC,CAAK;AACpC,WAAO;AAAA,MACL,SAAS,aAAaA,EAAM,QAAQ,MAAM,QAAQ,CAAC,UAAUa,EAAI,QAAQ,MAAM,QAAQ,CAAC;AAAA,MACxF,QAAQ;AAAA,IAAA;AAAA,EAEZ;AACA,SAAOJ,GAA2BC,CAAU;AAC9C;AAGO,SAASI,GACd7L,GACA2L,GACoB;AACpB,QAAMF,IAAaP,GAAkBlL,CAAC;AACtC,SAAIyL,EAAW,SAAS,UAAUA,EAAW,SAAS,UAC7CC,GAA+BD,GAAYE,CAAO,IAEpDH,GAA2BC,CAAU;AAC9C;ACrFO,SAASK,GAAuB3W,GAAc4W,GAAwB;AAC3E,QAAMxH,IAAU,OAAOpP,KAAQ,EAAE,EAAE,KAAA;AACnC,MAAI,CAAC4W,EAAQ,QAAOxH;AACpB,MAAI,CAACA,EAAS,QAAO,wBAAwBwH,CAAM;AAEnD,QAAMC,IAAazH,EAAQ,MAAM,4BAA4B;AAC7D,MAAIyH,KAAcA,EAAW,SAAS,MAAM;AAC1C,UAAMnM,IAAMmM,EAAW;AACvB,WAAOzH,EAAQ,MAAM,GAAG1E,CAAG,IAAIkM,IAASxH,EAAQ,MAAM1E,CAAG;AAAA,EAC3D;AACA,SAAO0E,IAAUwH;AACnB;ACIO,SAASE,GACdpX,GACAF,GACA+Q,GACQ;;AACR,QAAMpR,IAAUO,EAAI,SAAS,KAAK,CAACsK,MAAMA,EAAE,OAAOxK,CAAS;AAC3D,MAAI,CAACL,EAAS,QAAO;AACrB,QAAM4X,IAAiB,EAAE,GAAGrX,GAAK,UAAU,CAACP,CAAO,EAAA,GAC7C,EAAE,MAAAa,MAASuT,GAAUwD,GAAMxG,GAAU,EAAE,qBAAqB,IAAO;AACzE,MAAI;AAEF,cAAQ3Q,IADO,IAAI,UAAA,EAAY,gBAAgBI,GAAM,WAAW,EACjD,SAAP,gBAAAJ,EAAa,cAAa,IAAI,KAAA;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,SAASoX,GACPhX,GACAV,GAC8C;;AAC9C,MAAI;AACF,UAAMY,IAAS,IAAI,UAAA,EAAY,gBAAgBF,GAAM,WAAW,GAC1DM,IAAKJ,EAAO,cAAc,IAAIjB,EAAyB,KAAKK,CAAG,IAAI;AACzE,QAAI,CAACgB,EAAI,QAAO;AAChB,UAAM2W,IAAc3W,EAAG,aAAa,IAC9BsV,IAAQvW,GAA0BC,CAAG;AAC3C,IAAAgB,EAAG,YAAYJ,EAAO,eAAe0V,CAAK,CAAC;AAC3C,UAAMjW,MAAOC,IAAAM,EAAO,SAAP,gBAAAN,EAAa,cAAa,IACjCC,MAAOC,IAAAI,EAAO,SAAP,gBAAAJ,EAAa,cAAa;AACvC,WAAO,EAAE,MAAM,GAAGH,CAAI,GAAGE,CAAI,IAAI,aAAAoX,EAAA;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAASC,GACdlX,GACAN,GACA6Q,GACkC;AAClC,QAAMtQ,IAAQP,EAAI,SAAS,OAAON,EAAuB;AACzD,MAAI,CAACa,EAAM,OAAQ,QAAO,EAAE,MAAAD,GAAM,UAAU,GAAC;AAE7C,MAAImX,IAAanX;AACjB,QAAMoX,IAAmC,CAAA;AAEzC,aAAWjY,KAAWc,GAAO;AAC3B,UAAMX,IAAMJ,GAA4BC,CAAO;AAC/C,QAAI,CAACG,EAAK;AAEV,UAAM+X,IAAaL,GAA2BG,GAAY7X,CAAG;AAC7D,QAAI+X,GAAY;AACd,MAAAD,EAAS9X,CAAG,IAAI+X,EAAW,aAC3BF,IAAaE,EAAW;AACxB;AAAA,IACF;AAEA,UAAMC,IAAUR,GAAsBpX,GAAKP,EAAQ,IAAIoR,CAAQ;AAC/D,QAAI,CAAC+G,EAAS;AACd,IAAAF,EAAS9X,CAAG,IAAIgY;AAChB,UAAM1B,IAAQvW,GAA0BC,CAAG,GACrCoL,IAAMyM,EAAW,QAAQG,CAAO;AACtC,IAAI5M,KAAO,MACTyM,IAAaA,EAAW,MAAM,GAAGzM,CAAG,IAAIkL,IAAQuB,EAAW,MAAMzM,IAAM4M,EAAQ,MAAM;AAAA,EAEzF;AAEA,SAAO,EAAE,MAAMH,GAAY,UAAAC,EAAA;AAC7B;AC/FA,MAAMG,KAA+C;AAAA,EACnD,GAAK;AAAA,EACL,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AACX;AAEO,SAASC,GAAiBtE,GAA+B;AAC9D,SAAOqE,GAAcrE,CAAM,KAAKA;AAClC;ACHO,SAASuE,GAAWzX,GAAcoS,IAAS,MAAc;;AAC9D,MAAI,CAACpS,EAAM,QAAO;AAClB,QAAM0X,wBAAW,IAAI;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD,GACKC,wBAAe,IAAI,CAAC,OAAO,YAAY,UAAU,OAAO,CAAC,GAEzDC,IAAS5X,EAAK,MAAM,sEAAsE,KAAK,CAAA;AACrG,MAAI8O,IAAQ,GACR+I,IAA0B,CAAA;AAC9B,QAAMC,IAAgB,CAAA,GAChBzH,IAAM,CAAC3G,MAAc0I,EAAO,OAAO,KAAK,IAAI,GAAG1I,CAAC,CAAC;AAEvD,aAAWK,KAAO6N,GAAQ;AACxB,UAAMG,IAAMhO,GACNiO,IAAaH,EAAc,SAAS;AAE1C,QAAIE,EAAI,WAAW,MAAM,KAAKA,EAAI,WAAW,KAAK,GAAG;AACnD,MAAIC,IAAYF,EAAI,KAAKC,CAAG,MACnB,KAAK1H,EAAIvB,CAAK,IAAIiJ,EAAI,MAAM;AACrC;AAAA,IACF;AACA,QAAIA,EAAI,WAAW,IAAI,GAAG;AACxB,MAAAD,EAAI,KAAKC,EAAI,MAAM;AACnB;AAAA,IACF;AAEA,QAAIA,EAAI,WAAW,IAAI,GAAG;AACxB,YAAMpQ,KAAO/H,KAAAmY,EAAI,MAAM,cAAc,KAAK,CAAA,GAAI,CAAC,MAAlC,gBAAAnY,EAAqC;AAClD,UAAIiY,EAAcA,EAAc,SAAS,CAAC,MAAMlQ,GAAK;AACnD,QAAAkQ,EAAc,IAAA,GACdC,EAAI,KAAKC,CAAG;AACZ;AAAA,MACF;AACA,MAAAjJ,IAAQ,KAAK,IAAI,GAAGA,IAAQ,CAAC,GAC7BgJ,EAAI,KAAKzH,EAAIvB,CAAK,IAAIiJ,EAAI,MAAM;AAChC;AAAA,IACF;AAEA,QAAIA,EAAI,WAAW,GAAG,GAAG;AACvB,YAAMpQ,KAAO7H,KAAAiY,EAAI,MAAM,YAAY,KAAK,CAAA,GAAI,CAAC,MAAhC,gBAAAjY,EAAmC,eAC1CmY,IAAcF,EAAI,SAAS,IAAI,KAAMpQ,KAAO+P,EAAK,IAAI/P,CAAG;AAC9D,UAAIqQ,GAAY;AACd,QAAAF,EAAI,KAAKC,CAAG,GACRpQ,KAAOgQ,EAAS,IAAIhQ,CAAG,KAAK,CAACsQ,KAAaJ,EAAc,KAAKlQ,CAAG;AACpE;AAAA,MACF;AACA,MAAAmQ,EAAI,KAAKzH,EAAIvB,CAAK,IAAIiJ,EAAI,MAAM,GAC5BpQ,KAAO,CAACsQ,MACNN,EAAS,IAAIhQ,CAAG,IAAGkQ,EAAc,KAAKlQ,CAAG,IACxCmH,KAAS;AAEhB;AAAA,IACF;AAGA,QAAIkJ;AACF,MAAAF,EAAI,KAAKC,CAAG;AAAA,SACP;AACL,YAAMG,IAAMH,EAAI,QAAQ,QAAQ,GAAG,EAAE,KAAA;AACrC,MAAIG,KAAKJ,EAAI,KAAKzH,EAAIvB,CAAK,IAAIoJ,CAAG;AAAA,IACpC;AAAA,EACF;AAEA,SAAOJ,EAAI,KAAK;AAAA,CAAI;AACtB;AClFA,MAAMK,KAA0B,MAC1BC,KAA2B;AAG1B,SAASC,KAAqD;AACnE,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,EAAA;AAEZ;AAGO,SAASC,GACd9E,GACqB;AACrB,QAAM+E,IAAuCJ,IACvCK,IAAyCJ;AAC/C,SAAO;AAAA,IACL,OAAO,GAAG,KAAK,MAAM,OAAO,aAAaG,CAAa,CAAC;AAAA,IACvD,QAAQ,GAAG,KAAK,MAAM,OAAO,cAAcC,CAAc,CAAC;AAAA,EAAA;AAE9D;ACLO,MAAMC,GAAM;AAAA,EAWjB,YAAYjF,GAAoB;AAVhC,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,yBAAiC,CAAA;AACjC,IAAAA,EAAA;AAGN,SAAK,OAAOgV,GAEZ,KAAK,OAAOhH,EAAE,OAAO;AAAA,MACnB,OAAO;AAAA,MACP,SAAS,CAAC,MAAa;AACrB,QAAI,EAAE,WAAW,KAAK,aAAW,aAAA;AAAA,MACnC;AAAA,IAAA,CACD,GAED,KAAK,WAAWA,EAAE,UAAU,EAAE,OAAO,oBAAoB,GACzD,KAAK,SAASA,EAAE,OAAO,EAAE,OAAO,kBAAkB,GAClD,KAAK,WAAWA,EAAE,UAAU,EAAE,OAAO,oBAAoB,GAEzD,KAAK,OAAOA;AAAA,MACV;AAAA,MACA;AAAA,QACE,OAAO,kBAAkBgH,EAAK,aAAa,EAAE;AAAA,QAC7C,OAAO;AAAA,UACLA,EAAK,QAAQ,SAASA,EAAK,KAAK,MAAM;AAAA,UACtCA,EAAK,SAAS,UAAUA,EAAK,MAAM,MAAM;AAAA,QAAA,EACzC,KAAK,EAAE;AAAA,MAAA;AAAA,MAEX,CAAC,KAAK,UAAU,KAAK,QAAQ,KAAK,QAAQ;AAAA,IAAA,GAG5C,KAAK,KAAK,OAAO,KAAK,IAAI,GAC1B,KAAK,KAAK,KAAK,MAEf,KAAK,cAAA;AAAA,EACP;AAAA,EAEA,KAAK3S,IAAsB,SAAS,MAAM;AACxC,IAAAA,EAAO,OAAO,KAAK,EAAE,GACrB,KAAK,iBAAiB,CAAC,MAAqB;AAC1C,MAAI,EAAE,QAAQ,YAAU,KAAK,aAAA;AAAA,IAC/B,GACA,SAAS,iBAAiB,WAAW,KAAK,cAAc,GACxD,sBAAsB,MAAM,KAAK,GAAG,UAAU,IAAI,SAAS,CAAC;AAAA,EAC9D;AAAA,EAEA,QAAQ;AACN,SAAK,aAAA;AAAA,EACP;AAAA,EAEA,SAAS6X,GAAe;AACtB,SAAK,KAAK,QAAQA,GAClB,KAAK,cAAA;AAAA,EACP;AAAA;AAAA,EAGA,QAAQpG,GAAgBqG,GAAiB;AACvC,IAAIrG,MAAU,WACZ,KAAK,KAAK,QAAQA,GAClB,KAAK,KAAK,MAAM,QAAQA,IAEtBqG,MAAW,WACb,KAAK,KAAK,SAASA,GACnB,KAAK,KAAK,MAAM,SAASA;AAAA,EAE7B;AAAA;AAAA,EAGA,IAAI,OAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,SAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,iBAAiBrY,GAAiB;AAChC,SAAK,gBAAgB,KAAKA,CAAE;AAC5B,UAAMsY,IAAQ,KAAK,SAAS,cAAc,yBAAyB;AACnE,IAAAA,KAAA,QAAAA,EAAO,OAAOtY;AAAA,EAChB;AAAA,EAEA,IAAI,cAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,gBAAgB;;AACtB,SAAK,SAAS,YAAY;AAC1B,UAAMoY,IAAQlM,EAAE,OAAO,EAAE,OAAO,kBAAA,GAAqB,CAAC,KAAK,KAAK,KAAK,CAAC,GAChEoM,IAAQpM,EAAE,OAAO,EAAE,OAAO,0BAA0B;AAC1D,eAAWlM,KAAM,KAAK,gBAAiB,CAAAsY,EAAM,OAAOtY,CAAE;AACtD,UAAMuY,IAAWrM;AAAA,MACf;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAO1M,KAAAF,IAAA,KAAK,MAAK,MAAV,gBAAAE,EAAA,KAAAF,GAAc,uBAAsB;AAAA,QAC3C,gBAAckZ,KAAAC,IAAA,KAAK,MAAK,MAAV,gBAAAD,EAAA,KAAAC,GAAc,oBAAmB;AAAA,QAC/C,SAAS,MAAM,KAAK,aAAA;AAAA,MAAa;AAAA,MAEnC,CAACC,IAAW;AAAA,IAAA;AAEd,SAAK,SAAS,OAAON,GAAOE,GAAOC,CAAQ;AAAA,EAC7C;AAAA,EAEQ,eAAe;;AACrB,IAAI,KAAK,kBAAgB,SAAS,oBAAoB,WAAW,KAAK,cAAc,GACpF,KAAK,GAAG,UAAU,OAAO,SAAS,GAClC,WAAW,MAAM,KAAK,GAAG,OAAA,GAAU,GAAG,IACtC/Y,KAAAF,IAAA,KAAK,MAAK,YAAV,QAAAE,EAAA,KAAAF;AAAA,EACF;AACF;AAEA,SAASoZ,KAAwB;AAC/B,QAAM1Y,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,YACD,oGACKA;AACT;AC/HA,MAAM2Y,KAAqB;AAKpB,MAAMC,GAAe;AAAA,EAS1B,YAAY1F,GAA6B;AARjC,IAAAhV,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,YAAwB;AACxB,IAAAA,EAAA,iBAAyB;AACzB,IAAAA,EAAA;AACA,IAAAA,EAAA,mBAAY;AAGlB,SAAK,OAAOgV;AACZ,UAAM2F,IAAcd,GAAA;AACpB,SAAK,QAAQ,IAAII,GAAM;AAAA,MACrB,OAAOjF,EAAK,EAAE,iBAAiB;AAAA,MAC/B,WAAW;AAAA,MACX,OAAO2F,EAAY;AAAA,MACnB,QAAQA,EAAY;AAAA,MACpB,SAAS,MAAM,KAAK,WAAA;AAAA,MACpB,GAAG3F,EAAK;AAAA,IAAA,CACT,GACD,KAAK,aAAahH,EAAE,OAAO,EAAE,OAAO,qBAAqB,GACzD,KAAK,MAAM,KAAK,OAAO,KAAK,UAAU,GAEtC,KAAK,cAAcA;AAAA,MACjB;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MAAM,KAAK,gBAAA;AAAA,MAAgB;AAAA,MAEtC,CAAC4M,IAAc;AAAA,IAAA,GAEjB,KAAK,MAAM,iBAAiB,KAAK,WAAW,GAC5C,KAAK,oBAAA;AAEL,UAAMC,IAAc7M;AAAA,MAClB;AAAA,MACA,EAAE,OAAO,UAAU,MAAM,UAAU,SAAS,MAAM,KAAK,YAAU;AAAA,MACjE,CAACgH,EAAK,EAAE,iBAAiB,CAAC;AAAA,IAAA,GAEtB8F,IAAU9M;AAAA,MACd;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MAAM,KAAK,cAAA;AAAA,MAAc;AAAA,MAEpC,CAACgH,EAAK,EAAE,aAAa,CAAC;AAAA,IAAA;AAExB,SAAK,MAAM,OAAO,OAAO6F,GAAaC,CAAO;AAAA,EAC/C;AAAA,EAEA,KAAK3E,GAAiB4E,GAAwB;AAC5C,UAAM7Z,IAAM,KAAK,KAAK,MAAM,KACtB8Z,IAAM9E,EAAkBhV,GAAKiV,CAAO;AAC1C,QAAI,CAAC6E,EAAK;AAEV,SAAK,WAAA,GACL,KAAK,UAAU7E;AACf,UAAM8E,IAAQD,EAAI,OACZ/a,IAAM,KAAK,KAAK,SAAS,IAAIgb,EAAM,IAAI,GACvCrF,IACJqF,EAAM,eACLhb,IAAMA,EAAI,OAAOgb,EAAM,OAAkC,EAAE,KAAA/Z,GAAK,QAAQ,OAAA,CAAQ,IAAI;AAEvF,SAAK,YAAYga,GAAA,GACjB,KAAK,MAAM,SAAS,KAAK,KAAK,EAAE,2BAA2B,EAAE,MAAMH,EAAA,CAAgB,CAAC,GACpF,KAAK,gBAAA,GACL,KAAK,KAAK,IAAII,GAAW;AAAA,MACvB,QAAQ,KAAK;AAAA,MACb,OAAOC,GAAY,OAAO;AAAA,QACxB,KAAKxF;AAAA,QACL,YAAY,CAACyF,IAAYC,GAAA,CAAQ;AAAA,MAAA,CAClC;AAAA,IAAA,CACF,GACD,KAAK,MAAM,KAAK,KAAK,KAAK,WAAW;AAAA,EACvC;AAAA,EAEA,UAAU;AACR,SAAK,WAAA,GACD,KAAK,MAAM,GAAG,iBAAe,KAAK,MAAM,MAAA;AAAA,EAC9C;AAAA,EAEQ,YAAY;AAClB,QAAI,CAAC,KAAK,GAAI;AACd,UAAMtX,IAAOiV,GAAW,KAAK,GAAG,MAAM,IAAI,UAAU;AACpD,SAAK,GAAG,SAAS;AAAA,MACf,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,QAAQ,QAAQjV,EAAA;AAAA,IAAK,CAChE;AAAA,EACH;AAAA,EAEQ,kBAAkB;AACxB,UAAMuX,IAAO,KAAK,YACdzB,GAAA,IACAD,GAAA;AACJ,SAAK,MAAM,QAAQ0B,EAAK,OAAOA,EAAK,MAAM,GAC1C,KAAK,MAAM,YAAY,UAAU,OAAO,gBAAgB,KAAK,SAAS,GACtE,KAAK,oBAAA;AAAA,EACP;AAAA,EAEQ,kBAAkB;AACxB,SAAK,YAAY,CAAC,KAAK,WACvBC,GAAmB,KAAK,SAAS,GACjC,KAAK,gBAAA,GACL,sBAAsB,MAAA;;AAAM,cAAApa,IAAA,KAAK,OAAL,gBAAAA,EAAS;AAAA,KAAgB;AAAA,EACvD;AAAA,EAEQ,sBAAsB;AAC5B,SAAK,YAAY,QAAQ,KAAK,YAAY,KAAK,KAAK,EAAE,gBAAgB,IAAI,KAAK,KAAK,EAAE,iBAAiB,GACvG,KAAK,YAAY,aAAa,gBAAgB,KAAK,YAAY,SAAS,OAAO,GAC/E,KAAK,YAAY,gBAAgB,KAAK,YAAYqa,GAAA,IAAgBb,IAAc;AAAA,EAClF;AAAA,EAEQ,gBAAgB;AACtB,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,QAAS;AAC/B,UAAM5W,IAAO,KAAK,GAAG,MAAM,IAAI,SAAA,GACzB0X,IAAK,KAAK;AAChB,SAAK,KAAK,MAAM,OAAO,CAACtb,MAAM;AAC5B,YAAM0U,IAAIoB,EAAkB9V,GAAGsb,CAAE;AACjC,MAAI5G,MAAGA,EAAE,MAAM,aAAa9Q;AAAA,IAC9B,CAAC,GACD,KAAK,MAAM,MAAA;AAAA,EACb;AAAA,EAEQ,aAAa;AACnB,IAAI,KAAK,OACP,KAAK,GAAG,QAAA,GACR,KAAK,KAAK,OAEZ,KAAK,UAAU,MACf,KAAK,MAAM,YAAY,UAAU,OAAO,cAAc;AAAA,EACxD;AACF;AAEA,SAASkX,KAA6B;AACpC,MAAI;AACF,WAAO,aAAa,QAAQT,EAAkB,MAAM;AAAA,EACtD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASe,GAAmBG,GAAoB;AAC9C,MAAI;AACF,iBAAa,QAAQlB,IAAoBkB,IAAY,MAAM,GAAG;AAAA,EAChE,QAAQ;AAAA,EAER;AACF;AAEA,SAASf,KAA2B;AAClC,QAAM9Y,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,YACD,yJACKA;AACT;AAEA,SAAS2Z,KAA0B;AACjC,QAAM3Z,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,YACD,0JACKA;AACT;AC1LA,SAAS8Z,GAAc1a,IAAgB,UAA4B;AACjE,SAAOA;AACT;AAEO,SAAS2a,EACdC,GACAC,IAAS,IACTnP,GACA1L,IAAgB,UACP;AACT,SAAO0a,GAAc1a,CAAG,EAAE,YAAY4a,GAAWC,GAAQnP,CAAK;AAChE;AAEO,SAASoP,EAA0BF,GAAmB5a,IAAgB,UAAmB;AAC9F,SAAO0a,GAAc1a,CAAG,EAAE,kBAAkB4a,CAAS;AACvD;AAEO,SAASG,GAA0BH,GAAmB5a,IAAgB,UAAkB;AAC7F,SAAO0a,GAAc1a,CAAG,EAAE,kBAAkB4a,CAAS;AACvD;AC5BO,SAASI,GAAyB1a,GAAuB;AAC9D,QAAMgK,IAAI,OAAOhK,KAAQ,EAAE,EAAE,KAAA,EAAO,YAAA;AACpC,SAAOgK,MAAM,UAAUA,MAAM,WAAWA,MAAM;AAChD;AAGO,SAAS2Q,GAAqB3a,GAAuB;AAC1D,QAAM4a,IAAM,SAAS,cAAc,UAAU;AAC7C,SAAAA,EAAI,YAAY,OAAO5a,KAAQ,EAAE,GAC1B4a,EAAI,QAAQ,cAAc,IAAI,KAAK;AAC5C;AAGO,SAASC,GAAqB7a,GAAsB;AACzD,QAAM4a,IAAM,SAAS,cAAc,UAAU;AAC7C,SAAAA,EAAI,YAAY,OAAO5a,KAAQ,EAAE,IACzB4a,EAAI,QAAQ,eAAe,IAAI,QAAQ,WAAW,EAAE;AAC9D;AAMO,SAASE,GAA2B9a,GAAuB;AAChE,QAAM+J,IAAM,OAAO/J,KAAQ,EAAE;AAC7B,MAAI,CAAC+J,EAAI,KAAA,EAAQ,QAAO;AAExB,QAAM6Q,IAAM,SAAS,cAAc,UAAU;AAC7C,EAAAA,EAAI,YAAY7Q;AAChB,QAAMrJ,IAAOka,EAAI;AAGjB,SADIla,EAAK,cAAc,KAAK,KACxBA,EAAK,cAAc,IAAI,IAAU,MAEvBA,EAAK,eAAe,IAAI,QAAQ,WAAW,EAAE,EAC/C,WAAW;AACzB;AAGO,SAASqa,GAA2B/a,GAAsB;AAC/D,SAAO8a,GAA2B9a,CAAI,IAAI,KAAKA;AACjD;ACrCO,SAASgb,EAAmB7O,GAA8B;AAC/D,QAAM,IAAIA,EAAM,KAAA;AAChB,MAAI,CAAC,EAAG,QAAO;AACf,QAAMK,IAAI,EAAE,QAAQ,MAAM,EAAE;AAC5B,SAAI,mBAAmB,KAAKA,CAAC,IACpB,KAAKA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,GAAG,aAAa,KAEhE,mBAAmB,KAAKA,CAAC,IACpB,IAAIA,EAAE,YAAA,CAAa,KAErB;AACT;AAGO,SAASyO,GAAYC,GAA4B;AACtD,QAAMnX,IAAImX,EAAI,KAAA,EAAO,MAAM,iCAAiC;AAC5D,MAAI,CAACnX,EAAG,QAAO;AACf,QAAMyI,IAAI,CAAC,MAAc,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAC/D,SAAO,IAAIA,EAAEzI,EAAE,CAAC,CAAC,CAAC,GAAGyI,EAAEzI,EAAE,CAAC,CAAC,CAAC,GAAGyI,EAAEzI,EAAE,CAAC,CAAC,CAAC;AACxC;AAKO,SAASoX,GAAsBC,GAAoBC,GAA+B;AACvF,QAAMC,IAAMN,EAAmBI,CAAU;AACzC,MAAI,CAACE,EAAK,QAAOD,IAAe,8BAA8B;AAC9D,QAAME,IAAI,SAASD,EAAI,MAAM,GAAG,CAAC,GAAG,EAAE,GAChCE,IAAI,SAASF,EAAI,MAAM,GAAG,CAAC,GAAG,EAAE,GAChCpU,IAAI,SAASoU,EAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAEtC,SAAO,QAAQC,CAAC,IAAIC,CAAC,IAAItU,CAAC,IADhBmU,IAAe,OAAO,IACD;AACjC;AClBO,MAAMI,KAAmC;AAAA,EAC9C,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,iCAAiC;AAAA,EACjC,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,8BAA8B;AAAA,EAC9B,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,kCAAkC;AAAA,EAClC,qCAAqC;AAAA,EACrC,+BAA+B;AAAA,EAC/B,6BAA6B;AAAA,EAC7B,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,iCAAiC;AAAA,EACjC,gCAAgC;AAAA,EAChC,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,+BAA+B;AAAA,EAC/B,0CAA0C;AAAA,EAC1C,+BAA+B;AAAA,EAC/B,iCAAiC;AAAA,EACjC,oCAAoC;AAAA,EACpC,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,wCAAwC;AAAA,EACxC,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,2BAA2B;AAAA,EAC3B,+BAA+B;AAAA,EAC/B,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,sCAAsC;AAAA,EACtC,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,mCAAmC;AAAA,EACnC,iCAAiC;AAAA,EACjC,4CAA4C;AAAA,EAC5C,qCAAqC;AAAA,EACrC,sCAAsC;AAAA,EACtC,6CAA6C;AAAA,EAC7C,4BAA4B;AAAA,EAC5B,gCAAgC;AAAA,EAChC,8BAA8B;AAAA,EAC9B,gCAAgC;AAAA,EAChC,iCAAiC;AAAA,EACjC,qCAAqC;AAAA,EACrC,qCAAqC;AAAA,EACrC,yCAAyC;AAAA,EACzC,mCAAmC;AAAA,EACnC,sCAAsC;AAAA,EACtC,wCAAwC;AAAA,EACxC,yBAAyB;AAAA,EACzB,gCAAgC;AAAA,EAChC,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,4BAA4B;AAAA,EAC5B,+BAA+B;AAAA,EAC/B,+BAA+B;AAAA,EAC/B,gCAAgC;AAAA,EAChC,kCAAkC;AAAA,EAClC,4BAA4B;AAAA,EAC5B,yCAAyC;AAAA,EACzC,iCAAiC;AAAA,EACjC,0BAA0B;AAAA,EAC1B,mCAAmC;AAAA,EACnC,yBAAyB;AAAA,EACzB,kCAAkC;AAAA,EAClC,8BAA8B;AAAA,EAC9B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,wBAAwB;AAAA,EACxB,gCAAgC;AAAA,EAChC,4BAA4B;AAAA,EAC5B,iBAAiB;AAAA,EACjB,6BAA6B;AAAA,EAC7B,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,6BAA6B;AAAA,EAC7B,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,kCAAkC;AAAA,EAClC,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,gCAAgC;AAAA,EAChC,mBAAmB;AAAA,EACnB,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,oCAAoC;AAAA,EACpC,gCAAgC;AAAA,EAChC,wCAAwC;AAAA,EACxC,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,8BAA8B;AAAA,EAC9B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,gCAAgC;AAAA,EAChC,8BAA8B;AAAA,EAC9B,2CAA2C;AAAA,EAC3C,yBAAyB;AAAA,EACzB,6BAA6B;AAAA,EAC7B,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,iCAAiC;AAAA,EACjC,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,6BAA6B;AAAA,EAC7B,oCAAoC;AAAA,EACpC,oCAAoC;AAAA,EACpC,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,8BAA8B;AAAA,EAC9B,gCAAgC;AAAA,EAChC,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,iCAAiC;AAAA,EACjC,yCAAyC;AAAA,EACzC,sCAAsC;AAAA,EACtC,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,qCAAqC;AAAA,EACrC,0CAA0C;AAAA,EAC1C,wBAAwB;AAAA,EACxB,kCAAkC;AAAA,EAClC,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,kCAAkC;AAAA,EAClC,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,wBAAwB;AAC1B,GAEaC,KAAmC;AAAA,EAC9C,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,iCAAiC;AAAA,EACjC,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,8BAA8B;AAAA,EAC9B,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,kCAAkC;AAAA,EAClC,qCAAqC;AAAA,EACrC,+BAA+B;AAAA,EAC/B,6BAA6B;AAAA,EAC7B,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,iCAAiC;AAAA,EACjC,gCAAgC;AAAA,EAChC,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,+BAA+B;AAAA,EAC/B,0CAA0C;AAAA,EAC1C,+BAA+B;AAAA,EAC/B,iCAAiC;AAAA,EACjC,oCAAoC;AAAA,EACpC,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,wCAAwC;AAAA,EACxC,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,2BAA2B;AAAA,EAC3B,+BAA+B;AAAA,EAC/B,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,sCAAsC;AAAA,EACtC,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,mCAAmC;AAAA,EACnC,iCAAiC;AAAA,EACjC,4CAA4C;AAAA,EAC5C,qCAAqC;AAAA,EACrC,sCAAsC;AAAA,EACtC,6CAA6C;AAAA,EAC7C,4BAA4B;AAAA,EAC5B,gCAAgC;AAAA,EAChC,8BAA8B;AAAA,EAC9B,gCAAgC;AAAA,EAChC,iCAAiC;AAAA,EACjC,qCAAqC;AAAA,EACrC,qCAAqC;AAAA,EACrC,yCAAyC;AAAA,EACzC,mCAAmC;AAAA,EACnC,sCAAsC;AAAA,EACtC,wCAAwC;AAAA,EACxC,yBAAyB;AAAA,EACzB,gCAAgC;AAAA,EAChC,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,4BAA4B;AAAA,EAC5B,+BAA+B;AAAA,EAC/B,+BAA+B;AAAA,EAC/B,gCAAgC;AAAA,EAChC,kCAAkC;AAAA,EAClC,4BAA4B;AAAA,EAC5B,yCAAyC;AAAA,EACzC,iCAAiC;AAAA,EACjC,0BAA0B;AAAA,EAC1B,mCAAmC;AAAA,EACnC,yBAAyB;AAAA,EACzB,kCAAkC;AAAA,EAClC,8BAA8B;AAAA,EAC9B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,wBAAwB;AAAA,EACxB,gCAAgC;AAAA,EAChC,4BAA4B;AAAA,EAC5B,iBAAiB;AAAA,EACjB,6BAA6B;AAAA,EAC7B,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,6BAA6B;AAAA,EAC7B,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,kCAAkC;AAAA,EAClC,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,gCAAgC;AAAA,EAChC,mBAAmB;AAAA,EACnB,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,oCAAoC;AAAA,EACpC,gCAAgC;AAAA,EAChC,wCAAwC;AAAA,EACxC,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,8BAA8B;AAAA,EAC9B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,gCAAgC;AAAA,EAChC,8BAA8B;AAAA,EAC9B,2CAA2C;AAAA,EAC3C,yBAAyB;AAAA,EACzB,6BAA6B;AAAA,EAC7B,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,iCAAiC;AAAA,EACjC,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,6BAA6B;AAAA,EAC7B,oCAAoC;AAAA,EACpC,oCAAoC;AAAA,EACpC,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,8BAA8B;AAAA,EAC9B,gCAAgC;AAAA,EAChC,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,iCAAiC;AAAA,EACjC,yCAAyC;AAAA,EACzC,sCAAsC;AAAA,EACtC,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,qCAAqC;AAAA,EACrC,0CAA0C;AAAA,EAC1C,wBAAwB;AAAA,EACxB,kCAAkC;AAAA,EAClC,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,kCAAkC;AAAA,EAClC,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,wBAAwB;AAC1B,GAEMC,KAAoC;AAEnC,SAASC,GAAkBpF,IAAiC,IAA2B;AAC5F,QAAMqF,IAASrF,EAAQ,UAAUmF,IAE3BG,IAA+B,EAAE,GAAGL,IAAc,GAD3CI,MAAW,UAAUH,KAAeD,GACU;AAC3D,aAAW,CAACnc,GAAK8L,CAAK,KAAK,OAAO,QAAQoL,EAAQ,YAAY,CAAA,CAAE;AAC9D,IAAI,OAAOpL,KAAU,aAAU0Q,EAASxc,CAAG,IAAI8L;AAWjD,SAAO,EAAE,QAAAyQ,GAAQ,UAAAC,GAAU,GATJ,CAACxc,GAAKyc,MAAW;AACtC,QAAIvZ,IAAOsZ,EAASxc,CAAG,KAAKmc,GAAanc,CAAG,KAAKA;AACjD,QAAIyc;AACF,iBAAW,CAACC,GAAM5Q,CAAK,KAAK,OAAO,QAAQ2Q,CAAM;AAC/C,QAAAvZ,IAAOA,EAAK,WAAW,IAAIwZ,CAAI,KAAK,OAAO5Q,CAAK,CAAC;AAGrD,WAAO5I;AAAA,EACT,EAC2B;AAC7B;AC3oBO,MAAMyZ,KAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsBA,IAAIC,IAAsC;AAEnC,SAASC,KAA6B;AAC3C,SAAOD,MAAmB;AAC5B;AAEO,SAASE,KAA+B;AAC7C,EAAAF,KAAA,QAAAA,KACAA,IAAiB;AACnB;AAEA,SAASG,GAAcC,GAAoB/X,GAAqBgY,GAAwB;AACtF,QAAMC,IAAOjY,EAAO,sBAAA,GACdkY,IAAWF,EAAU,sBAAA;AAC3B,EAAAD,EAAM,MAAM,MAAM,GAAGE,EAAK,SAASC,EAAS,MAAM,CAAC,MACnDH,EAAM,MAAM,OAAO,GAAG,KAAK,IAAI,GAAGE,EAAK,OAAOC,EAAS,IAAI,CAAC,MAE5D,sBAAsB,MAAM;AAC1B,UAAMC,IAAUJ,EAAM,sBAAA;AACtB,IAAII,EAAQ,QAAQD,EAAS,QAAQ,MACnCH,EAAM,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,WAAWA,EAAM,MAAM,IAAI,KAAKI,EAAQ,QAAQD,EAAS,QAAQ,EAAE,CAAC,OAEpGC,EAAQ,SAAS,OAAO,cAAc,MACxCJ,EAAM,MAAM,MAAM,GAAGE,EAAK,MAAMC,EAAS,MAAMC,EAAQ,SAAS,CAAC;AAAA,EAErE,CAAC;AACH;AAGA,SAASC,GAAqBL,GAAoB;AAChD,EAAAA,EAAM;AAAA,IACJ;AAAA,IACA,CAACxI,MAAM;AAEL,MADUA,EAAE,OACN,QAAQ,uDAAuD,KACrEA,EAAE,eAAA;AAAA,IACJ;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,SAAS8I,GAAgBC,GAA0BvB,GAAa;AAC9D,QAAM5R,IAAIsR,EAAmBM,CAAG;AAChC,EAAI5R,QAAU,QAAQA;AACxB;AAGO,SAASoT,GAAuBtJ,GAAuC;;AAC5E,EAAA4I,GAAA,IACAxc,IAAA4T,EAAK,iBAAL,QAAA5T,EAAA,KAAA4T;AACA,QAAM,IAAIA,EAAK,KAAKoI,GAAA,EAAoB,GAElCmB,IAAa/B,EAAmBxH,EAAK,KAAK;AAChD,MAAIe,IAAQwI,KAAc,WACtBC,IAAS;AAEb,QAAMV,IAAQ9P,EAAE,OAAO;AAAA,IACrB,OAAO;AAAA,IACP,8BAA8B;AAAA,EAAA,CAC/B,GACKyQ,IAAQzQ,EAAE,OAAO;AAAA,IACrB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,cAAc,EAAE,mBAAmB;AAAA,EAAA,CACpC,GAEKqM,IAAWrM;AAAA,IACf;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO,EAAE,cAAc;AAAA,MACvB,cAAc,EAAE,cAAc;AAAA,IAAA;AAAA,IAEhC,CAAC,GAAG;AAAA,EAAA,GAGA7M,IAAO6M,EAAE,OAAO,EAAE,OAAO,2BAA2B;AAAA,IACxDA,EAAE,QAAQ,EAAE,OAAO,yBAAA,GAA4B,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAAA,IACvEqM;AAAA,EAAA,CACD,GAEKgE,IAASrQ,EAAE,SAAS;AAAA,IACxB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,cAAc,EAAE,oBAAoB;AAAA,EAAA,CACrC,GAEK0Q,IAAW1Q,EAAE,SAAS;AAAA,IAC1B,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAagH,EAAK,eAAe;AAAA,EAAA,CAClC,GAEK2J,IAAa,CAAC7B,GAAa8B,MAAoB;;AACnD,UAAM1T,IAAIsR,EAAmBM,CAAG;AAChC,IAAK5R,MACL6K,IAAQ7K,GACRkT,GAAgBC,GAAQnT,CAAC,GACzBwT,EAAS,QAAQxT,IACjB9J,IAAA4T,EAAK,cAAL,QAAA5T,EAAA,KAAA4T,GAAiB9J,KACb0T,KAAU5J,EAAK,eAAYA,EAAK,SAAS9J,CAAC;AAAA,EAChD;AAEA,EAAAkT,GAAgBC,GAAQtI,CAAK,GAC7B2I,EAAS,QAAQH,KAAc;AAE/B,QAAMM,IAAW,CAACD,MAAoB;;AACpC,QAAI,CAAAJ,GAMJ;AAAA,UALAA,IAAS,IACTd,IAAiB,MACjB,SAAS,oBAAoB,WAAWoB,GAAO,EAAI,GACnD,SAAS,oBAAoB,aAAaC,GAAO,EAAI,GACrDjB,EAAM,OAAA,GACFc,KAAU,CAAC5J,EAAK,YAAY;AAC9B,cAAM9J,IAAIsR,EAAmBzG,CAAK;AAClC,QAAI7K,KAAG8J,EAAK,SAAS9J,CAAC;AAAA,MACxB;AACA,OAAA9J,IAAA4T,EAAK,aAAL,QAAA5T,EAAA,KAAA4T;AAAA;AAAA,EACF,GAEMgK,IAAahR,EAAE,OAAO,EAAE,OAAO,6BAA6B;AAClE,aAAW8O,KAAOW,IAAsB;AACtC,UAAMwB,IAAMjR,EAAE,UAAU;AAAA,MACtB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO,EAAE,kCAAkC,EAAE,KAAA8O,GAAK;AAAA,MAClD,OAAO,cAAcA,CAAG;AAAA,MACxB,cAAcA;AAAA,IAAA,CACf;AACD,IAAAmC,EAAI,iBAAiB,SAAS,MAAMN,EAAW7B,GAAK,EAAK,CAAC,GAC1DmC,EAAI,iBAAiB,YAAY,CAAC3J,MAAM;AACtC,MAAAA,EAAE,eAAA,GACFqJ,EAAW7B,GAAK,EAAI,GACpB+B,EAAS,EAAI;AAAA,IACf,CAAC,GACDG,EAAW,OAAOC,CAAG;AAAA,EACvB;AAEA,EAAAZ,EAAO,iBAAiB,SAAS,MAAMM,EAAWN,EAAO,OAAO,EAAK,CAAC,GAEtEK,EAAS,iBAAiB,SAAS,MAAM;AACvC,UAAMxT,IAAIsR,EAAmBkC,EAAS,KAAK;AAC3C,IAAIxT,KAAGyT,EAAWzT,GAAG,EAAK;AAAA,EAC5B,CAAC,GACDwT,EAAS,iBAAiB,WAAW,CAACpJ,MAAM;AAC1C,UAAM4J,IAAK5J;AACX,QAAI4J,EAAG,QAAQ,SAAS;AACtB,MAAAA,EAAG,eAAA;AACH,YAAMhU,IAAIsR,EAAmBkC,EAAS,KAAK;AAC3C,MAAIxT,MACFyT,EAAWzT,GAAG,EAAI,GAClB2T,EAAS,EAAI;AAAA,IAEjB;AAAA,EACF,CAAC;AAED,QAAMM,IAA0B,CAAA;AAChC,EAAInK,EAAK,cACPmK,EAAS;AAAA,IACPnR;AAAA,MACE;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MAAM;;AACb,WAAA5M,IAAA4T,EAAK,YAAL,QAAA5T,EAAA,KAAA4T,IACA6J,EAAS,EAAK;AAAA,QAChB;AAAA,MAAA;AAAA,MAEF,CAAC,EAAE,cAAc,CAAC;AAAA,IAAA;AAAA,EACpB,GAIJJ,EAAM,OAAOtd,GAAM6d,GAAYX,GAAQK,CAAQ,GAC3CS,EAAS,UAAQV,EAAM,OAAOzQ,EAAE,OAAO,EAAE,OAAO,wBAAA,GAA2BmR,CAAQ,CAAC,GAExFrB,EAAM,OAAOW,CAAK,GAClBN,GAAqBL,CAAK,GAC1B9I,EAAK,UAAU,OAAO8I,CAAK,GAC3BD,GAAcC,GAAO9I,EAAK,QAAQA,EAAK,SAAS,GAEhDqF,EAAS,iBAAiB,SAAS,CAAC/E,MAAM;AACxC,IAAAA,EAAE,eAAA,GACFuJ,EAAS,EAAI;AAAA,EACf,CAAC;AAED,QAAMC,IAAQ,CAACxJ,MAAqB;;AAClC,IAAIA,EAAE,QAAQ,aACZA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACEiJ,OAAYnd,IAAA4T,EAAK,cAAL,QAAA5T,EAAA,KAAA4T,GAAiBuJ,KACjCM,EAAS,EAAK;AAAA,EAElB,GAEME,IAAQ,CAACK,MAAmB;AAChC,UAAMzP,IAAIyP,EAAG;AACb,IAAItB,EAAM,SAASnO,CAAC,KAAKqF,EAAK,OAAO,SAASrF,CAAC,KAC/CkP,EAAS,EAAI;AAAA,EACf;AAEA,WAAS,iBAAiB,WAAWC,GAAO,EAAI,GAChD,WAAW,MAAM,SAAS,iBAAiB,aAAaC,GAAO,EAAI,GAAG,CAAC,GAEvErB,IAAiB,MAAMmB,EAAS,EAAI,GAChC7J,EAAK,iBAAiB,MAAO0J,EAAS,MAAA;AAC5C;AASO,SAASW,GACdC,GACAtK,GACM;AACN,QAAMrF,IAAIqF,EAAK,KAAKoI,GAAA,EAAoB;AACxC,EAAKkC,EAAK,UAAOA,EAAK,QAAQ3P,EAAE,uBAAuB,IAEvD2P,EAAK,iBAAiB,aAAa,CAAChK,MAAM;;AACxC,IAAAA,EAAE,eAAA,IACFlU,IAAA4T,EAAK,iBAAL,QAAA5T,EAAA,KAAA4T;AAAA,EACF,CAAC,GAEDsK,EAAK,iBAAiB,SAAS,CAAChK,MAAM;;AACpC,IAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA;AACF,UAAMyI,IACJ/I,EAAK,aAAcsK,EAAK,QAAQ,UAAU,KAA4B,SAAS,MAC3E1S,MAAQxL,IAAA4T,EAAK,aAAL,gBAAA5T,EAAA,KAAA4T,OAAqBsK,EAAK;AACxC,IAAAhB,GAAuB;AAAA,MACrB,GAAGtJ;AAAA,MACH,QAAQsK;AAAA,MACR,WAAAvB;AAAA,MACA,OAAAnR;AAAA,IAAA,CACD;AAAA,EACH,CAAC;AACH;AC3MO,MAAM2S,GAAa;AAAA,EA2BxB,YAAYvK,GAA2B;AA1B/B,IAAAhV,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,mBAA+B,CAAA;AAC/B,IAAAA,EAAA,mBAAY;AACZ,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA,eAAQ;AAMR;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,EAAA,oBAA2B;AAE3B;AAAA,IAAAA,EAAA,4BAA4C;AAE5C;AAAA,IAAAA,EAAA,4BAAoC;AACpC,IAAAA,EAAA,6BAAqC;AAErC;AAAA,IAAAA,EAAA,wBAAiB;AACjB,IAAAA,EAAA,gBAAS;AAET;AAAA,IAAAA,EAAA,0BAAmB;AAEnB;AAAA,IAAAA,EAAA,2BAAoB;AAG1B,SAAK,OAAOgV,GACZ,KAAK,KAAKA,EAAK,IACf,KAAK,kBAAkB,KAAK,GAAG,WAC/B,KAAK,OAAA;AAAA,EACP;AAAA;AAAA,EAGA,SAAS;AACP,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,QAAIpI;AACJ,QAAI,KAAK,KAAK,SAAS;AACrB,MAAAA,KAAS,KAAK,GAAG,eAAe,IAAI,QAAQ,WAAW,EAAE;AAAA,aAChD,KAAK,KAAK,SAAS;AAC5B,MAAAA,IAAQ,KAAK,GAAG;AAAA,SACX;AACL,YAAM4S,IAAYC,GAAiB,KAAK,GAAG,SAAS;AAEpD,OADc,KAAK,GAAG,eAAe,IAAI,QAAQ,WAAW,EAAE,EACrD,SAAS,IAChB7S,IAAQ4S,IAER,KAAK,kBACL,CAAC,KAAK,UACNtD,GAAyBsD,CAAS,IAElC5S,IAAQ,KACCuP,GAAqBqD,CAAS,KAAK,CAAC,KAAK,mBAElD5S,IAAQ4S,IAGR5S,IAAQ;AAAA,IAEZ;AAEA,SAAK,KAAK,SAASA,CAAK,GACxB,KAAK,QAAQ,EAAK;AAAA,EACpB;AAAA;AAAA,EAGA,SAAS;AACP,IAAI,KAAK,cACT,KAAK,YAAY,IACjB,KAAK,GAAG,YAAY,KAAK,iBACzB,KAAK,KAAK,SAAA,GACV,KAAK,QAAQ,EAAK;AAAA,EACpB;AAAA,EAEA,QAAQ8S,IAAU,IAAM;AACtB,IAAK,KAAK,UACV,KAAK,QAAQ,IACb,KAAK,UAAU,QAAQ,CAACC,MAAQA,GAAK,GACrC,KAAK,YAAY,CAAA,GACjB,KAAK,GAAG,gBAAgB,iBAAiB,GACzC,KAAK,GAAG,UAAU,OAAO,mBAAmB,GACxCD,KAAW,CAAC,KAAK,cAAW,KAAK,GAAG,YAAY,KAAK;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB;AACd,UAAM7b,IAAM,OAAO,aAAA;AACnB,QAAI,CAACA,KAAOA,EAAI,eAAe,EAAG;AAClC,UAAMT,IAAQS,EAAI,WAAW,CAAC;AAC9B,IAAI,CAAC,KAAK,GAAG,SAAST,EAAM,cAAc,KAAK,CAAC,KAAK,GAAG,SAASA,EAAM,YAAY,MACnF,KAAK,aAAaA,EAAM,WAAA;AAAA,EAC1B;AAAA;AAAA,EAGA,KAAKwc,GAAiBhT,GAAgB;AACpC,SAAK,SAAS,IACd,KAAK,aAAA,GACL,KAAK,kBAAA;AACL,UAAM/I,IAAM,OAAO,aAAA;AACnB,QAAIgc,IAA8B;AAClC,IAAID,MAAY,kBAAiB/b,KAAA,QAAAA,EAAK,gBACpCgc,IAAeC,GAAmBjc,EAAI,WAAW,CAAC,CAAC;AAGrD,UAAMkc,IAAYH,MAAY,uBAAuBA,MAAY;AACjE,QAAIG,MAAalc,KAAA,QAAAA,EAAK,aAAY;AAChC,YAAMT,IAAQS,EAAI,WAAW,CAAC,GACxBmc,IAAe5c,EAAM,YACvB,CAAA,IACAwF,GAAoBxF,GAAO,KAAK,EAAE,GAChC6c,IAAcza,GAA6B,KAAK,IAAIpC,CAAK,GACzD8c,IAAkB/a,GAA+B/B,CAAK;AAC5D,WAAK,oBAAoB;AACzB,UAAI;AACF,cAAMuG,IAASiW,MAAY;AAC3B,QAAI9V,GAA6B,KAAK,IAAI1G,GAAOuG,GAAQqW,CAAY,IACnEpZ,GAA8B,KAAK,IAAIsZ,EAAgB,KAAKD,CAAW,KAEvEpE,EAAoB,gBAAgB,IAAO,OAAO,GAClDA,EAAoB+D,GAAS,IAAOhT,CAAK,GACpClG,GAAyC,KAAK,EAAE,KACnDE,GAA8B,KAAK,IAAIsZ,EAAgB,KAAKD,CAAW;AAAA,MAG7E,UAAA;AACE,aAAK,oBAAoB,IACzB3a,GAA+B,KAAK,EAAE;AAAA,MACxC;AACA,WAAK,cAAA,GACL,KAAK,eAAA;AACL;AAAA,IACF;AACE,MAAAuW,EAAoB,gBAAgB,IAAOkE,IAAY,UAAU,MAAM,GACvElE,EAAoB+D,GAAS,IAAOhT,CAAK;AAE3C,IAAIgT,MAAY,kBACd,KAAK,qBAAqBhT,KAAS,MACnC,KAAK,sBAAsBiT,IAG7B,KAAK,cAAA,GACL,KAAK,eAAA;AAAA,EACP;AAAA;AAAA,EAGA,cAAc5U,GAAqB;AACjC,SAAK,SAAS,IACd,KAAK,aAAA,GACL,KAAK,kBAAA;AACL,UAAMpH,IAAM,OAAO,aAAA;AACnB,QAAI,EAACA,KAAA,QAAAA,EAAK,YAAY;AACtB,UAAMnB,IAAOmK,GAAoBhJ,EAAI,YAAY,KAAK,EAAE;AACxD,IAAKnB,MACLyd,GAAyBzd,GAAMuI,CAAE,GACjC,KAAK,cAAA,GACL,KAAK,eAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQmV,GAAa;AACnB,SAAK,SAAS,IACd,KAAK,aAAA,GACL,KAAK,kBAAA;AACL,UAAMxP,IAAUwP,EAAI,KAAA;AACpB,QAAI,CAACxP,GAAS;AACZ,MAAAiL,EAAoB,QAAQ,GAC5B,KAAK,cAAA,GACL,KAAK,eAAA;AACL;AAAA,IACF;AACA,UAAMwE,IAAO,iCAAiC,KAAKzP,CAAO,IAAIA,IAAU,WAAWA,CAAO,IACpF/M,IAAM,OAAO,aAAA;AACnB,QAAI,CAACA,KAAOA,EAAI,eAAe,EAAG;AAClC,UAAMkC,IAASua,GAAmBzc,EAAI,YAAY,KAAK,EAAE;AACzD,IAAIkC,KACFA,EAAO,aAAa,QAAQsa,CAAI,GAC3Bta,EAAO,aAAa,KAAK,KAAGA,EAAO,aAAa,OAAO,UAAU,MAEtE8V,EAAoB,gBAAgB,IAAO,MAAM,GACjDA,EAAoB,cAAc,IAAOwE,CAAI,IAE/C,KAAK,cAAA,GACL,KAAK,eAAA;AAAA,EACP;AAAA;AAAA,EAGA,WAAWrc,GAAc;AACvB,SAAK,SAAS,IACd,KAAK,aAAA,GACL,KAAK,kBAAA,GACL6X,EAAoB,cAAc,IAAO7X,CAAI,GAC7C,KAAK,cAAA;AAAA,EACP;AAAA;AAAA,EAGA,WAAWxC,GAAc;AACvB,SAAK,SAAS,IACd,KAAK,aAAA,GACL,KAAK,kBAAA,GACLqa,EAAoB,cAAc,IAAOra,CAAI,GAC7C,KAAK,cAAA;AAAA,EACP;AAAA;AAAA,EAGA,UAAU;AACR,SAAK,aAAA,GACL,KAAK,kBAAA;AAAA,EACP;AAAA;AAAA,EAGA,cAAcyJ,GAAY;AACxB,SAAK,KAAK,YAAYsV,GAAmBtV,CAAE,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgBuV,GAAgB;AAC9B,SAAK,SAAS,IACd,KAAK,aAAA,GACL,KAAK,kBAAA;AACL,UAAM3c,IAAM,OAAO,aAAA;AACnB,QAAI,CAACA,KAAOA,EAAI,eAAe,EAAG;AAClC,UAAMT,IAAQS,EAAI,WAAW,CAAC;AAC9B,QAAI,GAAC,KAAK,GAAG,SAAST,EAAM,cAAc,KAAK,CAAC,KAAK,GAAG,SAASA,EAAM,YAAY,IAEnF;AAAA,UAAKA,EAAM,WAaJ;AACL,cAAMqd,IAAO,SAAS,cAAc,MAAM;AAC1C,QAAAA,EAAK,aAAa,SAAS,eAAeD,CAAM,GAAG,GACnDC,EAAK,YAAY,SAAS,eAAe,GAAQ,CAAC,GAClDrd,EAAM,WAAWqd,CAAI;AACrB,cAAMC,IAAQ,SAAS,YAAA;AACvB,QAAAA,EAAM,SAASD,EAAK,YAAa,CAAC,GAClCC,EAAM,SAAS,EAAI,GACnB7c,EAAI,gBAAA,GACJA,EAAI,SAAS6c,CAAK;AAAA,MACpB,OAvBsB;AACpB,cAAMD,IAAO,SAAS,cAAc,MAAM;AAC1C,QAAAA,EAAK,aAAa,SAAS,eAAeD,CAAM,GAAG;AACnD,YAAI;AACF,UAAAC,EAAK,YAAYrd,EAAM,iBAAiB,GACxCA,EAAM,WAAWqd,CAAI;AACrB,gBAAME,IAAW,SAAS,YAAA;AAC1B,UAAAA,EAAS,mBAAmBF,CAAI,GAChC5c,EAAI,gBAAA,GACJA,EAAI,SAAS8c,CAAQ;AAAA,QACvB,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAYA,WAAK,cAAA,GACL,KAAK,eAAA;AAAA;AAAA,EACP;AAAA;AAAA,EAGA,gBAAyB;AACvB,WAAO,KAAK,GAAG,sBAAA;AAAA,EACjB;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,CAAC,KAAK,WAAY;AACtB,UAAM9c,IAAM,OAAO,aAAA;AACnB,IAAKA,MACLA,EAAI,gBAAA,GACJA,EAAI,SAAS,KAAK,UAAU;AAAA,EAC9B;AAAA;AAAA,EAIQ,SAAS;AACf,UAAM,EAAE,IAAA/B,GAAI,MAAA8e,GAAM,WAAAC,EAAA,IAAc,KAAK;AACrC,IAAA/e,EAAG,aAAa,mBAAmB,MAAM,GACzCA,EAAG,UAAU,IAAI,mBAAmB,GACpCA,EAAG,UAAU,OAAO,UAAU;AAE9B,UAAM8T,IAAU,KAAK,KAAK,gBAAgB,IACpCkL,IACJF,MAAS,UAAU,CAAChL,EAAQ,KAAA,IAAS0G,GAA2B1G,CAAO;AACzE,SAAK,iBAAiBkL,GACtB,KAAK,SAAS,IACd,KAAK,mBACHF,MAAS,UACLhL,EAAQ,QAAQ,WAAW,EAAE,EAAE,SAAS,IACxCyG,GAAqBzG,CAAO,EAAE,SAAS,GAEzCkL,IAEFhf,EAAG,YAAY8e,MAAS,UAAU,KAAK,SAEvC9e,EAAG,YAAY8e,MAAS,UAAUxS,GAAWwH,CAAO,IAAIA,GAI1D,sBAAsB,MAAM;AAC1B,MAAA9T,EAAG,MAAA,GACHif,GAAgBjf,CAAE;AAAA,IACpB,CAAC;AAED,QAAIkf,IAAe,IAEfC,IAAoB;AAExB,UAAMC,IAAqB,MAAM;AAC/B,MAAAF,IAAe;AAAA,IACjB,GACMG,IAAmB,MAAM;AAC7B,MAAAH,IAAe,IACfC,IAAoB;AAAA,IACtB,GAEMG,IAAY,CAAC9L,MAAqB;AACtC,UAAIA,EAAE,QAAQ,UAAU;AACtB,QAAAA,EAAE,eAAA,GACF,KAAK,OAAA;AACL;AAAA,MACF;AACA,UAAIA,EAAE,QAAQ,SAAS;AAErB,YAAIA,EAAE,eAAe0L,KAAgB1L,EAAE,YAAY,IAAK;AACxD,YAAI2L,GAAmB;AACrB,UAAAA,IAAoB;AACpB;AAAA,QACF;AACA,YAAI,CAACJ,GAAW;AACd,UAAAvL,EAAE,eAAA,GACF,KAAK,OAAA;AACL;AAAA,QACF;AACA,YAAIsL,MAAS,QAAQ;AACnB,cAAItL,EAAE,UAAU;AACd,YAAAA,EAAE,eAAA,GACFuG,EAAoB,iBAAiB,GACrC,KAAK,cAAA,GACL,KAAK,eAAA;AACL;AAAA,UACF;AACA,gBAAMhY,IAAM,OAAO,aAAA;AACnB,cAAIA,KAAA,QAAAA,EAAK,YAAY;AACnB,kBAAMT,IAAQS,EAAI,WAAW,CAAC,GACxBzB,IAAKJ,GAAaoB,EAAM,gBAAgBtB,CAAE;AAChD,gBAAIM,KAAMN,EAAG,SAASM,CAAE,GAAG;AACzB,cAAAkT,EAAE,eAAA,GACFjO,GAAqBjF,GAAIgB,CAAK,GAC9B,KAAK,cAAA,GACL,KAAK,eAAA;AACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,QAAAkS,EAAE,eAAA,GACFuG,EAAoB,iBAAiB;AACrC;AAAA,MACF;AACA,UAAIvG,EAAE,QAAQ,eAAesL,MAAS,UAAUC,GAAW;AACzD,YAAIvL,EAAE,eAAe0L,EAAc;AACnC,cAAMnd,IAAM,OAAO,aAAA;AACnB,YAAI,EAACA,KAAA,QAAAA,EAAK,YAAY;AACtB,cAAMT,IAAQS,EAAI,WAAW,CAAC,GACxBzB,IAAKJ,GAAaoB,EAAM,gBAAgBtB,CAAE;AAChD,QAAIM,KAAMN,EAAG,SAASM,CAAE,KAAKsF,GAAyBtF,GAAIgB,CAAK,MAC7DkS,EAAE,eAAA,GACF,KAAK,cAAA,GACL,KAAK,eAAA;AAEP;AAAA,MACF;AACA,UAAIA,EAAE,QAAQ,YAAYsL,MAAS,UAAUC,GAAW;AACtD,YAAIvL,EAAE,eAAe0L,EAAc;AACnC,cAAMnd,IAAM,OAAO,aAAA;AACnB,YAAI,EAACA,KAAA,QAAAA,EAAK,YAAY;AACtB,cAAMT,IAAQS,EAAI,WAAW,CAAC,GACxBzB,IAAKJ,GAAaoB,EAAM,gBAAgBtB,CAAE;AAChD,QAAIM,KAAMN,EAAG,SAASM,CAAE,KAAK4F,GAA0B5F,GAAIgB,CAAK,MAC9DkS,EAAE,eAAA,GACF,KAAK,cAAA,GACL,KAAK,eAAA;AAAA,MAET;AAAA,IACF,GACM+L,IAAS,CAAC/L,MAAkB;AAEhC,iBAAW,MAAM;;AACf,YAAI,CAAC,KAAK,MAAO;AACjB,cAAMgM,IAAS,SAAS;AAOxB,YANIA,MAAWA,MAAWxf,KAAMA,EAAG,SAASwf,CAAM,MAC9C3D,SACAvc,IAAAkgB,KAAA,gBAAAA,EAAQ,YAAR,QAAAlgB,EAAA,KAAAkgB,GAAkB,sEAClBhgB,IAAAggB,KAAA,gBAAAA,EAAQ,YAAR,QAAAhgB,EAAA,KAAAggB,GAAkB,2DAElB/G,IAAA+G,KAAA,gBAAAA,EAAQ,YAAR,QAAA/G,EAAA,KAAA+G,GAAkB,uBAClBhH,IAAAgH,KAAA,gBAAAA,EAAQ,YAAR,QAAAhH,EAAA,KAAAgH,GAAkB,0CAA2C;AACjE,cAAMC,IAAUjM,EAAE;AAClB,SAAIkM,IAAAD,KAAA,gBAAAA,EAAS,YAAT,QAAAC,EAAA,KAAAD,GAAmB,uBACnBE,IAAAF,KAAA,gBAAAA,EAAS,YAAT,QAAAE,EAAA,KAAAF,GAAmB,sBACnBG,IAAAH,KAAA,gBAAAA,EAAS,YAAT,QAAAG,EAAA,KAAAH,GAAmB,8CACnBI,IAAAJ,KAAA,gBAAAA,EAAS,YAAT,QAAAI,EAAA,KAAAJ,GAAmB,gDACnBK,IAAAL,KAAA,gBAAAA,EAAS,YAAT,QAAAK,EAAA,KAAAL,GAAmB,0DACnB,SAAS,cAAc,wCAAwC,KACnE,KAAK,OAAA;AAAA,MACP,GAAG,CAAC;AAAA,IACN,GACMM,IAAa,MAAM;AACvB,WAAK,SAAS;AAAA,IAChB,GAEMC,IAAmB,MAAM;AAE7B,OADWhgB,EAAG,eAAe,IAAI,QAAQ,WAAW,EAAE,EAChD,SAAS,MAAG,KAAK,mBAAmB;AAAA,IAC5C,GAEMigB,IAAU,CAACzM,MAAsB;;AACrC,UAAIsL,MAAS,UAAUC,KAAa,GAACzf,IAAAkU,EAAE,kBAAF,QAAAlU,EAAiB,QAAQ,eAAc;AAC1E,QAAAkU,EAAE,eAAA,GACFuM,EAAA;AACA,cAAM7d,MAAO1C,IAAAgU,EAAE,kBAAF,gBAAAhU,EAAiB,QAAQ,kBAAiB;AACvD,QAAAua,EAAoB,cAAc,IAAOmG,GAAoBhe,CAAI,CAAC,GAClE8d,EAAA,GACA,KAAK,cAAA,GACL,KAAK,eAAA;AACL;AAAA,MACF;AACA,UAAIlB,MAAS,QAAS;AACtB,MAAAtL,EAAE,eAAA,GACFuM,EAAA;AACA,YAAM7d,MAAOuW,IAAAjF,EAAE,kBAAF,gBAAAiF,EAAiB,QAAQ,kBAAiB,IACjD8F,IAAOQ,IAAY7c,IAAOA,EAAK,QAAQ,UAAU,GAAG;AAC1D,MAAA6X,EAAoB,cAAc,IAAOwE,CAAI;AAAA,IAC/C,GAEM4B,IAAc,MAAM;AACxB,MAAK,KAAK,UACV,KAAK,yBAAA,GACL,KAAK,cAAA,GACL,KAAK,eAAA;AAAA,IACP,GAEMC,IAAU,MAAM;AACpB,MAAAL,EAAA,GACAC,EAAA,GACIlB,MAAS,UAAUC,KAAa,CAAC,KAAK,qBACxC9d,GAA2BjB,CAAE,GAE/BmgB,EAAA;AAAA,IACF,GAEME,IAAoB,CAACxS,MAAoD;AAC7E,UAAI,EAAEA,aAAa,SAAU,QAAO;AACpC,YAAMlH,IAAIkH,EAAE,QAAQ,GAAG;AACvB,UAAI,CAAClH,KAAK,CAAC3G,EAAG,SAAS2G,CAAC,EAAG,QAAO;AAClC,YAAM2Z,IAAO3Z,EAAE,aAAa,MAAM;AAClC,aAAI2Z,KAAQ,QAAQA,MAAS,MAAMA,MAAS,MAAY,OACjD3Z;AAAA,IACT,GAGM4Z,IAAmB,CAAC/M,MAAkB;AAC1C,MAAIsL,MAAS,UAAUA,MAAS,UAC3BuB,EAAkB7M,EAAE,MAAM,KAC/BA,EAAE,eAAA;AAAA,IACJ;AAEA,IAAAxT,EAAG,iBAAiB,WAAWsf,CAAS,GACxCtf,EAAG,iBAAiB,oBAAoBof,CAAkB,GAC1Dpf,EAAG,iBAAiB,kBAAkBqf,CAAgB,GACtDrf,EAAG,iBAAiB,QAAQuf,CAAM,GAClCvf,EAAG,iBAAiB,SAASigB,CAAO,GACpC,SAAS,iBAAiB,mBAAmBE,CAAW,GACxDngB,EAAG,iBAAiB,SAASogB,CAAO,GACpCpgB,EAAG,iBAAiB,WAAWmgB,CAAW,IACtCrB,MAAS,UAAUA,MAAS,YAC9B9e,EAAG,iBAAiB,SAASugB,GAAkB,EAAI,GACnDvgB,EAAG,iBAAiB,YAAYugB,GAAkB,EAAI,IAGxD,KAAK,UAAU;AAAA,MACb,MAAMvgB,EAAG,oBAAoB,WAAWsf,CAAS;AAAA,MACjD,MAAMtf,EAAG,oBAAoB,oBAAoBof,CAAkB;AAAA,MACnE,MAAMpf,EAAG,oBAAoB,kBAAkBqf,CAAgB;AAAA,MAC/D,MAAMrf,EAAG,oBAAoB,QAAQuf,CAAM;AAAA,MAC3C,MAAMvf,EAAG,oBAAoB,SAASigB,CAAO;AAAA,MAC7C,MAAM,SAAS,oBAAoB,mBAAmBE,CAAW;AAAA,MACjE,MAAMngB,EAAG,oBAAoB,SAASogB,CAAO;AAAA,MAC7C,MAAMpgB,EAAG,oBAAoB,WAAWmgB,CAAW;AAAA,MACnD,GAAIrB,MAAS,UAAUA,MAAS,SAC5B;AAAA,QACE,MAAM9e,EAAG,oBAAoB,SAASugB,GAAkB,EAAI;AAAA,QAC5D,MAAMvgB,EAAG,oBAAoB,YAAYugB,GAAkB,EAAI;AAAA,MAAA,IAEjE,CAAA;AAAA,IAAC;AAAA,EAET;AAAA,EAEQ,eAAe;AACrB,IAAI,SAAS,kBAAkB,KAAK,MAClC,KAAK,GAAG,MAAA;AAAA,EAEZ;AAAA,EAEQ,2BAA2B;AACjC,QAAI,CAAC,KAAK,sBAAsB,CAAC,KAAK,oBAAqB;AAC3D,UAAMxe,IAAM,OAAO,aAAA;AACnB,QAAI,EAACA,KAAA,QAAAA,EAAK,aAAY;AACpB,WAAK,oBAAA;AACL;AAAA,IACF;AACA,IAAIic,GAAmBjc,EAAI,WAAW,CAAC,CAAC,MAAM,KAAK,uBACjD,KAAK,oBAAA;AAAA,EAET;AAAA,EAEQ,sBAAsB;AAC5B,SAAK,qBAAqB,MAC1B,KAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEQ,iBAAiB;AACvB,QAAI,CAAC,KAAK,KAAK,kBAAmB;AAClC,QAAI,KAAK,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,QAAQ;AAC3D,WAAK,KAAK,kBAAkB,IAAI;AAChC;AAAA,IACF;AACA,UAAMA,IAAM,OAAO,aAAA;AACnB,QAAI,CAACA,KAAOA,EAAI,eAAe,GAAG;AAChC,WAAK,4BAA4B,IAAI;AACrC;AAAA,IACF;AACA,QAAI,CAAC,KAAK,GAAG,SAASA,EAAI,UAAU,GAAG;AACrC,WAAK,4BAA4B,IAAI;AACrC;AAAA,IACF;AACA,UAAMT,IAAQS,EAAI,WAAW,CAAC,GACxBma,IAAOna,EAAI,cAAc,KAAK,WAAWT,CAAK,IAAIA,EAAM,sBAAA,GAExDkf,IAA4CtG,EAA0B,eAAe,IACvF,WACAA,EAA0B,cAAc,IACtC,UACAA,EAA0B,aAAa,IACrC,YACA,QAEFuG,KAAQ,MAAM;AAClB,YAAM9Z,IAAI6X,GAAmBzc,EAAI,YAAY,KAAK,EAAE;AACpD,cAAO4E,KAAA,gBAAAA,EAAG,aAAa,YAAW;AAAA,IACpC,GAAA,GAEM+Z,IAASC,GAAgC,KAAK,IAAI5e,CAAG;AAE3D,QAAI6e,IAAYF,EAAO,aAAaG,GAAe,WAAW,GAC1DC,IAAYJ,EAAO;AACvB,IACE,CAACI,KACDxf,EAAM,aACN,KAAK,sBACL,KAAK,wBAAwB0c,GAAmB1c,CAAK,MAErDwf,IAAY,KAAK,qBAEfJ,EAAO,aAAW,KAAK,oBAAA;AAE3B,UAAMK,IAAclY,GAAkB9G,EAAI,YAAY,KAAK,EAAE,GACvDif,IAAajW,GAAoBhJ,EAAI,YAAY,KAAK,EAAE,GACxDkf,IAAeD,IAAapW,GAAcoW,CAAU,IAAI,MACxDE,IAAqB,KAAK,KAAK,eACjC/V,GAA0B,KAAK,KAAK,YAAY,IAChDpC,IACEoY,IACJF,KAAsCC,GAElCE,IAAwB;AAAA,MAC5B,cAAc;AAAA,MACd,MAAAlF;AAAA,MACA,SAAS;AAAA,QACP,MAAMhC,EAA0B,MAAM;AAAA,QACtC,QAAQA,EAA0B,QAAQ;AAAA,QAC1C,WAAWA,EAA0B,WAAW;AAAA,QAChD,eAAeA,EAA0B,eAAe;AAAA,QACxD,eACE6G,EAAY,iBAAiB7G,EAA0B,qBAAqB;AAAA,QAC9E,aAAa6G,EAAY,eAAe7G,EAA0B,mBAAmB;AAAA,QACrF,OAAAsG;AAAA,QACA,MAAAC;AAAA,QACA,WAAAG;AAAA,QACA,UAAUF,EAAO;AAAA,QACjB,UAAUG,GAAe,UAAU;AAAA,QACnC,YAAYH,EAAO;AAAA,QACnB,WAAAI;AAAA,QACA,QAAQ,CAAC,CAACE;AAAA,QACV,cAAAC;AAAA,QACA,oBAAAC;AAAA,QACA,uBAAAC;AAAA,MAAA;AAAA,IACF;AAEF,SAAK,qBAAqBC,GAC1B,KAAK,KAAK,kBAAkBA,CAAK;AAAA,EACnC;AAAA;AAAA,EAGQ,4BAA4BC,GAAgB;;AAClD,QACEA,MAAa,QACb,KAAK,sBACLxF,SACArc,KAAAF,IAAA,SAAS,kBAAT,gBAAAA,EAAwB,YAAxB,QAAAE,EAAA;AAAA,MAAAF;AAAA,MACE;AAAA,OAEF;AACA,OAAAkZ,KAAAC,IAAA,KAAK,MAAK,sBAAV,QAAAD,EAAA,KAAAC,GAA8B,KAAK;AACnC;AAAA,IACF;AACA,IAAI4I,MAAa,SAAM,KAAK,qBAAqB,QACjD1B,KAAAD,IAAA,KAAK,MAAK,sBAAV,QAAAC,EAAA,KAAAD,GAA8B2B;AAAA,EAChC;AAAA,EAEQ,WAAW/f,GAA8B;AAC/C,UAAMggB,IAAQhgB,EAAM,eAAA;AACpB,QAAIggB,EAAM,OAAQ,QAAOA,EAAM,CAAC;AAEhC,UAAMC,IAAMjgB,EAAM,WAAA;AAClB,IAAAigB,EAAI,SAAS,EAAI;AACjB,UAAM5C,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,YAAY,SAAS,eAAe,GAAQ,CAAC,GAClD4C,EAAI,WAAW5C,CAAI;AACnB,UAAM1D,IAAI0D,EAAK,sBAAA;AACf,WAAAA,EAAK,OAAA,GACE1D;AAAA,EACT;AACF;AAIA,SAASuD,GAAmBre,GAAmBC,GAA6C;AAC1F,SAAOD,KAAQA,MAASC,KAAM;AAC5B,QAAID,EAAK,aAAa,KAAMA,EAAqB,YAAY;AAC3D,aAAOA;AAET,IAAAA,IAAOA,EAAK;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAAS8e,GAAgBjf,GAAiB;AACxC,QAAMsB,IAAQ,SAAS,YAAA;AACvB,EAAAA,EAAM,mBAAmBtB,CAAE,GAC3BsB,EAAM,SAAS,EAAK;AACpB,QAAMS,IAAM,OAAO,aAAA;AACnB,EAAKA,MACLA,EAAI,gBAAA,GACJA,EAAI,SAAST,CAAK;AACpB;AAEA,SAASuf,GAAeW,GAA4B;AAClD,MAAI;AACF,UAAMjX,IAAI4P,GAA0BqH,CAAG;AACvC,WAAOjX,KAAQ;AAAA,EACjB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAASoW,GACPvgB,GACA2B,GAMA;AACA,QAAM0f,IAAOC,GAAqB3f,GAAK3B,CAAI;AAC3C,MAAI,CAACqhB,EAAM,QAAO,EAAE,UAAU,MAAM,YAAY,MAAM,WAAW,MAAM,WAAW,KAAA;AAElF,MAAIjU,IAA4B;AAChC,WAASxN,IAAyByhB,GAAMzhB,KAAMI,EAAK,SAASJ,CAAE,KAAKA,MAAOI,GAAMJ,IAAKA,EAAG;AACtF,IAAIA,EAAG,MAAM,eAAYwN,IAAaxN,EAAG,MAAM;AAGjD,QAAM4gB,IAAYe,GAA4BvhB,GAAMqhB,CAAI,GAClDX,IAAYc,GAA4BxhB,GAAMqhB,CAAI,GAElDrU,IAAW,OAAO,iBAAiBqU,CAAI,EAAE;AAE/C,SAAKjU,IAKHA,IAAad,EAAwBc,CAAU,IAJ/CA,IAAa0M,EAA0B,MAAM,IACzC,QACAxN,EAAwB,OAAO,iBAAiB+U,CAAI,EAAE,UAAU,GAK/D,EAAE,UAAArU,GAAU,YAAAI,GAAY,WAAAoT,GAAW,WAAAE,EAAA;AAC5C;AAGA,SAASa,GAA4BvhB,GAAmBqhB,GAAkC;;AACxF,WAASzhB,IAAyByhB,GAAMzhB,KAAMI,EAAK,SAASJ,CAAE,KAAKA,MAAOI,GAAMJ,IAAKA,EAAG,eAAe;AACrG,UAAM0gB,KAASphB,IAAAU,EAAG,MAAM,UAAT,gBAAAV,EAAgB;AAC/B,QAAIohB,EAAQ,QAAOA;AAEnB,UAAMmB,IAAWC,GAAuB9hB,EAAG,aAAa,OAAO,CAAC;AAChE,QAAI6hB,EAAU,QAAOA;AAAA,EACvB;AAGA,SADiB,OAAO,iBAAiBJ,CAAI,EAAE,SAC5B;AACrB;AAEA,SAASK,GAAuBlY,GAAyC;AACvE,MAAI,CAACA,EAAW,QAAO;AACvB,QAAMnG,IAAImG,EAAU,MAAM,gCAAgC;AAC1D,SAAKnG,KACKA,EAAE,CAAC,EAAE,KAAA,KACH;AACd;AAGA,SAASme,GAA4BxhB,GAAmBqhB,GAAkC;;AACxF,WAASzhB,IAAyByhB,GAAMzhB,KAAMI,EAAK,SAASJ,CAAE,KAAKA,MAAOI,GAAMJ,IAAKA,EAAG,eAAe;AACrG,UAAM0gB,KAASphB,IAAAU,EAAG,MAAM,oBAAT,gBAAAV,EAA0B;AACzC,QAAIohB,KAAU,CAACqB,GAAmBrB,CAAM,EAAG,QAAOA;AAElD,UAAMmB,IAAWG,GAA4BhiB,EAAG,aAAa,OAAO,CAAC;AACrE,QAAI6hB,EAAU,QAAOA;AAErB,UAAMI,IAAW,OAAO,iBAAiBjiB,CAAE,EAAE;AAC7C,QAAIiiB,KAAY,CAACF,GAAmBE,CAAQ,EAAG,QAAOA;AAAA,EACxD;AAGA,SAAO;AACT;AAEA,SAASD,GAA4BpY,GAAyC;AAC5E,MAAI,CAACA,EAAW,QAAO;AACvB,QAAMnG,IAAImG,EAAU,MAAM,sCAAsC;AAChE,MAAI,CAACnG,EAAG,QAAO;AACf,QAAMiB,IAAIjB,EAAE,CAAC,EAAE,KAAA;AACf,SAAOiB,KAAK,CAACqd,GAAmBrd,CAAC,IAAIA,IAAI;AAC3C;AAEA,SAASgd,GAAqB3f,GAAgB3B,GAAuC;AACnF,QAAMD,IAAO4B,EAAI;AACjB,SAAI,CAAC5B,KAAQ,CAACC,EAAK,SAASD,CAAI,IAAU,OACnCA,EAAK,aAAa,KAAK,YAAYA,EAAK,gBAAiBA;AAClE;AAEA,SAAS6d,GAAmB1c,GAAsB;AAChD,SAAO,GAAGA,EAAM,eAAe,QAAQ,IAAIA,EAAM,WAAW,IAAIA,EAAM,aAAa,QAAQ,IAAIA,EAAM,SAAS;AAChH;AAGA,SAASmd,GAAmBtV,GAAoB;AAC9C,QAAMe,IAA8B;AAAA,IAClC,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EAAA,GAEJlL,IAAMmK,EAAG,KAAA,EAAO,YAAA;AACtB,MAAIe,EAAIlL,CAAG,EAAG,QAAOkL,EAAIlL,CAAG;AAC5B,QAAMkjB,IAAM,WAAWljB,CAAG;AAC1B,MAAI,OAAO,MAAMkjB,CAAG,EAAG,QAAO;AAC9B,QAAMtV,IAA4B;AAAA,IAChC,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,IAAI,GAAG;AAAA,EAAA;AAEV,MAAIrI,IAAO,KACPsI,IAAQ;AACZ,aAAW,CAAC4M,GAAM0I,CAAM,KAAKvV,GAAO;AAClC,UAAM,IAAI,KAAK,IAAI6M,IAAOyI,CAAG;AAC7B,IAAI,IAAIrV,MACNA,IAAQ,GACRtI,IAAO4d;AAAA,EAEX;AACA,SAAO5d;AACT;AAEA,SAASwd,GAAmBrd,GAAoB;AAC9C,QAAMgF,IAAIhF,EAAE,KAAA,EAAO,YAAA;AAEnB,MADIgF,MAAM,iBAAiBA,MAAM,aAAaA,MAAM,aAAaA,MAAM,WACnEA,MAAM,sBAAsBA,MAAM,gBAAiB,QAAO;AAC9D,QAAM0Y,IAAO1Y,EAAE,MAAM,kEAAkE;AACvF,SAAI0Y,KACQA,EAAK,CAAC,MAAM,SAAY,WAAWA,EAAK,CAAC,CAAC,IAAI,OAC3C,IAER;AACT;AAEA,SAAS9V,GAAW5C,GAAmB;AACrC,SAAOA,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B;AAEA,SAASwW,GAAoBhe,GAAsB;AACjD,SAAOoK,GAAWpK,CAAI,EAAE,QAAQ,UAAU;AAAA,CAAI,EAAE,QAAQ,OAAO,MAAM;AACvE;AASO,SAASyb,GAAiBje,GAAsB;AACrD,QAAM4a,IAAM,SAAS,cAAc,UAAU;AAC7C,SAAAA,EAAI,YAAY5a,GAChB2iB,EAAK/H,EAAI,OAAO,GACTA,EAAI,UAAU,QAAQ,WAAW,EAAE;AAE1C,WAAS+H,EAAKjiB,GAAY;AACxB,UAAMkiB,IAAsB,CAAA;AAE5B,IADaliB,EAAoB,iBAAiB,GAAG,EACjD,QAAQ,CAACJ,MAAO;;AAClB,YAAMqH,IAAMrH,EAAG,QAAQ,YAAA;AACvB,UAAIqH,MAAQ,UAAUrH,EAAG,aAAa,eAAe,MAAM,KAAK;AAC9D,eAAOA,EAAG,aAAY,EAAAV,IAAAU,EAAG,eAAH,QAAAV,EAAe,aAAaU,EAAG,YAAYA;AACjE,QAAAA,EAAG,OAAA;AACH;AAAA,MACF;AAEA,UAAIqH,MAAQ,QAAQ;AAClB,cAAMsX,IAAO,SAAS,cAAc,MAAM,GACpCrR,IAAQtN,EAAG,aAAa,OAAO,GAC/ByZ,IAAOzZ,EAAG,aAAa,MAAM,GAC7BuiB,IAAOviB,EAAG,aAAa,MAAM,GAC7BoL,IAAmB,CAACpL,EAAG,aAAa,OAAO,KAAK,EAAE;AACxD,QAAIsN,KAAOlC,EAAO,KAAK,SAASkC,CAAK,EAAE,GACnCmM,KAAMrO,EAAO,KAAK,aAAaoX,GAAmB/I,CAAI,CAAC,EAAE,GACzD8I,KAAMnX,EAAO,KAAK,eAAemX,CAAI,EAAE;AAC3C,cAAME,IAAUrX,EAAO,OAAO,OAAO,EAAE,KAAK,GAAG;AAE/C,aADIqX,KAAS9D,EAAK,aAAa,SAAS8D,CAAO,GACxCziB,EAAG,aAAY,CAAA2e,EAAK,YAAY3e,EAAG,UAAU;AACpD,SAAAR,IAAAQ,EAAG,eAAH,QAAAR,EAAe,aAAamf,GAAM3e;AAClC;AAAA,MACF;AAyBA,UAAI,CAvBY;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,EAEW,SAASqH,CAAG,GAAG;AAC1B,QAAAib,EAAS,KAAKtiB,CAAE;AAChB;AAAA,MACF;AAEA,YAAM0iB,IAAe,CAAC,QAAQ,UAAU,OAAO,SAAS,OAAO,GACzDC,IAAiB,CAAC,qBAAqB;AAS7C,UARA,CAAC,GAAG3iB,EAAG,UAAU,EAAE,QAAQ,CAACmD,MAAS;AACnC,cAAMuY,IAAOvY,EAAK,KAAK,YAAA;AAIvB,QAFEuf,EAAa,SAAShH,CAAI,MACxBrU,MAAQ,QAAQA,MAAQ,SAASsb,EAAe,SAASjH,CAAI,KACxD1b,EAAG,gBAAgBmD,EAAK,IAAI;AAAA,MACvC,CAAC,GAEGkE,MAAQ,KAAK;AACf,cAAMiZ,IAAOtgB,EAAG,aAAa,MAAM,KAAK;AACxC,QAAI,gBAAgB,KAAKsgB,CAAI,KAAGtgB,EAAG,aAAa,QAAQ,GAAG,GACtDA,EAAG,aAAa,KAAK,KAAGA,EAAG,aAAa,OAAO,UAAU;AAAA,MAChE;AACA,OAAKqH,MAAQ,OAAO,WAAW,KAAKA,CAAG,MAAM,CAACub,GAAe5iB,CAAE,KAC7D6iB,GAAY7iB,GAAI,UAAU;AAAA,IAE9B,CAAC,GACDsiB,EAAS,QAAQ,CAACtiB,MAAO;;AACvB,aAAOA,EAAG,aAAY,EAAAV,IAAAU,EAAG,eAAH,QAAAV,EAAe,aAAaU,EAAG,YAAYA;AACjE,MAAAA,EAAG,OAAA;AAAA,IACL,CAAC;AAAA,EACH;AACF;AAEA,SAAS4iB,GAAe5iB,GAAsB;AAC5C,QAAMmH,IAAQnH,EAAG,aAAa,OAAO,KAAK;AAC1C,SAAO,uDAAuD,KAAKmH,CAAK;AAC1E;AAEA,SAAS0b,GAAY7iB,GAAamH,GAAe;AAC/C,QAAMsC,KAAOzJ,EAAG,aAAa,OAAO,KAAK,IAAI,KAAA;AAC7C,EAAAA,EAAG,aAAa,SAASyJ,IAAM,GAAGA,EAAI,QAAQ,UAAU,EAAE,CAAC,IAAItC,CAAK,KAAKA,CAAK;AAChF;AAEA,SAASqb,GAAmB/I,GAAsB;AAWhD,SAToC;AAAA,IAClC,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,IACL,GAAK;AAAA,EAAA,EAEIA,CAAI,KAAKA;AACtB;ACn8BO,MAAMqJ,GAAO;AAAA,EAkBlB,YAAY5P,GAAqB;AAjBjC,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,sBAA2B,CAAA;AAE3B;AAAA,IAAAA,EAAA,wBAAgC;AAChC,IAAAA,EAAA,sBAAoC;AAEpC;AAAA,IAAAA,EAAA,uBAAgB;AAEhB;AAAA,IAAAA,EAAA,4BAAqB,IAAI,gBAAA;AAEzB;AAAA,IAAAA,EAAA,uCAAgC,IAAI,gBAAA;AACpC,IAAAA,EAAA,2CAAoC;AACpC,IAAAA,EAAA;AAGN,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,OAAO,EAAE,OAAO,kBAAkB,GAC9C,KAAK,QAAQA,EAAE,OAAO,EAAE,OAAO,aAAa,GAC5C,KAAK,SAAS,KAAK,cAAA,GACnB,KAAK,GAAG,OAAO,KAAK,OAAO,KAAK,MAAM,GACtC,KAAK,iBAAiB,IAAI0M,GAAe;AAAA,MACvC,OAAO1F,EAAK;AAAA,MACZ,UAAUA,EAAK;AAAA,MACf,aAAaA,EAAK;AAAA,MAClB,GAAGA,EAAK;AAAA,IAAA,CACT,GAED,KAAK,+BAAA,GACDA,EAAK,iCACP,KAAK,mCAAA,GACL,KAAK,sCAAA,GACL,KAAK,kCAAA,IAGP,KAAK,MAAM,iBAAiB,YAAY,CAAC,MAAkB;AACzD,WAAK,uBAAuB,CAAC;AAAA,IAC/B,CAAC,GAED,KAAK,QAAA,GAELA,EAAK,MAAM,UAAU,CAACgB,MAAW;AAE/B,UAAI,KAAK,mBAAkBA,KAAA,gBAAAA,EAAQ,YAAW,WAAW;AACvD,aAAK,gBAAA,GACL,KAAK,QAAA;AACL;AAAA,MACF;AACA,UAAI,KAAK,gBAAgB;AACvB,aAAK,gBAAgB;AACrB;AAAA,MACF;AACA,WAAK,QAAA;AAAA,IACP,CAAC,GACDhB,EAAK,MAAM,mBAAmB,MAAM,KAAK,gBAAgB;AAAA,EAC3D;AAAA,EAEA,SAASlB,GAAe;AACtB,SAAK,MAAM,MAAM,WAAW,GAAGA,CAAK;AAAA,EACtC;AAAA;AAAA,EAGA,IAAI,sBAA2C;AAC7C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,mBAAmB;;AACjB,KAAA1S,IAAA,KAAK,iBAAL,QAAAA,EAAmB;AAAA,EACrB;AAAA,EAEA,IAAI,kBAA2B;AAC7B,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB;AAChB,QAAI,CAAC,KAAK,eAAgB;AAC1B,UAAMsa,IAAK,KAAK;AAChB,SAAK,iBAAiB,MACtB,KAAK,gBAAgB,IACjB,KAAK,iBACP,KAAK,aAAa,QAAQ,EAAK,GAC/B,KAAK,eAAe,OAEtB,KAAK,KAAK,QAAQ,OAAA;AAClB,UAAMmJ,IAAU,KAAK,MAAM;AAAA,MACzB,sBAAsBC,GAAUpJ,CAAE,CAAC;AAAA,IAAA;AAErC,IAAAmJ,KAAA,QAAAA,EAAS,UAAU,OAAO;AAAA,EAC5B;AAAA;AAAA,EAGA,UAAU;AACR,QAAI,KAAK,gBAAgB;AACvB,WAAK,gBAAgB;AACrB;AAAA,IACF;AACA,SAAK,QAAA;AAAA,EACP;AAAA,EAEA,UAAU;AACR,SAAK,mBAAmB,MAAA,GACxB,KAAK,8BAA8B,MAAA,GACnC,KAAK,aAAa,EAAK,GACvB,KAAK,kBAAA,GACL,KAAK,eAAe,QAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qCAAqC;AAC3C,UAAM7P,IAAO,EAAE,SAAS,IAAM,QAAQ,KAAK,8BAA8B,OAAA;AACzE,aAAS;AAAA,MACP;AAAA,MACA,CAAC,MAAkB;AACjB,YAAI,EAAE,WAAW,GAAG;AAClB,eAAK,oCAAoC;AACzC;AAAA,QACF;AACA,YAAI,CAAC,KAAK,gBAAgB;AACxB,eAAK,oCAAoC;AACzC;AAAA,QACF;AACA,cAAM+P,IAAY,KAAK,MAAM,cAAc,oBAAoB;AAC/D,YAAI,CAACA,GAAW;AACd,eAAK,oCAAoC;AACzC;AAAA,QACF;AACA,cAAMpV,IAAI,EAAE;AACZ,YAAI,EAAEA,aAAa,OAAO;AACxB,eAAK,oCAAoC;AACzC;AAAA,QACF;AACA,cAAM1N,IAAO0N,EAAE,aAAa,KAAK,YAAYA,EAAE,aAAaA;AAC5D,aAAK,oCAAoC,CAAC,EAAE1N,KAAQ8iB,EAAU,SAAS9iB,CAAI;AAAA,MAC7E;AAAA,MACA+S;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,wCAAwC;AAC9C,SAAK,MAAM,iBAAiB,SAAS,CAACM,MAAkB;AACtD,YAAM3F,IAAI2F,EAAE;AACZ,UAAI,EAAE3F,aAAa,MAAO;AAC1B,YAAM7N,IAAK6N,aAAa,UAAUA,IAAIA,EAAE;AACxC,UAAK7N,MACDA,MAAO,KAAK,SAASA,EAAG,QAAQ,eAAe,IAAG;AACpD,YAAI,KAAK,4CAA6C;AACtD,aAAK,iBAAA,GACL,KAAK,KAAK,MAAM,aAAa,IAAI;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,oCAAoC;AAC1C,SAAK,GAAG,iBAAiB,SAAS,CAACwT,MAAkB;AACnD,YAAM3F,IAAI2F,EAAE;AACZ,MAAM3F,aAAa,QACd,KAAK,GAAG,SAASA,CAAC,MACnB,KAAK,MAAM,SAASA,CAAC,KACrB,KAAK,OAAO,SAASA,CAAC,KACtB,KAAK,gDACT,KAAK,iBAAA,GACL,KAAK,KAAK,MAAM,aAAa,IAAI;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,iCAAiC;AACvC,UAAMqF,IAAO,EAAE,SAAS,IAAM,QAAQ,KAAK,mBAAmB,OAAA,GACxDgQ,IAAiB,CAACnjB,MAAyD;AAC/E,UAAI,EAAEA,aAAkB,SAAU,QAAO;AACzC,YAAM4G,IAAI5G,EAAO,QAAQ,GAAG;AAE5B,aADI,CAAC4G,KAAK,CAAC,KAAK,MAAM,SAASA,CAAC,KAC5B,CAACA,EAAE,aAAa,MAAM,IAAU,OAC7BA;AAAA,IACT;AACA,SAAK,MAAM;AAAA,MACT;AAAA,MACA,CAAC6M,MAAkB;AACjB,cAAM7M,IAAIuc,EAAe1P,EAAE,MAAM;AACjC,QAAK7M,MAEDA,EAAE,QAAQ,oBAAoB,KAClC6M,EAAE,eAAA;AAAA,MACJ;AAAA,MACAN;AAAA,IAAA;AAEF,UAAMiQ,IAAe,CAAC3P,MAAkB;AACtC,MAAK0P,EAAe1P,EAAE,MAAM,KAC5BA,EAAE,eAAA;AAAA,IACJ;AACA,SAAK,MAAM,iBAAiB,SAAS2P,GAAcjQ,CAAI,GACvD,KAAK,MAAM,iBAAiB,YAAYiQ,GAAcjQ,CAAI;AAAA,EAC5D;AAAA;AAAA,EAIQ,UAAU;AAChB,SAAK,kBAAA,GACL7G,EAAM,KAAK,KAAK;AAEhB,UAAM,EAAE,KAAAjN,EAAA,IAAQ,KAAK,KAAK;AAc1B,QAbA,KAAK,MAAM,MAAM,WAAWuM,GAAmBvM,EAAI,KAAK,KAAK,GAC7D,KAAK,MAAM,MAAM,aAAaA,EAAI,OAAO,wBACzC,KAAK,MAAM,MAAM,aAAaA,EAAI,OAAO,YACzC,KAAK,MAAM,MAAM,WAAWA,EAAI,OAAO,UACvC,KAAK,MAAM,MAAM,aAAasN,EAAwBtN,EAAI,OAAO,UAAU,GAC3E,KAAK,MAAM,MAAM,QAAQA,EAAI,OAAO,OACpC,KAAK,MAAM,MAAM,aAAaA,EAAI,OAAO,cAAc,QACvD,KAAK,MAAM,MAAM,YAAY,0BAA0BA,EAAI,OAAO,SAAS,GAC3E,KAAK,MAAM,MAAM;AAAA,MACf;AAAA,MACAiM,GAA4BjM,EAAI,MAAM;AAAA,IAAA,GAGpC,CAACA,EAAI,SAAS;AAChB,WAAK,MAAM;AAAA,QACT8M,EAAE,OAAO,EAAE,OAAO,kBAAkB;AAAA,UAClC,KAAK,KAAK,EAAE,kBAAkB;AAAA,QAAA,CAC/B;AAAA,MAAA;AAAA;AAGH,eAASkX,IAAK,GAAGA,IAAKhkB,EAAI,SAAS,QAAQgkB;AACzC,aAAK,MAAM,OAAO,KAAK,eAAehkB,EAAI,SAASgkB,CAAE,GAAGhkB,GAAKgkB,CAAE,CAAC;AASpE,UAAMC,IAAmB,KAAK,KAAK,kBAAkB,CAAC,YAAY,QAAQ,IAAI,CAAC,UAAU,GACnFC,IAAMC,GAAS,OAAO,KAAK,OAAO;AAAA,MACtC,OAAO,EAAE,MAAM,YAAY,MAAM,IAAO,KAAKF,EAAA;AAAA,MAC7C,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,MACX,OAAO,CAAC7P,MAAM,KAAK,kBAAkBA,CAAC;AAAA,MACtC,UAAU,CAACA,MAAM,KAAK,mBAAmBA,CAAC;AAAA,IAAA,CAC3C;AACD,SAAK,aAAa,KAAK8P,CAAG,GAE1B,KAAK,eAAA;AAAA,EACP;AAAA,EAEQ,eAAezkB,GAAkBO,GAAeokB,GAAsB;;AAC5E,UAAM7c,IAAI9H,EAAQ,OACZgR,IAAU,GAAGlJ,EAAE,cAAc,CAAC,MAAMA,EAAE,gBAAgB,CAAC,MAC3DA,EAAE,iBAAiB,CACrB,MAAMA,EAAE,eAAe,CAAC,MAElB8c,IACJ5kB,EAAQ,WAAW,MAAM,KAAK,KAAK,EAAE,6BAA6B,IAAIqY,GAAiBrY,EAAQ,MAAM,GACjGoS,MACJ3R,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,6BAA4B,KACtCV,GAA4BC,CAAO,IACnC,QACA6kB,IAAczS,IAChB,KAAK,KAAK,EAAE,8BAA8B;AAAA,MACxC,OAAOuS,IAAe;AAAA,MACtB,OAAO,KAAKvS,CAAK;AAAA,IAAA,CAClB,IACD,KAAK,KAAK,EAAE,uBAAuB,EAAE,OAAOuS,IAAe,GAAG,QAAQC,EAAA,CAAa,GAEjFE,IAAK5X,GAAoBpF,EAAE,KAAK,GAChCjF,IACJiiB,KAAM,OAAO,aAAaA,CAAE,0EAA0E,IAElGlC,IAAOvV,EAAE,OAAO;AAAA,MACpB,OAAO;AAAA,MACP,WAAWrN,EAAQ;AAAA,IAAA,CACpB,GAEK+kB,IAAO1X,EAAE,OAAO;AAAA,MACpB,OAAO,aAAa+E,IAAQ,iCAAiC,EAAE;AAAA,MAC/D,OAAO,KAAK,KAAK,EAAE,uBAAuB,EAAE,MAAMyS,GAAa;AAAA,MAC/D,OAAO,WAAW7T,CAAO,IAAIlJ,EAAE,kBAAkB,cAAcA,EAAE,eAAe,MAAM,EAAE,GAAGjF,CAAG;AAAA,IAAA,CAC/F,GAEKmiB,IAAU3X,EAAE,OAAO,EAAE,OAAO,yBAAyB;AAAA,MACzDA,EAAE,QAAQ,EAAE,OAAO,6BAA6B,OAAOwX,EAAA,GAAe,CAACA,CAAW,CAAC;AAAA,MACnFxX,EAAE,OAAO,EAAE,OAAO,iCAAiC;AAAA,QACjDA;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,iBAAiB;AAAA,UAAA;AAAA,UAEtC,CAAC4X,IAAU;AAAA,QAAA;AAAA,QAEb5X;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,aAAa;AAAA,YAChC,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,kBAAkB3U,EAAQ,EAAE;AAAA,YACnC;AAAA,UAAA;AAAA,UAEF,CAACklB,IAAU;AAAA,QAAA;AAAA,QAEb7X;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,eAAe;AAAA,YAClC,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,eAAe3U,EAAQ,EAAE;AAAA,YAChC;AAAA,UAAA;AAAA,UAEF,CAACmlB,IAAW;AAAA,QAAA;AAAA,MACd,CACD;AAAA,IAAA,CACF,GAEKC,IAAO/X,EAAE,OAAO;AAAA,MACpB,OAAO;AAAA,MACP,OAAOgY,GAAgBrlB,EAAQ,QAAQA,EAAQ,MAAM,SAAS;AAAA,IAAA,CAC/D;AAED,WAAAA,EAAQ,QAAQ,QAAQ,CAAC8S,GAAK7O,MAAM;AAClC,MAAAmhB,EAAK,OAAO,KAAK,cAAcplB,GAAS8S,GAAK7O,GAAG1D,CAAG,CAAC;AAAA,IACtD,CAAC,GAEDwkB,EAAK,OAAOK,CAAI,GAEhBxC,EAAK,OAAOmC,GAAMC,CAAO,GAEzBpC,EAAK,iBAAiB,SAAS,CAACjO,MAAM;AACpC,MAAKA,EAAE,OAAuB,QAAQ,WAAW,KAE7C,CAACA,EAAE,UAAU,KAAK,sDACtBA,EAAE,gBAAA,GACF,KAAK,KAAK,MAAM,aAAa,EAAE,MAAM,WAAW,WAAW3U,EAAQ,IAAI;AAAA,IACzE,CAAC,GAEM4iB;AAAA,EACT;AAAA,EAEQ,cACN5iB,GACAkT,GACAE,GACA7S,GACa;AACb,UAAM+kB,IAAUpS,EAAO,OAAO,WAAW,GACnCqS,IAAQlY,EAAE,OAAO;AAAA,MACrB,OAAO,aAAaiY,IAAU,aAAa,EAAE;AAAA,MAC7C,mBAAmBtlB,EAAQ;AAAA,MAC3B,qBAAqB,OAAOoT,CAAW;AAAA,MACvC,mBAAmB,KAAK,KAAK,EAAE,wBAAwB;AAAA,MACvD,OAAO,QAAQoS,GAAgBxlB,EAAQ,QAAQoT,CAAW,CAAC,IACzDF,EAAO,MAAM,kBAAkB,cAAcA,EAAO,MAAM,eAAe,MAAM,EACjF,GAAGA,EAAO,MAAM,gBAAgB,cAAcuS,GAASvS,EAAO,MAAM,aAAa,CAAC,MAAM,EAAE;AAAA,IAAA,CAC3F;AAED,eAAWoH,KAASpH,EAAO;AACzB,MAAAqS,EAAM,OAAO,KAAK,aAAavlB,GAASoT,GAAakH,GAAO/Z,CAAG,CAAC;AAGlE,IAAI+kB,KACFC,EAAM,iBAAiB,YAAY,CAAC5Q,MAAkB;AACpD,MAAKA,EAAE,OAAuB,QAAQ,WAAW,MACjDA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACF,KAAK,wBAAwB3U,EAAQ,IAAIoT,CAAW;AAAA,IACtD,CAAC;AAOH,UAAMsS,IAAWhB,GAAS,OAAOa,GAAO;AAAA,MACtC,OAAO,EAAE,MAAM,UAAU,KAAK,CAAC,QAAQ,EAAA;AAAA,MACvC,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,MACX,OAAO,CAAC5Q,MAAM,KAAK,gBAAgBA,GAAG3U,EAAQ,IAAIoT,CAAW;AAAA,MAC7D,UAAU,CAACuB,MAAM,KAAK,iBAAiBA,GAAG3U,EAAQ,IAAIoT,CAAW;AAAA,MACjE,UAAU,MAAM;AAAA,MAGhB;AAAA,IAAA,CACD;AACD,gBAAK,aAAa,KAAKsS,CAAQ,GAExBH;AAAA,EACT;AAAA,EAEQ,aACNvlB,GACAoT,GACAkH,GACA/Z,GACa;;AACb,UAAM8Q,IAAqB,EAAE,KAAA9Q,GAAK,QAAQ,OAAA,GACpCjB,IAAM,KAAK,KAAK,SAAS,IAAIgb,EAAM,IAAI;AAC7C,QAAInL,IAAQ;AACZ,QAAImL,EAAM,YAAY;AACpB,YAAMqL,IAAarL,EAAM,SAAS,YAAU7Z,IAAAnB,KAAA,gBAAAA,EAAK,mBAAL,gBAAAmB,EAAqB,UAAS,QACpEuQ,IAAUL;AAAA,QACd2J,EAAM;AAAA,QACNA,EAAM;AAAA,QACNA,EAAM;AAAA,MAAA,GAOFsL,IAAW7U,GAA+BuJ,EAAM,YAAYtJ,CAAO;AACzE,MAAI4U,EAAS,SAAS,YAEpBzW,IAAQ,eADUwW,IAAa,oBAAoB,mBACnB,KAAKC,EAAS,IAAI,WAElDzW,IAAQ,kJAAkJ1B;AAAAA,QACxJmY,EAAS;AAAA,MAAA,CACV;AAAA,IAEL,MAAA,CAAWtmB,KAAA,QAAAA,EAAK,gBACd6P,IAAQ7P,EAAI,cAAcgb,EAAM,OAAcjJ,CAAG,IACxC/R,IACT6P,IAAQ,2GAA2G1B;AAAAA,MACjHnO,EAAI;AAAA,IAAA,CACL,WAED6P,IAAQ,2CAA2C1B;AAAAA,MACjD,KAAK,KAAK,EAAE,uBAAuB,EAAE,MAAM6M,EAAM,MAAM;AAAA,IAAA,CACxD;AAGH,UAAMuL,KAAcvmB,KAAA,gBAAAA,EAAK,SAAQgb,EAAM,MAEjCnZ,IAAKkM,EAAE,OAAO;AAAA,MAClB,OAAO,YAAYiN,EAAM,aAAa,cAAc,EAAE;AAAA,MACtD,WAAWA,EAAM;AAAA,MACjB,mBAAmBta,EAAQ;AAAA,MAC3B,qBAAqB,OAAOoT,CAAW;AAAA,MACvC,qBAAqB,KAAK,KAAK,EAAE,mBAAmB;AAAA,IAAA,CACrD,GAGK0S,IAAUzY,EAAE,OAAO,EAAE,OAAO,qBAAqB,MAAM8B,GAAO,GAG9D4W,IAAe1Y,EAAE,OAAO,EAAE,OAAO,uBAAuB;AAAA,MAC5DA,EAAE,QAAQ,EAAE,OAAO,0BAA0B,OAAOwY,EAAA,GAAe,CAACA,CAAW,CAAC;AAAA,MAChFxY,EAAE,OAAO,EAAE,OAAO,+BAA+B;AAAA,QAC/CA;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,iBAAiB;AAAA,YACpC,SAAS,CAACsH,MAAaA,EAAE,gBAAA;AAAA,UAAgB;AAAA,UAE3C,CAACsQ,IAAU;AAAA,QAAA;AAAA,QAEb3lB,KAAA,QAAAA,EAAK,kBAAkB,CAACgb,EAAM,aAC1BjN;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,iBAAiB;AAAA,YACpC,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,cAAc2F,CAAK;AAAA,YAC1B;AAAA,UAAA;AAAA,UAEF,CAAC0L,IAAU;AAAA,QAAA,IAEb;AAAA,QACJ3Y;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,iBAAiB;AAAA,YACpC,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,eAAe,KAAK2F,EAAM,IAAIuL,CAAW;AAAA,YAChD;AAAA,UAAA;AAAA,UAEF,CAACI,IAAU;AAAA,QAAA;AAAA,QAEb5Y;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,aAAa;AAAA,YAChC,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,gBAAgB2F,EAAM,EAAE;AAAA,YAC/B;AAAA,UAAA;AAAA,UAEF,CAAC4K,IAAU;AAAA,QAAA;AAAA,QAEb7X;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,eAAe;AAAA,YAClC,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,aAAa2F,EAAM,EAAE;AAAA,YAC5B;AAAA,UAAA;AAAA,UAEF,CAAC6K,IAAW;AAAA,QAAA;AAAA,MACd,CACD;AAAA,IAAA,CACF;AAED,WAAAhkB,EAAG,OAAO4kB,GAAcD,CAAO,GAE/B3kB,EAAG,iBAAiB,SAAS,CAACwT,MAAM;AAClC,UAAI,KAAK,mBAAmB2F,EAAM,IAElC;AAAA,YAAI3F,EAAE,QAAQ;AACZ,UAAAA,EAAE,gBAAA,GACF,KAAK,KAAK,MAAM,aAAa,EAAE,MAAM,WAAW,WAAW3U,EAAQ,IAAI;AACvE;AAAA,QACF;AACA,QAAA2U,EAAE,gBAAA,GACF,KAAK,KAAK,MAAM,aAAa;AAAA,UAC3B,MAAM;AAAA,UACN,WAAW3U,EAAQ;AAAA,UACnB,aAAAoT;AAAA,UACA,SAASkH,EAAM;AAAA,QAAA,CAChB;AAAA;AAAA,IACH,CAAC,GAEGA,EAAM,aACRnZ,EAAG,iBAAiB,YAAY,CAACwT,MAAM;AACrC,MAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACF,KAAK,eAAe,KAAK2F,EAAM,IAAIuL,CAAW;AAAA,IAChD,CAAC,IACQvmB,KAAA,QAAAA,EAAK,kBACd6B,EAAG,iBAAiB,YAAY,CAACwT,MAAM;AACrC,MAAAA,EAAE,gBAAA,GACF,KAAK,cAAc2F,CAAK;AAAA,IAC1B,CAAC,GAGInZ;AAAA,EACT;AAAA,EAEQ,gBAA6B;AACnC,UAAM+kB,IAAsD;AAAA,MAC1D,EAAE,QAAQ,KAAK,OAAO,KAAK,KAAK,EAAE,qBAAqB,EAAA;AAAA,MACvD,EAAE,QAAQ,OAAO,OAAO,KAAK,KAAK,EAAE,uBAAuB,EAAA;AAAA,IAAE,GAEzDC,IAAM9Y,EAAE,OAAO,EAAE,OAAO,wBAAwB;AAAA,MACpDA,EAAE,QAAQ,IAAI,CAAC,KAAK,KAAK,EAAE,mBAAmB,CAAC,CAAC;AAAA,IAAA,CACjD;AACD,eAAW8G,KAAK+R;AACd,MAAAC,EAAI;AAAA,QACF9Y;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SAAS,MACP,KAAK,KAAK,MAAM,OAAO,CAAC5N,MAAM;AAC5B,cAAAA,EAAE,SAAS,KAAK6W,GAAcnC,EAAE,MAAM,CAAC;AAAA,YACzC,CAAC;AAAA,UAAA;AAAA,UAEL,CAACA,EAAE,KAAK;AAAA,QAAA;AAAA,MACV;AAGJ,WAAOgS;AAAA,EACT;AAAA;AAAA;AAAA,EAKQ,uBAAuBxR,GAAe;AAC5C,QAAI,KAAK,KAAK,MAAM,IAAI,SAAS,SAAS,EAAG;AAC7C,UAAM3F,IAAI2F,EAAE;AACZ,IAAI,CAAC3F,KAAK,CAAC,KAAK,MAAM,SAASA,CAAC,MAChC2F,EAAE,eAAA,GACFA,EAAE,gBAAA,GACF,KAAK,2BAAA;AAAA,EACP;AAAA;AAAA,EAGQ,6BAA6B;;AACnC,UAAMyR,IAAM,KAAK,KAAK;AACtB,QAAI,GAAC3lB,IAAA2lB,EAAI,IAAI,MAAM,MAAd,QAAA3lB,EAAiB,gBAAgB;AACtC,SAAK,KAAK,MAAM,OAAO,CAAChB,MAAM;AAC5B,UAAIA,EAAE,SAAS,SAAS,EAAG;AAC3B,YAAM4mB,IAAWD,EAAI,YAAY,MAAM;AACtC,MAAAC,EAAS,MAA8B,UAAU;AAClD,YAAMrmB,IAAUsW,GAAc,GAAG;AACjC,MAAAtW,EAAQ,QAAQ,CAAC,EAAE,OAAO,KAAKqmB,CAAQ,GACvC5mB,EAAE,SAAS,KAAKO,CAAO;AAAA,IACzB,CAAC;AAGD,UAAMsmB,KAAa1M,KAAAjZ,IADP,KAAK,KAAK,MAAM,IACL,SAAS,CAAC,MAAd,gBAAAA,EAAiB,QAAQ,OAAzB,gBAAAiZ,EAA6B,OAAO;AACvD,IAAK0M,KAEL,sBAAsB,MAAM;AAC1B,YAAMjM,IAAM9E,EAAkB,KAAK,KAAK,MAAM,KAAK+Q,EAAW,EAAE;AAChE,MAAIjM,KAAK,KAAK,cAAcA,EAAI,KAAK;AAAA,IACvC,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,wBAAwBha,GAAmB+S,GAAqB;;AACtE,UAAMgT,IAAM,KAAK,KAAK;AACtB,QAAI,GAAC3lB,IAAA2lB,EAAI,IAAI,MAAM,MAAd,QAAA3lB,EAAiB,gBAAgB;AACtC,UAAM4lB,IAAWD,EAAI,YAAY,MAAM;AACtC,IAAAC,EAAS,MAA8B,UAAU,IAElD,KAAK,KAAK,MAAM,OAAO,CAAC5mB,MAAM;AAC5B,YAAMkW,IAAML,EAAY7V,GAAGY,CAAS;AACpC,UAAI,CAACsV,EAAK;AACV,YAAM7C,IAAM6C,EAAI,QAAQvC,CAAW;AACnC,MAAI,CAACN,KAAOA,EAAI,OAAO,SAAS,KAChCA,EAAI,OAAO,KAAKuT,CAAQ;AAAA,IAC1B,CAAC,GAED,sBAAsB,MAAM;AAC1B,YAAMhM,IAAM9E,EAAkB,KAAK,KAAK,MAAM,KAAK8Q,EAAS,EAAE;AAC9D,MAAIhM,KAAK,KAAK,cAAcA,EAAI,KAAK;AAAA,IACvC,CAAC;AAAA,EACH;AAAA,EAEQ,cAAcC,GAAc;AAClC,QAAI,KAAK,mBAAmBA,EAAM,GAAI;AACtC,SAAK,aAAa,EAAI;AAEtB,UAAMhb,IAAM,KAAK,KAAK,SAAS,IAAIgb,EAAM,IAAI;AAC7C,QAAI,EAAChb,KAAA,QAAAA,EAAK,gBAAgB;AAE1B,UAAM4kB,IAAU,KAAK,MAAM;AAAA,MACzB,sBAAsBC,GAAU7J,EAAM,EAAE,CAAC;AAAA,IAAA,GAErCiM,IAAcrC,KAAA,gBAAAA,EAAS,cAAc;AAC3C,QAAI,CAACqC,EAAa;AAElB,UAAMrlB,IACJ5B,EAAI,eAAe,WACfinB,EAAY,cAAcjnB,EAAI,eAAe,QAAQ,IACrDinB,EAAY;AAElB,QAAI,CAACrlB,EAAQ;AAEb,SAAK,iBAAiBoZ,EAAM,IAC5B4J,KAAA,QAAAA,EAAS,UAAU,IAAI;AAEvB,UAAMjP,KACJ3V,EAAI,eAAe,SAAS,SACxB,OAAQgb,EAAM,MAAchb,EAAI,eAAe,OAAO,KAAK,EAAE;AAGnE,SAAK,eAAe,IAAIsf,GAAa;AAAA,MACnC,IAAI1d;AAAA,MACJ,cAAc+T;AAAA,MACd,MAAM3V,EAAI,eAAe;AAAA,MACzB,WAAW,CAAC,CAACA,EAAI,eAAe;AAAA,MAChC,aAAaA,EAAI,eAAe;AAAA,MAChC,cAAc,KAAK,KAAK,MAAM,IAAI;AAAA,MAClC,UAAU,CAAC2M,MAAU;AACnB,cAAMua,IAAUlnB,EAAI,eAAgB,SAC9BmnB,IAAYnM,EAAM;AACxB,aAAK,aAAa,EAAK,GACvB,KAAK,KAAK,MAAM,OAAO,CAAC7a,MAAM;AAC5B,gBAAM4a,IAAM9E,EAAkB9V,GAAGgnB,CAAS;AAC1C,UAAIpM,MAAMA,EAAI,MAAM,MAAcmM,CAAO,IAAIva;AAAA,QAC/C,CAAC;AAAA,MACH;AAAA,MACA,UAAU,MAAM,KAAK,aAAa,EAAI;AAAA,MACtC,mBAAmB,CAACsW,MAAiC;AACnD,aAAK,KAAK,QAAQ,OAAOA,CAAK;AAAA,MAChC;AAAA,IAAA,CACD,GAEGjjB,EAAI,eAAe,SAAS,UAC9B,KAAK,KAAK,QAAQ,OAAO,KAAK,YAAY,GAI5C,KAAK,KAAK,MAAM,aAAa;AAAA,MAC3B,MAAM;AAAA,MACN,WAAW4kB,EAAS,aAAa,iBAAiB;AAAA,MAClD,aAAa,OAAOA,EAAS,aAAa,mBAAmB,CAAC;AAAA,MAC9D,SAAS5J,EAAM;AAAA,IAAA,CAChB;AAAA,EACH;AAAA;AAAA,EAGQ,aAAaoM,GAAoB;AACvC,QAAI,CAAC,KAAK,eAAgB;AAC1B,UAAM3L,IAAK,KAAK;AAChB,SAAK,iBAAiB,MAClB,KAAK,iBACP,KAAK,aAAa,QAAQ2L,CAAS,GACnC,KAAK,eAAe,OAEtB,KAAK,KAAK,QAAQ,OAAA;AAClB,UAAMxC,IAAU,KAAK,MAAM;AAAA,MACzB,sBAAsBC,GAAUpJ,CAAE,CAAC;AAAA,IAAA;AAErC,IAAAmJ,KAAA,QAAAA,EAAS,UAAU,OAAO,eAEtB,KAAK,kBACP,KAAK,gBAAgB,IACrB,KAAK,QAAA;AAAA,EAET;AAAA;AAAA;AAAA,EAKQ,sCAAsC;AAC5C,IAAI,KAAK,kBAAgB,KAAK,iBAAA;AAAA,EAChC;AAAA,EAEQ,oBAAoByC,GAAsC;AAChE,UAAMrnB,IAAM,KAAK,KAAK,SAAS,IAAIqnB,CAAS;AAC5C,QAAIrnB,KAAA,QAAAA,EAAK,mBAAmB;AAC1B,YAAMqZ,IAAMrZ,EAAI,kBAAkB,CAAC0P,MAAM,KAAK,KAAK,SAAS,YAAYA,CAAC,CAAC;AAC1E,aAAI,MAAM,QAAQ2J,CAAG,IAAU,EAAE,QAAQA,EAAA,IAClCA;AAAA,IACT;AACA,WAAO,EAAE,QAAQ,CAAC,KAAK,KAAK,SAAS,YAAYgO,CAAS,CAAC,EAAA;AAAA,EAC7D;AAAA,EAEQ,mBAAmBzlB,GAAiB0lB,GAAiC;AAC3E,QAAI,CAACA,EAAS;AACd,UAAM,EAAE,MAAAC,GAAM,GAAGC,EAAA,IAASF;AAC1B,WAAO,OAAO1lB,EAAO,OAAO4lB,CAAI,GAC5BD,KAAQ,OAAOA,KAAS,aAC1B3lB,EAAO,MAAM,OAAO,EAAE,GAAIA,EAAO,MAAM,QAAQ,IAAK,GAAG2lB,EAAA;AAAA,EAE3D;AAAA;AAAA,EAGQ,4BACNE,GACmC;;AACnC,QAAI,CAACA,EAAc;AACnB,UAAItmB,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,6BAA4B,GAAM,QAAOsmB;AAC3D,UAAM,EAAE,mBAAmBC,GAAK,GAAGF,MAASC;AAC5C,WAAO,OAAO,KAAKD,CAAI,EAAE,SAASA,IAAO;AAAA,EAC3C;AAAA;AAAA,EAGQ,8BAA8BG,GAAkC;;AACtE,UAAMjnB,IAAUsW,GAAc2Q,EAAK,iBAAiB,GAAG;AACvD,gBAAK,mBAAmBjnB,GAAS,KAAK,4BAA4BinB,EAAK,YAAY,CAAC,IAChFxmB,IAAAwmB,EAAK,iBAAL,QAAAxmB,EAAmB,SACrBwmB,EAAK,aAAa,QAAQ,CAACnT,GAAQV,MAAgB;;AACjD,OAAA3S,IAAAT,EAAQ,QAAQoT,CAAW,MAA3B,QAAA3S,EAA8B,OAAO,KAAK,GAAGqT;AAAA,IAC/C,CAAC,KAEDnT,IAAAX,EAAQ,QAAQ,CAAC,MAAjB,QAAAW,EAAoB,OAAO,KAAK,GAAGsmB,EAAK,SAEnCjnB;AAAA,EACT;AAAA,EAEQ,kCAAkCinB,GAAkC;;AAE1E,QADIA,EAAK,iBAAiBA,EAAK,kBAAkB,UAC5CxmB,IAAAwmB,EAAK,iBAAL,gBAAAxmB,EAAmB,WAAU,KAAK,EAAG,QAAO;AACjD,UAAM6M,IAAQ,KAAK,4BAA4B2Z,EAAK,YAAY;AAChE,WAAO,CAAC,EAAC3Z,KAAA,QAAAA,EAAO;AAAA,EAClB;AAAA,EAEQ,qBAAqBtN,GAAqE;;AAChG,aAASoT,IAAc,GAAGA,IAAcpT,EAAQ,QAAQ,QAAQoT,KAAe,GAAG;AAChF,YAAMkH,KAAQ7Z,IAAAT,EAAQ,QAAQoT,CAAW,MAA3B,gBAAA3S,EAA8B,OAAO;AACnD,UAAI6Z,EAAO,QAAO,EAAE,OAAAA,GAAO,aAAAlH,EAAA;AAAA,IAC7B;AAAA,EAEF;AAAA,EAEQ,kBAAkBuB,GAA2B;;AACnD,SAAK,oCAAA;AACL,UAAMlO,IAAOkO,EAAE,MACTZ,IAAStN,EAAK,aAAa,aAAa,GACxCkgB,IAAYlgB,EAAK,aAAa,iBAAiB,GAC/CygB,IAAczgB,EAAK,aAAa,SAAS,GACzC0gB,IAAc1gB,EAAK,aAAa,mBAAmB,GACnD2gB,IAAWzS,EAAE,YAAY;AAG/B,QAAIZ,GAAQ;AACV,OAAAtT,IAAAgG,EAAK,kBAAL,QAAAhG,EAAoB,YAAYgG,IAChC,KAAK,KAAK,MAAM,OAAO,CAAChH,MAAM;AAC5B,QAAAA,EAAE,SAAS,OAAO2nB,GAAU,GAAG9Q,GAAcvC,CAAM,CAAC;AAAA,MACtD,CAAC;AACD;AAAA,IACF;AAGA,QAAIoT,MAAgB,YAAYR,GAAW;AACzC,OAAAhmB,IAAA8F,EAAK,kBAAL,QAAA9F,EAAoB,YAAY8F;AAChC,YAAMwgB,IAAO,KAAK,oBAAoBN,CAAS,GACzCU,IAAa,KAAK,8BAA8BJ,CAAI;AAC1D,WAAK,KAAK,MAAM,OAAO,CAACxnB,MAAM;AAC5B,QAAAA,EAAE,SAAS,OAAO2nB,GAAU,GAAGC,CAAU;AAAA,MAC3C,CAAC;AACD,YAAM7mB,IAAO,KAAK,qBAAqB6mB,CAAU;AACjD,MAAI7mB,KACF,KAAK,KAAK,MAAM,aAAa;AAAA,QAC3B,MAAM;AAAA,QACN,WAAW6mB,EAAW;AAAA,QACtB,aAAa7mB,EAAK;AAAA,QAClB,SAASA,EAAK,MAAM;AAAA,MAAA,CACrB;AAEH;AAAA,IACF;AAGA,QAAI0mB,GAAa;AACf,OAAAtN,IAAAnT,EAAK,kBAAL,QAAAmT,EAAoB,YAAYnT;AAChC,YAAM4gB,IAAa/Q,GAAc,GAAG;AACpC,WAAK,KAAK,MAAM,OAAO,CAAC7W,MAAM;AAC5B,cAAM4a,IAAM9E,EAAkB9V,GAAGynB,CAAW;AAC5C,YAAI,CAAC7M,EAAK;AACV,cAAMiN,IAAUjN,EAAI,QAAQ,QAAQA,EAAI,WAAW,GAC7C9O,IAAM+b,EAAQ,OAAO,UAAU,CAACvf,MAAMA,EAAE,OAAOmf,CAAW;AAChE,YAAI3b,IAAM,EAAG;AACb,cAAM,CAACgc,CAAK,IAAID,EAAQ,OAAO,OAAO/b,GAAK,CAAC;AAC5C,QAAA8b,EAAW,QAAQ,CAAC,EAAE,OAAO,KAAKE,CAAK,GAIvC9nB,EAAE,SAAS,OAAO2nB,GAAU,GAAGC,CAAU,GACzC3R,GAAoBjW,GAAG4a,EAAI,QAAQ,EAAE;AAAA,MACvC,CAAC,GACD,KAAK,KAAK,MAAM,aAAa;AAAA,QAC3B,MAAM;AAAA,QACN,WAAWgN,EAAW;AAAA,QACtB,aAAa;AAAA,QACb,SAASH;AAAA,MAAA,CACV;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,mBAAmBvS,GAA2B;AACpD,SAAK,oCAAA;AACL,UAAM6S,IAAW7S,EAAE,YAAY,GACzByS,IAAWzS,EAAE,YAAY;AAC/B,IAAI6S,MAAaJ,KACjB,KAAK,KAAK,MAAM,OAAO,CAAC3nB,MAAM;AAC5B,YAAM,CAAC8nB,CAAK,IAAI9nB,EAAE,SAAS,OAAO+nB,GAAU,CAAC;AAC7C,MAAA/nB,EAAE,SAAS,OAAO2nB,GAAU,GAAGG,CAAK;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEQ,gBAAgB5S,GAA2BtU,GAAmB+S,GAAqB;;AACzF,SAAK,oCAAA;AACL,UAAM3M,IAAOkO,EAAE,MACTyS,IAAWzS,EAAE,YAAY,GACzBwS,IAAc1gB,EAAK,aAAa,mBAAmB,GACnDkgB,IAAYlgB,EAAK,aAAa,iBAAiB,GAC/CygB,IAAczgB,EAAK,aAAa,SAAS;AAE/C,QAAI0gB,MAAgB,YAAYR,GAAW;AACzC,OAAAlmB,IAAAgG,EAAK,kBAAL,QAAAhG,EAAoB,YAAYgG;AAChC,YAAMwgB,IAAO,KAAK,oBAAoBN,CAAS;AAC/C,UAAI,KAAK,kCAAkCM,CAAI,GAAG;AAChD,cAAMI,IAAa,KAAK,8BAA8BJ,CAAI;AAC1D,aAAK,KAAK,MAAM,OAAO,CAACxnB,MAAM;AAC5B,gBAAMgoB,IAAShoB,EAAE,SAAS,UAAU,CAACoL,MAAMA,EAAE,OAAOxK,CAAS,GACvDqnB,IAAWD,KAAU,IAAIA,IAAS,IAAIhoB,EAAE,SAAS;AACvD,UAAAA,EAAE,SAAS,OAAOioB,GAAU,GAAGL,CAAU;AAAA,QAC3C,CAAC;AACD,cAAM7mB,IAAO,KAAK,qBAAqB6mB,CAAU;AACjD,QAAI7mB,KACF,KAAK,KAAK,MAAM,aAAa;AAAA,UAC3B,MAAM;AAAA,UACN,WAAW6mB,EAAW;AAAA,UACtB,aAAa7mB,EAAK;AAAA,UAClB,SAASA,EAAK,MAAM;AAAA,QAAA,CACrB;AAEH;AAAA,MACF;AACA,YAAMsT,IAASmT,EAAK;AACpB,WAAK,KAAK,MAAM,OAAO,CAACxnB,MAAM;;AAC5B,cAAMkW,IAAMlW,EAAE,SAAS,KAAK,CAACoL,MAAMA,EAAE,OAAOxK,CAAS;AACrD,QAAKsV,OACLlV,IAAAkV,EAAI,QAAQvC,CAAW,MAAvB,QAAA3S,EAA0B,OAAO,OAAO2mB,GAAU,GAAG,GAAGtT;AAAA,MAC1D,CAAC;AACD,YAAMtT,IAAOsT,EAAO,CAAC;AACrB,MAAItT,KACF,KAAK,KAAK,MAAM,aAAa;AAAA,QAC3B,MAAM;AAAA,QACN,WAAAH;AAAA,QACA,aAAA+S;AAAA,QACA,SAAS5S,EAAK;AAAA,MAAA,CACf;AAEH;AAAA,IACF;AAEA,IAAI0mB,KACF,KAAK,KAAK,MAAM,OAAO,CAACznB,MAAM;;AAC5B,YAAM4a,IAAM9E,EAAkB9V,GAAGynB,CAAW;AAC5C,UAAI,CAAC7M,EAAK;AACV,YAAMiN,IAAUjN,EAAI,QAAQ,QAAQA,EAAI,WAAW,GAC7C9O,IAAM+b,EAAQ,OAAO,UAAU,CAACvf,MAAMA,EAAE,OAAOmf,CAAW;AAChE,UAAI3b,IAAM,EAAG;AACb,YAAM,CAACgc,CAAK,IAAID,EAAQ,OAAO,OAAO/b,GAAK,CAAC,GACtCoc,IAAYloB,EAAE,SAAS,KAAK,CAACoL,MAAMA,EAAE,OAAOxK,CAAS;AAC3D,OAAAI,IAAAknB,KAAA,gBAAAA,EAAW,QAAQvU,OAAnB,QAAA3S,EAAiC,OAAO,OAAO2mB,GAAU,GAAGG,IAC5D7R,GAAoBjW,GAAG4a,EAAI,QAAQ,EAAE;AAAA,IACvC,CAAC;AAAA,EAEL;AAAA,EAEQ,iBAAiB1F,GAA2BtU,GAAmB+S,GAAqB;AAC1F,SAAK,oCAAA;AACL,UAAMoU,IAAW7S,EAAE,YAAY,GACzByS,IAAWzS,EAAE,YAAY;AAC/B,IAAI6S,MAAaJ,KACjB,KAAK,KAAK,MAAM,OAAO,CAAC3nB,MAAM;AAC5B,YAAMkW,IAAMlW,EAAE,SAAS,KAAK,CAACoL,MAAMA,EAAE,OAAOxK,CAAS,GAC/CyS,IAAM6C,KAAA,gBAAAA,EAAK,QAAQvC;AACzB,UAAI,CAACN,EAAK;AACV,YAAM,CAACyU,CAAK,IAAIzU,EAAI,OAAO,OAAO0U,GAAU,CAAC;AAC7C,MAAA1U,EAAI,OAAO,OAAOsU,GAAU,GAAGG,CAAK;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,eAAexM,GAAY;AACjC,SAAK,KAAK,MAAM,OAAO,CAACtb,MAAM;AAC5B,MAAAA,EAAE,WAAWA,EAAE,SAAS,OAAO,CAACoL,MAAMA,EAAE,OAAOkQ,CAAE;AAAA,IACnD,CAAC,GACD,KAAK,KAAK,MAAM,aAAa,IAAI;AAAA,EACnC;AAAA,EAEQ,kBAAkBA,GAAY;AACpC,SAAK,KAAK,MAAM,OAAO,CAACtb,MAAM;AAC5B,YAAM8L,IAAM9L,EAAE,SAAS,UAAU,CAAC,MAAM,EAAE,OAAOsb,CAAE;AACnD,UAAIxP,IAAM,EAAG;AACb,YAAM3J,IAAQ,gBAAgBnC,EAAE,SAAS8L,CAAG,CAAC;AAC7C,MAAA3J,EAAM,KAAK,GAAGA,EAAM,EAAE,KAAK,KAAK,IAAA,EAAM,SAAS,EAAE,CAAC,IAClDA,EAAM,UAAUA,EAAM,QAAQ,IAAI,CAACiE,OAAO;AAAA,QACxC,GAAGA;AAAA,QACH,IAAI,GAAGA,EAAE,EAAE,KAAK,KAAK,MAAM,SAAS,EAAE,CAAC;AAAA,QACvC,QAAQA,EAAE,OAAO,IAAI,CAACkC,OAAO,EAAE,GAAGA,GAAG,IAAI,GAAGA,EAAE,EAAE,KAAK,KAAK,IAAA,EAAM,SAAS,EAAE,CAAC,KAAK;AAAA,MAAA,EACjF,GACFtI,EAAE,SAAS,OAAO8L,IAAM,GAAG,GAAG3J,CAAK;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEQ,aAAamZ,GAAY;AAC/B,SAAK,KAAK,MAAM,OAAO,CAACtb,MAAM;AAC5B,YAAM4a,IAAM9E,EAAkB9V,GAAGsb,CAAE;AACnC,UAAI,CAACV,EAAK;AACV,YAAMvH,IAAMuH,EAAI,QAAQ,QAAQA,EAAI,WAAW;AAC/C,MAAAvH,EAAI,SAASA,EAAI,OAAO,OAAO,CAAC/K,MAAMA,EAAE,OAAOgT,CAAE,GACjDrF,GAAoBjW,GAAG4a,EAAI,QAAQ,EAAE;AAAA,IACvC,CAAC,GACD,KAAK,KAAK,MAAM,aAAa,IAAI;AAAA,EACnC;AAAA,EAEQ,gBAAgBU,GAAY;AAClC,SAAK,KAAK,MAAM,OAAO,CAACtb,MAAM;AAC5B,YAAM4a,IAAM9E,EAAkB9V,GAAGsb,CAAE;AACnC,UAAI,CAACV,EAAK;AACV,YAAMvH,IAAMuH,EAAI,QAAQ,QAAQA,EAAI,WAAW,GACzC9O,IAAMuH,EAAI,OAAO,UAAU,CAAC/K,MAAMA,EAAE,OAAOgT,CAAE;AACnD,UAAIxP,IAAM,EAAG;AACb,YAAM3J,IAAQ,gBAAgBkR,EAAI,OAAOvH,CAAG,CAAC;AAC7C,MAAA3J,EAAM,KAAK,GAAGA,EAAM,EAAE,KAAK,KAAK,IAAA,EAAM,SAAS,EAAE,CAAC,IAClDkR,EAAI,OAAO,OAAOvH,IAAM,GAAG,GAAG3J,CAAK;AAAA,IACrC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,4CAAqD;AAC3D,WACE,KAAK,qCACL,KAAK,gDAAA;AAAA,EAET;AAAA,EAEQ,kDAA2D;AACjE,QAAI,CAAC,KAAK,eAAgB,QAAO;AACjC,UAAMwiB,IAAY,KAAK,MAAM,cAAc,oBAAoB;AAC/D,QAAI,CAACA,EAAW,QAAO;AACvB,UAAMlhB,IAAM,OAAO,aAAA;AACnB,QAAI,CAACA,KAAOA,EAAI,eAAe,KAAKA,EAAI,YAAa,QAAO;AAC5D,UAAM0kB,IAAgB,CAACrd,MAA4B;AACjD,UAAI,CAACA,EAAG,QAAO;AACf,YAAMpJ,IAAKoJ,EAAE,aAAa,KAAK,YAAYA,EAAE,aAAaA;AAC1D,aAAO,CAAC,CAACpJ,KAAMijB,EAAU,SAASjjB,CAAE;AAAA,IACtC;AACA,WAAOymB,EAAc1kB,EAAI,UAAU,KAAK0kB,EAAc1kB,EAAI,SAAS;AAAA,EACrE;AAAA,EAEQ,iBAAiB;;AACvB,UAAMA,IAAM,KAAK,KAAK,MAAM;AAE5B,IADA,KAAK,MAAM,iBAAiB,cAAc,EAAE,QAAQ,CAAC/B,MAAOA,EAAG,UAAU,OAAO,aAAa,CAAC,GACzF+B,MACDA,EAAI,SAAS,aACfzC,IAAA,KAAK,MACF,cAAc,6BAA6B0jB,GAAUjhB,EAAI,SAAS,CAAC,IAAI,MAD1E,QAAAzC,EAEI,UAAU,IAAI,kBAElBE,IAAA,KAAK,MACF,cAAc,sBAAsBwjB,GAAUjhB,EAAI,OAAO,CAAC,IAAI,MADjE,QAAAvC,EAEI,UAAU,IAAI;AAAA,EAEtB;AAAA,EAEQ,oBAAoB;AAC1B,eAAWkK,KAAK,KAAK,aAAc,CAAAA,EAAE,QAAA;AACrC,SAAK,eAAe,CAAA;AAAA,EACtB;AACF;AAIA,SAASwa,GAAgBwC,GAAwBC,GAA4B;AAG3E,SAAO,4CADLA,KAAa,QAAQA,IAAY,IAAI,OAAO,KAAK,IAAIA,GAAW,GAAG,CAAC,QAAQ,EACxB;AACxD;AAEA,SAAStC,GAAgBzR,GAAuB1N,GAAuB;AACrE,QAAM2N,IAAQD,EAAO,MAAM,GAAG,EAAE,IAAI,MAAM,GACpCE,IAAQD,EAAM,OAAO,CAAC,GAAGE,MAAM,IAAIA,GAAG,CAAC,GACvC6T,IAAQ/T,EAAM3N,CAAK,KAAK;AAC9B,SAAO,GAAG0hB,CAAK,2BAA4BA,IAAQ9T,IAAS,KAAK,QAAQ,CAAC,CAAC;AAC7E;AAEA,SAASwR,GAASjS,GAAyC;AACzD,SAAOA,MAAO,QAAQ,eAAeA,MAAO,WAAW,aAAa;AACtE;AAEA,SAAS2Q,GAAUtZ,GAAmB;AACpC,SAAI,OAAO,MAAQ,OAAe,IAAI,SAAe,IAAI,OAAOA,CAAC,IAC1DA,EAAE,QAAQ,WAAW,MAAM;AACpC;AAEA,SAASmd,GAAI7Y,GAA2B;AACtC,QAAMhO,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,YAAYgO,GACRhO;AACT;AACA,SAAS8jB,KAAW;AAClB,SAAO+C;AAAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS9C,KAAW;AAClB,SAAO8C;AAAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS7C,KAAY;AACnB,SAAO6C;AAAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAShC,KAAW;AAClB,SAAOgC;AAAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS/B,KAAW;AAClB,SAAO+B;AAAAA,IACL;AAAA,EAAA;AAEJ;ACroCO,MAAMC,GAAY;AAAA,EAMvB,YAAY5T,GAA0B;AAL9B,IAAAhV,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,YAAwB;AACxB,IAAAA,EAAA,iBAAkB;AAGxB,SAAK,OAAOgV,GACZ,KAAK,QAAQ,IAAIiF,GAAM;AAAA,MACrB,OAAOjF,EAAK,EAAE,cAAc;AAAA,MAC5B,WAAW;AAAA,MACX,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS,MAAM,KAAK,WAAA;AAAA,MACpB,GAAGA,EAAK;AAAA,IAAA,CACT;AAED,UAAM6T,IAAa7a,EAAE,OAAO,EAAE,OAAO,qBAAqB;AAC1D,SAAK,MAAM,KAAK,OAAO6a,CAAU;AAEjC,UAAMC,IAAU9a;AAAA,MACd;AAAA,MACA,EAAE,OAAO,UAAU,MAAM,UAAU,SAAS,MAAM,KAAK,QAAM;AAAA,MAC7D,CAAC,KAAK,KAAK,EAAE,iBAAiB,CAAC;AAAA,IAAA,GAE3B6M,IAAc7M;AAAA,MAClB;AAAA,MACA,EAAE,OAAO,UAAU,MAAM,UAAU,SAAS,MAAM,KAAK,YAAU;AAAA,MACjE,CAAC,KAAK,KAAK,EAAE,iBAAiB,CAAC;AAAA,IAAA,GAE3B+a,IAAc/a;AAAA,MAClB;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MAAM,KAAK,UAAA;AAAA,MAAU;AAAA,MAEhC,CAAC,KAAK,KAAK,EAAE,qBAAqB,CAAC;AAAA,IAAA;AAErC,SAAK,MAAM,OAAO,OAAO8a,GAASjO,GAAakO,CAAW,GAG1D,KAAK,KAAK,IAAI5N,GAAW;AAAA,MACvB,QAAQ0N;AAAA,MACR,OAAOzN,GAAY,OAAO;AAAA,QACxB,KAAK;AAAA,QACL,YAAY,CAACC,IAAYC,GAAA,GAAUF,GAAY,SAAS,GAAG,EAAI,CAAC;AAAA,MAAA,CACjE;AAAA,IAAA,CACF;AAAA,EACH;AAAA,EAEA,KAAK/Y,GAAsB;AACzB,SAAK,SAAA,GACL,KAAK,MAAM,KAAKA,CAAM;AAAA,EACxB;AAAA,EAEQ,WAAW;AACjB,UAAM2mB,IAASjU,GAAU,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,UAAU;AAAA,MAChE,qBAAqB,KAAK,KAAK,uBAAuB;AAAA,IAAA,CACvD;AACD,SAAK,UAAUiU,EAAO,MACtB,KAAK,SAASA,EAAO,IAAI;AAAA,EAC3B;AAAA,EAEQ,SAAShlB,GAAc;AAC7B,IAAK,KAAK,MACV,KAAK,GAAG,SAAS;AAAA,MACf,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,QAAQ,QAAQA,EAAA;AAAA,IAAK,CAChE;AAAA,EACH;AAAA,EAEA,MAAc,QAAQ;AACpB,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,KAAK,OAAO,GAChD,KAAK,OAAO,KAAK,KAAK,EAAE,yBAAyB,CAAC;AAAA,IACpD,QAAQ;AACN,YAAMilB,IAAK,SAAS,cAAc,UAAU;AAC5C,MAAAA,EAAG,QAAQ,KAAK,SAChB,SAAS,KAAK,YAAYA,CAAE,GAC5BA,EAAG,OAAA,GACHpN,EAAoB,MAAM,GAC1B,SAAS,KAAK,YAAYoN,CAAE,GAC5B,KAAK,OAAO,KAAK,KAAK,EAAE,cAAc,CAAC;AAAA,IACzC;AAAA,EACF;AAAA,EAEQ,YAAY;AAClB,SAAK,UAAUhQ,GAAW,KAAK,OAAO,GACtC,KAAK,SAAS,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEQ,YAAY;AAClB,UAAMiQ,IAAO,IAAI,KAAK,CAAC,KAAK,OAAO,GAAG,EAAE,MAAM,2BAA2B,GACnE9I,IAAM,IAAI,gBAAgB8I,CAAI,GAC9BzgB,IAAI,SAAS,cAAc,GAAG;AACpC,IAAAA,EAAE,OAAO2X,GACT3X,EAAE,WAAW,SAAS,KAAK,IAAA,CAAK,SAChCA,EAAE,MAAA,GACF,WAAW,MAAM,IAAI,gBAAgB2X,CAAG,GAAG,GAAI;AAAA,EACjD;AAAA,EAEQ,OAAOpc,GAAc;AAC3B,UAAM2L,IAAI3B,EAAE,OAAO,EAAE,OAAO,WAAA,GAAc,CAAChK,CAAI,CAAC;AAChD,SAAK,MAAM,KAAK,OAAO2L,CAAC,GACxB,sBAAsB,MAAMA,EAAE,UAAU,IAAI,YAAY,CAAC,GACzD,WAAW,MAAM;AACf,MAAAA,EAAE,UAAU,OAAO,YAAY,GAC/B,WAAW,MAAMA,EAAE,OAAA,GAAU,GAAG;AAAA,IAClC,GAAG,IAAI;AAAA,EACT;AAAA,EAEQ,aAAa;;AACnB,KAAAvO,IAAA,KAAK,OAAL,QAAAA,EAAS,WACT,KAAK,KAAK;AAAA,EACZ;AACF;ACpHA,MAAM+nB,KAA6B;AAAA,EACjC,EAAE,QAAQ,KAAK,SAAS,uBAAuB,MAAMC,GAAU,CAAC,CAAC,CAAC,EAAA;AAAA;AAAA,EAElE;AAAA,IACE,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAMA,GAAU,CAAC,GAAG,CAAC,CAAC;AAAA,IACtB,UAAU;AAAA,EAAA;AAEd;AAWO,MAAMC,GAAU;AAAA,EAIrB,YAAYrU,GAAwB;AAHpC,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AAGN,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,SAAS,EAAE,OAAO,2BAA2B,GACzD,KAAK,QAAA;AAAA,EACP;AAAA,EAEA,UAAU;AACR,SAAK,QAAA;AAAA,EACP;AAAA,EAEQ,UAAU;AAChB,IAAAG,EAAM,KAAK,EAAE;AACb,UAAMmb,IAAgB,IAAI,IAAI,KAAK,KAAK,2BAA2B,EAAE,GAC/DC,IAAgB,CAACC,MACrBA,EAAK,OAAO,CAACppB,MAAM,CAACkpB,EAAc,IAAIlpB,EAAE,IAAI,CAAC,GACzCqpB,IAAgB;AAAA,MACpB,GAAGF,EAAc,KAAK,KAAK,SAAS,WAAW,SAAS,CAAC;AAAA,MACzD,GAAGA,EAAc,KAAK,KAAK,SAAS,WAAW,QAAQ,CAAC;AAAA,IAAA,GAGpD7D,IAAO1X,EAAE,OAAO,EAAE,OAAO,aAAa;AAE5C,IAAA0X,EAAK,OAAO,KAAK,oBAAoB,GACjC+D,EAAc,UAChB/D,EAAK;AAAA,MACH,KAAK;AAAA,QACH,KAAK,KAAK,mBAAmB,KAAK,KAAK,EAAE,sBAAsB;AAAA,QAC/D+D;AAAA,MAAA;AAAA,IACF,GAIJ,KAAK,GAAG,OAAO/D,CAAI;AAAA,EACrB;AAAA,EAEQ,qBAAkC;AACxC,UAAMgE,IAAO1b,EAAE,OAAO,EAAE,OAAO,mBAAmB;AAClD,eAAWxH,KAAK2iB,IAAc;AAC5B,YAAM3L,IAAO,KAAK,KAAK,EAAEhX,EAAE,OAAO;AAClC,MAAAkjB,EAAK;AAAA,QACH1b;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,qBAAqB;AAAA,YACrB,eAAexH,EAAE;AAAA,YACjB,OAAOA,EAAE,WAAW,KAAK,KAAK,EAAEA,EAAE,QAAQ,IAAIgX;AAAA,UAAA;AAAA,UAEhD;AAAA,YACExP,EAAE,QAAQ,EAAE,OAAO,uBAAuB,MAAMxH,EAAE,MAAM;AAAA,YACxDwH,EAAE,QAAQ,EAAE,OAAO,yBAAyB,CAACwP,CAAI,CAAC;AAAA,UAAA;AAAA,QACpD;AAAA,MACF;AAAA,IAEJ;AACA,WAAA6H,GAAS,OAAOqE,GAAM;AAAA,MACpB,OAAO,EAAE,MAAM,YAAY,MAAM,SAAS,KAAK,GAAA;AAAA,MAC/C,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,IAAA,CACZ,GACM1b,EAAE,WAAW,EAAE,OAAO,sBAAsB;AAAA,MACjDA,EAAE,OAAO,EAAE,OAAO,kBAAA,GAAqB,CAAC,KAAK,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAAA,MACxE0b;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEQ,gBAAgBzpB,GAA8B;;AACpD,SAAImB,IAAAnB,EAAI,mBAAJ,QAAAmB,EAAoB,OAAQ,QAAOnB,EAAI,eAAe,KAAA;AAC1D,QAAIA,EAAI,aAAa,UAAU;AAC7B,YAAM0pB,IACJ,KAAK,KAAK,8BAA8B,KAAK,KAAK,EAAE,+BAA+B;AACrF,aAAO,GAAG1pB,EAAI,IAAI,MAAM0pB,CAAM;AAAA,IAChC;AACA,WAAO1pB,EAAI;AAAA,EACb;AAAA,EAEQ,kBAAkBia,GAAesP,GAAsC;AAC7E,UAAME,IAAO1b,EAAE,OAAO,EAAE,OAAO,mBAAmB;AAClD,eAAW/N,KAAOupB,GAAM;AACtB,YAAMI,IAAW3pB,EAAI,aAAa,UAC5BiO,IAA0B,CAAA;AAChC,MAAI0b,KACF1b,EAAS,KAAKF,EAAE,QAAQ,EAAE,OAAO,sBAAsB,eAAe,OAAA,CAAQ,CAAC,GAEjFE,EAAS;AAAA,QACPF,EAAE,QAAQ,EAAE,OAAO,uBAAuB,MAAM/N,EAAI,MAAM;AAAA,QAC1D+N,EAAE,QAAQ,EAAE,OAAO,yBAAyB,CAAC/N,EAAI,IAAI,CAAC;AAAA,MAAA,GAExDypB,EAAK;AAAA,QACH1b;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,qBAAqB;AAAA,YACrB,mBAAmB/N,EAAI;AAAA,YACvB,OAAO,KAAK,gBAAgBA,CAAG;AAAA,UAAA;AAAA,UAEjCiO;AAAA,QAAA;AAAA,MACF;AAAA,IAEJ;AACA,WAAAmX,GAAS,OAAOqE,GAAM;AAAA,MACpB,OAAO,EAAE,MAAM,UAAU,MAAM,SAAS,KAAK,GAAA;AAAA,MAC7C,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,IAAA,CACZ,GACM1b,EAAE,WAAW,EAAE,OAAO,sBAAsB;AAAA,MACjDA,EAAE,OAAO,EAAE,OAAO,qBAAqB,CAACkM,CAAK,CAAC;AAAA,MAC9CwP;AAAA,IAAA,CACD;AAAA,EACH;AACF;AAEA,SAASN,GAAUzU,GAAyB;AAC1C,QAAMC,IAAQD,EAAM,OAAO,CAACnJ,GAAGqJ,MAAMrJ,IAAIqJ,GAAG,CAAC,GACvCxC,IAAI,IACJM,IAAM,GACNkX,IAASxX,IAAIM,KAAOgC,EAAM,SAAS;AACzC,MAAIE,IAAI;AAWR,SAAO,mDAVOF,EACX,IAAI,CAACzN,MAAM;AACV,UAAM4iB,IAAM5iB,IAAI0N,IAASiV,GACnB7L,IAAO,YAAYnJ,CAAC,kBAAkBiV,EAAG;AAAA,MAC7C;AAAA,IAAA,CACD;AACD,WAAAjV,KAAKiV,IAAKnX,GACHqL;AAAA,EACT,CAAC,EACA,KAAK,EAAE,CACqD;AACjE;AC1KA,MAAM+L,KAA6C;AAAA,EACjD,IAAI,EAAE,OAAO,KAAK,OAAO,KAAA;AAAA,EACzB,KAAK,EAAE,OAAO,KAAK,OAAO,MAAA;AAAA,EAC1B,OAAO,EAAE,OAAO,KAAK,OAAO,QAAA;AAC9B,GAaaC,KAAN,MAAMA,GAAa;AAAA,EAWxB,YAAYhV,GAA2B;AAV/B,IAAAhV,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,gBAAwB;AACxB,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,oBAAuD,CAAA;AACvD,IAAAA,EAAA;AACA,IAAAA,EAAA,mBAA2B;AAC3B,IAAAA,EAAA;AAGN,SAAK,OAAOgV,GACZ,KAAK,QAAQ,IAAIiF,GAAM;AAAA,MACrB,OAAOjF,EAAK,EAAE,eAAe;AAAA,MAC7B,WAAW;AAAA,MACX,OAAO;AAAA;AAAA,MAEP,SAAS,MAAM,KAAK,qBAAA;AAAA,MACpB,GAAGA,EAAK;AAAA,IAAA,CACT,GAED,KAAK,SAAShH,EAAE,UAAU;AAAA,MACxB,OAAO;AAAA,MACP,SAAS;AAAA,MACT,OAAO;AAAA,IAAA,CACR,GACD,KAAK,OAAO,iBAAiB,QAAQ,MAAM;AACzC,WAAK,0BAAA,GACL,KAAK,0BAAA;AAAA,IACP,CAAC,GAED,KAAK,WAAWA,EAAE,OAAO,EAAE,OAAO,0BAA0B,CAAC,KAAK,MAAM,CAAC,GACzE,KAAK,MAAM,KAAK,UAAU,IAAI,wBAAwB,GACtD,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ;AAGpC,UAAMic,IAAWjc,EAAE,OAAO,EAAE,OAAO,gBAAgB;AAClD,KAAC,MAAM,OAAO,OAAO,EAAsB,QAAQ,CAAC5N,MAAM;AACzD,YAAM6e,IAAMjR;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAO,sBAAsB5N,MAAM,KAAK,SAAS,+BAA+B,EAAE;AAAA,UAClF,MAAM;AAAA,UACN,SAAS,MAAM,KAAK,UAAUA,CAAC;AAAA,QAAA;AAAA,QAEjC,CAAC8pB,GAAc9pB,CAAC,GAAG2pB,GAAQ3pB,CAAC,EAAE,KAAK;AAAA,MAAA;AAErC,WAAK,WAAWA,CAAC,IAAI6e,GACrBgL,EAAS,OAAOhL,CAAG;AAAA,IACrB,CAAC,GACD,KAAK,MAAM,iBAAiBgL,CAAQ;AAAA,EACtC;AAAA,EAEA,KAAK5nB,GAAsB;AACzB,SAAK,QAAA,GACL,KAAK,UAAU,KAAK,MAAM,GAC1B,KAAK,MAAM,KAAKA,CAAM,GACtB,KAAK,cAAc,MAAM,KAAK,0BAAA,GAC9B,OAAO,iBAAiB,UAAU,KAAK,WAAW;AAAA,EACpD;AAAA,EAEA,UAAUjC,GAAkB;AAC1B,SAAK,SAASA;AACd,UAAM+pB,IAAOJ,GAAQ3pB,CAAC;AACtB,SAAK,SAAS,MAAM,YAAY,kBAAkB,GAAG+pB,EAAK,KAAK,IAAI;AACnE,eAAW/d,KAAK,OAAO,KAAK,KAAK,UAAU;AACzC,WAAK,WAAWA,CAAC,EAAE,UAAU,OAAO,8BAA8BA,MAAMhM,CAAC;AAE3E;AAAA,MAAsB,MACpB,sBAAsB,MAAM,KAAK,2BAA2B;AAAA,IAAA;AAAA,EAEhE;AAAA,EAEQ,UAAU;AAChB,UAAM4oB,IAASjU,GAAU,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,UAAU;AAAA,MAChE,qBAAqB;AAAA,IAAA,CACtB;AAED,SAAK,OAAO,SAASiU,EAAO;AAAA,EAC9B;AAAA,EAKQ,4BAA4B;AAClC,IAAI,KAAK,aAAa,QAAM,qBAAqB,KAAK,SAAS,GAC/D,KAAK,YAAY,sBAAsB,MAAM;AAC3C,WAAK,YAAY,MACjB,KAAK,kBAAA;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EAEQ,oBAAoB;AAC1B,QAAK,KAAK,OAAO;AACjB,UAAI;AACF,cAAM9nB,IAAM,KAAK,OAAO,iBAClBgB,IAAOhB,KAAA,gBAAAA,EAAK,iBACZG,IAAOH,KAAA,gBAAAA,EAAK;AAClB,YAAI,CAACgB,KAAQ,CAACb,EAAM;AACpB,cAAMkK,IAAM,KAAK,IAAIrJ,EAAK,cAAcb,EAAK,YAAY,GACnD+oB,IAAQ,KAAK;AAAA,UACjB;AAAA,UACA,OAAO,cAAcJ,GAAa;AAAA,QAAA,GAG9BlnB,IAAO,KAAK,IAAI,KAAK,IAAI,KAAK,KAAKyI,CAAG,GAD9B,GACsC,GAAG6e,CAAK;AAC5D,aAAK,SAAS,MAAM,SAAS,GAAGtnB,CAAI;AAAA,MACtC,QAAQ;AAAA,MAER;AAAA,EACF;AAAA,EAEQ,4BAA4B;;AAClC,KAAA1B,IAAA,KAAK,aAAL,QAAAA,EAAe;AACf,QAAI;AACF,YAAMF,IAAM,KAAK,OAAO,iBAClBG,IAAOH,KAAA,gBAAAA,EAAK;AAClB,UAAI,CAACG,KAAQ,OAAO,iBAAmB,IAAa;AACpD,WAAK,WAAW,IAAI,eAAe,MAAM,KAAK,2BAA2B,GACzE,KAAK,SAAS,QAAQA,CAAI;AAC1B,YAAMG,IAAON,EAAI;AACjB,MAAIM,KAAM,KAAK,SAAS,QAAQA,CAAI;AAAA,IACtC,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,uBAAuB;;AAC7B,IAAI,KAAK,gBACP,OAAO,oBAAoB,UAAU,KAAK,WAAW,GACrD,KAAK,cAAc,UAErBJ,IAAA,KAAK,aAAL,QAAAA,EAAe,cACf,KAAK,WAAW,QACZ,KAAK,aAAa,SACpB,qBAAqB,KAAK,SAAS,GACnC,KAAK,YAAY;AAAA,EAErB;AACF;AAAA;AAzDEpB,EAnFWgqB,IAmFa,uBAAsB;AAnFzC,IAAMK,KAANL;AA8IP,SAASE,GAAc9pB,GAA8B;AACnD,QAAM0B,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GAClC1B,MAAM,OACR0B,EAAG,YACD,gMACK1B,MAAM,QACb0B,EAAG,YACD,gKAEFA,EAAG,YACD,gKACGA;AACT;AC9JA,MAAMwoB,KAAgB;AAAA,EACpB,EAAE,UAAU,uBAAuB,OAAO,WAAW,OAAO,GAAA;AAAA,EAC5D,EAAE,OAAO,SAAS,OAAO,uDAAA;AAAA,EACzB,EAAE,UAAU,wBAAwB,OAAO,eAAe,OAAO,qDAAA;AAAA,EACjE,EAAE,UAAU,8BAA8B,OAAO,mBAAmB,OAAO,4CAAA;AAAA,EAC3E,EAAE,UAAU,sBAAsB,OAAO,UAAU,OAAO,6BAAA;AAAA,EAC1D,EAAE,OAAO,aAAa,OAAO,sCAAA;AAAA,EAC7B,EAAE,OAAO,SAAS,OAAO,oBAAA;AAAA,EACzB,EAAE,OAAO,WAAW,OAAO,iBAAA;AAAA,EAC3B,EAAE,OAAO,WAAW,OAAO,2BAAA;AAC7B,GAEMC,KAAa,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AAE3F,MAAMC,GAAgB;AAAA,EAqB3B,YAAYxV,GAA8B;AApB1C,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA,gBAA8B;AAC9B,IAAAA,EAAA,cAA0C,CAAA;AAC1C,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA,sBAA8B;AAC9B,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,6BAAsB;AACtB,IAAAA,EAAA,8BAAuB;AACvB,IAAAA,EAAA,uBAAgB;AACP,IAAAA,EAAA,yBAAkB,MAAM,KAAK,oBAAA;AAG5C,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,OAAO,EAAE,OAAO,uBAAuB,MAAM,WAAW,GACpE,KAAK,OAAA,GACL,KAAK,KAAA,GACLgH,EAAK,aAAa,OAAO,KAAK,EAAE,GAGhC,KAAK,GAAG;AAAA,MACN;AAAA,MACA,MAAM;;AACJ,SAAA5T,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,MACf;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,OAAOqpB,GAAsB;AAC3B,SAAK,SAASA;AAAA,EAChB;AAAA,EAEA,SAAS;AACP,SAAK,SAAS,MACd,KAAK,KAAA;AAAA,EACP;AAAA,EAEA,OAAO;AACL,SAAK,GAAG,UAAU,IAAI,YAAY,GAClC,KAAK,qBAAA;AAAA,EACP;AAAA,EAEA,OAAO;AACL,SAAK,GAAG,UAAU,OAAO,YAAY,GACrC,KAAK,UAAU,UAAU,OAAO,YAAY,GAC5C,KAAK,uBAAA,GACD,KAAK,kBACP,qBAAqB,KAAK,aAAa,GACvC,KAAK,gBAAgB;AAAA,EAEzB;AAAA;AAAA,EAGA,OAAOvH,GAA8B;AACnC,QAAI,CAACA,KAAS,CAAC,KAAK,QAAQ;AAC1B,WAAK,KAAA;AACL;AAAA,IACF;AACA,SAAK,KAAA;AAEL,UAAMwH,IAAIxH,EAAM;AAChB,SAAK,WAAW,QAAQwH,EAAE,IAAI,GAC9B,KAAK,WAAW,UAAUA,EAAE,MAAM,GAClC,KAAK,WAAW,aAAaA,EAAE,SAAS,GACxC,KAAK,WAAW,iBAAiBA,EAAE,aAAa,GAChD,KAAK,WAAW,MAAMA,EAAE,aAAa,GACrC,KAAK,WAAW,MAAMA,EAAE,WAAW,GACnC,KAAK,WAAW,aAAaA,EAAE,UAAU,MAAM,GAC/C,KAAK,WAAW,eAAeA,EAAE,UAAU,QAAQ,GACnD,KAAK,WAAW,cAAcA,EAAE,UAAU,OAAO;AAEjD,UAAMC,IAAU,CAAC,CAACD,EAAE;AAIpB,QAHA,KAAK,eAAeA,EAAE,MACtB,KAAK,KAAK,OAAO,MAAM,UAAUC,IAAU,KAAK,QAE5CD,EAAE,WAAW;AACf,YAAM5N,IAAM8N,GAAgBF,EAAE,SAAS;AACvC,MAAI5N,MAAK,KAAK,WAAW,QAAQA;AAAA,IACnC;AACA,SAAK,aAAa,QAAQ4N,EAAE,YACvBE,GAAgBF,EAAE,SAAS,KAAK,YACjC,WACAA,EAAE,aAAU,KAAK,iBAAiB,QAAQG,GAAYH,EAAE,QAAQ,IACpE,KAAK,eAAe,QAAQI,GAAcJ,EAAE,QAAQ,GACpD,KAAK,iBAAiB,QAAQK,GAAgBL,EAAE,UAAU,GAC1D,KAAK,kBAAkBA,EAAE,QAAQA,EAAE,YAAY,GAE/C,KAAK,oBAAA;AAAA,EACP;AAAA,EAEA,UAAU;AACR,SAAK,uBAAA,GACD,KAAK,iBAAe,qBAAqB,KAAK,aAAa,GAC/D,KAAK,GAAG,OAAA;AAAA,EACV;AAAA;AAAA,EAIQ,SAAS;AACf,UAAMM,IAAM,MAAMhd,EAAE,OAAO,EAAE,OAAO,4BAA4B,GAC1D2B,IAAI,KAAK,KAAK,GAGdsb,IAAO,CAAC3H,GAAanX,MAAiB,MAAA;;AAAM,cAAA/K,IAAA,KAAK,WAAL,gBAAAA,EAAa,KAAKkiB,GAAKnX;AAAA;AAEzE,SAAK,KAAK,OAAO,KAAK,KAAK,KAAKwD,EAAE,cAAc,GAAGsb,EAAK,MAAM,GAAG,EAAE,YAAY,OAAO,GACtF,KAAK,KAAK,SAAS,KAAK,KAAK,KAAKtb,EAAE,gBAAgB,GAAGsb,EAAK,QAAQ,GAAG,EAAE,WAAW,UAAU,GAC9F,KAAK,KAAK,YAAY,KAAK,KAAK,KAAKtb,EAAE,mBAAmB,GAAGsb,EAAK,WAAW,GAAG;AAAA,MAC9E,gBAAgB;AAAA,IAAA,CACjB,GACD,KAAK,KAAK,gBAAgB,KAAK,KAAK,KAAKtb,EAAE,uBAAuB,GAAGsb,EAAK,eAAe,GAAG;AAAA,MAC1F,gBAAgB;AAAA,IAAA,CACjB,GAED,KAAK,KAAK,YAAY,KAAK;AAAA,MACzBC;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,mBAAmB;AAAA,MACrBsb,EAAK,aAAa;AAAA,IAAA,GAEpB,KAAK,KAAK,cAAc,KAAK;AAAA,MAC3BC;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,qBAAqB;AAAA,MACvBsb,EAAK,eAAe;AAAA,IAAA,GAEtB,KAAK,KAAK,aAAa,KAAK;AAAA,MAC1BC;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,oBAAoB;AAAA,MACtBsb,EAAK,cAAc;AAAA,IAAA,GAGrB,KAAK,KAAK,KAAK,KAAK;AAAA,MAClBC;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,uBAAuB;AAAA,MACzBsb,EAAK,qBAAqB;AAAA,IAAA,GAE5B,KAAK,KAAK,KAAK,KAAK;AAAA,MAClBC;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,qBAAqB;AAAA,MACvBsb,EAAK,mBAAmB;AAAA,IAAA,GAG1B,KAAK,mBAAmBjd,EAAE,UAAU;AAAA,MAClC,OAAO;AAAA,MACP,OAAO2B,EAAE,oBAAoB;AAAA,MAC7B,UAAU,CAAC2F,MAAa;;AACtB,YAAI,KAAK,oBAAqB;AAC9B,cAAM/J,IAAO+J,EAAE,OAA6B;AAC5C,QAAI/J,MAAQ,MAAInK,IAAA,KAAK,WAAL,QAAAA,EAAa,cAAc,SACtCE,IAAA,KAAK,WAAL,QAAAA,EAAa,cAAc,OAAOiK,CAAG;AAAA,MAC5C;AAAA,IAAA,CACD;AACD;AACE,YAAM4f,IAAc,SAAS,cAAc,QAAQ;AACnD,MAAAA,EAAY,QAAQ,IACpBA,EAAY,cAAcxb,EAAE,gBAAgB,GAC5C,KAAK,iBAAiB,OAAOwb,CAAW;AACxC,iBAAWlgB,KAAMF,IAAwB;AACvC,cAAMqgB,IAAM,SAAS,cAAc,QAAQ;AAC3C,QAAAA,EAAI,QAAQ,OAAOngB,CAAE,GACrBmgB,EAAI,cAAc,OAAOngB,CAAE,GAC3B,KAAK,iBAAiB,OAAOmgB,CAAG;AAAA,MAClC;AAAA,IACF;AACA,SAAK,kBAAkB,KAAK,OAAO,CAAC,KAAK,gBAAgB,CAAC,GAC1D,KAAK,gBAAgB,MAAM,UAAU,QAGrC,KAAK,mBAAmBpd,EAAE,UAAU;AAAA,MAClC,OAAO;AAAA,MACP,OAAO2B,EAAE,oBAAoB;AAAA,MAC7B,UAAU,CAAC2F,MAAa;;AACtB,cAAMjJ,IAAKiJ,EAAE,OAA6B;AAC1C,QAAIjJ,KAAGjL,IAAA,KAAK,WAAL,QAAAA,EAAa,KAAK,YAAYiL,MAChC/K,IAAA,KAAK,WAAL,QAAAA,EAAa,KAAK;AAAA,MACzB;AAAA,IAAA,CACD;AACD,eAAWopB,KAAKJ,IAAe;AAC7B,YAAMc,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,QAAQV,EAAE,OACdU,EAAI,cAAcV,EAAE,WAAW/a,EAAE+a,EAAE,QAAQ,IAAIA,EAAE,OACjD,KAAK,iBAAiB,OAAOU,CAAG;AAAA,IAClC;AAGA,SAAK,iBAAiBpd,EAAE,UAAU;AAAA,MAChC,OAAO;AAAA,MACP,OAAO2B,EAAE,kBAAkB;AAAA,MAC3B,UAAU,CAAC2F,MAAa;;AACtB,cAAMjJ,IAAKiJ,EAAE,OAA6B;AAC1C,QAAIjJ,OAAGjL,IAAA,KAAK,WAAL,QAAAA,EAAa,cAAciL;AAAA,MACpC;AAAA,IAAA,CACD;AACD;AACE,YAAM8e,IAAc,SAAS,cAAc,QAAQ;AACnD,MAAAA,EAAY,QAAQ,IACpBA,EAAY,cAAcxb,EAAE,kBAAkB,GAC9C,KAAK,eAAe,OAAOwb,CAAW;AAAA,IACxC;AACA,eAAWlgB,KAAMsf,IAAY;AAC3B,YAAMa,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,QAAQngB,GACZmgB,EAAI,cAAcngB,GAClB,KAAK,eAAe,OAAOmgB,CAAG;AAAA,IAChC;AAGA,SAAK,mBAAmBpd,EAAE,UAAU;AAAA,MAClC,OAAO;AAAA,MACP,OAAO2B,EAAE,oBAAoB;AAAA,MAC7B,UAAU,CAAC2F,MAAa;;AACtB,cAAMjJ,IAAKiJ,EAAE,OAA6B;AAC1C,QAAIjJ,OAAGjL,IAAA,KAAK,WAAL,QAAAA,EAAa,gBAAgBiL;AAAA,MACtC;AAAA,IAAA,CACD;AACD;AACE,YAAM8e,IAAc,SAAS,cAAc,QAAQ;AACnD,MAAAA,EAAY,QAAQ,IACpBA,EAAY,cAAcxb,EAAE,oBAAoB,GAChD,KAAK,iBAAiB,OAAOwb,CAAW;AAAA,IAC1C;AACA,eAAW9Y,KAAK9D,IAA0B;AACxC,YAAM6c,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,QAAQ/Y,EAAE,OACd+Y,EAAI,cAAc/Y,EAAE,OACpB,KAAK,iBAAiB,OAAO+Y,CAAG;AAAA,IAClC;AAGA,SAAK,aAAapd,EAAE,SAAS;AAAA,MAC3B,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO2B,EAAE,mBAAmB;AAAA,MAC5B,OAAO;AAAA,IAAA,CACR,GACD0P,GAAqB,KAAK,YAAY;AAAA,MACpC,WAAW,KAAK,KAAK;AAAA,MACrB,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,GAAA1P;AAAA,MACA,cAAc,MAAA;;AAAM,gBAAAvO,IAAA,KAAK,WAAL,gBAAAA,EAAa;AAAA;AAAA,MACjC,UAAU,CAAC0b;;AAAQ,gBAAA1b,IAAA,KAAK,WAAL,gBAAAA,EAAa,KAAK,aAAa0b;AAAA;AAAA,MAClD,UAAU,MAAA;;AAAM,gBAAA1b,IAAA,KAAK,WAAL,gBAAAA,EAAa;AAAA;AAAA,IAAQ,CACtC,GAGD,KAAK,eAAe4M,EAAE,SAAS;AAAA,MAC7B,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO2B,EAAE,wBAAwB;AAAA,MACjC,OAAO;AAAA,IAAA,CACR,GACD0P,GAAqB,KAAK,cAAc;AAAA,MACtC,WAAW,KAAK,KAAK;AAAA,MACrB,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,GAAA1P;AAAA,MACA,cAAc,MAAA;;AAAM,gBAAAvO,IAAA,KAAK,WAAL,gBAAAA,EAAa;AAAA;AAAA,MACjC,UAAU,CAAC0b;;AAAQ,gBAAA1b,IAAA,KAAK,WAAL,gBAAAA,EAAa,KAAK,eAAe0b;AAAA;AAAA,MACpD,UAAU,MAAA;;AAAM,gBAAA1b,IAAA,KAAK,WAAL,gBAAAA,EAAa;AAAA;AAAA,IAAQ,CACtC,GAGD,KAAK,KAAK,OAAO,KAAK;AAAA,MACpB8pB;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,oBAAoB;AAAA,MACtB,MAAM,KAAK,iBAAA;AAAA,IAAiB,GAI9B,KAAK,KAAK,SAAS,KAAK;AAAA,MACtBub;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,gBAAgB;AAAA,MAClBsb,EAAK,QAAQ;AAAA,IAAA,GAIf,KAAK,KAAK,QAAQ,KAAK;AAAA,MACrBC;AAAA,QACE;AAAA,MAAA;AAAA,MAEFvb,EAAE,qBAAqB;AAAA,MACvBsb,EAAK,cAAc;AAAA,IAAA,GAGrB,KAAK,YAAYjd,EAAE,OAAO,EAAE,OAAO,mCAAmC,GACtE,KAAK,YAAYA,EAAE,SAAS;AAAA,MAC1B,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,WAAY,CAACsH,MAAa;;AACxB,cAAM4J,IAAK5J;AACX,QAAI4J,EAAG,QAAQ,WACbA,EAAG,eAAA,GACH,KAAK,WAAA,KACIA,EAAG,QAAQ,aACpBA,EAAG,eAAA,GACH,KAAK,UAAU,UAAU,OAAO,YAAY,IAC5C9d,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,MAEjB;AAAA,IAAA,CACD;AACD,UAAMiqB,IAAerd;AAAA,MACnB;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,aAAa,CAACsH,MAAaA,EAAE,eAAA;AAAA,QAC7B,SAAS,MAAM,KAAK,WAAA;AAAA,MAAW;AAAA,MAEjC,CAAC3F,EAAE,eAAe,CAAC;AAAA,IAAA;AAErB,SAAK,UAAU,OAAO,KAAK,WAAW0b,CAAY,GAElD,KAAK,GAAG;AAAA,MACN,KAAK,OAAO,CAAC,KAAK,KAAK,MAAM,KAAK,KAAK,QAAQ,KAAK,KAAK,WAAW,KAAK,KAAK,aAAa,CAAC;AAAA,MAC5FL,EAAA;AAAA,MACA,KAAK,OAAO,CAAC,KAAK,kBAAkB,KAAK,gBAAgB,KAAK,gBAAgB,CAAC;AAAA,MAC/EA,EAAA;AAAA,MACA,KAAK,OAAO,CAAC,KAAK,YAAY,KAAK,YAAY,CAAC;AAAA,MAChDA,EAAA;AAAA,MACA,KAAK,OAAO,CAAC,KAAK,KAAK,WAAW,KAAK,KAAK,aAAa,KAAK,KAAK,UAAU,CAAC;AAAA,MAC9EA,EAAA;AAAA,MACA,KAAK,OAAO,CAAC,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC;AAAA,MACxC,KAAK;AAAA,MACLA,EAAA;AAAA,MACA,KAAK,OAAO,CAAC,KAAK,KAAK,MAAM,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,CAAC;AAAA,MAC/D,KAAK;AAAA,IAAA;AAAA,EAET;AAAA,EAEQ,mBAAmB;;AACzB,UAAMM,IAAU,CAAC,KAAK,UAAU,UAAU,SAAS,YAAY;AAC/D,SAAK,UAAU,UAAU,OAAO,YAAY,GACxC,KAAK,UAAU,UAAU,SAAS,YAAY,KAC5CA,MACF,KAAK,UAAU,QAAQ,KAAK,gBAAgB,KAE9C,sBAAsB,MAAM,KAAK,UAAU,MAAA,CAAO,MAElDlqB,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,EAEjB;AAAA,EAEQ,aAAa;AACnB,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAMgf,IAAM,KAAK,UAAU,MAAM,KAAA;AACjC,SAAK,OAAO,QAAQA,CAAG,GACvB,KAAK,UAAU,UAAU,OAAO,YAAY,GAC5C,KAAK,UAAU,QAAQ;AAAA,EACzB;AAAA,EAEQ,iBAA8B;AACpC,WACE,KAAK,KAAK,cACT,KAAK,KAAK,aAAa,cAAc,iBAAiB,KACvD,KAAK,KAAK;AAAA,EAEd;AAAA,EAEQ,sBAAsB;AAC5B,IAAI,KAAK,iBAAe,qBAAqB,KAAK,aAAa;AAC/D,UAAMmL,IAAK,KAAK;AAChB,SAAK,gBAAgB,sBAAsB,MAAM;AAE/C,MADA,KAAK,gBAAgB,GACjB,GAAC,KAAK,UAAUA,MAAO,KAAK,UAAU,CAAC,KAAK,GAAG,UAAU,SAAS,YAAY,MAClF,KAAK,mBAAmB,KAAK,OAAO,cAAA,CAAe;AAAA,IACrD,CAAC;AAAA,EACH;AAAA,EAEQ,uBAAuB;;AAC7B,QAAI,KAAK,qBAAsB;AAC/B,SAAK,uBAAuB,IACT,KAAK,eAAA,EACb,iBAAiB,UAAU,KAAK,iBAAiB,EAAE,SAAS,IAAM,IAC7EnqB,IAAA,KAAK,KAAK,aACP,cAAc,UAAU,MAD3B,QAAAA,EAEI,iBAAiB,UAAU,KAAK,iBAAiB,EAAE,SAAS,GAAA,IAChE,OAAO,iBAAiB,UAAU,KAAK,iBAAiB,EAAE,SAAS,IAAM;AAAA,EAC3E;AAAA,EAEQ,yBAAyB;;AAC/B,QAAI,CAAC,KAAK,qBAAsB;AAChC,SAAK,uBAAuB,IACT,KAAK,eAAA,EACb,oBAAoB,UAAU,KAAK,eAAe,IAC7DA,IAAA,KAAK,KAAK,aACP,cAAc,UAAU,MAD3B,QAAAA,EAEI,oBAAoB,UAAU,KAAK,kBACvC,OAAO,oBAAoB,UAAU,KAAK,eAAe;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB2E,GAAiB;AAC1C,UAAMkY,IAAW,KAAK,KAAK,aAAa,sBAAA,GAClCuN,IAAW,KAAK,eAAA,EAAiB,sBAAA,GACjC7Y,IAAM,GACN8Y,IAAO,GACP3E,IAAM,KAAK,GAAG,sBAAA,GACd4E,IAAK5E,EAAI,SAAS,KAAK,GAAG,aAC1B6E,IAAK7E,EAAI,UAAU,KAAK,GAAG,gBAAgB,IAE3C8E,IAAUJ,EAAS,MAAMvN,EAAS,MAAMwN,GACxCI,IAAaL,EAAS,SAASvN,EAAS,MAAM0N,IAAKF,GACnDK,IAAWN,EAAS,OAAOvN,EAAS,OAAOwN,GAC3CM,IAAYP,EAAS,QAAQvN,EAAS,OAAOyN,IAAKD;AAGxD,QAAIrG,IADcrf,EAAO,MAAMkY,EAAS,MAClB0N,IAAKhZ;AAC3B,IAAAyS,IAAM,KAAK,IAAIwG,GAAS,KAAK,IAAIxG,GAAKyG,CAAU,CAAC;AAEjD,QAAIG,IAAOjmB,EAAO,OAAOkY,EAAS,OAAOlY,EAAO,QAAQ,IAAI2lB,IAAK;AACjE,IAAAM,IAAO,KAAK,IAAIF,GAAU,KAAK,IAAIE,GAAMD,CAAS,CAAC,GAEnD,KAAK,GAAG,MAAM,MAAM,GAAG3G,CAAG,MAC1B,KAAK,GAAG,MAAM,OAAO,GAAG4G,CAAI;AAAA,EAC9B;AAAA,EAEQ,kBAAkBC,GAAiBrY,GAAyB;AAElE,QADA,KAAK,gBAAgB,MAAM,UAAUqY,IAAS,KAAK,QAC/C,EAACA,GAGL;AAAA,UADA,KAAK,sBAAsB,IACvBrY,MAAW;AACb,aAAK,iBAAiB,QAAQ;AAAA,WACzB;AAEL,cAAMsY,IADSnhB,GAAuB,KAAK,CAACE,MAAOA,MAAO2I,CAAM,KAG9D7I,GAAuB;AAAA,UAAO,CAAC1E,GAAM4E,MACnC,KAAK,IAAIA,IAAK2I,CAAM,IAAI,KAAK,IAAIvN,IAAOuN,CAAM,IAAI3I,IAAK5E;AAAA,QAAA;AAE3D,aAAK,iBAAiB,QAAQ,OAAO6lB,CAAK;AAAA,MAC5C;AACA,WAAK,sBAAsB;AAAA;AAAA,EAC7B;AAAA,EAEQ,WAAWprB,GAAaqrB,GAAa;;AAC3C,KAAA/qB,IAAA,KAAK,KAAKN,CAAG,MAAb,QAAAM,EAAgB,UAAU,OAAO,aAAa+qB;AAAA,EAChD;AAAA,EAEQ,KACNnoB,GACAkW,GACAkS,GACAnjB,IAAsC,CAAA,GACnB;AACnB,UAAMP,IAAIsF;AAAA,MACR;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAAkM;AAAA,QACA,aAAa,CAAC5E,MAAaA,EAAE,eAAA;AAAA,QAC7B,SAAS8W;AAAA,MAAA;AAAA,MAEX,CAACpoB,CAAI;AAAA,IAAA;AAEP,kBAAO,OAAO0E,EAAE,OAAOO,CAAK,GACrBP;AAAA,EACT;AAAA,EAEQ,SAAS2jB,GAAkBnS,GAAekS,GAAwC;AACxF,WAAOpe;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAAkM;AAAA,QACA,aAAa,CAAC5E,MAAaA,EAAE,eAAA;AAAA,QAC7B,SAAS8W;AAAA,MAAA;AAAA,MAEX,CAACC,CAAI;AAAA,IAAA;AAAA,EAET;AAAA,EAEQ,OAAOne,GAAsC;AACnD,WAAOF,EAAE,OAAO,EAAE,OAAO,6BAAA,GAAgCE,CAAQ;AAAA,EACnE;AACF;AAEA,SAASgd,EAAQpb,GAA2B;AAC1C,QAAMhO,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,YAAYgO,GACRhO;AACT;AAEA,SAAS+oB,GAAYrN,GAAsB;AACzC,QAAM8O,IAAQ9O,EAAK,YAAA,EAAc,QAAQ,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE,KAAA;AACpE,aAAWkN,KAAKJ;AACd,QAAKI,EAAE,SACHA,EAAE,MAAM,YAAA,EAAc,SAAS4B,CAAK;aAAU5B,EAAE;AAEtD,SAAO;AACT;AAEA,SAASI,GAAcvf,GAA4B;AACjD,MAAI,CAACA,EAAK,QAAO;AACjB,QAAMhG,IAAIgG,EAAI,KAAA,EAAO,MAAM,sBAAsB;AACjD,MAAI,CAAChG,EAAG,QAAO;AACf,QAAM0F,IAAK,GAAG,KAAK,MAAM,WAAW1F,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1C,MAAIglB,GAAW,SAAStf,CAAE,EAAG,QAAOA;AACpC,QAAM+Y,IAAM,WAAW/Y,CAAE;AACzB,MAAI5E,IAAOkkB,GAAW,CAAC,GACnB5b,IAAQ;AACZ,aAAWnD,KAAK+e,IAAY;AAC1B,UAAMnqB,IAAI,KAAK,IAAI,WAAWoL,CAAC,IAAIwY,CAAG;AACtC,IAAI5jB,IAAIuO,MACNA,IAAQvO,GACRiG,IAAOmF;AAAA,EAEX;AACA,SAAOnF;AACT;AAEA,SAAS0kB,GAAgBxf,GAA4B;AACnD,MAAI,CAACA,EAAK,QAAO;AACjB,QAAMghB,IAAO/d,EAAwBjD,CAAG;AACxC,SAAOgD,GAAyB,KAAK,CAAC8D,MAAMA,EAAE,UAAUka,CAAI,IAAIA,IAAO;AACzE;AAEA,SAAS3B,GAAgBxb,GAA8B;AACrD,QAAM5D,IAAI4D,EAAM,KAAA;AAChB,MAAI,CAAC5D,EAAG,QAAO;AACf,MAAIA,EAAE,WAAW,GAAG,GAAG;AACrB,QAAI,kBAAkB,KAAKA,CAAC,GAAG;AAC7B,YAAMuR,IAAIvR,EAAE,CAAC,GACPwR,IAAIxR,EAAE,CAAC,GACP9C,IAAI8C,EAAE,CAAC;AACb,aAAO,IAAIuR,CAAC,GAAGA,CAAC,GAAGC,CAAC,GAAGA,CAAC,GAAGtU,CAAC,GAAGA,CAAC,GAAG,YAAA;AAAA,IACrC;AACA,WAAI,kBAAkB,KAAK8C,CAAC,IAAUA,EAAE,YAAA,IACjCA;AAAA,EACT;AACA,QAAMjG,IAAIiG,EAAE,MAAM,yCAAyC;AAC3D,MAAI,CAACjG,EAAG,QAAO;AACf,QAAMinB,IAAQ,CAACthB,MAAc,OAAOA,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AACnE,SAAO,IAAIshB,EAAMjnB,EAAE,CAAC,CAAC,CAAC,GAAGinB,EAAMjnB,EAAE,CAAC,CAAC,CAAC,GAAGinB,EAAMjnB,EAAE,CAAC,CAAC,CAAC;AACpD;AClmBO,SAASknB,GAA4BC,GAAyB;AAgBnE,SAfkC;AAAA,IAChC,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,GAAG;AAAA,IACH,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,IACX,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EAAA,EAEEA,CAAO,KAAK;AACvB;ACqDO,SAASC,GACdC,GACAC,GACAC,GACyB;AACzB,MAAI,EAACF,KAAA,QAAAA,EAAa,OAAO,QAAO,EAAE,SAAS,IAAM,MAAM,WAAW,KAAK,GAAA;AAEvE,MADgBA,EAAY,MAAMC,CAAM,UACpB,EAAE,SAAS,IAAM,MAAM,WAAW,KAAK,GAAA;AAC3D,QAAMjM,IAA2BgM,EAAY,qBAAqB,SAAS,SAAS,WAC9EG,KAAOH,EAAY,mBAAmB,IAAI,UAAUE;AAC1D,SAAO,EAAE,SAAS,IAAO,MAAAlM,GAAM,KAAAmM,EAAA;AACjC;ACvDO,MAAMC,GAAgB;AAAA,EAI3B,YAAYhY,GAA8B;AAH1C,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AAGN,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,OAAO;AAAA,MACjB,OAAO;AAAA,MACP,cAAcgH,EAAK,EAAE,gCAAgC;AAAA,IAAA,CACtD,GACDA,EAAK,MAAM,mBAAmB,MAAM,KAAK,MAAM,GAC/CA,EAAK,MAAM,UAAU,MAAM,KAAK,MAAM,GACtC,KAAK,KAAA;AAAA,EACP;AAAA,EAEA,WAAWmX,GAAa;AACtB,SAAK,GAAG,SAAS,CAACA;AAAA,EACpB;AAAA,EAEA,OAAO;AACL,IAAAhe,EAAM,KAAK,EAAE;AACb,UAAM5H,IAAQ,KAAK,YAAA;AACnB,QAAI,CAACA,EAAM,QAAQ;AACjB,WAAK,GAAG,SAAS;AACjB;AAAA,IACF;AACA,SAAK,GAAG,SAAS,IAEjBA,EAAM,QAAQ,CAACa,GAAMxC,MAAM;AACzB,MAAIA,IAAI,KACN,KAAK,GAAG,OAAOoJ,EAAE,QAAQ,EAAE,OAAO,uBAAuB,eAAe,OAAA,GAAU,CAAC,GAAG,CAAC,CAAC,GAEtF5G,EAAK,WAAW,CAACA,EAAK,UACxB,KAAK,GAAG;AAAA,QACN4G;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,OAAO5G,EAAK;AAAA,UAAA;AAAA,UAEd,CAACA,EAAK,KAAK;AAAA,QAAA;AAAA,MACb,IAGF,KAAK,GAAG;AAAA,QACN4G;AAAA,UACE;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,OAAO,KAAK,KAAK,EAAE,qCAAqC,EAAE,OAAO5G,EAAK,OAAO;AAAA,YAC7E,SAAS,MAAMA,EAAK,QAAA;AAAA,UAAS;AAAA,UAE/B,CAACA,EAAK,KAAK;AAAA,QAAA;AAAA,MACb;AAAA,IAGN,CAAC;AAAA,EACH;AAAA,EAEQ,cAA2B;;AACjC,UAAM,EAAE,OAAA6lB,GAAO,UAAAlb,GAAU,cAAAmb,GAAc,iBAAAC,GAAiB,gBAAAC,EAAA,IAAmB,KAAK,MAC1EvpB,IAAMopB,EAAM,WACZ/rB,IAAM+rB,EAAM;AAElB,QAAI,CAACppB;AACH,aAAO,CAAC,EAAE,OAAOqpB,GAAc,SAAS,IAAM;AAGhD,QAAIrpB,EAAI,SAAS,WAAW;AAC1B,YAAMyS,IAAML,EAAY/U,GAAK2C,EAAI,SAAS;AAC1C,aAAKyS,IACE;AAAA,QACL,EAAE,OAAO4W,GAAc,SAAS,IAAO,SAASC,EAAA;AAAA,QAChD,EAAE,OAAO,KAAK,aAAa7W,EAAI,MAAM,GAAG,SAAS,GAAA;AAAA,MAAK,IAHvC,CAAC,EAAE,OAAO4W,GAAc,SAAS,IAAM;AAAA,IAK1D;AAEA,UAAM5W,IAAML,EAAY/U,GAAK2C,EAAI,SAAS,GACpCmX,IAAM9E,EAAkBhV,GAAK2C,EAAI,OAAO;AAC9C,QAAI,CAACyS,KAAO,CAAC0E;AACX,aAAO,CAAC,EAAE,OAAOkS,GAAc,SAAS,IAAM;AAGhD,UAAMG,MAAYjsB,IAAA2Q,EAAS,IAAIiJ,EAAI,MAAM,IAAI,MAA3B,gBAAA5Z,EAA8B,SAAQ4Z,EAAI,MAAM;AAClE,WAAO;AAAA,MACL;AAAA,QACE,OAAO,KAAK,aAAa1E,EAAI,MAAM;AAAA,QACnC,SAAS;AAAA,QACT,SAAS,MAAM8W,EAAevpB,EAAI,SAAS;AAAA,MAAA;AAAA,MAE7C,EAAE,OAAOwpB,GAAW,SAAS,GAAA;AAAA,IAAK;AAAA,EAEtC;AAAA,EAEQ,aAAa3Y,GAA+B;AAClD,WAAIA,MAAW,MAAY,KAAK,KAAK,EAAE,6BAA6B,IAChEA,MAAW,QAAc,KAAK,KAAK,EAAE,2BAA2B,IAC7DA;AAAA,EACT;AACF;ACnGO,SAAS4Y,GAAsBtY,GAA0C;AAC9E,QAAM,EAAE,SAAAuY,GAAS,QAAAC,GAAQ,QAAAnrB,IAAS,SAAS,MAAM,SAAAorB,GAAS,aAAAb,MAAgB5X,GACpErF,IAAIqF,EAAK,KAAKoI,GAAA,EAAoB,GAGlCsQ,IAAkB,CAACb,MAA0C;AACjE,YAAQA,GAAA;AAAA,MACN,KAAK;AACH,eAAOld,EAAE,2BAA2B;AAAA,MACtC,KAAK;AACH,eAAOA,EAAE,wBAAwB;AAAA,MACnC,KAAK;AACH,eAAOA,EAAE,2BAA2B;AAAA,MACtC;AACE,eAAOA,EAAE,qBAAqB;AAAA,IAAA;AAAA,EAEpC,GACMge,IAAO,CAACd,MACZF,GAAuBC,GAAaC,GAAQa,EAAgBb,CAAM,CAAC,GAE/De,IAAQ,IAAI3T,GAAM;AAAA,IACtB,OAAOtK,EAAE,eAAe;AAAA,IACxB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAA8d;AAAA,IACA,GAAA9d;AAAA,EAAA,CACD,GAEK+V,IAAO1X,EAAE,OAAO,EAAE,OAAO,oBAAoB;AAEnD,MAAI6f,IAAQ,IACRC,IAAO,GACPC,IAAU,IACVC,IAAU,IACV9jB,IAA+B;AAEnC,QAAM+jB,IAAQjgB,EAAE,OAAO;AAAA,IACrB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,EAAA,CACP,GAEKkgB,IAAYlgB,EAAE,SAAS;AAAA,IAC3B,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa2B,EAAE,2BAA2B;AAAA,IAC1C,cAAcA,EAAE,oBAAoB;AAAA,EAAA,CACrC;AAED,MAAIwe,IAAmD;AACvD,EAAAD,EAAU,iBAAiB,SAAS,MAAM;AACxC,IAAIC,kBAAyBA,CAAU,GACvCA,IAAa,WAAW,MAAM;AAC5B,MAAAN,IAASK,EAA+B,OACnCE,EAAA;AAAA,IACP,GAAG,GAAG;AAAA,EACR,CAAC;AAED,QAAMC,IAASrgB,EAAE,OAAO,EAAE,OAAO,0BAA0B,GAErDsgB,IAActgB;AAAA,IAClB;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,MAAM;AACb,QAAI,CAAC+f,KAAWC,KACXO,EAAST,IAAO,GAAG,EAAI;AAAA,MAC9B;AAAA,IAAA;AAAA,IAEF,CAACne,EAAE,kBAAkB,CAAC;AAAA,EAAA,GAGlB6e,IAAaxgB;AAAA,IACjB;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,MAAMygB,EAAA;AAAA,IAAW;AAAA,IAE5B,CAAC9e,EAAE,eAAe,CAAC;AAAA,EAAA;AAGrB,WAAS+e,EAASC,GAAoB;AACpC,IAAIA,KACFV,EAAM,cAAcU,GACpBV,EAAM,MAAM,UAAU,OAEtBA,EAAM,cAAc,IACpBA,EAAM,MAAM,UAAU;AAAA,EAE1B;AAEA,WAASW,IAAsB;AAE7B,IADcP,EAAO,iBAAiB,yBAAyB,EACzD,QAAQ,CAAC7nB,MAAM;AACnB,YAAMkV,IAAMlV,EAAkB,QAAQ;AACtC,MAAAA,EAAE,UAAU,OAAO,eAAe,CAAC,CAAC0D,KAAYwR,MAAOxR,EAAS,EAAE;AAAA,IACpE,CAAC;AAAA,EACH;AAEA,WAAS2kB,EAAYtoB,GAAsBuoB,GAAiB;;AAE1D,QADKA,KAAQ3gB,EAAMkgB,CAAM,GACrB9nB,EAAM,WAAW,KAAK,CAACuoB,GAAQ;AACjC,MAAAT,EAAO,OAAOrgB,EAAE,OAAO,EAAE,OAAO,0BAAA,GAA6B,CAAC2B,EAAE,eAAe,CAAC,CAAC,CAAC,GAClF2e,EAAY,MAAM,UAAUP,IAAU,KAAK;AAC3C;AAAA,IACF;AACA,eAAWgB,KAAMxoB,GAAO;AACtB,YAAMyoB,IAAQD,EAAG,gBAAgBA,EAAG,KAC9BE,KAAWjhB,EAAE,OAAO,EAAE,OAAO,+BAA+B,GAC5DkhB,KAAOlhB;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAO+gB,EAAG,SAASA,EAAG;AAAA,UACtB,WAAWA,EAAG;AAAA,UACd,SAAS,MAAM;AACb,YAAA7kB,IAAW6kB,GACXH,EAAA,GACAJ,EAAW,WAAW;AAAA,UACxB;AAAA,UACA,YAAY,CAAClZ,MAAa;AACxB,YAAAA,EAAE,eAAA,GACFpL,IAAW6kB,GACXN,EAAA;AAAA,UACF;AAAA,QAAA;AAAA,QAEF,CAAA;AAAA,MAAC,GAEGU,KAAMnhB,EAAE,OAAO;AAAA,QACnB,OAAO;AAAA,QACP,KAAK;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AACD,MAAAmhB,GAAI,MAAMH,GACVG,GAAI,UAAU,MAAM;AAClB,QAAAA,GAAI,MAAM,UAAU;AAAA,MACtB;AACA,YAAMC,KAAMphB,EAAE,OAAO,EAAE,OAAO,+BAA+B;AAAA,SAC3D5M,IAAA2tB,EAAG,UAAH,QAAA3tB,EAAU,SAAS2tB,EAAG,QAAQpf,EAAE,cAAc;AAAA,MAAA,CAC/C;AAID,UAHAuf,GAAK,OAAOC,IAAKC,EAAG,GACpBH,GAAS,OAAOC,EAAI,GAEhB3B,EAAQ,YAAY;AACtB,cAAM8B,IAAa1B,EAAK,QAAQ;AAChC,YAAI,GAAC0B,EAAW,WAAWA,EAAW,SAAS,SAExC;AACL,gBAAMC,KAASthB;AAAA,YACb;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,OAAO;AAAA,cACP,OAAOqhB,EAAW,UAAU1f,EAAE,qBAAqB,IAAI0f,EAAW;AAAA,cAClE,UAAU,CAACA,EAAW;AAAA,cACtB,GAAIA,EAAW,UACX;AAAA,gBACE,SAAS,OAAO/Z,OAAa;AAG3B,sBAFAA,GAAE,eAAA,GACFA,GAAE,gBAAA,GACE,EAAC,OAAO,QAAQ3F,EAAE,uBAAuB,CAAC;AAC9C,wBAAI;AACF,4BAAM4d,EAAQ,WAAYwB,EAAG,EAAE,IAC3B7kB,KAAA,gBAAAA,EAAU,QAAO6kB,EAAG,OACtB7kB,IAAW,MACXskB,EAAW,WAAW,KAExB,MAAMJ,EAAA;AAAA,oBACR,SAASmB,IAAK;AACZ,sBAAAb,EAASa,cAAe,QAAQA,GAAI,UAAU5f,EAAE,sBAAsB,CAAC;AAAA,oBACzE;AAAA,gBACF;AAAA,cAAA,IAEF,CAAA;AAAA,YAAC;AAAA,YAEP,CAAC,GAAG;AAAA,UAAA;AAEN,UAAAsf,GAAS,OAAOK,EAAM;AAAA,QACxB;AAAA,MACF;AAEA,MAAAjB,EAAO,OAAOY,EAAQ;AAAA,IACxB;AACA,IAAAX,EAAY,MAAM,UAAUP,IAAU,KAAK;AAAA,EAC7C;AAEA,iBAAeQ,EAASrnB,GAAW4nB,GAAiB;AAClD,QAAI,CAAAd,GACJ;AAAA,MAAAA,IAAU,IACVM,EAAY,WAAW,IACvBI,EAAS,IAAI;AACb,UAAI;AACF,cAAMc,IAAM,MAAMjC,EAAQ,UAAU,EAAE,OAAAM,GAAO,MAAM3mB,GAAG;AACtD,QAAA6mB,IAAUyB,EAAI,SACd1B,IAAO5mB,GACP2nB,EAAYW,EAAI,OAAOV,CAAM;AAAA,MAC/B,SAASxZ,GAAG;AACV,QAAAoZ,EAASpZ,aAAa,QAAQA,EAAE,UAAU3F,EAAE,oBAAoB,CAAC;AAAA,MACnE,UAAA;AACE,QAAAqe,IAAU,IACVM,EAAY,WAAW;AAAA,MACzB;AAAA;AAAA,EACF;AAEA,iBAAeF,IAAY;AACzB,IAAAN,IAAO,GACP5jB,IAAW,MACXskB,EAAW,WAAW,IACtBrgB,EAAMkgB,CAAM,GACZ,MAAME,EAAS,GAAG,EAAK,GACvBK,EAAA;AAAA,EACF;AAEA,WAASH,IAAa;;AACpB,KAAKrtB,IAAA8I,KAAA,gBAAAA,EAAU,QAAV,QAAA9I,EAAe,WACpBosB,EAAOtjB,EAAS,IAAI,MAAM,GAC1B0jB,EAAM,MAAA;AAAA,EACR;AAGA,QAAMjI,IAAU3X,EAAE,OAAO,EAAE,OAAO,6BAA6B,GACzDyhB,IAAUzhB,EAAE,OAAO,EAAE,OAAO,iCAAiC;AAGnE,MAFAyhB,EAAQ,OAAOvB,CAAS,GAEpBX,EAAQ,UAAU;AACpB,UAAMmC,IAAU/B,EAAK,QAAQ;AAC7B,QAAI,GAAC+B,EAAQ,WAAWA,EAAQ,SAAS,SAElC;AACL,YAAMC,IAAS3hB,EAAE,SAAS;AAAA,QACxB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,aAAa2B,EAAE,2BAA2B;AAAA,QAC1C,UAAU,CAAC+f,EAAQ;AAAA,MAAA,CACpB,GACKE,IAAS5hB;AAAA,QACb;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,OAAO0hB,EAAQ,UAAU,KAAKA,EAAQ;AAAA,UACtC,UAAU,CAACA,EAAQ;AAAA,UACnB,GAAIA,EAAQ,UACR;AAAA,YACE,SAAS,YAAY;AACnB,oBAAMG,IAAIF,EAAO,MAAM,KAAA;AACvB,kBAAKE;AACL,oBAAI;AACF,wBAAMtC,EAAQ,SAAUsC,CAAC,GACzBF,EAAO,QAAQ,IACf,MAAMvB,EAAA;AAAA,gBACR,SAAS9Y,GAAG;AACV,kBAAAoZ,EAASpZ,aAAa,QAAQA,EAAE,UAAU3F,EAAE,mBAAmB,CAAC;AAAA,gBAClE;AAAA,YACF;AAAA,UAAA,IAEF,CAAA;AAAA,QAAC;AAAA,QAEP,CAACA,EAAE,YAAY,CAAC;AAAA,MAAA;AAElB,MAAA8f,EAAQ,OAAOE,GAAQC,CAAM;AAAA,IAC/B;AAAA,EACF;AAEA,MAAIrC,EAAQ,YAAY;AACtB,UAAMuC,IAAanC,EAAK,QAAQ;AAChC,QAAI,GAACmC,EAAW,WAAWA,EAAW,SAAS,SAExC;AACL,YAAMC,IAAU/hB,EAAE,SAAS;AAAA,QACzB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO;AAAA,MAAA,CACR;AACD,MAAA+hB,EAAQ,iBAAiB,UAAU,YAAY;;AAC7C,cAAMrF,KAAKtpB,IAAA2uB,EAA6B,UAA7B,gBAAA3uB,EAAqC;AAEhD,YADC2uB,EAA6B,QAAQ,IAClC,EAACrF;AACL,cAAI;AACF,kBAAM6C,EAAQ,WAAY7C,CAAC,GAC3B,MAAM0D,EAAA;AAAA,UACR,SAAS9Y,IAAG;AACV,YAAAoZ,EAASpZ,cAAa,QAAQA,GAAE,UAAU3F,EAAE,sBAAsB,CAAC;AAAA,UACrE;AAAA,MACF,CAAC;AACD,YAAMqgB,IAAQhiB;AAAA,QACZ;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,OAAO8hB,EAAW,UAAU,KAAKA,EAAW;AAAA,UAC5C,UAAU,CAACA,EAAW;AAAA,UACtB,GAAIA,EAAW,UAAU,EAAE,SAAS,MAAMC,EAAQ,MAAA,MAAY,CAAA;AAAA,QAAC;AAAA,QAEjE,CAACpgB,EAAE,eAAe,CAAC;AAAA,MAAA;AAErB,MAAA8f,EAAQ,OAAOO,GAAOD,CAAO;AAAA,IAC/B;AAAA,EACF;AAEA,EAAApK,EAAQ,OAAO8J,CAAO;AAEtB,QAAMQ,IAAajiB,EAAE,OAAO,EAAE,OAAO,8BAA8B,CAACqgB,GAAQC,CAAW,CAAC;AAExF,EAAA5I,EAAK,OAAOC,GAASsI,GAAOgC,CAAU,GAEtCrC,EAAM,KAAK,OAAOlI,CAAI,GACtBkI,EAAM,OAAO;AAAA,IACX5f;AAAA,MACE;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MAAM4f,EAAM,MAAA;AAAA,MAAM;AAAA,MAE7B,CAACje,EAAE,eAAe,CAAC;AAAA,IAAA;AAAA,IAErB6e;AAAA,EAAA,GAGFZ,EAAM,KAAKvrB,CAAM,GACZ+rB,EAAA;AACP;AChVO,SAAS8B,GAAwBlY,GAAiD;AACvF,MAAImY,IAASnY,EAAQ;AACrB,QAAMrI,IAAIqI,EAAQ,GACZoY,IAAa,CAACnR,MAA2B;AAC7C,IAAAA,EAAI,UAAU,OAAO,aAAakR,CAAM,GACxClR,EAAI,aAAa,gBAAgB,OAAOkR,CAAM,CAAC,GAC/ClR,EAAI,QAAiBtP,EAATwgB,IAAW,8BAAiC,yBAAN;AAAA,EACpD,GACME,IAASriB;AAAA,IACb;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,cAAc2B,EAAE,oBAAoB;AAAA,MACpC,SAAS,MAAM;AACb,QAAAwgB,IAASnY,EAAQ,YAAA,GACjBoY,EAAWC,CAAM;AAAA,MACnB;AAAA,IAAA;AAAA,IAEF,CAACC,IAAS;AAAA,EAAA;AAEZ,EAAAF,EAAWC,CAAM;AAEjB,QAAMhW,IAAWrM;AAAA,IACf;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO2B,EAAE,cAAc;AAAA,MACvB,cAAcA,EAAE,2BAA2B;AAAA,MAC3C,SAAS,MAAMqI,EAAQ,QAAA;AAAA,IAAQ;AAAA,IAEjC,CAACwC,IAAW;AAAA,EAAA;AAGd,SAAOxM,EAAE,OAAO,EAAE,OAAO,yBAAyB;AAAA,IAChDA,EAAE,OAAO,EAAE,OAAO,uCAAA,GAA0C,CAAC2B,EAAE,sBAAsB,CAAC,CAAC;AAAA,IACvF3B,EAAE,OAAO,EAAE,OAAO,4BAA4B,CAACqiB,GAAQhW,CAAQ,CAAC;AAAA,EAAA,CACjE;AACH;AAEA,SAASG,KAAwB;AAC/B,QAAM1Y,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,YACD,oGACKA;AACT;AAEA,SAASwuB,KAAsB;AAC7B,QAAMxuB,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,eAAe,GAC1CA,EAAG,YACD,opDACKA;AACT;AAGO,SAASyuB,GACdhb,GACAib,GACA7gB,GACa;AACb,QAAM+V,IAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAiB;AAChD,MAAI,CAACuH,EAAK;AACR,WAAAmQ,EAAK;AAAA,MACH1X,EAAE,OAAO,EAAE,OAAO,gBAAA,GAAmB,CAAC2B,EAAE,sBAAsB,CAAC,CAAC;AAAA,IAAA,GAE3D+V;AAET,aAAWrZ,KAAKkJ,GAAM;AACpB,UAAM6B,IAAQC,EAAoBhL,EAAE,GAAG,GACjCokB,IAAMziB,EAAE,OAAO,EAAE,OAAO,mBAAmB,GAC3C0iB,IAAU1iB,EAAE,OAAO,EAAE,OAAO,uBAAuB;AACzD,KAAI3B,EAAE,SAAS,UAAUA,EAAE,SAAS,YAClCqkB,EAAQ;AAAA,MACN1iB;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,SAAS,CAACsH,MAAa;AACrB,YAAAA,EAAE,gBAAA,GACFkb,EAAS,cAAcnkB,CAAC;AAAA,UAC1B;AAAA,QAAA;AAAA,QAEF,CAACsD,EAAE,8BAA8B,CAAC;AAAA,MAAA;AAAA,IACpC,GAGJ+gB,EAAQ;AAAA,MACN1iB;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,OAAO2B,EAAE,4BAA4B,EAAE,OAAAyH,GAAO;AAAA,UAC9C,SAAS,CAAC9B,MAAa;AACrB,YAAAA,EAAE,gBAAA,GACFkb,EAAS,OAAOpZ,CAAK;AAAA,UACvB;AAAA,QAAA;AAAA,QAEF,CAACzH,EAAE,aAAa,CAAC;AAAA,MAAA;AAAA,IACnB,GAEF8gB,EAAI;AAAA,MACFziB;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,SAAS,MAAMwiB,EAAS,UAAUnkB,CAAC;AAAA,QAAA;AAAA,QAErC;AAAA,UACE2B,EAAE,QAAQ,EAAE,OAAO,uBAAuB,CAAC3B,EAAE,KAAK,CAAC;AAAA,UACnD2B,EAAE,QAAQ,EAAE,OAAO,qBAAqB,CAACoJ,CAAK,CAAC;AAAA,QAAA;AAAA,MACjD;AAAA,MAEFsZ;AAAA,IAAA,GAEFhL,EAAK,OAAO+K,CAAG;AAAA,EACjB;AACA,SAAO/K;AACT;AC9FA,SAASiL,GAAoBplB,GAA6C;AACxE,QAAM,KAAKA,KAAO,IAAI,KAAA;AACtB,SAAI,CAAC,KAAK,EAAE,YAAA,MAAkB,SAAe,SACzC,iBAAiB,KAAK,CAAC,IAAU,MACjC,mBAAmB,KAAK,CAAC,KACzB,gBAAgB,KAAK,CAAC,IAAU,OAC7B;AACT;AAEA,SAASqlB,GAAmBrlB,GAAaqV,GAA0B;AACjE,QAAMjR,KAAKpE,KAAO,IAAI,KAAA;AACtB,MAAI,CAACoE,EAAG,QAAOiR,MAAS,MAAM,MAAM;AACpC,QAAMrb,IAAIoK,EAAE,MAAM,gBAAgB,GAC5BzE,IAAI3F,IAAI,WAAWA,EAAE,CAAC,CAAC,IAAIqb,MAAS,MAAM,MAAM;AACtD,SAAyB,KAAK,IAA1BA,MAAS,MAAqB,MAClB,MADuB,KAAK,IAAI,GAAG,KAAK,MAAM1V,CAAC,CAAC,CAAC;AAEnE;AA0BO,MAAM2lB,GAAW;AAAA,EAoBtB,YAAY7b,GAAyB;AAnBrC,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,oBAAuB;AACvB,IAAAA,EAAA,kBAA8B;AAC9B,IAAAA,EAAA,4BAAqB;AACrB,IAAAA,EAAA,8BAAuB;AACvB,IAAAA,EAAA,gCAAwD;AAW9D,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,SAAS,EAAE,OAAO,4BAA4B,GAC1D,KAAK,aAAa,IAAIgf,GAAgB;AAAA,MACpC,OAAOhY,EAAK;AAAA,MACZ,UAAUA,EAAK;AAAA,MACf,cAAcA,EAAK,gBAAgBA,EAAK,EAAE,yBAAyB;AAAA,MACnE,GAAGA,EAAK;AAAA,MACR,iBAAiB,MAAMA,EAAK,gBAAA;AAAA,MAC5B,gBAAgB,CAAC0G,MAAO1G,EAAK,eAAe0G,CAAE;AAAA,IAAA,CAC/C,GACD,KAAK,SAAS1N,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC,KAAK,WAAW,EAAE,CAAC,GACxE,KAAK,YAAYA,EAAE,OAAO,EAAE,OAAO,kBAAkB,GACrD,KAAK,GAAG,OAAO,KAAK,QAAQ,KAAK,SAAS,GAC1C,KAAK,oBAAA,GACL,KAAK,QAAA,GACLgH,EAAK,MAAM,UAAU,CAACgB,MAA8B;AAClD,UAAI,MAAK,oBACT;AAAA,aAAIA,KAAA,gBAAAA,EAAQ,YAAW,WAAW;AAChC,eAAK,4BAAA;AACL;AAAA,QACF;AACA,aAAIA,KAAA,gBAAAA,EAAQ,YAAW,WAAW;AAChC,eAAK,QAAA;AACL;AAAA,QACF;AAEA,QAAI,KAAK,qCACT,KAAK,QAAA;AAAA;AAAA,IACP,CAAC,GACDhB,EAAK,MAAM,mBAAmB,MAAM;AAClC,MAAI,KAAK,uBACT,KAAK,aAAa,SAClB,KAAK,oBAAA,GACL,KAAK,QAAA;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EA5CQ,wBAAiC;;AACvC,aAAO5T,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,0BAAyB;AAAA,EAChD;AAAA,EAEQ,gBAAyB;;AAC/B,aAAOA,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,kBAAiB;AAAA,EACxC;AAAA;AAAA,EAyCA,mBAAmBmU,GAAkBib,GAAkC;AACrE,SAAK,qBAAqB,IAC1B,KAAK,uBAAuB,IAC5B,KAAK,yBAAyBA,GAC9B,KAAK,sBAAsBjb,CAAI;AAAA,EACjC;AAAA,EAEA,sBAAsB;AACpB,IAAK,KAAK,uBACV,KAAK,qBAAqB,IAC1B,KAAK,uBAAuB,IAC5B,KAAK,yBAAyB,MAC9B,KAAK,GAAG,UAAU,OAAO,2BAA2B,GACpDpH,EAAM,KAAK,MAAM,GACjB,KAAK,OAAO,OAAO,KAAK,WAAW,EAAE,GACrC,KAAK,oBAAA,GACL,KAAK,QAAA;AAAA,EACP;AAAA,EAEA,uBAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,yBAAkC;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,0BAAmC;AACjC,gBAAK,uBAAuB,CAAC,KAAK,sBAC3B,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ,sBAAsB;AAC5B,QAAI,KAAK,mBAAoB;AAC7B,UAAM2iB,IAAO,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/B,SAAK,OAAO,SAAS,CAACA;AAAA,EACxB;AAAA,EAEQ,sBAAsBvb,GAAkB;AAC9C,UAAMib,IAAW,KAAK;AACtB,IAAKA,MACL,KAAK,iBAAA,GACLriB,EAAM,KAAK,MAAM,GACjBA,EAAM,KAAK,SAAS,GACpB,KAAK,GAAG,UAAU,IAAI,2BAA2B,GACjD,KAAK,OAAO,SAAS,IACrB,KAAK,OAAO;AAAA,MACV+hB,GAAwB;AAAA,QACtB,QAAQ,KAAK;AAAA,QACb,GAAG,KAAK,KAAK;AAAA,QACb,SAAS,MAAMM,EAAS,QAAA;AAAA,QACxB,aAAa,MAAM,KAAK,wBAAA;AAAA,MAAwB,CACjD;AAAA,IAAA,GAEH,KAAK,UAAU,OAAOD,GAAwBhb,GAAMib,GAAU,KAAK,KAAK,CAAC,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGQ,kCAA2C;AACjD,UAAMO,IAAK,SAAS;AACpB,QAAI,CAACA,KAAM,CAAC,KAAK,GAAG,SAASA,CAAE,EAAG,QAAO;AACzC,QAAIA,EAAG,QAAQ,YAAY,EAAG,QAAO;AACrC,UAAM5nB,IAAM4nB,EAAG;AACf,WAAI5nB,MAAQ,WAAWA,MAAQ,cAAcA,MAAQ;AAAA,EAEvD;AAAA;AAAA,EAGQ,8BAA8B;AACpC,QAAI,KAAK,mBAAoB;AAC7B,UAAM4nB,IAAK,SAAS;AACpB,QAAI3Z,IAAuB,MACvB4Z,IAAW,GACXC,IAAS;AAYb,QAXIF,KAAM,KAAK,GAAG,SAASA,CAAE,MAC3B3Z,IAAQ2Z,EAAG,aAAa,eAAe,GAErC3Z,MACC2Z,aAAc,oBAAoBA,aAAc,yBAEjDC,IAAWD,EAAG,kBAAkB,GAChCE,IAASF,EAAG,gBAAgB,KAGhC,KAAK,QAAA,GACD,CAAC3Z,EAAO;AACZ,UAAMtU,IAAO,KAAK,aAAasU,CAAK;AAEpC,QADAtU,KAAA,QAAAA,EAAM,SACFA,aAAgB,oBAAoBA,aAAgB,qBAAqB;AAC3E,YAAM2B,IAAM3B,EAAK,MAAM;AACvB,MAAAA,EAAK,kBAAkB,KAAK,IAAIkuB,GAAUvsB,CAAG,GAAG,KAAK,IAAIwsB,GAAQxsB,CAAG,CAAC;AAAA,IACvE;AAAA,EACF;AAAA,EAEQ,aAAa2S,GAAmC;AACtD,eAAWtV,KAAM,KAAK,GAAG,iBAAiB,iBAAiB;AACzD,UAAKA,EAAmB,aAAa,eAAe,MAAMsV,EAAO,QAAOtV;AAE1E,WAAO;AAAA,EACT;AAAA,EAEQ,UAAU;AAChB,QAAI,KAAK,mBAAoB;AAC7B,SAAK,iBAAA,GACLqM,EAAM,KAAK,SAAS;AAEpB,UAAMtK,IAAM,KAAK,KAAK,MAAM,WACtB3C,IAAM,KAAK,KAAK,MAAM;AAE5B,QAAI,CAAC2C,GAAK;AACR,WAAK,UAAU,OAAO,KAAK,eAAe3C,CAAG,CAAC;AAC9C;AAAA,IACF;AAEA,QAAI2C,EAAI,SAAS,WAAW;AAC1B,YAAMlD,IAAUsV,EAAY/U,GAAK2C,EAAI,SAAS;AAC9C,UAAI,CAAClD,EAAS;AACd,WAAK,UAAU,OAAO,KAAK,mBAAmBA,CAAO,CAAC;AACtD;AAAA,IACF;AAGA,UAAMqa,IAAM9E,EAAkBhV,GAAK2C,EAAI,OAAO;AAC9C,QAAI,CAACmX,GAAK;AACR,YAAMkW,IAAOljB,EAAE,OAAO,EAAE,OAAO,aAAa;AAAA,QAC1C,KAAK,QAAQ,SAAS,KAAK,KAAK,EAAE,uBAAuB,CAAC;AAAA,QAC1D,KAAK,QAAQ,QAAQ,KAAK,KAAK,EAAE,sBAAsB,CAAC;AAAA,MAAA,CACzD;AACD,WAAK,UAAU,OAAOkjB,CAAI,GAC1B,KAAK,UAAU;AAAA,QACbljB,EAAE,OAAO,EAAE,OAAO,gBAAA,GAAmB,CAAC,KAAK,KAAK,EAAE,0BAA0B,CAAC,CAAC;AAAA,MAAA;AAEhF;AAAA,IACF;AACA,UAAM/N,IAAM,KAAK,KAAK,SAAS,IAAI+a,EAAI,MAAM,IAAI,GAE3CkW,IAAOljB,EAAE,OAAO,EAAE,OAAO,aAAa;AAAA,MAC1C,KAAK,QAAQ,SAAS,KAAK,KAAK,EAAE,uBAAuB,CAAC;AAAA,MAC1D,KAAK,QAAQ,QAAQ,KAAK,KAAK,EAAE,sBAAsB,CAAC;AAAA,IAAA,CACzD;AACD,SAAK,UAAU,OAAOkjB,CAAI,GAEtB,KAAK,eAAe,UAClBlW,EAAI,MAAM,aACZ,KAAK,UAAU;AAAA,MACbhN,EAAE,OAAO,EAAE,OAAO,mBAAmB;AAAA,QACnC,KAAK,KAAK,EAAE,yBAAyB;AAAA,QACrCA,EAAE,OAAO,EAAE,OAAO,qBAAqB;AAAA,UACrCA;AAAA,YACE;AAAA,YACA;AAAA,cACE,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS,MAAM;AACb,qBAAK,KAAK,MAAM,OAAO,CAAC5N,MAAM;AAC5B,wBAAM,IAAI8V,EAAkB9V,GAAG4a,EAAI,MAAM,EAAE;AAC3C,kBAAI,KAAG,OAAO,EAAE,MAAM;AAAA,gBACxB,CAAC;AAAA,cACH;AAAA,YAAA;AAAA,YAEF,CAAC,KAAK,KAAK,EAAE,+BAA+B,CAAC;AAAA,UAAA;AAAA,QAC/C,CACD;AAAA,MAAA,CACF;AAAA,IAAA,IAEM/a,IACT,KAAK,UAAU,OAAO,KAAK,iBAAiB+a,EAAI,OAAO/a,EAAI,MAAM,CAAC,IAElE,KAAK,UAAU;AAAA,MACb+N,EAAE,OAAO,EAAE,OAAO,mBAAmB;AAAA,QACnC,KAAK,KAAK,EAAE,iCAAiC,EAAE,MAAMgN,EAAI,MAAM,KAAA,CAAM;AAAA,MAAA,CACtE;AAAA,IAAA,IAIL,KAAK,UAAU,OAAO,KAAK,qBAAqBA,EAAI,KAAK,CAAC;AAAA,EAE9D;AAAA,EAEQ,QAAQmW,GAAehgB,GAAe;AAC5C,WAAOnD;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO,iBAAiB,KAAK,eAAemjB,IAAM,0BAA0B,EAAE;AAAA,QAC9E,MAAM;AAAA,QACN,SAAS,MAAM;AACb,eAAK,aAAaA,GAClB,KAAK,QAAA;AAAA,QACP;AAAA,MAAA;AAAA,MAEF,CAAChgB,CAAK;AAAA,IAAA;AAAA,EAEV;AAAA;AAAA,EAIQ,eAAejQ,GAA4B;AACjD,UAAMkwB,IAAW,KAAK,cAAA,GAChBC,IAAsB,CAAA;AAC5B,WAAKD,IAmBHC,EAAK,KAAKrjB,EAAE,OAAO,EAAE,OAAO,qBAAqB,CAAC,KAAK,KAAK,EAAE,4BAA4B,CAAC,CAAC,CAAC,IAlB7FqjB,EAAK;AAAA,MACHrjB,EAAE,OAAO,EAAE,OAAO,kBAAA,GAAqB,CAAC,KAAK,KAAK,EAAE,sBAAsB,CAAC,CAAC;AAAA,MAC5E,KAAK;AAAA,QAAW,KAAK,KAAK,EAAE,wBAAwB;AAAA,QAAG9M,EAAI,KAAK;AAAA,QAAS,CAACmL,MACxE,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,KAAK,UAAUiM;AAAA,QACnB,CAAC;AAAA,QACD;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QAAW,KAAK,KAAK,EAAE,0BAA0B;AAAA,QAAGnL,EAAI,KAAK,aAAa;AAAA,QAAI,CAACmL,MAClF,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,KAAK,YAAYiM;AAAA,QACrB,CAAC;AAAA,QACD;AAAA,QACA;AAAA,MAAA;AAAA,IACF,GAKJglB,EAAK;AAAA,MACH,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,6BAA6B;AAAA,QACzCzjB,GAAqB1M,EAAI,KAAK,KAAK;AAAA,QACnC,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,KAAK,QAAQsN,GAA4BrB,CAAC;AAAA,QAC9C,CAAC;AAAA,QACH,KAAK,KAAK,EAAE,wCAAwC;AAAA,QACpD;AAAA,MAAA;AAAA,MAEF2B,EAAE,OAAO,EAAE,OAAO,kBAAA,GAAqB,CAAC,KAAK,KAAK,EAAE,6BAA6B,CAAC,CAAC;AAAA,MACnF,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,+BAA+B;AAAA,QAC3C9M,EAAI,OAAO;AAAA,QACX,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,kBAAkBiM;AAAA,QAC7B,CAAC;AAAA,QACH;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,kCAAkC;AAAA,QAC9CnL,EAAI,OAAO;AAAA,QACX,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,yBAAyBiM;AAAA,QACpC,CAAC;AAAA,QACH;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,2BAA2B;AAAA,QACvCnL,EAAI,OAAO;AAAA,QACX,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,aAAaiM;AAAA,QACxB,CAAC;AAAA,QACH;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACHnL,EAAI,OAAO;AAAA,QACX,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,WAAWiM;AAAA,QACtB,CAAC;AAAA,QACH;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACHnL,EAAI,OAAO,cAAc;AAAA,QACzB,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,aAAaiM;AAAA,QACxB,CAAC;AAAA,QACH;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,2BAA2B;AAAA,QACvCnL,EAAI,OAAO,cAAc;AAAA,QACzB,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,aAAaiM;AAAA,QACxB,CAAC;AAAA,QACH,KAAK,KAAK,EAAE,sCAAsC;AAAA,QAClD;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,0BAA0B;AAAA,QACtCnL,EAAI,OAAO;AAAA,QACX,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,QAAQiM;AAAA,QACnB,CAAC;AAAA,QACH;AAAA,MAAA;AAAA,MAEF,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,0BAA0B;AAAA,QACtCnL,EAAI,OAAO;AAAA,QACX,CAACmL,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,UAAAA,EAAE,OAAO,YAAYiM;AAAA,QACvB,CAAC;AAAA,QACH;AAAA,MAAA;AAAA,MAEF,KAAK,wBAAwBnL,CAAG;AAAA,IAAA,GAE3B8M,EAAE,QAAQ,EAAE,OAAO,WAAW,UAAU,CAACsH,MAAaA,EAAE,eAAA,EAAe,GAAK+b,CAAI;AAAA,EACzF;AAAA;AAAA,EAIQ,mBAAmB1wB,GAA+B;;AACxD,UAAM8H,IAAI9H,EAAQ,OACZ2wB,MAAclwB,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,6BAA4B,IACxD2R,IAAQue,IAAc5wB,GAA4BC,CAAO,IAAI,QAC7D4wB,IAAyBD,KAC1B,MAAM;AACL,YAAME,IAAQ,KAAK;AAAA,QACjB,KAAK,KAAK,EAAE,+BAA+B;AAAA,QAC3C/oB,EAAE,qBAAqB;AAAA,QACvB,CAAC4D,MACC,KAAK,KAAK,MAAM,OAAO,CAAC,MAAM;AAC5B,gBAAMb,IAAIyK,EAAY,GAAGtV,EAAQ,EAAE;AACnC,cAAI,CAAC6K,EAAG;AACR,gBAAMoF,IAAUvE,EAAE,KAAA;AAClB,UAAAb,EAAE,MAAM,oBAAoBoF,KAAW;AAAA,QACzC,CAAC;AAAA,QACH,KAAK,KAAK,EAAE,0CAA0C;AAAA,QACtD,WAAWjQ,EAAQ,EAAE;AAAA,MAAA;AAEvB,aAAA6wB,EAAM;AAAA,QACJxjB,EAAE,OAAO,EAAE,OAAO,oBAAoB;AAAA,UACpC,KAAK,KAAK,EAAE,mCAAmC;AAAA,QAAA,CAChD;AAAA,MAAA,GAEIwjB;AAAA,IACT,OACA;AACJ,WAAOxjB,EAAE,QAAQ,EAAE,OAAO,WAAW,UAAU,CAACsH,MAAaA,EAAE,eAAA,KAAoB;AAAA,MACjFtH,EAAE,OAAO,EAAE,OAAO,qBAAqB;AAAA,QACrC,KAAK,KAAK,EAAE+E,IAAQ,oCAAoC,0BAA0B;AAAA,MAAA,CACnF;AAAA,MACD,GAAIwe,IAAyB,CAACA,CAAsB,IAAI,CAAA;AAAA,MACxD,GAAI7a,GAAoB/V,EAAQ,MAAM,IAClC;AAAA,QACE,KAAK;AAAA,UACHA,EAAQ;AAAA,UACR,CAAC+T,MACC,KAAK,KAAK,MAAM,OAAO,CAACtU,MAAM;AAC5B,kBAAMoL,IAAIyK,EAAY7V,GAAGO,EAAQ,EAAE;AACnC,YAAI6K,KAAGoL,GAAiBpL,GAAGkJ,CAAM;AAAA,UACnC,CAAC;AAAA,UACH,WAAW/T,EAAQ,EAAE;AAAA,QAAA;AAAA,MACvB,IAEF,CAAA;AAAA,MACJ,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,oCAAoC;AAAA,QAChD8H,EAAE,mBAAmB;AAAA,QACrB,CAAC4D,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,gBAAMoL,IAAIyK,EAAY7V,GAAGO,EAAQ,EAAE;AACnC,UAAI6K,MAAGA,EAAE,MAAM,kBAAkBa,KAAK;AAAA,QAC1C,CAAC;AAAA,QACD,WAAW1L,EAAQ,EAAE;AAAA,QACrB,KAAK,KAAK,EAAE,2CAA2C;AAAA,MAAA;AAAA,MAEzD,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,0BAA0B;AAAA,QACtCoN,GAAwBtF,EAAE,KAAK;AAAA,QAC/B,CAAC4D,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,gBAAMoL,IAAIyK,EAAY7V,GAAGO,EAAQ,EAAE;AACnC,UAAI6K,MAAGA,EAAE,MAAM,QAAQsC,GAA+BzB,CAAC;AAAA,QAC3D,CAAC;AAAA,QACD,WAAW1L,EAAQ,EAAE;AAAA,QACrB,KAAK,KAAK,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE5C,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,4BAA4B;AAAA,QACxC,CAAC8H,EAAE,YAAYA,EAAE,cAAcA,EAAE,eAAeA,EAAE,WAAW;AAAA,QAC7D,CAACgpB,MACC,KAAK,KAAK,MAAM,OAAO,CAACrxB,MAAM;AAC5B,gBAAMoL,IAAIyK,EAAY7V,GAAGO,EAAQ,EAAE;AACnC,UAAK6K,MACL,CAACA,EAAE,MAAM,YAAYA,EAAE,MAAM,cAAcA,EAAE,MAAM,eAAeA,EAAE,MAAM,WAAW,IACnFimB;AAAA,QACJ,CAAC;AAAA,QACH,WAAW9wB,EAAQ,EAAE;AAAA,QACrB,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,MAAA;AAAA,MAEbA,EAAQ,WAAW,MACf,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,8BAA8B;AAAA,QAC1C8H,EAAE,aAAa;AAAA,QACf;AAAA,QACA;AAAA,QACA,CAAC4D,MAAM;AACL,gBAAM2Q,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM3Q,CAAC,CAAC,CAAC;AACjD,eAAK,KAAK,MAAM,OAAO,CAAC,MAAM;AAC5B,kBAAMb,IAAIyK,EAAY,GAAGtV,EAAQ,EAAE;AACnC,YAAI6K,MAAGA,EAAE,MAAM,YAAYwR,IAAI,IAAIA,IAAI;AAAA,UACzC,CAAC;AAAA,QACH;AAAA,QACA;AAAA,QACA,WAAWrc,EAAQ,EAAE;AAAA,MAAA,IAEvB;AAAA,MACJA,EAAQ,WAAW,OAAO,CAAC8H,EAAE,0BACzB,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,+BAA+B;AAAA,QAC3CA,EAAE,oBAAoB;AAAA,QACtB;AAAA,QACA;AAAA,QACA,CAAC4D,MAAM;AACL,gBAAM2Q,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM3Q,CAAC,CAAC,CAAC;AACjD,eAAK,KAAK,MAAM,OAAO,CAAC,MAAM;AAC5B,kBAAMb,IAAIyK,EAAY,GAAGtV,EAAQ,EAAE;AACnC,YAAI6K,MAAGA,EAAE,MAAM,mBAAmBwR,IAAI,IAAIA,IAAI;AAAA,UAChD,CAAC;AAAA,QACH;AAAA,QACA;AAAA,QACA,WAAWrc,EAAQ,EAAE;AAAA,QACrB,KAAK,KAAK,EAAE,mCAAmC;AAAA,MAAA,IAEjD;AAAA,MACJA,EAAQ,WAAW,MACf,KAAK;AAAA,QACH,KAAK,KAAK,EAAE,mCAAmC;AAAA,QAC/C,CAAC,CAAC8H,EAAE;AAAA,QACJ,CAACipB,MACC,KAAK,KAAK,MAAM,OAAO,CAACtxB,MAAM;AAC5B,gBAAMoL,IAAIyK,EAAY7V,GAAGO,EAAQ,EAAE;AACnC,UAAI6K,MAAGA,EAAE,MAAM,0BAA0BkmB,KAAW;AAAA,QACtD,CAAC;AAAA,QACH,KAAK,KAAK,EAAE,uCAAuC;AAAA,QACnD,WAAW/wB,EAAQ,EAAE;AAAA,MAAA,IAEvB;AAAA,IAAA,CACL;AAAA,EACH;AAAA;AAAA,EAIQ,iBAAiBsa,GAAc0W,GAAyC;AAC9E,UAAMC,IAAO5jB,EAAE,QAAQ,EAAE,OAAO,WAAW,UAAU,CAACsH,MAAaA,EAAE,eAAA,EAAe,CAAG;AACvF,eAAWkc,KAASG;AAClB,MAAAC,EAAK,OAAO,KAAK,OAAOJ,GAAOvW,CAAK,CAAC;AAEvC,WAAO2W;AAAA,EACT;AAAA,EAEQ,aAAazb,GAAiBrV,GAAa8L,GAAgB;AACjE,SAAK,KAAK,MAAM,OAAO,CAACxM,MAAM;AAC5B,YAAM4a,IAAM9E,EAAkB9V,GAAG+V,CAAO;AACxC,MAAK6E,MACJA,EAAI,MAAM,MAAcla,CAAG,IAAI8L;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEQ,OAAO4kB,GAAyBvW,GAA2B;;AACjE,UAAM9E,IAAU8E,EAAM,IAChB4W,IAAK,SAAS1b,CAAO,IAAIqb,EAAM,GAAG,IAClCvxB,IAAM,KAAK,KAAK,SAAS,IAAIgb,EAAM,IAAI,GACvC6W,IAAW7xB,KAAA,gBAAAA,EAAK,cAChBsL,IAAO0P,EAAM,MAAkCuW,EAAM,GAAG,GACxD5kB,IACiBrB,MAAqBumB,KAAA,gBAAAA,EAAWN,EAAM,OACvDO,IAAW,CAAC1lB,MAAW,KAAK,aAAa8J,GAASqb,EAAM,KAAKnlB,CAAC;AAEpE,YAAQmlB,EAAM,MAAA;AAAA,MACZ,KAAK;AACH,eAAIvW,EAAM,SAAS,UAAUuW,EAAM,QAAQ,SAClC,KAAK;AAAA,UACVA,EAAM;AAAA,UACN,OAAO5kB,KAAS,EAAE;AAAA,UAClBmlB;AAAA,UACAP,EAAM;AAAA,UACNK;AAAA,UACA,CAACxlB,MACC2D,GAAqB3D,CAAC,IAClB,KAAK,KAAK,EAAE,8BAA8B,IAC1C;AAAA,QAAA,IAGH,KAAK,eAAemlB,EAAM,OAAO,OAAO5kB,KAAS,EAAE,GAAGmlB,GAAUP,EAAM,MAAMK,CAAE;AAAA,MACvF,KAAK;AACH,eAAO,KAAK;AAAA,UACVL,EAAM;AAAA,UACN,OAAO5kB,KAAS,CAAC;AAAA,UACjB4kB,EAAM,OAAO;AAAA,UACbA,EAAM,OAAO;AAAA,UACbO;AAAA,UACAP,EAAM,QAAQ;AAAA,UACdK;AAAA,QAAA;AAAA,MAEJ,KAAK,SAAS;AACZ,cAAMG,IAAY/W,EAAM,MAAkCuW,EAAM,GAAG,GAC7DS,IACsBD,KAAa,OAAO,OAAOA,CAAQ,EAAE,KAAA,IAAS;AAC1E,eAAO,KAAK;AAAA,UACVR,EAAM;AAAA,UACNS;AAAA,UACA,CAAC5lB,MAAM0lB,EAAS1lB,EAAE,MAAM;AAAA,UACxBwlB;AAAA,UACAL,EAAM,eAAe;AAAA,QAAA;AAAA,MAEzB;AAAA,MACA,KAAK,UAAU;AACb,cAAMU,IAAOV,EAAM,QAAQ,gBAAgBA,EAAM,QAAQ,mBACnDxc,KAAO5T,IAAAowB,EAAM,YAAN,QAAApwB,EAAe,SACxBowB,EAAM,UACNU,IACE3jB,KACA,CAAA;AACN,YAAI2jB,KAAQV,EAAM,eAAe;AAC/B,gBAAMS,IACiB1mB,KAAQ,OAAO,OAAOA,CAAG,EAAE,KAAA,IAAS;AAC3D,iBAAO,KAAK;AAAA,YACVimB,EAAM;AAAA,YACNS;AAAA,YACAzjB,EAAwB,KAAK,KAAK,MAAM,IAAI,OAAO,UAAU;AAAA,YAC7D,CAACnC,MAAM0lB,EAAS1lB,CAAC;AAAA,YACjBwlB;AAAA,YACA7c;AAAA,YACAwc,EAAM;AAAA,UAAA;AAAA,QAEV;AACA,cAAMW,IAAaD,IACf1jB,EAAwB,OAAO5B,KAAS,EAAE,CAAC,IAC3C,OAAOA,KAAS,EAAE;AACtB,YAAIslB,KAAQV,EAAM,kBAAkB,aAAa;AAC/C,gBAAM1vB,IAAK,KAAK,sBAAsB0vB,EAAM,OAAOW,GAAYnd,GAAM+c,GAAUF,CAAE;AACjF,iBAAIL,EAAM,QAAM1vB,EAAG,OAAOkM,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAACwjB,EAAM,IAAI,CAAC,CAAC,GACtE1vB;AAAA,QACT;AACA,eAAO,KAAK,aAAa0vB,EAAM,OAAOW,GAAYnd,GAAM+c,GAAUF,CAAE;AAAA,MACtE;AAAA,MACA,KAAK;AACH,eAAO,KAAK,aAAaL,EAAM,OAAO,CAAC,CAAC5kB,GAAOmlB,GAAUP,EAAM,MAAMK,CAAE;AAAA,MACzE,KAAK;AACH,eAAO,KAAK;AAAA,UACVL,EAAM;AAAA,UACN,OAAO5kB,KAAS,EAAE;AAAA,UAClBmlB;AAAA,UACAP,EAAM,eAAe;AAAA,UACrBK;AAAA,UACA,EAAE,SAAA1b,GAAS,SAASqb,EAAM,IAAA;AAAA,QAAI;AAAA,MAElC,KAAK;AAAA,MACL,KAAK,QAAQ;AACX,YAAIA,EAAM,QAAQ,WAAW,KAAK;AAChC,iBAAO,KAAK;AAAA,YACVA,EAAM;AAAA,YACN,OAAO5kB,KAAS,EAAE;AAAA,YAClB,CAACP,MAAM0lB,EAAS1lB,CAAC;AAAA,YACjBwlB;AAAA,YACAL,EAAM;AAAA,UAAA;AAGV,YAAIA,EAAM,QAAQ,cAAcA,EAAM,eAAe;AACnD,gBAAMY,IACiB7mB,KAAQ,OAAO,OAAOA,CAAG,EAAE,KAAA,IAAS;AAC3D,iBAAO,KAAK;AAAA,YACVimB,EAAM;AAAA,YACNY;AAAA,YACA,CAAC/lB,MAAM0lB,EAAS1lB,EAAE,MAAM;AAAA,YACxBwlB;AAAA,YACAL,EAAM;AAAA,YACN,KAAK,KAAK,MAAM,IAAI,OAAO;AAAA,UAAA;AAAA,QAE/B;AACA,cAAMf,IAAM,KAAK;AAAA,UACfe,EAAM;AAAA,UACN,OAAO5kB,KAAS,EAAE;AAAA,UAClBmlB;AAAA,UACAP,EAAM,eAAe;AAAA,UACrBK;AAAA,QAAA;AAEF,eAAIL,EAAM,QAAMf,EAAI,OAAOziB,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAACwjB,EAAM,IAAI,CAAC,CAAC,GACvEf;AAAA,MACT;AAAA,MACA,KAAK,WAAW;AAEd,cAAMvpB,IAAI+T,EAAM,OACVoX,IAAO;AAAA,UACX,OAAOnrB,EAAE,cAAc,CAAC;AAAA,UACxB,OAAOA,EAAE,gBAAgB,CAAC;AAAA,UAC1B,OAAOA,EAAE,iBAAiB,CAAC;AAAA,UAC3B,OAAOA,EAAE,eAAe,CAAC;AAAA,QAAA,GAErBjH,IAAM,KAAK,KAAK,SAAS,IAAIgb,EAAM,IAAI,GACvCqX,IAAKryB,KAAAA,gBAAAA,EAAK,cACVsyB,IAA8C;AAAA,UAClD,QAAOD,KAAA,gBAAAA,EAAI,eAAc,CAAC;AAAA,UAC1B,QAAOA,KAAA,gBAAAA,EAAI,iBAAgB,CAAC;AAAA,UAC5B,QAAOA,KAAA,gBAAAA,EAAI,kBAAiB,CAAC;AAAA,UAC7B,QAAOA,KAAA,gBAAAA,EAAI,gBAAe,CAAC;AAAA,QAAA;AAE7B,eAAO,KAAK,cAAcd,EAAM,OAAOa,GAAM,CAACZ,MAAS;AACrD,eAAK,KAAK,MAAM,OAAO,CAACrxB,MAAM;AAC5B,kBAAM4a,IAAM9E,EAAkB9V,GAAG+V,CAAO;AACxC,gBAAI,CAAC6E,EAAK;AACV,kBAAMwX,IAAKxX,EAAI,MAAM;AACrB,aAACwX,EAAG,YAAYA,EAAG,cAAcA,EAAG,eAAeA,EAAG,WAAW,IAAIf;AAAA,UACvE,CAAC;AAAA,QACH,GAAG,GAAGI,CAAE,QAAQU,CAAS;AAAA,MAC3B;AAAA,MACA,KAAK,kBAAkB;AACrB,cAAMlB,IAAO,MAAM,QAAQzkB,CAAK,IAC3BA,IACD,MAAM,QAAQklB,KAAA,gBAAAA,EAAWN,EAAM,IAAI,IAChCM,EAASN,EAAM,GAAG,IACnB,CAAA;AACN,eAAO,KAAK;AAAA,UACVA,EAAM;AAAA,UACNH;AAAA,UACAG,EAAM,WAAW,CAAA;AAAA,UACjBrb;AAAA,UACAqb,EAAM;AAAA,UACNA,EAAM;AAAA,UACNK;AAAA,QAAA;AAAA,MAEJ;AAAA,MACA;AACE,eAAO7jB,EAAE,KAAK;AAAA,IAAA;AAAA,EAEpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,qBACNmD,GACA5K,GACAksB,GACAtc,GACAuc,GACAC,GACAC,GACa;;AACb,UAAMC,MAAWzxB,IAAAqxB,EAAe,CAAC,MAAhB,gBAAArxB,EAAmB,UAAS,SACvCskB,IAAO1X,EAAE,OAAO,EAAE,OAAO,YAAY;AAC3C,IAAA0X,EAAK,OAAO1X,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC,CAAC;AAE7D,UAAM2hB,IAAS9kB,EAAE,OAAO,EAAE,OAAO,uBAAuB,GAElD+kB,IAAgB,CAACC,MAAuD;AAC5E,WAAK,KAAK,MAAM,OAAO,CAAC5yB,MAAM;AAC5B,cAAM4a,IAAM9E,EAAkB9V,GAAG+V,CAAO;AACxC,YAAI,CAAC6E,EAAK;AACV,cAAMvJ,IAAQuJ,EAAI,MAAM,OAClBzP,IAAMkG,EAAMihB,CAAW,GACvBO,IAAuB,MAAM,QAAQ1nB,CAAG,IACzCA,EAAwB,IAAI,CAACsJ,OAAO,EAAE,GAAGA,EAAA,EAAI,IAC9C,CAAA;AACJ,QAAApD,EAAMihB,CAAW,IAAIM,EAAOC,CAAG;AAAA,MACjC,CAAC;AAAA,IACH,GAEMC,IAAW,CAAClsB,GAAe8E,MAAkC;AACjE,MAAAinB;AAAA,QAAc,CAAC1B,MACbA,EAAK,IAAI,CAACxc,GAAGjQ,MAAOA,MAAMoC,IAAQ,EAAE,GAAG6N,GAAG,GAAG/I,EAAA,IAAU+I,CAAE;AAAA,MAAA;AAAA,IAE7D,GAEMse,IAAW,CAACnsB,MAAkB;AAClC,MAAA+rB,EAAc,CAAC1B,MAASA,EAAK,OAAO,CAAC+B,GAAGxuB,MAAMA,MAAMoC,CAAK,CAAC;AAAA,IAC5D;AAEA,aAASpC,IAAI,GAAGA,IAAI2B,EAAM,QAAQ3B,KAAK;AACrC,YAAMyuB,IAAU9sB,EAAM3B,CAAC,GACjB0uB,IAAUtlB,EAAE,OAAO,EAAE,OAAO,4BAA4B,GACxDulB,IAAUvlB,EAAE,OAAO,EAAE,OAAO,iCAAiC,GAC7DnK,IAAMmK,EAAE,UAAU;AAAA,QACtB,OAAO;AAAA,QACP,GAAI4kB,IAAc,EAAE,iBAAiB,GAAGA,CAAW,QAAQhuB,CAAC,OAAA,IAAW,CAAA;AAAA,QACvE,UAAU,CAAC0Q,MACT4d,EAAStuB,GAAG,EAAE,SAAU0Q,EAAE,OAA6B,MAAA,CAAO;AAAA,MAAA,CACjE;AACD,iBAAWke,KAAKf,GAAgB;AAC9B,cAAMrH,IAAM,SAAS,cAAc,QAAQ;AAC3C,QAAAA,EAAI,QAAQoI,EAAE,OACdpI,EAAI,cAAcoI,EAAE,OAChBA,EAAE,UAAUH,EAAQ,cAAa,WAAW,KAChDxvB,EAAI,OAAOunB,CAAG;AAAA,MAChB;AACA,UAAI,CAACqH,EAAe,KAAK,CAACe,MAAMA,EAAE,UAAUH,EAAQ,OAAO,KAAKA,EAAQ,SAAS;AAC/E,cAAMjI,IAAM,SAAS,cAAc,QAAQ;AAC3C,QAAAA,EAAI,QAAQiI,EAAQ,SACpBjI,EAAI,cAAciI,EAAQ,SAC1BjI,EAAI,WAAW,IACfvnB,EAAI,aAAaunB,GAAKvnB,EAAI,UAAU;AAAA,MACtC;AACA,YAAM4vB,IAAMzlB,EAAE,SAAS;AAAA,QACrB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,aAAa;AAAA,QACb,OAAOqlB,EAAQ;AAAA,QACf,GAAIT,IAAc,EAAE,iBAAiB,GAAGA,CAAW,QAAQhuB,CAAC,QAAA,IAAY,CAAA;AAAA,QACxE,SAAS,CAAC0Q,MAAa4d,EAAStuB,GAAG,EAAE,MAAO0Q,EAAE,OAA4B,MAAA,CAAO;AAAA,MAAA,CAClF,GACKoe,IAAK1lB;AAAA,QACT;AAAA,QACE;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACR,OAAO,KAAK,KAAK,EAAE,eAAe;AAAA,UAClC,SAAS,MAAMmlB,EAASvuB,CAAC;AAAA,QAAA;AAAA,QAE3B,CAAC,GAAG;AAAA,MAAA;AAEN,MAAA2uB,EAAQ,OAAO1vB,GAAK4vB,GAAKC,CAAE,GAC3BJ,EAAQ,OAAOC,CAAO;AAEtB,YAAMI,IAAS3lB,EAAE,OAAO,EAAE,OAAO,mCAAmC,GAC9D4lB,IAAanH,GAA4B4G,EAAQ,OAAO,GACxDQ,KAAWvyB,IAAA+xB,EAAQ,oBAAR,gBAAA/xB,EAAyB,QACpCwyB,IACJD,KAAYA,EAAS,WAAW,GAAG,IAAIA,IAAWD;AACpD,MAAAD,EAAO;AAAA,QACL3lB,EAAE,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM;AAAA,UACN,aAAa,KAAK,KAAK,EAAE,oCAAoC;AAAA,UAC7D,OAAOqlB,EAAQ,SAAS;AAAA,UACxB,GAAIT,IAAc,EAAE,iBAAiB,GAAGA,CAAW,QAAQhuB,CAAC,SAAA,IAAa,CAAA;AAAA,UACzE,SAAS,CAAC0Q,MAAa4d,EAAStuB,GAAG,EAAE,OAAQ0Q,EAAE,OAA4B,MAAA,CAAO;AAAA,QAAA,CACnF;AAAA,QACDtH,EAAE,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM;AAAA,UACN,aAAa,KAAK,KAAK,EAAE,sCAAsC;AAAA,UAC/D,OAAOqlB,EAAQ,WAAW;AAAA,UAC1B,GAAIT,IAAc,EAAE,iBAAiB,GAAGA,CAAW,QAAQhuB,CAAC,QAAA,IAAY,CAAA;AAAA,UACxE,SAAS,CAAC0Q,MAAa4d,EAAStuB,GAAG,EAAE,SAAU0Q,EAAE,OAA4B,MAAA,CAAO;AAAA,QAAA,CACrF;AAAA,MAAA;AAEH,YAAMye,IAAS/lB,EAAE,SAAS;AAAA,QACxB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAO8lB,EAAU,UAAU,IAAIA,IAAYF;AAAA,QAC3C,GAAIhB,IAAc,EAAE,iBAAiB,GAAGA,CAAW,QAAQhuB,CAAC,UAAU,CAAA;AAAA,MAAC,CACxE;AACD,MAAAya,GAAqB0U,GAAQ;AAAA,QAC3B,YAAY;AAAA,QACZ,GAAG,KAAK,KAAK;AAAA,QACb,UAAU,CAACjX,MAAQoW,EAAStuB,GAAG,EAAE,iBAAiBkY,GAAK;AAAA,MAAA,CACxD,GACD6W,EAAO,OAAOI,CAAM,GACpBT,EAAQ,OAAOK,CAAM,GAErBb,EAAO,OAAOQ,CAAO;AAAA,IACvB;AAEA,UAAM1D,IAAS5hB;AAAA,MACb;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MACP+kB,EAAc,CAAC1B,MAAS;AAAA,UACtB,GAAGA;AAAA,UACH;AAAA,YACE,SAASwB;AAAA,YACT,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS;AAAA,UAAA;AAAA,QACX,CACD;AAAA,MAAA;AAAA,MAEL,CAAC,KAAK,KAAK,EAAE,uBAAuB,CAAC;AAAA,IAAA;AAGvC,WAAAnN,EAAK,OAAOoN,GAAQlD,CAAM,GACtB+C,KAAMjN,EAAK,OAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC5DjN;AAAA,EACT;AAAA;AAAA,EAIQ,WACNvU,GACAvE,GACAmlB,GACA5G,IAAc,IACd6I,GACA;AACA,WAAOhmB,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDnD,EAAE,SAAS;AAAA,QACT,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAApB;AAAA,QACA,aAAAue;AAAA,QACA,GAAI6I,IAAa,EAAE,iBAAiBA,EAAA,IAAe,CAAA;AAAA,QACnD,SAAS,CAAC1e,MAAayc,EAAUzc,EAAE,OAA4B,KAAK;AAAA,MAAA,CACrE;AAAA,IAAA,CACF;AAAA,EACH;AAAA;AAAA,EAGQ,YACNnE,GACAvE,GACAmlB,GACA5G,GACA6I,GACAC,GACa;AACb,UAAMC,IAAS,KAAK,KAAK,aACnBC,IAAgB,CAAC,EAACD,KAAA,QAAAA,EAAQ,gBAAeA,EAAO,eAAe,IAC/DE,KACJF,KAAA,gBAAAA,EAAQ,iBAAgB,OACvB,CAAC,CAACA,EAAO,gBAAgB,CAAC,CAACA,EAAO,uBAC/BG,IAAoB,CAAC,EACzBH,KAAA,QAAAA,EAAQ,eACRA,KAAA,QAAAA,EAAQ,wBACRA,KAAA,QAAAA,EAAQ,eAEJI,IAAkBH,KAAiBC,GAEnC3D,IAAMziB,EAAE,OAAO,EAAE,OAAO,uBAAuB,GAC/C2hB,IAAS3hB,EAAE,SAAS;AAAA,MACxB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAApB;AAAA,MACA,aAAAue;AAAA,MACA,GAAI6I,IAAa,EAAE,iBAAiBA,EAAA,IAAe,CAAA;AAAA,MACnD,SAAS,CAAC1e,MAAayc,EAAUzc,EAAE,OAA4B,KAAK;AAAA,IAAA,CACrE,GACKif,IAAS,OAA0B;AAAA,MACvC,SAASN,EAAI;AAAA,MACb,SAASA,EAAI;AAAA,MACb,YAAYtE,EAAO;AAAA,IAAA;AAErB,IAAAc,EAAI,OAAOd,CAAM;AAEjB,UAAM6E,IAAW,CAACpU,MAAgB;AAChC,YAAMzQ,IAAIyQ,EAAI,KAAA;AACd,MAAKzQ,MACLoiB,EAASpiB,CAAC,GACVggB,EAAO,QAAQhgB;AAAA,IACjB,GAEM8kB,IAAW,CAACvtB,GAAkCwtB,MAAqB;AACvE,MAAAxtB,EAAE,MAAM,CAACoO,MAAM;AACb,gBAAQ,MAAM,iBAAiBof,CAAQ,IAAIpf,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AAEA,QAAI6e,GAAe;AACjB,YAAMpE,IAAU/hB,EAAE,SAAS;AAAA,QACzB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU,CAACsH,MAAa;;AACtB,gBAAMxT,IAAKwT,EAAE,QACPoV,KAAItpB,IAAAU,EAAG,UAAH,gBAAAV,EAAW;AAErB,UADAU,EAAG,QAAQ,IACN4oB,KACL+J;AAAA,YACEP,EAAO,YAAaxJ,GAAG6J,EAAA,CAAQ,EAAE,KAAK,CAACnU,MAAQoU,EAAS,OAAOpU,CAAG,CAAC,CAAC;AAAA,YACpE;AAAA,UAAA;AAAA,QAEJ;AAAA,MAAA,CACD,GACK0P,IAAanD;AAAA,QACjBuH,KAAA,gBAAAA,EAAQ;AAAA,QACR;AAAA,QACA,KAAK,KAAK,EAAE,2BAA2B;AAAA,MAAA;AAEzC,MAAI,CAACpE,EAAW,WAAWA,EAAW,SAAS,WAG7CW,EAAI;AAAA,QACFziB;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO8hB,EAAW,UACd,KAAK,KAAK,EAAE,8BAA8B,IAC1CA,EAAW;AAAA,YACf,UAAU,CAACA,EAAW;AAAA,YACtB,GAAIA,EAAW,UACX,EAAE,SAAS,MAAMC,EAAQ,MAAA,MACzB,CAAA;AAAA,UAAC;AAAA,UAEP,CAAC,KAAK,KAAK,EAAE,yBAAyB,CAAC;AAAA,QAAA;AAAA,MACzC,GAEFU,EAAI,OAAOV,CAAO;AAAA,IAEtB;AAEA,IAAIqE,KACF3D,EAAI;AAAA,MACFziB;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,OAAO,KAAK,KAAK,EAAE,+BAA+B;AAAA,UAClD,SAAS,MAAM;AACb,gBAAIkmB,EAAO,cAAc;AACvB,cAAA5G,GAAsB;AAAA,gBACpB,SAAS4G,EAAO;AAAA,gBAChB,aAAaA,KAAA,gBAAAA,EAAQ;AAAA,gBACrB,QAAQ,CAAC9T,MAAQoU,EAASpU,CAAG;AAAA,gBAC7B,GAAG,KAAK,KAAK;AAAA,gBACb,QAAQ,KAAK,GAAG,QAAQ,UAAU;AAAA,cAAA,CACnC;AACD;AAAA,YACF;AACA,YAAI8T,EAAO,wBACTO;AAAA,cACEP,EAAO,qBAAqBK,EAAA,CAAQ,EAAE,KAAK,CAACnU,MAAQ;AAClD,gBAAIA,KAAO,QAAQ,OAAOA,CAAG,EAAE,UAAQoU,EAAS,OAAOpU,CAAG,CAAC;AAAA,cAC7D,CAAC;AAAA,cACD;AAAA,YAAA;AAAA,UAGN;AAAA,QAAA;AAAA,QAEF,CAAC,KAAK,KAAK,EAAE,0BAA0B,CAAC;AAAA,MAAA;AAAA,IAC1C;AAIJ,QAAIuU;AACJ,QAAIL,GAAiB;AACnB,YAAMM,IAAiB,CAAC,KAAK,KAAK,EAAE,6BAA6B,CAAC;AAClE,MAAIT,KAAeS,EAAK,KAAK,KAAK,KAAK,EAAE,6BAA6B,CAAC,GACnER,KAAgBQ,EAAK,KAAK,KAAK,KAAK,EAAE,8BAA8B,CAAC,GACzED,IAAW,GAAGC,EAAK,KAAK,KAAK,KAAK,EAAE,gCAAgC,CAAC,CAAC,GAAG,KAAK,KAAK;AAAA,QACjF;AAAA,MAAA,CACD;AAAA,IACH,OAAWP,IACTM,IAAW,KAAK,KAAK,EAAE,uCAAuC,IAE9DA,IAAW,KAAK,KAAK,EAAE,+BAA+B;AAGxD,WAAO3mB,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDsf;AAAA,MACAziB,EAAE,OAAO,EAAE,OAAO,oBAAoB,CAAC2mB,CAAQ,CAAC;AAAA,IAAA,CACjD;AAAA,EACH;AAAA,EACQ,eACNxjB,GACAvE,GACAmlB,GACAY,GACAqB,GACAa,GACA;AACA,UAAMC,IAAS9mB,EAAE,OAAO,EAAE,OAAO,kBAAkB,OAAO,gBAAgB,GACpEib,IAAKjb,EAAE,YAAY;AAAA,MACvB,OAAO;AAAA,MACP,GAAIgmB,IAAa,EAAE,iBAAiBA,EAAA,IAAe,CAAA;AAAA,MACnD,SAAS,CAAC1e,MAAa;AACrB,cAAMjJ,IAAKiJ,EAAE,OAA+B;AAE5C,YADAyc,EAAS1lB,CAAC,GACNwoB,GAAM;AACR,gBAAMlG,IAAMkG,EAAKxoB,CAAC;AAClB,UAAAyoB,EAAO,cAAcnG,KAAO,IAC5BmG,EAAO,MAAM,UAAUnG,IAAM,KAAK;AAAA,QACpC;AAAA,MACF;AAAA,IAAA,CACD;AAED,QADA1F,EAAG,QAAQrc,GACPioB,GAAM;AACR,YAAMlG,IAAMkG,EAAKjoB,CAAK;AACtB,MAAI+hB,MACFmG,EAAO,cAAcnG,GACrBmG,EAAO,MAAM,UAAU;AAAA,IAE3B;AACA,WAAO9mB;AAAA,MACL;AAAA,MACA,EAAE,OAAO,WAAA;AAAA,MACT;AAAA,QACEA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,QAChD8X;AAAA,QACA6L;AAAA,QACAnC,IAAO3kB,EAAE,OAAO,EAAE,OAAO,oBAAoB,CAAC2kB,CAAI,CAAC,IAAI;AAAA,MAAA;AAAA,IACzD;AAAA,EAEJ;AAAA,EACQ,aACNxhB,GACAvE,GACAmoB,GACAC,GACAjD,GACAxF,IAAO,GACPyH,GACArB,GACa;AACb,UAAMnB,IAAQ,KAAK,kBAAkBrgB,GAAOvE,GAAOmoB,GAAKC,GAAKjD,GAAUxF,GAAMyH,CAAU;AACvF,WAAKrB,IACE3kB,EAAE,OAAO,EAAE,OAAO,YAAY,OAAO,2DAA2D;AAAA,MACrGwjB;AAAA,MACAxjB,EAAE,OAAO,EAAE,OAAO,oBAAoB,CAAC2kB,CAAI,CAAC;AAAA,IAAA,CAC7C,IAJiBnB;AAAA,EAKpB;AAAA,EAEQ,kBACNrgB,GACAvE,GACAmoB,GACAC,GACAjD,GACAxF,IAAO,GACPyH,GACA;AACA,UAAMiB,IAAO,CAAC/pB,MAAc;AAC1B,YAAM1E,IAAI,KAAK,IAAIwuB,GAAK,KAAK,IAAID,GAAK7pB,CAAC,CAAC;AACxC,UAAI,CAACqhB,KAAQA,KAAQ,EAAG,QAAO/lB;AAC/B,YAAM4F,IAAI,KAAK,OAAO5F,IAAIuuB,KAAOxI,CAAI;AACrC,aAAO,QAAQwI,IAAM3oB,IAAImgB,GAAM,YAAY,EAAE,CAAC;AAAA,IAChD;AAEA,QAAI,CAAC,KAAK,yBAAyB;AACjC,YAAMkH,IAAMzlB,EAAE,SAAS;AAAA,QACrB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAO,OAAOpB,CAAK;AAAA,QACnB,KAAAmoB;AAAA,QACA,KAAAC;AAAA,QACA,MAAAzI;AAAA,QACA,GAAIyH,IAAa,EAAE,iBAAiBA,MAAe,CAAA;AAAA,MAAC,CACrD,GAEKkB,IAAc,MAAM;AACxB,cAAMvlB,IAAI8jB,EAAI,MAAM,KAAA,GACd0B,IAAKF,EAAKroB,CAAK;AACrB,YAAI+C,MAAM,IAAI;AACZ,UAAA8jB,EAAI,QAAQ,OAAO0B,CAAE,GACrBpD,EAASoD,CAAE;AACX;AAAA,QACF;AACA,cAAM9oB,IAAI,OAAOsD,CAAC,GACZnE,IAAIypB,EAAK,OAAO,MAAM5oB,CAAC,IAAI8oB,IAAK9oB,CAAC;AACvC,QAAAonB,EAAI,QAAQ,OAAOjoB,CAAC,GACpBumB,EAASvmB,CAAC;AAAA,MACZ;AAGA,aAAIupB,IAAM,KACRtB,EAAI,iBAAiB,QAAQyB,CAAW,GACxCzB,EAAI,iBAAiB,WAAW,CAACne,MAAM;AACrC,QAAKA,EAAoB,QAAQ,WAASme,EAAI,KAAA;AAAA,MAChD,CAAC,MAEDA,EAAI,iBAAiB,SAAS,MAAM;AAClC,cAAM9jB,IAAI8jB,EAAI,MAAM,KAAA;AACpB,YAAI9jB,MAAM,GAAI;AACd,cAAMtD,IAAI,OAAOsD,CAAC;AAClB,QAAI,OAAO,MAAMtD,CAAC,KAClB0lB,EAASkD,EAAK5oB,CAAC,CAAC;AAAA,MAClB,CAAC,GACDonB,EAAI,iBAAiB,QAAQyB,CAAW,GACxCzB,EAAI,iBAAiB,WAAW,CAACne,MAAM;AACrC,QAAKA,EAAoB,QAAQ,WAAS4f,EAAA;AAAA,MAC5C,CAAC,IAGIlnB,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,QACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,QAChDsiB;AAAA,MAAA,CACD;AAAA,IACH;AAEA,UAAM2B,IAAKH,EAAKroB,CAAK,GACfxJ,IAAQ4K,EAAE,SAAS;AAAA,MACvB,MAAM;AAAA,MACN,KAAA+mB;AAAA,MACA,KAAAC;AAAA,MACA,MAAAzI;AAAA,MACA,OAAO,OAAO6I,CAAE;AAAA,IAAA,CACjB,GAEKpR,IAAMhW,EAAE,SAAS;AAAA,MACrB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAA+mB;AAAA,MACA,KAAAC;AAAA,MACA,MAAAzI;AAAA,MACA,OAAO,OAAO6I,CAAE;AAAA,MAChB,GAAIpB,IAAa,EAAE,iBAAiBA,MAAe,CAAA;AAAA,IAAC,CACrD,GAEKqB,IAAiB,CAACnqB,MAAc;AACpC,YAAMM,IAAIypB,EAAK/pB,CAAC;AAChB,MAAA9H,EAAM,QAAQ,OAAOoI,CAAC,GACtBwY,EAAI,QAAQ,OAAOxY,CAAC,GACpBumB,EAASvmB,CAAC;AAAA,IACZ;AAEA,WAAApI,EAAM,iBAAiB,SAAS,MAAM;AACpC,MAAAiyB,EAAe,OAAOjyB,EAAM,KAAK,CAAC;AAAA,IACpC,CAAC,GAED4gB,EAAI,iBAAiB,SAAS,MAAM;AAClC,YAAMrU,IAAIqU,EAAI,MAAM,KAAA;AACpB,UAAIrU,MAAM,GAAI;AACd,YAAMpE,IAAM,OAAOoE,CAAC;AACpB,MAAI,OAAO,MAAMpE,CAAG,MACpBnI,EAAM,QAAQ,OAAO6xB,EAAK1pB,CAAG,CAAC;AAAA,IAChC,CAAC,GAEDyY,EAAI,iBAAiB,QAAQ,MAAM;AACjC,YAAMrU,IAAIqU,EAAI,MAAM,KAAA,GACdmR,IAAKF,EAAK,OAAO7xB,EAAM,KAAK,CAAC;AACnC,UAAIuM,MAAM,IAAI;AACZ,QAAA0lB,EAAeF,CAAE;AACjB;AAAA,MACF;AACA,YAAM5pB,IAAM,OAAOoE,CAAC;AACpB,UAAI,OAAO,MAAMpE,CAAG,GAAG;AACrB,QAAA8pB,EAAeF,CAAE;AACjB;AAAA,MACF;AACA,MAAAE,EAAe9pB,CAAG;AAAA,IACpB,CAAC,GAEDyY,EAAI,iBAAiB,WAAW,CAAC1O,MAAM;AACrC,MAAKA,EAAoB,QAAQ,WAAS0O,EAAI,KAAA;AAAA,IAChD,CAAC,GAEMhW,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDnD,EAAE,OAAO,EAAE,OAAO,0BAA0B,CAAC5K,GAAO4gB,CAAG,CAAC;AAAA,IAAA,CACzD;AAAA,EACH;AAAA,EACQ,YACN7S,GACAvE,GACAmlB,GACAa,GACAzH,IAAc,WACd;AACA,UAAMmK,IAAY1C,IAAc,GAAGA,CAAW,UAAU,QAClD2C,IAAY3C,IAAc,GAAGA,CAAW,UAAU,QAClDtT,IAAOtR,EAAE,SAAS;AAAA,MACtB,MAAM;AAAA,MACN,GAAIsnB,IAAY,EAAE,iBAAiBA,MAAc,CAAA;AAAA,IAAC,CACnD,GACKtxB,IAAOgK,EAAE,SAAS;AAAA,MACtB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAAmd;AAAA,MACA,GAAIoK,IAAY,EAAE,iBAAiBA,MAAc,CAAA;AAAA,IAAC,CACnD;AAED,QAAIC,IAAY5oB,EAAM,KAAA;AAEtB,UAAM6oB,IAAmB,MAAM;AAC7B,MAAAnW,EAAK,QAAQ,WACbA,EAAK,UAAU,IAAI,6BAA6B,GAChDA,EAAK,QAAQ6L,KAAe,KAAK,KAAK,EAAE,wBAAwB;AAAA,IAClE,GAEMuK,IAAc,CAACzD,MAAmB;AACtC,YAAMrhB,IAAUqhB,EAAO,KAAA;AACvB,MAAAjuB,EAAK,QAAQ4M;AACb,YAAMkM,IAAMN,EAAmB5L,CAAO;AACtC,MAAIkM,KACFwC,EAAK,QAAQxC,GACbwC,EAAK,UAAU,OAAO,6BAA6B,GACnDA,EAAK,QAAQ,MAEbmW,EAAA;AAAA,IAEJ;AAEA,IAAAC,EAAY9oB,CAAK;AAEjB,UAAM+oB,IAAc,CAAC7Y,MAAgB;AACnC,MAAA9Y,EAAK,QAAQ8Y,GACbwC,EAAK,QAAQxC,GACbwC,EAAK,UAAU,OAAO,6BAA6B,GACnDA,EAAK,QAAQ,IACbkW,IAAY1Y;AAAA,IACd,GAEM8Y,IAAa,CAAC9Y,MAAgB;AAClC,MAAA6Y,EAAY7Y,CAAG,GACfiV,EAASjV,CAAG;AAAA,IACd;AAEA,WAAAuC,GAAqBC,GAAM;AAAA,MACzB,UAAU,MAAMtb,EAAK,MAAM,KAAA,KAAUsb,EAAK;AAAA,MAC1C,aAAA6L;AAAA,MACA,YAAY;AAAA,MACZ,GAAG,KAAK,KAAK;AAAA,MACb,WAAWwK;AAAA,MACX,UAAUC;AAAA,MACV,SAAS,MAAM;AACb,QAAAF,EAAY,EAAE,GACdF,IAAY,IACZzD,EAAS,EAAE;AAAA,MACb;AAAA,IAAA,CACD,GAED/tB,EAAK,iBAAiB,SAAS,MAAM;AACnC,YAAMuH,IAAMvH,EAAK,OACX8Y,IAAMN,EAAmBjR,CAAG;AAClC,MAAIuR,KACFwC,EAAK,QAAQxC,GACbwC,EAAK,UAAU,OAAO,6BAA6B,GACnDA,EAAK,QAAQ,IACbkW,IAAY1Y,KACFvR,EAAI,WACdkqB,EAAA,GACAD,IAAY,KAEdzD,EAASxmB,CAAG;AAAA,IACd,CAAC,GAEDvH,EAAK,iBAAiB,QAAQ,MAAM;AAClC,YAAMuH,IAAMvH,EAAK,MAAM,KAAA;AACvB,UAAI,CAACuH,GAAK;AACR,QAAAmqB,EAAY,EAAE,GACdF,IAAY,IACZzD,EAAS,EAAE;AACX;AAAA,MACF;AACA,YAAMjV,IAAMN,EAAmBjR,CAAG;AAClC,UAAIuR,GAAK;AACP,QAAA4Y,EAAY5Y,CAAG,GACf0Y,IAAY1Y,GACRA,MAAQvR,KAAKwmB,EAASjV,CAAG;AAC7B;AAAA,MACF;AACA,MAAA4Y,EAAYF,CAAS,GACrBzD,EAASyD,CAAS;AAAA,IACpB,CAAC,GAEMxnB,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDnD,EAAE,OAAO,EAAE,OAAO,kBAAkB,CAACsR,GAAMtb,CAAI,CAAC;AAAA,IAAA,CACjD;AAAA,EACH;AAAA,EACQ,aACNmN,GACAvE,GACAoL,GACA+Z,GACAiC,GACA;AACA,UAAMnwB,IAAMmK,EAAE,UAAU;AAAA,MACtB,OAAO;AAAA,MACP,GAAIgmB,IAAa,EAAE,iBAAiBA,EAAA,IAAe,CAAA;AAAA,MACnD,UAAU,CAAC1e,MAAayc,EAAUzc,EAAE,OAA6B,KAAK;AAAA,IAAA,CACvE;AACD,eAAWke,KAAKxb,GAAS;AACvB,YAAMoT,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,QAAQoI,EAAE,OACdpI,EAAI,cAAcoI,EAAE,OAChBA,EAAE,UAAU5mB,MAAOwe,EAAI,WAAW,KACtCvnB,EAAI,OAAOunB,CAAG;AAAA,IAChB;AACA,WAAOpd,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDtN;AAAA,IAAA,CACD;AAAA,EACH;AAAA;AAAA,EAGQ,wBAAwB3C,GAA4B;AAC1D,UAAM20B,IAAU,OAAO5oB,GAA0B/L,EAAI,MAAM,CAAC,GACtD8W,IAAUjN,GAAuB,IAAI,CAACE,OAAQ;AAAA,MAClD,OAAO,OAAOA,CAAE;AAAA,MAChB,OAAO,OAAOA,CAAE;AAAA,IAAA,EAChB,GACI0nB,IAAO3kB,EAAE,OAAO,EAAE,OAAO,oBAAoB;AAAA,MACjD,KAAK,KAAK,EAAE,+BAA+B;AAAA,IAAA,CAC5C,GACKwjB,IAAQ,KAAK;AAAA,MACjB,KAAK,KAAK,EAAE,2BAA2B;AAAA,MACvCqE;AAAA,MACA7d;AAAA,MACA,CAAC3L,MACC,KAAK,KAAK,MAAM,OAAO,CAACjM,MAAM;AAC5B,cAAM6xB,IAASjnB,GAAiC,OAAOqB,CAAC,CAAC;AACzD,QAAI4lB,MAAW,SAAW,OAAO7xB,EAAE,OAAO,sBACrCA,EAAE,OAAO,sBAAsB6xB;AAAA,MACtC,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IAAA;AAEF,WAAAT,EAAM,OAAOmB,CAAI,GACVnB;AAAA,EACT;AAAA;AAAA,EAGQ,sBACNrgB,GACAvE,GACAoL,GACA+Z,GACAiC,GACAtO,IAAO,IACP;AACA,UAAMzb,IAAQ+D,EAAE,OAAO;AAAA,MACrB,OAAO,kCAAkC0X,IAAO,wBAAwB,EAAE;AAAA,MAC1E,MAAM;AAAA,MACN,cAAcvU;AAAA,IAAA,CACf;AACD,eAAWqiB,KAAKxb,GAAS;AACvB,YAAMsJ,IAASkS,EAAE,UAAU5mB;AAC3B,MAAA3C,EAAM;AAAA,QACJ+D;AAAA,UACE;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO,qBAAqBsT,IAAS,gCAAgC,EAAE;AAAA,YACvE,gBAAgBA,IAAS,SAAS;AAAA,YAClC,OAAOkS,EAAE;AAAA,YACT,GAAIQ,IAAa,EAAE,iBAAiB,GAAGA,CAAU,IAAIR,EAAE,KAAK,GAAA,IAAO,CAAA;AAAA,YACnE,SAAS,MAAMzB,EAASyB,EAAE,KAAK;AAAA,UAAA;AAAA,UAEjC,CAACA,EAAE,KAAK;AAAA,QAAA;AAAA,MACV;AAAA,IAEJ;AACA,WAAOxlB,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDlH;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EACQ,aACNkH,GACAvE,GACAmlB,GACAY,GACAqB,GACa;AACb,UAAMvD,IAAMziB,EAAE,SAAS;AAAA,MACrB,OAAO;AAAA,MACP,OAAO;AAAA,IAAA,GACN;AAAA,MACDA,EAAE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,GAAIgmB,IAAa,EAAE,iBAAiBA,EAAA,IAAe,CAAA;AAAA,QACnD,UAAU,CAAC1e,MAAayc,EAAUzc,EAAE,OAA4B,OAAO;AAAA,QACvE,GAAI1I,IAAQ,EAAE,SAAS,OAAS,CAAA;AAAA,MAAC,CAC3B;AAAA,MACRoB,EAAE,QAAQ,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,IAAA,CAChD;AACD,WAAKwhB,IACE3kB,EAAE,OAAO,EAAE,OAAO,YAAY,OAAO,2DAA2D;AAAA,MACrGyiB;AAAA,MACAziB,EAAE,OAAO,EAAE,OAAO,oBAAoB,CAAC2kB,CAAI,CAAC;AAAA,IAAA,CAC7C,IAJiBlC;AAAA,EAKpB;AAAA,EACQ,cACNtf,GACA,CAACxB,GAAGoN,GAAGrU,GAAGoM,CAAC,GACXid,GACAa,GACAL,GACA;AACA,UAAMuD,IAAS;AAAA,MACb,KAAK,KAAK,EAAE,wBAAwB;AAAA,MACpC,KAAK,KAAK,EAAE,0BAA0B;AAAA,MACtC,KAAK,KAAK,EAAE,2BAA2B;AAAA,MACvC,KAAK,KAAK,EAAE,yBAAyB;AAAA,IAAA,GAEjCC,IAAW,CAAC7qB,MAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAMA,CAAC,CAAC,CAAC,GAGlE2qB,IAAoB;AAAA,MACxBE,EAAS,OAAOpmB,KAAK,CAAC,CAAC;AAAA,MACvBomB,EAAS,OAAOhZ,KAAK,CAAC,CAAC;AAAA,MACvBgZ,EAAS,OAAOrtB,KAAK,CAAC,CAAC;AAAA,MACvBqtB,EAAS,OAAOjhB,KAAK,CAAC,CAAC;AAAA,IAAA,GAEnBkhB,IAAO,MAAMjE,EAAS,CAAC,GAAG8D,CAAO,CAAC,GAElCI,IAAY,CAAC5pB,GAAuBH,MAAgB;AACxD,YAAMunB,IAAMzlB,EAAE,SAAS;AAAA,QACrB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,OAAO,OAAO3B,KAAK,CAAC;AAAA,QACpB,OAAOypB,EAAO5pB,CAAG;AAAA,QACjB,GAAI0mB,IAAc,EAAE,iBAAiB,GAAGA,CAAW,IAAI1mB,CAAG,OAAO,CAAA;AAAA,MAAC,CACnE;AACD,aAAAunB,EAAI,iBAAiB,SAAS,MAAM;AAClC,cAAM9jB,IAAI8jB,EAAI,MAAM,KAAA;AACpB,YAAI9jB,MAAM,GAAI;AACd,cAAMpE,IAAM,OAAOoE,CAAC;AACpB,QAAI,OAAO,MAAMpE,CAAG,MACpBsqB,EAAQ3pB,CAAG,IAAI6pB,EAASxqB,CAAG,GAC3ByqB,EAAA;AAAA,MACF,CAAC,GACDvC,EAAI,iBAAiB,QAAQ,MAAM;AACjC,cAAM9jB,IAAI8jB,EAAI,MAAM,KAAA;AACpB,YAAI9jB,MAAM,IAAI;AACZ,UAAA8jB,EAAI,QAAQ,OAAOoC,EAAQ3pB,CAAG,CAAC;AAC/B;AAAA,QACF;AACA,cAAMX,IAAM,OAAOoE,CAAC,GACdnJ,IAAIuvB,EAAS,OAAO,MAAMxqB,CAAG,IAAIsqB,EAAQ3pB,CAAG,IAAIX,CAAG;AACzD,QAAAkoB,EAAI,QAAQ,OAAOjtB,CAAC,GACpBqvB,EAAQ3pB,CAAG,IAAI1F,GACfwvB,EAAA;AAAA,MACF,CAAC,GACDvC,EAAI,iBAAiB,WAAW,CAACne,MAAM;AACrC,QAAKA,EAAoB,QAAQ,WAASme,EAAI,KAAA;AAAA,MAChD,CAAC,GACMA;AAAA,IACT,GAEMyC,IAAgB,CAAC7pB,GAAuBH,MAAgB;AAC5D,YAAM+mB,IAAM8C,EAAS1pB,KAAK,CAAC,GACrBjJ,IAAQ4K,EAAE,SAAS;AAAA,QACvB,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO,OAAOilB,CAAG;AAAA,QACjB,OAAO6C,EAAO5pB,CAAG;AAAA,MAAA,CAClB;AAED,MAAA9I,EAAM,iBAAiB,SAAS,MAAM;AACpC,cAAMoD,IAAIuvB,EAAS,OAAO3yB,EAAM,KAAK,CAAC;AACtC,QAAAyyB,EAAQ3pB,CAAG,IAAI1F,GACfwd,EAAI,QAAQ,OAAOxd,CAAC,GACpBwvB,EAAA;AAAA,MACF,CAAC;AAED,YAAMhS,IAAMhW,EAAE,SAAS;AAAA,QACrB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,OAAO,OAAOilB,CAAG;AAAA,QACjB,OAAO6C,EAAO5pB,CAAG;AAAA,QACjB,GAAI0mB,IAAc,EAAE,iBAAiB,GAAGA,CAAW,IAAI1mB,CAAG,OAAO,CAAA;AAAA,MAAC,CACnE;AAED,aAAA8X,EAAI,iBAAiB,SAAS,MAAM;AAClC,cAAMrU,IAAIqU,EAAI,MAAM,KAAA;AACpB,YAAIrU,MAAM,GAAI;AACd,cAAMwmB,IAAO,OAAOxmB,CAAC;AACrB,YAAI,OAAO,MAAMwmB,CAAI,EAAG;AACxB,cAAM3vB,IAAIuvB,EAASI,CAAI;AACvB,QAAA/yB,EAAM,QAAQ,OAAOoD,CAAC,GACtBqvB,EAAQ3pB,CAAG,IAAI1F,GACfwvB,EAAA;AAAA,MACF,CAAC,GAEDhS,EAAI,iBAAiB,QAAQ,MAAM;AACjC,cAAMrU,IAAIqU,EAAI,MAAM,KAAA;AACpB,YAAIrU,MAAM,IAAI;AACZ,UAAAqU,EAAI,QAAQ,OAAO6R,EAAQ3pB,CAAG,CAAC,GAC/B9I,EAAM,QAAQ,OAAOyyB,EAAQ3pB,CAAG,CAAC;AACjC;AAAA,QACF;AACA,cAAMiqB,IAAO,OAAOxmB,CAAC,GACfnJ,IAAIuvB,EAAS,OAAO,MAAMI,CAAI,IAAIN,EAAQ3pB,CAAG,IAAIiqB,CAAI;AAC3D,QAAAnS,EAAI,QAAQ,OAAOxd,CAAC,GACpBpD,EAAM,QAAQ,OAAOoD,CAAC,GACtBqvB,EAAQ3pB,CAAG,IAAI1F,GACfwvB,EAAA;AAAA,MACF,CAAC,GAEDhS,EAAI,iBAAiB,WAAW,CAAC1O,MAAM;AACrC,QAAKA,EAAoB,QAAQ,WAAS0O,EAAI,KAAA;AAAA,MAChD,CAAC,GAEMhW,EAAE,OAAO,EAAE,OAAO,oBAAoB;AAAA,QAC3CA,EAAE,QAAQ,EAAE,OAAO,uBAAA,GAA0B,CAAC8nB,EAAO5pB,CAAG,CAAC,CAAC;AAAA,QAC1D9I;AAAA,QACA4gB;AAAA,MAAA,CACD;AAAA,IACH;AAEA,WAAOhW,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MACrCA,EAAE,OAAO,EAAE,OAAO,iCAAiC;AAAA,QACjDA,EAAE,SAAS,EAAE,OAAO,kBAAA,GAAqB,CAAC,GAAGmD,CAAK,GAAG,KAAK,KAAK,EAAE,2BAA2B,CAAC,EAAE,CAAC;AAAA,QAChGohB,IACIvkB;AAAA,UACE;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS,MAAM;AACb,oBAAMlL,IAAOyvB,EAAU,IAAI,CAACrnB,MAAM6qB,EAAS,OAAO7qB,CAAC,CAAC,CAAC;AACrD,uBAAStG,IAAI,GAAGA,IAAI,GAAGA,IAAK,CAAAixB,EAAQjxB,CAAC,IAAI9B,EAAK8B,CAAC;AAC/C,cAAAmtB,EAAS,CAAC,GAAG8D,CAAO,CAAC;AAAA,YACvB;AAAA,UAAA;AAAA,UAEF,CAAC,KAAK,KAAK,EAAE,0BAA0B,CAAC;AAAA,QAAA,IAE1C;AAAA,MAAA,CACL;AAAA,MACD,KAAK,0BACD7nB;AAAA,QACE;AAAA,QACA,EAAE,OAAO,kBAAA;AAAA,QACT,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC9B,MAAQgqB,EAAc,CAACvmB,GAAGoN,GAAGrU,GAAGoM,CAAC,EAAE5I,CAAG,GAAGA,CAAG,CAAC;AAAA,MAAA,IAEjE8B;AAAA,QACE;AAAA,QACA,EAAE,OAAO,kBAAA;AAAA,QACT,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC9B,MAAQ+pB,EAAU,CAACtmB,GAAGoN,GAAGrU,GAAGoM,CAAC,EAAE5I,CAAG,GAAGA,CAAG,CAAC;AAAA,MAAA;AAAA,IAC7D,CACL;AAAA,EACH;AAAA;AAAA,EAGQ,qBACNkqB,GACAC,GACAC,GACAtC,GAC0E;AAC1E,UAAMrmB,IAAQK,EAAE,SAAS;AAAA,MACvB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,MACN,GAAIgmB,IAAa,EAAE,iBAAiBA,EAAA,IAAe,CAAA;AAAA,MACnD,GAAIoC,IAAY,EAAE,SAAS,OAAS,CAAA;AAAA,IAAC,CACtC,GACKG,IAAUvoB,EAAE,QAAQ;AAAA,MACxB,OAAO;AAAA,MACP,QAAQ,CAACooB;AAAA,IAAA,GACR,CAACC,CAAa,CAAC,GACZv0B,IAAKkM,EAAE,OAAO,EAAE,OAAO,uBAAuB;AAAA,MAClDA,EAAE,SAAS,EAAE,OAAO,8BAA8B;AAAA,QAChDL;AAAA,QACAK,EAAE,QAAQ,EAAE,OAAO,0BAAA,GAA6B,CAAC,KAAK,KAAK,EAAE,0BAA0B,CAAC,CAAC;AAAA,MAAA,CAC1F;AAAA,MACDuoB;AAAA,IAAA,CACD;AACD,WAAA5oB,EAAM,iBAAiB,UAAU,MAAM2oB,EAAS3oB,EAAM,OAAO,CAAC,GAMvD,EAAE,IAAA7L,GAAI,YALM,CAACqqB,GAAaqK,MAAqB;AACpD,MAAA7oB,EAAM,UAAUwe,GACZqK,MAAY,WAAWD,EAAQ,cAAcC,IACjDD,EAAQ,SAAS,CAACpK;AAAA,IACpB,EACa;AAAA,EACf;AAAA,EAEQ,wBACNhb,GACA8gB,GACAwE,GACA1E,GACAiC,GACAhc,GACA2a,GACa;AACb,QAAI+D,IAAa,CAACzE;AAClB,UAAMhoB,IAAQ+D,EAAE,OAAO;AAAA,MACrB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,cAAcmD;AAAA,IAAA,CACf,GAEKwlB,IAAY,MAAM;AACtB,MAAA1sB,EAAM,UAAU,OAAO,0BAA0BysB,CAAU;AAC3D,YAAMF,IAAUE,IAAa,KAAKloB,EAAwByjB,KAAUwE,CAAY;AAChF,MAAAtoB,EAAMlE,CAAK;AACX,iBAAWupB,KAAKxb,GAAS;AACvB,cAAMsJ,IAAS,CAACoV,KAAclD,EAAE,UAAUgD;AAC1C,QAAAvsB,EAAM;AAAA,UACJ+D;AAAA,YACE;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,OAAO,qBAAqBsT,IAAS,gCAAgC,EAAE;AAAA,cACvE,gBAAgBA,IAAS,SAAS;AAAA,cAClC,OAAOkS,EAAE;AAAA,cACT,GAAIQ,IAAa,EAAE,iBAAiB,GAAGA,CAAU,IAAIR,EAAE,KAAK,GAAA,IAAO,CAAA;AAAA,cACnE,SAAS,MAAM;AACb,gBAAAkD,IAAa,IACbzE,IAASuB,EAAE,OACXoD,EAAc,WAAW,EAAK,GAC9BD,EAAA,GACA5E,EAASyB,EAAE,KAAK;AAAA,cAClB;AAAA,YAAA;AAAA,YAEF,CAACA,EAAE,KAAK;AAAA,UAAA;AAAA,QACV;AAAA,MAEJ;AAAA,IACF,GAEMoD,IAAgB,KAAK;AAAA,MACzBF;AAAA,MACAD;AAAA,MACA,CAACtK,MAAO;AACN,YAAIA,GAAI;AACN,UAAAuK,IAAa,IACbzE,IAAS,IACT2E,EAAc,WAAW,IAAMH,CAAY,GAC3CE,EAAA,GACA5E,EAAS,EAAE;AACX;AAAA,QACF;AACA,QAAA2E,IAAa,IACbzE,IAASwE,GACTG,EAAc,WAAW,EAAK,GAC9BD,EAAA,GACA5E,EAAS0E,CAAY;AAAA,MACvB;AAAA,MACA,GAAGzC,CAAU;AAAA,IAAA;AAGf,IAAA2C,EAAA;AAEA,UAAMjR,IAAO1X,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MAC3CA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDylB,EAAc;AAAA,MACd3sB;AAAA,IAAA,CACD;AACD,WAAI0oB,KAAMjN,EAAK,OAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC5DjN;AAAA,EACT;AAAA,EAEQ,0BACNvU,GACA8gB,GACAF,GACAiC,GACA6C,GACAlE,GACa;AACb,UAAMmE,IAAW,KAAK,kBAAkBD,CAAc;AACtD,QAAIH,IAAa,CAACzE,EAAO,KAAA;AACzB,UAAMtkB,IAAQK,EAAE,SAAS;AAAA,MACvB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,GAAIgmB,IAAa,EAAE,iBAAiBA,MAAe,CAAA;AAAA,IAAC,CACrD,GAEK+C,IAAY,MAAM;AACtB,MAAAppB,EAAM,WAAW+oB,GACjB/oB,EAAM,QAAQ+oB,IAAa,KAAKzE,GAChCtkB,EAAM,cAAc+oB,IAAa,KAAK,KAAK,KAAK,EAAE,iCAAiC,GACnF/oB,EAAM,UAAU,OAAO,8BAA8B+oB,CAAU;AAAA,IACjE,GAEME,IAAgB,KAAK;AAAA,MACzBF;AAAA,MACA,GAAGI,CAAQ;AAAA,MACX,CAAC3K,MAAO;AACN,YAAIA,GAAI;AACN,UAAAuK,IAAa,IACbzE,IAAS,IACT2E,EAAc,WAAW,IAAM,GAAGE,CAAQ,IAAI,GAC9CC,EAAA,GACAhF,EAAS,EAAE;AACX;AAAA,QACF;AACA,QAAA2E,IAAa,IACbzE,IAAS,GAAG6E,CAAQ,MACpBF,EAAc,WAAW,EAAK,GAC9BG,EAAA,GACAhF,EAASE,CAAM;AAAA,MACjB;AAAA,MACA,GAAG+B,CAAU;AAAA,IAAA;AAGf,IAAA+C,EAAA,GAEAppB,EAAM,iBAAiB,SAAS,MAAM;AACpC,MAAI+oB,MACJzE,IAAStkB,EAAM,OACfokB,EAASE,CAAM;AAAA,IACjB,CAAC,GAEDtkB,EAAM,iBAAiB,QAAQ,MAAM;AACnC,UAAI+oB,EAAY;AAEhB,MADU/oB,EAAM,MAAM,KAAA,MAEpBskB,IAAS,GAAG6E,CAAQ,MACpBnpB,EAAM,QAAQskB,GACdF,EAASE,CAAM;AAAA,IAEnB,CAAC;AAED,UAAMvM,IAAO1X,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MAC3CA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDylB,EAAc;AAAA,MACdjpB;AAAA,IAAA,CACD;AACD,WAAIglB,KAAMjN,EAAK,OAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC5DjN;AAAA,EACT;AAAA,EAEQ,kBAAkB9Y,GAAuB;AAE/C,UAAMrH,KADKqH,KAAS,IAAI,KAAA,EACZ,MAAM,gBAAgB;AAClC,WAAIrH,IAAU,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,MAAM,WAAWA,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAC9D;AAAA,EACT;AAAA,EAEQ,qBACN4L,GACAvE,GACAmlB,GACAiC,GACArB,GACAkE,GACA;AACA,UAAMG,IAAgBH,MAAmB;AACzC,QAAI,CAAC,KAAK;AACR,aAAIG,IACK,KAAK;AAAA,QACV7lB;AAAA,QACAvE;AAAA,QACAmlB;AAAA,QACAiC;AAAA,QACA6C;AAAA,QACAlE;AAAA,MAAA,IAGG,KAAK,WAAWxhB,GAAOvE,KAAS,IAAImlB,GAAU,IAAIiC,CAAU;AAGrE,UAAMe,IAAM,IACNC,IAAM,IACNzI,IAAO,GACP0I,IAAO,CAAC/pB,MAAc,KAAK,IAAI8pB,GAAK,KAAK,IAAID,GAAK,KAAK,MAAM7pB,CAAC,CAAC,CAAC,GAChE4rB,IAAW7B,EAAK,KAAK,kBAAkB4B,KAAkBjqB,KAAS,MAAM,CAAC;AAC/E,QAAIqlB,IAASrlB,EAAM,KAAA,GACf8pB,IAAaM,KAAiB,CAAC/E;AAEnC,UAAMgF,IAAYjpB,EAAE,OAAO,EAAE,OAAO,wBAAwB,GACtD5K,IAAQ4K,EAAE,SAAS;AAAA,MACvB,MAAM;AAAA,MACN,KAAA+mB;AAAA,MACA,KAAAC;AAAA,MACA,MAAAzI;AAAA,IAAA,CACD,GACKvI,IAAMhW,EAAE,SAAS;AAAA,MACrB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAA+mB;AAAA,MACA,KAAAC;AAAA,MACA,MAAAzI;AAAA,MACA,iBAAiByH;AAAA,IAAA,CAClB;AACD,IAAAiD,EAAU,OAAO7zB,GAAO4gB,CAAG;AAE3B,UAAMkT,IAAa,MAAM;AAGvB,UAFAD,EAAU,UAAU,OAAO,iCAAiCP,CAAU,GACtE1S,EAAI,WAAW0S,GACXA;AACF,QAAAtzB,EAAM,QAAQ,OAAO0zB,CAAQ,GAC7B9S,EAAI,QAAQ;AAAA,WACP;AACL,cAAMxY,IAAIypB,EAAK,KAAK,kBAAkBhD,KAAU,GAAG6E,CAAQ,IAAI,CAAC;AAChE,QAAA1zB,EAAM,QAAQ,OAAOoI,CAAC,GACtBwY,EAAI,QAAQ,OAAOxY,CAAC;AAAA,MACtB;AAAA,IACF;AAEA,QAAIorB,IAAuE;AAC3E,IAAII,MACFJ,IAAgB,KAAK;AAAA,MACnBF;AAAA,MACA,GAAGI,CAAQ;AAAA,MACX,CAAC3K,MAAO;AACN,YAAIA,GAAI;AACN,UAAAuK,IAAa,IACbzE,IAAS,IACT2E,EAAe,WAAW,IAAM,GAAGE,CAAQ,IAAI,GAC/CI,EAAA,GACAnF,EAAS,EAAE;AACX;AAAA,QACF;AACA,QAAA2E,IAAa,IACbzE,IAAS,GAAG6E,CAAQ,MACpBF,EAAe,WAAW,EAAK,GAC/BM,EAAA,GACAnF,EAASE,CAAM;AAAA,MACjB;AAAA,MACA,GAAG+B,CAAU;AAAA,IAAA,IAIjBkD,EAAA;AAEA,UAAMC,IAAe,MAAM;AACzB,MAAKT,MACLA,IAAa,IACbE,KAAA,QAAAA,EAAe,WAAW,KAC1BM,EAAA;AAAA,IACF;AAEA,IAAA9zB,EAAM,iBAAiB,SAAS,MAAM;AACpC,MAAA+zB,EAAA;AACA,YAAM3rB,IAAIypB,EAAK,OAAO7xB,EAAM,KAAK,CAAC;AAClC,MAAA4gB,EAAI,QAAQ,OAAOxY,CAAC,GACpBymB,IAAS,GAAGzmB,CAAC,MACbumB,EAASE,CAAM;AAAA,IACjB,CAAC,GAEDjO,EAAI,iBAAiB,SAAS,MAAM;AAClC,UAAI0S,EAAY;AAChB,YAAMP,IAAO,OAAOnS,EAAI,KAAK;AAC7B,MAAI,OAAO,MAAMmS,CAAI,MACrB/yB,EAAM,QAAQ,OAAO6xB,EAAKkB,CAAI,CAAC;AAAA,IACjC,CAAC,GAEDnS,EAAI,iBAAiB,QAAQ,MAAM;AACjC,UAAI0S,EAAY;AAChB,YAAM/mB,IAAIqU,EAAI,MAAM,KAAA,GACdmR,IAAKF,EAAK,OAAO7xB,EAAM,KAAK,CAAC,GAC7BoI,IAAIypB,EAAKtlB,MAAM,MAAM,OAAO,MAAM,OAAOA,CAAC,CAAC,IAAIwlB,IAAK,OAAOxlB,CAAC,CAAC;AACnE,MAAAsiB,IAAS,GAAGzmB,CAAC,MACbwY,EAAI,QAAQ,OAAOxY,CAAC,GACpBpI,EAAM,QAAQ,OAAOoI,CAAC,GACtBumB,EAASE,CAAM;AAAA,IACjB,CAAC,GAEDjO,EAAI,iBAAiB,WAAW,CAAC1O,MAAM;AACrC,MAAKA,EAAoB,QAAQ,WAAS0O,EAAI,KAAA;AAAA,IAChD,CAAC;AAED,UAAM0B,IAAO1X,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MAC3CA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChD,GAAIylB,IAAgB,CAACA,EAAc,EAAE,IAAI,CAAA;AAAA,MACzCK;AAAA,IAAA,CACD;AACD,WAAItE,KAAMjN,EAAK,OAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC5DjN;AAAA,EACT;AAAA,EAEQ,kBAAkB9Y,GAAemlB,GAA+BiC,GAAoB;AAC1F,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,EAAE,yBAAyB;AAAA,MACrCpnB;AAAA,MACAmlB;AAAA,MACAiC;AAAA,MACA,KAAK,KAAK,EAAE,6BAA6B;AAAA,IAAA;AAAA,EAE7C;AAAA,EAEQ,kBACN7iB,GACA5F,GACAwmB,GACAiC,GACArB,GACA;AACA,QAAI,CAAC,KAAK,yBAAyB;AACjC,YAAMyE,IAAK,KAAK,WAAWjmB,GAAO5F,GAAKwmB,GAAU,IAAIiC,CAAU;AAC/D,aAAIrB,KAAMyE,EAAG,OAAOppB,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC1DyE;AAAA,IACT;AAEA,UAAM5f,IAAOmZ,GAAoBplB,CAAG;AACpC,QAAIiM,MAAS,UAAU;AACrB,YAAMkO,IAAO1X,EAAE,OAAO,EAAE,OAAO,YAAY;AAC3C0X,aAAAA,EAAK,OAAO1X,EAAE,SAAS,EAAE,OAAO,kBAAA,GAAqB,CAACmD,CAAK,CAAC,CAAC,GAC7DuU,EAAK;AAAA,QACH1X,EAAE,OAAO,EAAE,OAAO,oBAAoB;AAAA,UACpC,KAAK,KAAK,EAAE,6BAA6B;AAAA,QAAA,CAC1C;AAAA,MAAA,GAEH0X,EAAK;AAAA,QACH1X,EAAE,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM;AAAA,UACN,OAAOzC;AAAA,UACP,aAAa,KAAK,KAAK,EAAE,oCAAoC;AAAA,UAC7D,iBAAiByoB;AAAA,UACjB,SAAS,CAAC1e,MAAayc,EAAUzc,EAAE,OAA4B,KAAK;AAAA,QAAA,CACrE;AAAA,MAAA,GAECqd,KAAMjN,EAAK,OAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC5DjN;AAAAA,IACT;AAEA,UAAM9E,IAA4BpJ,GAC5Bwd,IAAMpU,MAAS,MAAM,MAAM,MAC3BmU,IAAM,GACNsC,IAAWzW,MAAS,SAAS,MAAMgQ,GAAmBrlB,GAAKqV,MAAS,MAAM,MAAM,IAAI,GAEpF0W,IAAS,CAACpsB,MAAc,KAAK,IAAI6pB,GAAK,KAAK,IAAIC,GAAK,KAAK,MAAM9pB,CAAC,CAAC,CAAC,GAElE9H,IAAQ4K,EAAE,SAAS;AAAA,MACvB,MAAM;AAAA,MACN,KAAA+mB;AAAA,MACA,KAAAC;AAAA,MACA,MAAM;AAAA,MACN,OAAO,OAAOqC,CAAQ;AAAA,MACtB,UAAUzW,MAAS;AAAA,IAAA,CACpB,GAEKoD,IAAMhW,EAAE,SAAS;AAAA,MACrB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAA+mB;AAAA,MACA,KAAAC;AAAA,MACA,MAAM;AAAA,MACN,OAAO,OAAOqC,CAAQ;AAAA,MACtB,UAAUzW,MAAS;AAAA,MACnB,GAAIoT,IAAa,EAAE,iBAAiBA,MAAe,CAAA;AAAA,IAAC,CACrD,GAEKuD,IAAQ,CAAC/wB,MAAc;AAC3B,YAAM,IAAI8wB,EAAO9wB,CAAC;AAClB,MAAApD,EAAM,QAAQ,OAAO,CAAC,GACtB4gB,EAAI,QAAQ,OAAO,CAAC,GACpB+N,EAASnR,MAAS,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI;AAAA,IAC5C;AAEA,IAAAxd,EAAM,iBAAiB,SAAS,MAAM;AACpC,MAAIwd,MAAS,UACb2W,EAAM,OAAOn0B,EAAM,KAAK,CAAC;AAAA,IAC3B,CAAC,GAED4gB,EAAI,iBAAiB,SAAS,MAAM;AAClC,UAAIpD,MAAS,OAAQ;AACrB,YAAMjR,IAAIqU,EAAI,MAAM,KAAA;AACpB,UAAIrU,MAAM,GAAI;AACd,YAAMwmB,IAAO,OAAOxmB,CAAC;AACrB,MAAI,OAAO,MAAMwmB,CAAI,MACrB/yB,EAAM,QAAQ,OAAOk0B,EAAOnB,CAAI,CAAC;AAAA,IACnC,CAAC,GAEDnS,EAAI,iBAAiB,QAAQ,MAAM;AACjC,UAAIpD,MAAS,OAAQ;AACrB,YAAMjR,IAAIqU,EAAI,MAAM,KAAA,GACdmR,IAAKmC,EAAO,OAAOl0B,EAAM,KAAK,CAAC;AACrC,UAAIuM,MAAM,IAAI;AACZ,QAAA4nB,EAAMpC,CAAE;AACR;AAAA,MACF;AACA,YAAMgB,IAAO,OAAOxmB,CAAC;AACrB,MAAA4nB,EAAM,OAAO,MAAMpB,CAAI,IAAIhB,IAAKgB,CAAI;AAAA,IACtC,CAAC,GAEDnS,EAAI,iBAAiB,WAAW,CAAC1O,MAAM;AACrC,MAAIsL,MAAS,UACRtL,EAAoB,QAAQ,WAAS0O,EAAI,KAAA;AAAA,IAChD,CAAC;AAED,UAAMiT,IAAYjpB;AAAA,MAChB;AAAA,MACA,EAAE,OAAO,8BAA8B4S,MAAS,SAAS,gBAAgB,EAAE,GAAA;AAAA,MAC3E,CAACxd,GAAO4gB,CAAG;AAAA,IAAA,GAGPwT,IAAYxpB,EAAE,OAAO,EAAE,OAAO,yDAAyD,GACvFypB,IAAa,CAAClyB,GAAwBvB,MAAiB;AAC3D,MAAAwzB,EAAU;AAAA,QACRxpB;AAAA,UACE;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO,sBAAsB4S,MAASrb,IAAI,+BAA+B,EAAE;AAAA,YAC3E,SAAS,MAAM;AACb,cAAkBwsB,EAAdxsB,MAAM,SAAiB,KAClBA,MAAM,OAAe,GAAGqrB,GAAmBrlB,GAAK,IAAI,CAAC,OAChD,GAAGqlB,GAAmBrlB,GAAK,GAAG,CAAC,GAFhB;AAAA,YAG/B;AAAA,UAAA;AAAA,UAEF,CAACvH,CAAI;AAAA,QAAA;AAAA,MACP;AAAA,IAEJ;AACA,IAAAyzB,EAAW,QAAQ,KAAK,KAAK,EAAE,uBAAuB,CAAC,GACvDA,EAAW,MAAM,IAAI,GACrBA,EAAW,KAAK,GAAG;AAEnB,UAAM/R,IAAO1X,EAAE,OAAO,EAAE,OAAO,cAAc;AAAA,MAC3CA,EAAE,SAAS,EAAE,OAAO,qBAAqB,CAACmD,CAAK,CAAC;AAAA,MAChDqmB;AAAA,MACAP;AAAA,IAAA,CACD;AACD,WAAItE,KAAMjN,EAAK,OAAO1X,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC2kB,CAAI,CAAC,CAAC,GAC5DjN;AAAA,EACT;AAAA,EAEQ,oBAAoB9Y,GAAemlB,GAA+BiC,GAAoB;AAC5F,UAAMf,IAAMzkB,EAAwB5B,CAAK;AACzC,WAAO,KAAK,sBAAsB,KAAK,KAAK,EAAE,2BAA2B,GAAGqmB,GAAK1kB,IAA0BwjB,GAAUiC,CAAU;AAAA,EACjI;AAAA,EAEQ,wBACNtf,GACAqd,GACAiC,GACA;AACA,WAAO,KAAK;AAAA,MACV,KAAK,KAAK,EAAE,iCAAiC;AAAA,MAC7Ctf;AAAA,MACA;AAAA,QACE,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,MAAQ;AAAA,MAEnC,CAACrI,MAAM0lB,EAAS1lB,CAAkB;AAAA,MAClC2nB;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEQ,qBAAqB/Y,GAA2B;AACtD,UAAMhb,IAAM,KAAK,KAAK,SAAS,IAAIgb,EAAM,IAAI,GACvCrF,IACJqF,EAAM,eACLhb,IAAMA,EAAI,OAAOgb,EAAM,OAAc,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,QAAQ,OAAA,CAAQ,IAAI,KAElFyK,IAAO1X,EAAE,OAAO,EAAE,OAAO,gBAAgB,GAEzC0pB,IAAS1pB,EAAE,OAAO,EAAE,OAAO,0BAA0B;AAAA,MACzDA,EAAE,OAAO,EAAE,OAAO,sBAAA,GAAyB,CAAC,KAAK,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAAA,IAAA,CAClF,GAEK6a,IAAa7a,EAAE,OAAO,EAAE,OAAO,WAAW,GAE1C2pB,IAAO,IAAIxc,GAAW;AAAA,MAC1B,QAAQ0N;AAAA,MACR,OAAOzN,GAAY,OAAO;AAAA,QACxB,KAAKxF;AAAA,QACL,YAAY,CAACyF,IAAYC,GAAA,CAAQ;AAAA,MAAA,CAClC;AAAA,IAAA,CACF;AACD,SAAK,WAAWqc;AAEhB,UAAMjH,IAAU1iB,EAAE,OAAO,EAAE,OAAO,0BAA0B;AAAA,MAC1DA;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,SAAS,MAAM;AACb,iBAAK,KAAK,MAAM,OAAO,CAAC,MAAM;AAC5B,oBAAM8G,IAAIoB,EAAkB,GAAG+E,EAAM,EAAE;AACvC,cAAInG,KAAG,OAAOA,EAAE,MAAM;AAAA,YACxB,CAAC;AAAA,UACH;AAAA,QAAA;AAAA,QAEF,CAAC,KAAK,KAAK,EAAE,gCAAgC,CAAC;AAAA,MAAA;AAAA,MAEhD9G;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,SAAS,MAAM;AACb,kBAAMhK,IAAO2zB,EAAK,MAAM,IAAI,SAAA;AAC5B,iBAAK,KAAK,MAAM,OAAO,CAACv3B,MAAM;AAC5B,oBAAM0U,IAAIoB,EAAkB9V,GAAG6a,EAAM,EAAE;AACvC,cAAInG,MAAGA,EAAE,MAAM,aAAa9Q;AAAA,YAC9B,CAAC;AAAA,UACH;AAAA,QAAA;AAAA,QAEF,CAAC,KAAK,KAAK,EAAE,4BAA4B,CAAC;AAAA,MAAA;AAAA,IAC5C,CACD;AAED,WAAA0hB,EAAK;AAAA,MACHgS;AAAA,MACA7O;AAAA,MACA7a,EAAE,OAAO,EAAE,OAAO,iBAAA,GAAoB,CAAC,KAAK,KAAK,EAAE,sBAAsB,CAAC,CAAC;AAAA,MAC3E0iB;AAAA,IAAA,GAEKhL;AAAA,EACT;AAAA,EAEQ,mBAAmB;AACzB,IAAI,KAAK,aACP,KAAK,SAAS,QAAA,GACd,KAAK,WAAW;AAAA,EAEpB;AACF;ACxqEO,MAAMkS,GAAW;AAAA,EAOtB,YAAY5iB,GAAyB;AANrC,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA,oBAAwB;AACxB,IAAAA,EAAA;AACA,IAAAA,EAAA,YAAwB;AAG9B,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,OAAO,EAAE,OAAO,iBAAiB,GAC7C,KAAK,OAAOA,EAAE,OAAO,EAAE,OAAO,uBAAuB,GACrD,KAAK,QAAA,GACLgH,EAAK,MAAM,UAAU,MAAM;AACzB,MAAI,KAAK,gBAAc,KAAK,cAAA;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AACX,SAAK,cAAA;AAAA,EACP;AAAA,EAEQ,aAAsB;AAC5B,WAAO,KAAK,GAAG,gBAAgB,KAAK,GAAG,iBAAiB,QAAQ,KAAK,GAAG,eAAA,EAAiB,SAAS;AAAA,EACpG;AAAA,EAEQ,UAAU;AAChB,IAAA7G,EAAM,KAAK,EAAE;AACb,UAAM2Y,IAAM9Y,EAAE,OAAO,EAAE,OAAO,wBAAwB;AAAA,MACpD,KAAK,QAAQ,QAAQ,MAAM;AAAA,MAC3B,KAAK,QAAQ,QAAQ,KAAK,KAAK,EAAE,qBAAqB,CAAC;AAAA,MACvDA,EAAE,OAAO,EAAE,OAAO,qBAAqB;AAAA,MACvCA;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,SAAS,MAAM,KAAK,MAAA;AAAA,QAAM;AAAA,QAE5B,CAAC,KAAK,KAAK,EAAE,aAAa,CAAC;AAAA,MAAA;AAAA,IAC7B,CACD;AACD,SAAK,GAAG,OAAO8Y,GAAK,KAAK,IAAI,GAC7B,KAAK,cAAA;AAAA,EACP;AAAA,EAEQ,QAAQqK,GAAgBhgB,GAAe;AAC7C,WAAOnD;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO,sBAAsBmjB,MAAQ,KAAK,aAAa,+BAA+B,EAAE;AAAA,QACxF,MAAM;AAAA,QACN,SAAS,MAAM;AACb,eAAK,aAAaA,GAClB,KAAK,QAAA;AAAA,QACP;AAAA,MAAA;AAAA,MAEF,CAAChgB,CAAK;AAAA,IAAA;AAAA,EAEV;AAAA,EAEQ,gBAAgB;AACtB,SAAK,WAAA,GACLhD,EAAM,KAAK,IAAI;AACf,UAAM6a,IAASjU,GAAU,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,UAAU;AAAA,MAChE,qBAAqB;AAAA,IAAA,CACtB,GACK/Q,IAAO,KAAK,eAAe,SAASglB,EAAO,OAAOA,EAAO;AAC/D,SAAK,KAAK,IAAI7N,GAAW;AAAA,MACvB,QAAQ,KAAK;AAAA,MACb,OAAOC,GAAY,OAAO;AAAA,QACxB,KAAKpX;AAAA,QACL,YAAY,CAACqX,IAAYC,GAAA,GAAUF,GAAY,SAAS,GAAG,EAAI,CAAC;AAAA,MAAA,CACjE;AAAA,IAAA,CACF;AAAA,EACH;AAAA,EAEA,MAAc,QAAQ;AACpB,QAAI,CAAC,KAAK,GAAI;AACd,UAAMpX,IAAO,KAAK,GAAG,MAAM,IAAI,SAAA;AAC/B,QAAI;AACF,YAAM,UAAU,UAAU,UAAUA,CAAI;AAAA,IAC1C,QAAQ;AACN,YAAMilB,IAAK,SAAS,cAAc,UAAU;AAC5C,MAAAA,EAAG,QAAQjlB,GACX,SAAS,KAAK,YAAYilB,CAAE,GAC5BA,EAAG,OAAA,GACHpN,EAAoB,MAAM,GAC1B,SAAS,KAAK,YAAYoN,CAAE;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,aAAa;AACnB,IAAI,KAAK,OACP,KAAK,GAAG,QAAA,GACR,KAAK,KAAK;AAAA,EAEd;AAAA,EAEA,UAAU;AACR,SAAK,WAAA;AAAA,EACP;AACF;AC5EO,MAAM4O,GAAO;AAAA,EAYlB,YAAY7iB,GAAqB;AAXjC,IAAAhV,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,qBAAqD,CAAA;AACrD,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AAGN,SAAK,OAAOgV,GACZ,KAAK,KAAKhH,EAAE,UAAU,EAAE,OAAO,aAAa,GAC5C,KAAK,WAAWgH,EAAK,YAAY,EAAI,GACrC,KAAK,QAAA,GACLA,EAAK,MAAM,UAAU,MAAM,KAAK,OAAO,GACvC,KAAK,MAAA;AAAA,EACP;AAAA;AAAA,EAGA,WAAW8iB,GAAkB;AAC3B,SAAK,GAAG,UAAU,OAAO,sBAAsBA,CAAO;AAAA,EACxD;AAAA,EAEA,QAAQvyB,GAAe;AACrB,SAAK,KAAK,OAAOA;AACjB,eAAW6G,KAAK,CAAC,UAAU,QAAQ;AACjC,WAAK,YAAYA,CAAC,EAAE,UAAU,OAAO,8BAA8BA,MAAM7G,CAAC;AAAA,EAE9E;AAAA,EAEA,UAAU,GAAgB;AACxB,SAAK,KAAK,QAAQ;AAClB,eAAW6G,KAAK,CAAC,SAAS,QAAQ,QAAQ,GAAY;AACpD,YAAM+f,IAAK/f,MAAM;AACjB,WAAK,aAAaA,CAAC,EAAE,UAAU,OAAO,8BAA8B+f,CAAE,GACtE,KAAK,aAAa/f,CAAC,EAAE,aAAa,gBAAgB+f,IAAK,SAAS,OAAO;AAAA,IACzE;AAAA,EACF;AAAA;AAAA,EAGA,mBAAmB;AACjB,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,KAAK,iBAAkB;AACtD,UAAM5gB,IAAM,iBAAiB,KAAK,KAAK,gBAAgB,EAAE,iBAAiB,cAAc,EAAE,KAAA,GACpFwsB,IAAOvb,EAAmBjR,CAAG,KAAKkR,GAAYlR,CAAG;AACvD,QAAI,CAACwsB,EAAM;AACX,UAAMC,IAAOxb,EAAmBub,CAAI;AACpC,QAAI,CAACC,EAAM;AACX,UAAMC,IAAW,IAAID,EAAK,MAAM,CAAC,EAAE,aAAa;AAChD,IAAI,KAAK,YAAY,MAAM,YAAA,MAAkBC,MAAU,KAAK,YAAY,QAAQA;AAAA,EAClF;AAAA;AAAA,EAGA,oBAAoB3W,GAAiB;AACnC,UAAMrC,IAAM,KAAK;AACjB,QAAI,CAACA,EAAK;AACV,IAAAA,EAAI,gBAAgBqC,IAAS4W,GAAA,IAAuBC,IAAqB;AACzE,UAAMje,IAAQoH,IAAS,KAAK,KAAK,EAAE,uBAAuB,IAAI,KAAK,KAAK,EAAE,mBAAmB;AAC7F,IAAArC,EAAI,QAAQ/E,GACZ+E,EAAI,aAAa,cAAc/E,CAAK,GACpC+E,EAAI,aAAa,gBAAgBqC,IAAS,SAAS,OAAO;AAAA,EAC5D;AAAA;AAAA,EAGA,uBAAuBA,GAAiB;AACtC,UAAMrC,IAAM,KAAK;AACjB,QAAI,CAACA,EAAK;AACV,IAAAA,EAAI,aAAa,gBAAgBqC,IAAS,SAAS,OAAO;AAC1D,UAAMpH,IAAQoH,IAAS,KAAK,KAAK,EAAE,0BAA0B,IAAI,KAAK,KAAK,EAAE,0BAA0B;AACvG,IAAArC,EAAI,QAAQ/E,GACZ+E,EAAI,aAAa,cAAc/E,CAAK;AAAA,EACtC;AAAA;AAAA,EAGA,wBAAwBoH,GAAiB;AACvC,UAAMrC,IAAM,KAAK;AACjB,IAAKA,MACLA,EAAI,aAAa,gBAAgBqC,IAAS,SAAS,OAAO,GAC1DrC,EAAI,UAAU,OAAO,iCAAiCqC,CAAM;AAAA,EAC9D;AAAA,EAEQ,UAAU;AAChB,IAAAnT,EAAM,KAAK,EAAE;AACb,UAAM,IAAI,KAAK,KAAK,GAEdiqB,IAAYpqB,EAAE,OAAO,EAAE,OAAO,oCAAoC,MAAM,SAAS,cAAc,EAAE,aAAa,EAAA,CAAG,GACjHqqB,IAAYC,GAAW;AAAA,MAC3B,QAAQ,KAAK,KAAK,SAAS;AAAA,MAC3B,OAAO,EAAE,eAAe;AAAA,MACxB,MAAMC,GAAA;AAAA,MACN,OAAO,EAAE,eAAe;AAAA,MACxB,SAAS,MAAM,KAAK,KAAK,aAAa,QAAQ;AAAA,IAAA,CAC/C,GACKC,IAAYF,GAAW;AAAA,MAC3B,QAAQ,KAAK,KAAK,SAAS;AAAA,MAC3B,OAAO,EAAE,eAAe;AAAA,MACxB,MAAMG,GAAA;AAAA,MACN,OAAO,EAAE,eAAe;AAAA,MACxB,SAAS,MAAM,KAAK,KAAK,aAAa,QAAQ;AAAA,IAAA,CAC/C;AACD,IAAAL,EAAU,OAAOC,GAAWG,CAAS,GACrC,KAAK,cAAc,EAAE,QAAQH,GAAW,QAAQG,EAAA;AAEhD,UAAME,IAAW1qB,EAAE,OAAO;AAAA,MACxB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,cAAc,EAAE,cAAc;AAAA,IAAA,CAC/B,GACK2qB,IAAW,CAACC,GAAoB1e,GAAemS,MACnDre;AAAA,MACE;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAAkM;AAAA,QACA,cAAcA;AAAA,QACd,gBAAgB0e,MAAU,KAAK,KAAK,QAAQ,SAAS;AAAA,QACrD,SAAS,MAAM,KAAK,KAAK,cAAcA,CAAK;AAAA,MAAA;AAAA,MAE9C,CAACvM,CAAI;AAAA,IAAA;AAET,SAAK,eAAe;AAAA,MAClB,OAAOsM,EAAS,SAAS,EAAE,cAAc,GAAGE,IAAS;AAAA,MACrD,MAAMF,EAAS,QAAQ,EAAE,aAAa,GAAGG,IAAU;AAAA,MACnD,QAAQH,EAAS,UAAU,EAAE,eAAe,GAAGI,IAAe;AAAA,IAAA,GAEhEL,EAAS,OAAO,KAAK,aAAa,OAAO,KAAK,aAAa,MAAM,KAAK,aAAa,MAAM;AAEzF,UAAMM,IAAyB,CAACN,CAAQ;AACxC,QAAI,KAAK,KAAK,yBAAyB,KAAK,KAAK,gBAAgB;AAC/D,YAAMO,IAAUjrB,EAAE,SAAS;AAAA,QACzB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,cAAc,EAAE,oBAAoB;AAAA,QACpC,OAAO,EAAE,oBAAoB;AAAA,QAC7B,OAAO;AAAA,MAAA,CACR;AACD,MAAAqR,GAAqB4Z,GAAS;AAAA,QAC5B,WAAW,KAAK,KAAK;AAAA,QACrB,YAAY;AAAA,QACZ;AAAA,QACA,UAAU,CAACnc,MAAQ,KAAK,KAAK,eAAgBA,CAAG;AAAA,MAAA,CACjD,GACD,KAAK,cAAcmc,GACnBD,EAAe,KAAKhrB,EAAE,OAAO,EAAE,OAAO,uBAAuB,CAACirB,CAAO,CAAC,CAAC;AAAA,IACzE;AACE,WAAK,cAAc;AAGrB,SAAK,UAAUC,EAAU;AAAA,MACvB,OAAO;AAAA,MACP,OAAO,EAAE,kBAAkB;AAAA,MAC3B,MAAMC,GAAA;AAAA,MACN,OAAO,EAAE,aAAa;AAAA,MACtB,SAAS,KAAK,KAAK;AAAA,IAAA,CACpB,GACD,KAAK,UAAUD,EAAU;AAAA,MACvB,OAAO;AAAA,MACP,OAAO,EAAE,kBAAkB;AAAA,MAC3B,MAAME,GAAA;AAAA,MACN,OAAO,EAAE,aAAa;AAAA,MACtB,SAAS,KAAK,KAAK;AAAA,IAAA,CACpB;AAED,UAAMC,IAAmC,CAAA;AACzC,IAAI,KAAK,KAAK,0BAA0B,MAAS,OAAO,KAAK,KAAK,iBAAkB,cAClFA,EAAkB;AAAA,MAChBH,EAAU;AAAA,QACR,OAAO;AAAA,QACP,OAAO,EAAE,yBAAyB;AAAA,QAClC,MAAMI,GAAA;AAAA,QACN,OAAO,EAAE,oBAAoB;AAAA,QAC7B,SAAS,MAAM,KAAK,KAAK,cAAA;AAAA,MAAe,CACzC;AAAA,IAAA,GAIH,KAAK,KAAK,2BAA2B,MACrC,OAAO,KAAK,KAAK,kBAAmB,cAEpCD,EAAkB;AAAA,MAChBH,EAAU;AAAA,QACR,OAAO;AAAA,QACP,OAAO,EAAE,0BAA0B;AAAA,QACnC,MAAMK,GAAA;AAAA,QACN,OAAO,EAAE,qBAAqB;AAAA,QAC9B,SAAS,MAAM,KAAK,KAAK,eAAA;AAAA,MAAgB,CAC1C;AAAA,IAAA,GAGD,KAAK,KAAK,4BAA4B,OACpC,OAAO,KAAK,KAAK,mBAAoB,cACvCF,EAAkB;AAAA,MAChBH,EAAU;AAAA,QACR,OAAO;AAAA,QACP,OAAO,EAAE,wBAAwB;AAAA,QACjC,MAAMM,GAAA;AAAA,QACN,OAAO,EAAE,mBAAmB;AAAA,QAC5B,SAAS,MAAM,KAAK,KAAK,gBAAA;AAAA,MAAiB,CAC3C;AAAA,IAAA,GAGD,OAAO,KAAK,KAAK,qBAAsB,cACzCH,EAAkB;AAAA,MAChBH,EAAU;AAAA,QACR,OAAO;AAAA,QACP,OAAO,EAAE,0BAA0B;AAAA,QACnC,MAAMO,GAAA;AAAA,QACN,OAAO,EAAE,qBAAqB;AAAA,QAC9B,SAAS,MAAM,KAAK,KAAK,kBAAA;AAAA,MAAmB,CAC7C;AAAA,IAAA;AAIP,UAAMC,IACJL,EAAkB,SAAS,KAAKrrB,EAAE,OAAO,EAAE,OAAO,mBAAA,GAAsBqrB,CAAiB,GAErFM,IAAaT,EAAU;AAAA,MAC3B,OAAO,EAAE,gBAAgB;AAAA,MACzB,MAAMU,GAAA;AAAA,MACN,OAAO,EAAE,gBAAgB;AAAA,MACzB,SAAS,KAAK,KAAK;AAAA,IAAA,CACpB,GAEKC,IAAYX,EAAU;AAAA,MAC1B,OAAO;AAAA,MACP,OAAO,EAAE,mBAAmB;AAAA,MAC5B,MAAMY,GAAA;AAAA,MACN,OAAO,EAAE,mBAAmB;AAAA,MAC5B,SAAS,KAAK,KAAK;AAAA,IAAA,CACpB,GAEKC,IAAmB,KAAK,KAAK,2BAA2B,IACxDC,IAA+B,CAAA;AACrC,IAAID,KACFC,EAAc;AAAA,MACZd,EAAU;AAAA,QACR,OAAO;AAAA,QACP,OAAO,EAAE,0BAA0B;AAAA,QACnC,MAAMe,GAAA;AAAA,QACN,OAAO,EAAE,qBAAqB;AAAA,QAC9B,SAAS,MAAM,KAAK,KAAK,eAAA;AAAA,MAAe,CACzC;AAAA,IAAA,GAGD,KAAK,KAAK,6BAA6B,KACzCD,EAAc;AAAA,MACX,KAAK,oBAAoBd,EAAU;AAAA,QAClC,OAAO;AAAA,QACP,OAAO,EAAE,uBAAuB;AAAA,QAChC,MAAMgB,GAAA;AAAA,QACN,OAAO,EAAE,uBAAuB;AAAA,QAChC,SAAS,CAAC5kB,MAAa,KAAK,KAAK,iBAAiBA,EAAE,aAA4B;AAAA,MAAA,CACjF;AAAA,IAAA,IAGH,KAAK,oBAAoB,QAE3B0kB,EAAc,KAAKL,GAAYE,CAAS;AAExC,UAAMM,IAAgC,CAAA;AAEtC,IAAI,OAAO,KAAK,KAAK,yBAA0B,aAC7CA,EAAe;AAAA,MACZ,KAAK,mBAAmBC,GAAY;AAAA,QACnC,OAAO;AAAA,QACP,OAAO,EAAE,0BAA0B;AAAA,QACnC,MAAMC,GAAA;AAAA,QACN,SAAS;AAAA,QACT,SAAS,MAAM,KAAK,KAAK,sBAAA;AAAA,MAAuB,CACjD;AAAA,IAAA,IAGH,KAAK,mBAAmB,QAIxB,KAAK,KAAK,yBAAyB,MACnC,OAAO,KAAK,KAAK,sBAAuB,aAExCF,EAAe;AAAA,MACZ,KAAK,gBAAgBC,GAAY;AAAA,QAChC,OAAO;AAAA,QACP,OAAO,EAAE,mBAAmB;AAAA,QAC5B,MAAMjC,GAAA;AAAA,QACN,SAAS;AAAA,QACT,SAAS,MAAM,KAAK,KAAK,mBAAA;AAAA,MAAoB,CAC9C;AAAA,IAAA,IAGH,KAAK,gBAAgB;AAGvB,UAAMmC,IACJH,EAAe,SAAS,KAAKnsB,EAAE,OAAO,EAAE,OAAO,mBAAA,GAAsBmsB,CAAc,GAE/EI,IAA0B,CAAA;AAChC,IAAI,KAAK,KAAK,cAAc,MAC1BA,EAAS,KAAKvsB,EAAE,OAAO,EAAE,OAAO,sBAAsB,CAAC,oBAAoB,CAAC,CAAC,GAG/E,KAAK,GAAG;AAAA,MACN,GAAGusB;AAAA,MACHvsB,EAAE,OAAO,EAAE,OAAO,sBAAsB,CAACoqB,CAAS,CAAC;AAAA,MACnDpqB,EAAE,OAAO,EAAE,OAAO,0CAAA,GAA6CgrB,CAAc;AAAA,MAC7EhrB,EAAE,OAAO,EAAE,OAAO,mBAAA,GAAsB,CAAC,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA,MACpE,GAAI0rB,IAAsB,CAACA,CAAmB,IAAI,CAAA;AAAA,MAClD,GAAIY,IAAmB,CAACA,CAAgB,IAAI,CAAA;AAAA,MAC5CtsB,EAAE,OAAO,EAAE,OAAO,qBAAqB;AAAA,MACvCA,EAAE,OAAO,EAAE,OAAO,mBAAA,GAAsBgsB,CAAa;AAAA,IAAA,GAGvD,KAAK,QAAQ,KAAK,KAAK,IAAI,GAC3B,KAAK,UAAU,KAAK,KAAK,KAAK;AAAA,EAChC;AAAA,EAEQ,QAAQ;AACd,SAAK,QAAQ,WAAW,CAAC,KAAK,KAAK,MAAM,QAAA,GACzC,KAAK,QAAQ,WAAW,CAAC,KAAK,KAAK,MAAM,QAAA;AAAA,EAC3C;AACF;AAEA,SAASQ,GAAYx2B,GAA2B;AAC9C,SAAOgK,EAAE,QAAQ,EAAE,OAAO,0BAA0B,CAAChK,CAAI,CAAC;AAC5D;AAEA,SAASk1B,EAAUlkB,GAMG;AACpB,QAAMylB,IAAQzlB,EAAK,QAAQ,IAAIA,EAAK,KAAK,KAAK;AAC9C,SAAOhH;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO,+BAA+BysB,CAAK;AAAA,MAC3C,MAAM;AAAA,MACN,OAAOzlB,EAAK;AAAA,MACZ,cAAcA,EAAK;AAAA,MACnB,SAASA,EAAK;AAAA,IAAA;AAAA,IAEhB,CAACA,EAAK,MAAMwlB,GAAYxlB,EAAK,KAAK,CAAC;AAAA,EAAA;AAEvC;AAEA,SAASsjB,GAAWtjB,GAME;AACpB,QAAMrT,IAAMqT,EAAK,SACb,sEACA;AACJ,SAAOhH;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAOrM;AAAA,MACP,MAAM;AAAA,MACN,OAAOqT,EAAK;AAAA,MACZ,cAAcA,EAAK;AAAA,MACnB,SAASA,EAAK;AAAA,IAAA;AAAA,IAEhB,CAACA,EAAK,MAAMwlB,GAAYxlB,EAAK,KAAK,CAAC;AAAA,EAAA;AAEvC;AAEA,SAASolB,GAAYplB,GAMC;AACpB,QAAMylB,IAAQzlB,EAAK,QAAQ,IAAIA,EAAK,KAAK,KAAK;AAC9C,SAAOhH;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO,2CAA2CysB,CAAK;AAAA,MACvD,MAAM;AAAA,MACN,OAAOzlB,EAAK;AAAA,MACZ,cAAcA,EAAK;AAAA,MACnB,gBAAgBA,EAAK,UAAU,SAAS;AAAA,MACxC,SAASA,EAAK;AAAA,IAAA;AAAA,IAEhB,CAACA,EAAK,IAAI;AAAA,EAAA;AAEd;AAEA,MAAM0lB,KACJ;AAEF,SAASvB,KAAuB;AAC9B,SAAOwB,EAAYD,EAAc;AACnC;AACA,SAAStB,KAAuB;AAC9B,SAAOuB,EAAYD,IAAgB,EAAE,OAAO,IAAM;AACpD;AACA,SAASd,KAAsB;AAC7B,SAAOe,EAAY;AAAA,IACjB;AAAA,IACA;AAAA,EAAA,CACD;AACH;AACA,SAASpC,KAAyB;AAChC,SAAOoC;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAASlC,KAAyB;AAChC,SAAOkC;AAAA,IACL;AAAA,EAAA;AAEJ;AAEA,SAASV,KAA2B;AAClC,SAAOU;AAAA,IACL;AAAA,IACA,EAAE,UAAU,UAAA;AAAA,EAAU;AAE1B;AACA,SAAST,KAA2B;AAClC,SAAOS;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAASb,KAAyB;AAChC,SAAOnR;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS2Q,KAA8B;AACrC,SAAOqB;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAASpB,KAA+B;AACtC,SAAOoB;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAASnB,KAA0B;AACjC,SAAO7Q;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS8Q,KAA4B;AACnC,SAAO9Q;AAAA,IACL;AAAA,EAAA;AAEJ;AAEA,SAAS0R,KAAgC;AACvC,SAAOM;AAAA,IACL;AAAA,EAAA;AAEJ;AAEA,SAASxC,KAAkC;AACzC,SAAOxP;AAAA,IACL;AAAA,EAAA;AAEJ;AAEA,SAASuP,KAAiC;AACxC,SAAOyC;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS9B,KAAsB;AAC7B,SAAO+B;AAAA,IACL;AAAA,EAAA;AAEJ;AACA,SAAS9B,KAAuB;AAC9B,SAAO6B;AAAA,IACL;AAAA,IACA,EAAE,OAAO,KAAA;AAAA,EAAK;AAElB;AAEA,SAAS5B,KAA4B;AACnC,SAAO6B;AAAA,IACL;AAAA,EAAA;AAEJ;AAEA,SAASD,EACPv6B,GACA4U,GACY;AACZ,QAAM6lB,KAAU7lB,KAAA,gBAAAA,EAAM,YAAW,iBAC3BlT,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,EAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW+4B,CAAO,GAClC/4B,EAAG,aAAa,eAAe,MAAM;AACrC,QAAMyhB,IAAO,SAAS,gBAAgB,8BAA8B,GAAG,GACjEuX,IAAuB,CAAA;AAC7B,MAAI9lB,KAAA,QAAAA,EAAM,SAASA,EAAK,UAAU,GAAG;AACnC,UAAMxJ,IAAIwJ,EAAK;AACf,IAAA8lB,EAAW,KAAK,4BAA4BtvB,CAAC,wBAAwB;AAAA,EACvE;AACA,EAAIwJ,KAAA,QAAAA,EAAM,SAAO8lB,EAAW,KAAK,+BAA+B,GAC5DA,EAAW,UAAQvX,EAAK,aAAa,aAAauX,EAAW,KAAK,GAAG,CAAC;AAC1E,QAAMC,IAAQ,MAAM,QAAQ36B,CAAC,IAAIA,IAAI,CAACA,CAAC;AACvC,aAAW46B,KAAMD,GAAO;AACtB,UAAME,IAAO,SAAS,gBAAgB,8BAA8B,MAAM;AAC1E,IAAAA,EAAK,aAAa,KAAKD,CAAE,GACzBC,EAAK,aAAa,QAAQ,cAAc,GACpCjmB,KAAA,QAAAA,EAAM,YAAUimB,EAAK,aAAa,aAAajmB,EAAK,QAAQ,GAChEuO,EAAK,OAAO0X,CAAI;AAAA,EAClB;AACA,SAAAn5B,EAAG,OAAOyhB,CAAI,GACPzhB;AACT;AAEA,SAAS6mB,GAAI7Y,GAA2B;AACtC,QAAMhO,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,aAAa,eAAe,MAAM,GACrCA,EAAG,YAAYgO,GACRhO;AACT;AACA,SAAS84B,GAAS9qB,GAA2B;AAC3C,QAAMhO,IAAK,SAAS,gBAAgB,8BAA8B,KAAK;AACvE,SAAAA,EAAG,aAAa,SAAS,IAAI,GAC7BA,EAAG,aAAa,UAAU,IAAI,GAC9BA,EAAG,aAAa,WAAW,WAAW,GACtCA,EAAG,aAAa,eAAe,MAAM,GACrCA,EAAG,YAAYgO,GACRhO;AACT;AC7kBO,MAAMo5B,KAAqB,mBACrBC,KAA+B;AAQrC,SAASC,GAAsBl6B,GAAuB;AAM3D,SAAO,KAAK,UAL2B;AAAA,IACrC,MAAMg6B;AAAA,IACN,eAAeC;AAAA,IACf,KAAAj6B;AAAA,EAAA,CAE4B;AAChC;AAEA,SAASm6B,GAAShvB,GAA0C;AAC1D,SAAO,OAAOA,KAAM,YAAYA,MAAM,QAAQ,CAAC,MAAM,QAAQA,CAAC;AAChE;AAEA,SAASivB,GAAgBjvB,GAA2B;AAIlD,MAHI,CAACgvB,GAAShvB,CAAC,KACXA,EAAE,YAAY,OACd,CAACgvB,GAAShvB,EAAE,IAAI,KAChB,CAAC,MAAM,QAAQA,EAAE,QAAQ,EAAG,QAAO;AACvC,aAAWiK,KAAOjK,EAAE,UAAU;AAC5B,QAAI,CAACgvB,GAAS/kB,CAAG,KAAK,CAAC,MAAM,QAAQA,EAAI,OAAO,EAAG,QAAO;AAC1D,eAAW7C,KAAO6C,EAAI;AACpB,UAAI,CAAC+kB,GAAS5nB,CAAG,KAAK,CAAC,MAAM,QAAQA,EAAI,MAAM,EAAG,QAAO;AAAA,EAE7D;AACA,SAAO;AACT;AAKO,SAAS8nB,GAAkBhwB,GAA8B;AAC9D,QAAMqF,KAAWrF,KAAO,IAAI,KAAA;AAC5B,MAAI,CAACqF,EAAS,QAAO;AACrB,MAAIlP;AACJ,MAAI;AACF,IAAAA,IAAS,KAAK,MAAMkP,CAAO;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,CAACyqB,GAAS35B,CAAM,EAAG,QAAO;AAE9B,MAAIA,EAAO,SAASw5B,IAAoB;AACtC,QAAIx5B,EAAO,kBAAkBy5B,GAA8B,QAAO;AAClE,UAAMj6B,IAAMQ,EAAO;AACnB,WAAK45B,GAAgBp6B,CAAG,IACjB,gBAAgBA,CAAG,IADQ;AAAA,EAEpC;AAEA,SAAIo6B,GAAgB55B,CAAM,IACjB,gBAAgBA,CAAM,IAGxB;AACT;AAGO,SAAS85B,GAAiBt6B,GAAyB;AACxD,QAAM4B,IAAO,gBAAgB5B,CAAG;AAChC,SAAA4B,EAAK,WAAWA,EAAK,SAAS,IAAI,CAACwT,MAAQmlB,GAAgBnlB,CAAG,CAAC,GACxDxT;AACT;AAEA,SAAS24B,GAAgBnlB,GAAuB;AAC9C,SAAO;AAAA,IACL,GAAGA;AAAA,IACH,IAAIb,GAAI,KAAK;AAAA,IACb,SAASa,EAAI,QAAQ,IAAI,CAAC7C,OAAS;AAAA,MACjC,GAAGA;AAAA,MACH,IAAIgC,GAAI,KAAK;AAAA,MACb,QAAQhC,EAAI,OAAO,IAAI,CAAC2C,OAAS;AAAA,QAC/B,GAAGA;AAAA,QACH,IAAIX,GAAI,KAAK;AAAA,MAAA,EACb;AAAA,IAAA,EACF;AAAA,EAAA;AAEN;ACvEO,MAAMimB,GAAe;AAAA,EAM1B,YAAY1mB,GAA6B;AALjC,IAAAhV,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AAGN,SAAK,OAAOgV;AACZ,UAAMrF,IAAIqF,EAAK;AACf,SAAK,QAAQ,IAAIiF,GAAM;AAAA,MACrB,OAAOtK,EAAE,iBAAiB;AAAA,MAC1B,WAAW;AAAA,MACX,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,GAAAA;AAAA,IAAA,CACD,GAED,KAAK,SAAS3B,EAAE,KAAK,EAAE,OAAO,yBAAyB;AAAA,MACrD2B,EAAE,iBAAiB;AAAA,MACnBA,EAAE,iBAAiB;AAAA,MACnBA,EAAE,iBAAiB;AAAA,IAAA,CACpB,GAED,KAAK,WAAW3B,EAAE,YAAY;AAAA,MAC5B,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,aAAa2B,EAAE,uBAAuB;AAAA,MACtC,MAAM;AAAA,IAAA,CACP,GAED,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,KAAK,QAAQ;AAEjD,UAAMgsB,IAAY3tB;AAAA,MAChB;AAAA,MACA,EAAE,OAAO,UAAU,MAAM,UAAU,SAAS,MAAM,KAAK,MAAM,QAAM;AAAA,MACnE,CAAC2B,EAAE,eAAe,CAAC;AAAA,IAAA,GAEfisB,IAAW5tB;AAAA,MACf;AAAA,MACA,EAAE,OAAO,UAAU,MAAM,UAAU,SAAS,MAAM,KAAK,KAAK,qBAAmB;AAAA,MAC/E,CAAC2B,EAAE,8BAA8B,CAAC;AAAA,IAAA,GAE9BksB,IAAW7tB;AAAA,MACf;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,MAAM,KAAK,OAAA;AAAA,MAAO;AAAA,MAE7B,CAAC2B,EAAE,iBAAiB,CAAC;AAAA,IAAA;AAEvB,SAAK,MAAM,OAAO,OAAOgsB,GAAWC,GAAUC,CAAQ;AAAA,EACxD;AAAA,EAEA,MAAM,KAAKx5B,GAAsB;;AAC/B,SAAK,OAAO,UAAU,OAAO,4BAA4B,GACzD,KAAK,SAAS,QAAQ,IACtB,KAAK,MAAM,KAAKA,CAAM;AACtB,UAAMuT,IAAW,QAAMtU,KAAAF,IAAA,KAAK,MAAK,kBAAV,gBAAAE,EAAA,KAAAF,OAAgC;AACvD,IAAIwU,EAAQ,KAAA,MAAQ,KAAK,SAAS,QAAQA;AAAA,EAC5C;AAAA,EAEA,MAAc,qBAAqB;;AACjC,UAAM5R,IAAQ,QAAM1C,KAAAF,IAAA,KAAK,MAAK,kBAAV,gBAAAE,EAAA,KAAAF,OAAgC;AACpD,QAAI,CAAC4C,EAAK,QAAQ;AAChB,WAAK,SAAS,KAAK,KAAK,EAAE,0BAA0B,GAAG,EAAI;AAC3D;AAAA,IACF;AACA,SAAK,SAAS,QAAQA,GACtB,KAAK,SAAS,KAAK,KAAK,EAAE,2BAA2B,GAAG,EAAK;AAAA,EAC/D;AAAA,EAEQ,SAAS;AACf,UAAMuH,IAAM,KAAK,SAAS,MAAM,KAAA;AAChC,QAAI,CAACA,GAAK;AACR,WAAK,SAAS,KAAK,KAAK,EAAE,iBAAiB,GAAG,EAAI;AAClD;AAAA,IACF;AACA,UAAMrK,IAAMq6B,GAAkBhwB,CAAG;AACjC,QAAI,CAACrK,GAAK;AACR,WAAK,SAAS,KAAK,KAAK,EAAE,mBAAmB,GAAG,EAAI;AACpD;AAAA,IACF;AACA,SAAK,KAAK,QAAQA,CAAG,GACrB,KAAK,MAAM,MAAA;AAAA,EACb;AAAA,EAEQ,SAAS46B,GAAiBC,GAAkB;AAClD,IAAA5tB,EAAM,KAAK,MAAM,GACjB,KAAK,OAAO,UAAU,OAAO,8BAA8B4tB,CAAO,GAClE,KAAK,OAAO,OAAOD,CAAO;AAAA,EAC5B;AACF;AAEA,eAAsBE,KAAyC;AAC7D,MAAI;AACF,WAAQ,MAAM,UAAU,UAAU,SAAA,KAAe;AAAA,EACnD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsBC,GAAqBj4B,GAAgC;AACzE,MAAI;AACF,iBAAM,UAAU,UAAU,UAAUA,CAAI,GACjC;AAAA,EACT,QAAQ;AACN,UAAMilB,IAAK,SAAS,cAAc,UAAU;AAC5C,IAAAA,EAAG,QAAQjlB,GACX,SAAS,KAAK,YAAYilB,CAAE,GAC5BA,EAAG,OAAA;AACH,UAAMiT,IAAKrgB,EAAoB,MAAM;AACrC,oBAAS,KAAK,YAAYoN,CAAE,GACrBiT;AAAA,EACT;AACF;ACtBO,MAAMC,GAAW;AAAA,EAmHtB,YAAYnnB,GAAqB;AAlHxB,IAAAhV,EAAA;AACA,IAAAA,EAAA;AACD,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,cAAmB;AACnB,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA,oCAAgE;AAChE,IAAAA,EAAA,qBAA6B;AAE7B;AAAA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA,2BAAoB;AAEpB;AAAA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA,6BAAkC,CAAA;AAClC,IAAAA,EAAA,wBAAwC;AACxC,IAAAA,EAAA,8BAA8C;AAC9C,IAAAA,EAAA,yBAAkB;AAClB,IAAAA,EAAA,uBAAuC;AACvC,IAAAA,EAAA;AACS,IAAAA,EAAA,gCAAyB,MAAM;AAC9C,MAAI,KAAK,uBAAqB,KAAK,iBAAA;AAAA,IACrC;AAEiB,IAAAA,EAAA,6BAAsB,MAAM;;AAC3C,YAAMo8B,IAAKC,SAA6B,KAAK;AAC7C,OAAAj7B,IAAA,KAAK,WAAL,QAAAA,EAAa,oBAAoBg7B,IACjC,KAAK,kBAAA;AAAA,IACP;AAGQ;AAAA,IAAAp8B,EAAA,yBAAkB,CAACsV,MAAqB;;AAC9C,UAAIA,EAAE,QAAQ,SAAU;AACxB,UAAI,KAAK,WAAW,wBAAwB;AAC1C,QAAAA,EAAE,eAAA,GACF,KAAK,qBAAA;AACL;AAAA,MACF;AAGA,UAFI,KAAK,SAAS,YACd,CAAC,KAAK,MAAM,aACZ,SAAS,cAAc,yBAAyB,EAAG;AACvD,YAAM3F,IAAI2F,EAAE;AACZ,WAAIlU,IAAAuO,KAAA,gBAAAA,EAAG,YAAH,QAAAvO,EAAA,KAAAuO,GAAa,mBAAoB;AACrC,YAAMohB,IAAK,SAAS;AAEpB,UADIA,MAAOA,EAAG,YAAY,WAAWA,EAAG,YAAY,cAAcA,EAAG,sBACjEA,KAAMA,MAAO,SAAS,QAAQ,CAAC,KAAK,KAAK,SAASA,CAAE,EAAG;AAC3D,MAAAzb,EAAE,eAAA;AACF,YAAMzR,IAAM,KAAK,MAAM;AACvB,UAAIA,EAAI,SAAS,SAAS;AACxB,aAAK,OAAO,iBAAA,GACZ,KAAK,MAAM,aAAa,EAAE,MAAM,WAAW,WAAWA,EAAI,WAAW;AACrE;AAAA,MACF;AACA,WAAK,mBAAA;AAAA,IACP;AAQQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA7D,EAAA,8BAAuB,CAACsV,MAAqB;AAInD,UAFI,EADSA,EAAE,WAAWA,EAAE,YAElBA,EAAE,IAAI,YAAA,MACN,IAAK;AACf,YAAM3F,IAAI2F,EAAE;AAEZ,UADI,CAAC3F,KAAK,CAAC,KAAK,KAAK,SAASA,CAAC,KAC3B,KAAK,4BAA4BA,CAAC,EAAG;AACzC,YAAM2sB,IAAO,CAAChnB,EAAE,UACVinB,IAAOjnB,EAAE;AACf,MAAIgnB,KAAQ,CAAC,KAAK,MAAM,aACpBC,KAAQ,CAAC,KAAK,MAAM,cACxBjnB,EAAE,eAAA,GACEgnB,SAAW,WAAA,SACL,WAAA;AAAA,IACZ;AAgCE,QALA,KAAK,OAAOtnB,GACZ,KAAK,OAAOoI,GAAkB,EAAE,QAAQpI,EAAK,QAAQ,UAAUA,EAAK,UAAU,GAC9E,KAAK,WAAW,IAAIjV,GAAA,GAGhBiV,EAAK;AACP,iBAAW/U,KAAO+U,EAAK,OAAQ,MAAK,SAAS,SAAS/U,CAAG;AAG3D,UAAMu8B,IAAaC,GAAiBznB,EAAK,UAAU;AACnD,IAAA0nB,GAA0BF,GAAYxnB,EAAK,YAAY,KAAK,KAAK,CAAC;AAClE,UAAM2nB,IAAe3nB,EAAK,aAAaA,EAAK,YACtC4nB,IAAmBH,GAAiBE,CAAY;AACtD,IAAAD,GAA0BE,GAAkBD,GAAc,KAAK,KAAK,CAAC,GACrE,KAAK,mBAAmB,gBAAgBC,CAAgB,GACxD,KAAK,QAAQ,IAAIjnB,GAAM6mB,CAAU;AAEjC,UAAMK,IAAgBrgB,EAAmB,KAAK,KAAK,eAAe,EAAE;AACpE,IACE,KAAK,KAAK,eAAe,QACzB,OAAO,KAAK,KAAK,WAAW,EAAE,KAAA,MAAW,MACzC,CAACqgB,KAED,QAAQ,KAAK,qCAAqC,KAAK,KAAK,WAAW,GAEzE,KAAK,sBAAsBA,KAAiB,QAE5C,KAAK,QAAQ7nB,EAAK,SAAS,SAC3B,KAAK,OAAOhH,EAAE,OAAO,EAAE,OAAO,WAAW,GACzC,KAAK,gBAAA,GACL,KAAK,OAAOA,EAAE,OAAO,EAAE,OAAO,WAAW,GACzCgH,EAAK,UAAU,OAAO,KAAK,IAAI,GAE/B,KAAK,SAAA,GACL,KAAK,cAAA,GACL,KAAK,gBAAA,GACL,KAAK,uBAAA,GAEL,KAAK,iBAAA,GACL,KAAK,wBAAA,GACL,KAAK,wBAAA,GAEL,KAAK,MAAM,UAAU,MAAM,KAAK,WAAW;AAAA,EAC7C;AAAA;AAAA,EAnEQ,4BAA4BnT,GAAuB;AACzD,UAAMC,IACJD,aAAkB,UAAUA,IAAUA,EAAO;AAC/C,WAAKC,IACD,GAAAA,EAAG,QAAQ,oBAAoB,KAC/BA,EAAG,QAAQ,YAAY,KACRA,EAAG,QAAQ,4EAA4E,KAH1F;AAAA,EAMlB;AAAA,EAEQ,aAAa;AACnB,IAAI,KAAK,OAAO,mBAAiB,KAAK,OAAO,gBAAA,GAC7C,KAAK,yBAAA,GACL,KAAK,MAAM,KAAA;AAAA,EACb;AAAA,EAEQ,aAAa;AACnB,IAAI,KAAK,OAAO,mBAAiB,KAAK,OAAO,gBAAA,GAC7C,KAAK,yBAAA,GACL,KAAK,MAAM,KAAA;AAAA,EACb;AAAA;AAAA,EAkDA,SAASZ,GAAe;AACtB,SAAK,yBAAA,GACL,KAAK,MAAM,QAAQA,CAAG,GACtB,KAAK,0BAAA;AAAA,EACP;AAAA,EAEA,WAAqB;AACnB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAoB;AAClB,SAAK,OAAO,iBAAA,GACZ,KAAK,yBAAA,GACL,KAAK,MAAM,OAAO,CAACd,MAAM;AACvB,MAAAA,EAAE,WAAW,CAAA;AAAA,IACf,CAAC,GACD,KAAK,MAAM,aAAa,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAsB;AACpB,SAAK,OAAO,iBAAA,GACZ,KAAK,yBAAA;AACL,UAAM08B,IAAS,gBAAgB,KAAK,gBAAgB,GAC9CC,IAAiB,KAAK,oBAAoB,SAC5C,KAAK,oBAAoB,IAAI,CAAC1wB,OAAO,EAAE,GAAGA,EAAA,EAAI,IAC9C;AACJ,SAAK,MAAM,OAAO,CAACjM,MAAM;AACvB,aAAO,OAAOA,GAAG08B,CAAM,GACnBC,QAAkB,YAAYA;AAAA,IACpC,CAAC,GACD,KAAK,MAAM,aAAa,IAAI;AAAA,EAC9B;AAAA;AAAA,EAGA,aAAaxV,GAAkC;AAC7C,UAAMyV,IAAYP,GAAiBlV,CAAO;AAC1C,IAAAmV,GAA0BM,GAAWzV,GAAS,KAAK,KAAK,CAAC,GACzD,KAAK,mBAAmB,gBAAgByV,CAAS;AAAA,EACnD;AAAA,EAEA,aAAaznB,GAAkB;AAC7B,SAAK,sBAAsBA,EAAK,IAAIgC,EAAiB,GACrD,KAAK,0BAAA;AAAA,EACP;AAAA,EAEA,eAA2B;AACzB,WAAI,KAAK,oBAAoB,SAAe,KAAK,sBAC1C,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEQ,4BAA4B;AAClC,QAAI,CAAC,KAAK,oBAAoB,OAAQ;AACtC,UAAM0lB,IAAW,KAAK,oBAAoB,IAAI,CAAC5wB,OAAO,EAAE,GAAGA,EAAA,EAAI;AAC/D,SAAK,MAAM,OAAO,CAACjM,MAAM;AACvB,MAAAA,EAAE,YAAY68B;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB5wB,GAAsB;AACtC,UAAMyL,IAAaP,GAAkBlL,CAAC;AACtC,WAAO,KAAK,eAAegL,EAAoBS,EAAW,GAAG,GAAG,EAAK;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,sBAAsBzL,GAAsB;AAC1C,UAAMyL,IAAaP,GAAkBlL,CAAC;AACtC,QAAIyL,EAAW,SAAS;AACtB,aAAO,KAAK,qBAAqBA,CAAU;AAE7C,QAAIA,EAAW,SAAS,QAAQ;AAC9B,YAAMV,IAAQC,EAAoBS,EAAW,GAAG;AAChD,UAAI,KAAK,2BAA2BV,CAAK,EAAG,QAAO;AACnD,YAAM5V,IAAOiW;AAAA,QACXL;AAAA,QACA,KAAK,MAAM,IAAI,OAAO,aAAa;AAAA,MAAA;AAErC,aAAO,KAAK,eAAe5V,GAAM,EAAI;AAAA,IACvC;AACA,WAAO,KAAK,kBAAkBsW,CAAU;AAAA,EAC1C;AAAA;AAAA,EAGA,eAAezL,GAAsB;AACnC,WAAO,KAAK,kBAAkBA,CAAC;AAAA,EACjC;AAAA;AAAA,EAGA,WAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,SAAS,GAAgB;;AACvB,IAAI,KAAK,UAAU,MACnB,KAAK,QAAQ,GACb,KAAK,gBAAA,GACL,KAAK,iBAAA,GACL,KAAK,wBAAA,IACLjL,IAAA,KAAK,WAAL,QAAAA,EAAa,UAAU,IACvB,KAAK,wBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe0b,GAAgC;AAC7C,QAAIA,KAAO,QAAQ,OAAOA,CAAG,EAAE,KAAA,MAAW;AACxC,WAAK,sBAAsB;AAAA,SACtB;AACL,YAAM5R,IAAIsR,EAAmB,OAAOM,CAAG,CAAC;AACxC,UAAI,CAAC5R,GAAG;AACN,gBAAQ,KAAK,wCAAwC4R,CAAG;AACxD;AAAA,MACF;AACA,WAAK,sBAAsB5R;AAAA,IAC7B;AACA,SAAK,iBAAA,GACL,KAAK,wBAAA,GACL,KAAK,wBAAA;AAAA,EACP;AAAA;AAAA,EAGA,iBAAqC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,OAAO8J,IAA0C,IAAI;AACnD,WAAOD,GAAU,KAAK,MAAM,KAAK,KAAK,UAAU;AAAA,MAC9C,QAAQ,KAAK,KAAK,UAAU;AAAA,MAC5B,qBAAqBC,EAAK,uBAAuB;AAAA,IAAA,CAClD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAkC;AACtC,SAAK,OAAO,iBAAA;AACZ,UAAMknB,IAAK,MAAMD,GAAqBb,GAAsB,KAAK,MAAM,GAAG,CAAC;AAC3E,gBAAK,WAAWc,IAAK,KAAK,KAAK,EAAE,oBAAoB,IAAI,KAAK,KAAK,EAAE,wBAAwB,CAAC,GACvFA;AAAA,EACT;AAAA;AAAA,EAGA,sBAA4B;AAC1B,SAAK,OAAO,iBAAA,GACZ,KAAK,sBAAA,GACA,KAAK,eAAgB,KAAK,KAAK,IAAI;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,wBAAwB3wB,GAAsB;AAC5C,UAAM7J,IAAS65B,GAAkBhwB,CAAG;AACpC,WAAK7J,KACL,KAAK,kBAAkBA,CAAM,GACtB,MAFa;AAAA,EAGtB;AAAA,EAEA,cAAgCzB,GAAyB;;AACvD,SAAK,SAAS,SAASA,CAAG,IAC1BmB,IAAA,KAAK,cAAL,QAAAA,EAAgB;AAAA,EAClB;AAAA,EAEA,aAAayC,GAAuB;AAClC,SAAK,MAAM,aAAaA,CAAG;AAAA,EAC7B;AAAA,EAEA,UAAU;;AACR,SAAK,qBAAA,GACL,KAAK,kBAAA,GACL,KAAK,yBAAA,GACL,KAAK,8BAAA,GACD,KAAK,eAAa,OAAO,aAAa,KAAK,WAAW,GACtDw4B,GAAA,MAA6B,KAAK,QAAWa,GAAA,GACjD,SAAS,oBAAoB,WAAW,KAAK,iBAAiB,EAAI,GAClE,SAAS,oBAAoB,WAAW,KAAK,sBAAsB,EAAI,IACvE57B,KAAAF,IAAA,KAAK,WAAL,gBAAAA,EAAa,YAAb,QAAAE,EAAA,KAAAF,KACAkZ,KAAAC,IAAA,KAAK,eAAL,gBAAAA,EAAiB,YAAjB,QAAAD,EAAA,KAAAC,KACAkH,KAAAD,IAAA,KAAK,YAAL,gBAAAA,EAAc,YAAd,QAAAC,EAAA,KAAAD,IACA,KAAK,KAAK,OAAA;AAAA,EACZ;AAAA;AAAA,EAIQ,kBAAkB;AACxB,SAAK,KAAK,aAAa,iBAAiB,KAAK,KAAK;AAAA,EACpD;AAAA,EAEQ,2BAAoC;AAC1C,WAAI,KAAK,UAAU,SAAe,KAC9B,KAAK,UAAU,UAAgB,KAC5B,OAAO,WAAW,8BAA8B,EAAE;AAAA,EAC3D;AAAA,EAEQ,mBAAmB;AACzB,QAAI,CAAC,KAAK,qBAAqB;AAC7B,WAAK,KAAK,MAAM,eAAe,cAAc,GAC7C,KAAK,KAAK,MAAM,eAAe,mBAAmB;AAClD;AAAA,IACF;AACA,UAAM2b,IAAO,KAAK,yBAAA;AAClB,SAAK,KAAK,MAAM,YAAY,gBAAgB,KAAK,mBAAmB,GACpE,KAAK,KAAK,MAAM,YAAY,qBAAqBxgB,GAAsB,KAAK,qBAAqBwgB,CAAI,CAAC;AAAA,EACxG;AAAA,EAEQ,gCAAgC;AACtC,IAAI,KAAK,kBACP,KAAK,cAAc,oBAAoB,UAAU,KAAK,sBAAsB,GAC5E,KAAK,gBAAgB;AAAA,EAEzB;AAAA;AAAA,EAGQ,0BAA0B;AAEhC,QADA,KAAK,8BAAA,GACD,KAAK,UAAU,YAAY,KAAK,qBAAqB;AACvD,YAAMC,IAAK,OAAO,WAAW,8BAA8B;AAC3D,MAAAA,EAAG,iBAAiB,UAAU,KAAK,sBAAsB,GACzD,KAAK,gBAAgBA;AAAA,IACvB;AAAA,EACF;AAAA,EAEQ,0BAA0B;;AAChC,KAAAh8B,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,EACf;AAAA,EAEQ,WAAW;;AACjB,SAAK,SAAS,IAAIy2B,GAAO;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,GAAG,KAAK,KAAK;AAAA,MACb,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,kBAAkB,KAAK;AAAA,MACvB,uBAAuB,KAAK,KAAK,0BAA0B;AAAA,MAC3D,gBAAgB,CAACwF,MAAO,KAAK,eAAeA,CAAE;AAAA,MAC9C,eAAe,CAAC1tB,MAAM,KAAK,SAASA,CAAC;AAAA,MACrC,cAAc,CAAC,MAAM,KAAK,SAAS,CAAC;AAAA,MACpC,QAAQ,MAAM;AACZ,aAAK,WAAA;AAAA,MACP;AAAA,MACA,QAAQ,MAAM;AACZ,aAAK,WAAA;AAAA,MACP;AAAA,MACA,gBAAgB,MAAM,KAAK,mBAAA;AAAA,MAC3B,0BAAwBvO,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,4BAA2B;AAAA,MACjE,aAAWE,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,qBAAoB;AAAA,MAC7C,4BAA0BiZ,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,8BAA6B;AAAA,MACrE,kBAAkB,CAACxU,MAAW,KAAK,qBAAqBA,CAAM;AAAA,MAC9D,WAAW,MAAM,KAAK,aAAA;AAAA,MACtB,UAAU,MAAM,KAAK,YAAA;AAAA,MACrB,wBAAsBuU,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,0BAAyB;AAAA,MAC7D,oBAAoB,MAAM,KAAK,KAAK,kBAAA;AAAA,MACpC,uBAAuB,MAAM,KAAK,qBAAA;AAAA,MAClC,yBAAuBkH,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,2BAA0B;AAAA,MAC/D,eAAe,MAAM,KAAK,YAAA;AAAA,MAC1B,0BAAwBC,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,4BAA2B;AAAA,MACjE,gBAAgB,MAAM,KAAK,cAAA;AAAA,MAC3B,2BAAyBC,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,4BAA2B;AAAA,MAClE,iBAAiB,MAAM,KAAK,KAAK,cAAA;AAAA,MACjC,mBAAmB,MAAM,KAAK,oBAAA;AAAA,MAC9B,SAAS,CAAC4b,GAAoB,KAAK,KAAK,IAAI,KAAK,sBAAsB;AAAA,IAAA,CACxE,GAED,KAAK,UAAU,IAAI9S,GAAgB,EAAE,cAAc,KAAK,MAAM,GAAG,KAAK,KAAK,EAAA,CAAG;AAC9E,UAAM+S,IAAK,KAAK,KAAK;AACrB,SAAK,YAAY,IAAIlU,GAAU;AAAA,MAC7B,UAAU,KAAK;AAAA,MACf,GAAG,KAAK,KAAK;AAAA,MACb,kBACEkU,KAAA,gBAAAA,EAAI,6BAA0B5b,IAAA4b,KAAA,gBAAAA,EAAI,wBAAJ,gBAAA5b,EAAyB;AAAA,MACzD,4BAA4B4b,KAAA,gBAAAA,EAAI;AAAA,MAChC,yBAAyBA,KAAA,gBAAAA,EAAI;AAAA,IAAA,CAC9B;AACD,UAAMC,IAAW,KAAK,KAAK,oBAAoB;AAC/C,SAAK,KAAK,UAAU,OAAO,sBAAsBA,CAAQ,GACzD,KAAK,SAAS,IAAI5Y,GAAO;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,iBAAiB4Y;AAAA,MACjB,8BAA8B,KAAK,KAAK,iCAAiC;AAAA,MACzE,WAAW,KAAK;AAAA,MAChB,IAAI,KAAK,KAAK;AAAA,MACd,GAAG,KAAK,KAAK;AAAA,IAAA,CACd,GACD,KAAK,aAAa,IAAI3M,GAAW;AAAA,MAC/B,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,eAAcjP,IAAA,KAAK,KAAK,OAAV,QAAAA,EAAc,eACxB,KAAK,KAAK,EAAE,2BAA2B,IACvC,KAAK,KAAK,EAAE,yBAAyB;AAAA,MACzC,gBAAgB,CAAC5gB,MAAc;AAC7B,aAAK,OAAO,iBAAA,GACZ,KAAK,MAAM,aAAa,EAAE,MAAM,WAAW,WAAAA,GAAW;AAAA,MACxD;AAAA,MACA,iBAAiB,MAAM,KAAK,mBAAA;AAAA,MAC5B,aAAa,KAAK,KAAK;AAAA,MACvB,IAAI,KAAK,KAAK;AAAA,MACd,GAAG,KAAK,KAAK;AAAA,IAAA,CACd,GACD,KAAK,aAAa,IAAI42B,GAAW;AAAA,MAC/B,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG,KAAK,KAAK;AAAA,IAAA,CACd,GAED,KAAK,KAAK,OAAO,KAAK,UAAU,IAAI,KAAK,OAAO,IAAI,KAAK,WAAW,EAAE,GACtE,KAAK,eAAe5pB,EAAE,OAAO,EAAE,OAAO,oBAAoB,GAC1D,KAAK,KAAK,OAAO,KAAK,OAAO,IAAI,KAAK,MAAM,KAAK,YAAY;AAAA,EAC/D;AAAA;AAAA,EAGQ,2BAA2B;AACjC,UAAM+iB,IAAK,SAAS;AACpB,IAAIA,KAAM,KAAK,WAAW,GAAG,SAASA,CAAE,OAAM,KAAA;AAAA,EAChD;AAAA;AAAA,EAGQ,qBAAqB;AAC3B,SAAK,qBAAA,GACL,KAAK,OAAO,iBAAA,GACZ,KAAK,MAAM,aAAa,IAAI;AAAA,EAC9B;AAAA,EAEQ,SAASxrB,GAAe;AAC9B,IAAI,KAAK,SAASA,MAClB,KAAK,qBAAA,GACL,KAAK,wBAAA,GACDA,MAAM,YAAU,KAAK,OAAO,iBAAA,GAChC,KAAK,OAAOA,GACZ,KAAK,OAAO,QAAQA,CAAC,GACrB4I,EAAM,KAAK,IAAI,GACX5I,MAAM,YACR,KAAK,KAAK,UAAU,OAAO,iBAAiB,GAC5C,KAAK,KAAK,MAAM,eAAe,uBAAuB,GACtD,KAAK,KAAK,OAAO,KAAK,UAAU,IAAI,KAAK,OAAO,IAAI,KAAK,WAAW,EAAE,MAEtE,KAAK,KAAK,UAAU,IAAI,iBAAiB,GACzC,KAAK,KAAK,MAAM,eAAe,uBAAuB,GACtD,KAAK,KAAK,OAAO,KAAK,WAAW,EAAE,GAEnC,eAAe,MAAM,KAAK,WAAW,WAAA,CAAY;AAAA,EAErD;AAAA,EAEQ,gBAAgB;AACtB,SAAK,KAAK,iBAAiB,WAAW,CAAC+P,MAAM;AAC3C,UAAIA,EAAE,QAAQ,YAAYA,EAAE,QAAQ,aAAa;AAC/C,cAAMnM,IAAOmM,EAAE,OAAuB;AACtC,YAAInM,MAAQ,WAAWA,MAAQ,cAAemM,EAAE,OAAuB;AACrE;AAEF,cAAMzR,IAAM,KAAK,MAAM;AACvB,YAAI,CAACA,EAAK;AACV,QAAAyR,EAAE,eAAA,GACEzR,EAAI,SAAS,aACf,KAAK,MAAM,OAAO,CAACzD,MAAM;AACvB,UAAAA,EAAE,WAAWA,EAAE,SAAS,OAAO,CAAC,MAAM,EAAE,OAAOyD,EAAI,SAAS;AAAA,QAC9D,CAAC,GACD,KAAK,MAAM,aAAa,IAAI,MAE5B,KAAK,MAAM,OAAO,CAACzD,MAAM;AACvB,gBAAMkW,IAAMlW,EAAE,SAAS,KAAK,CAACoL,MAAMA,EAAE,OAAO3H,EAAI,SAAS;AACzD,cAAI,CAACyS,EAAK;AACV,gBAAM7C,IAAM6C,EAAI,QAAQzS,EAAI,WAAW;AACvC,UAAK4P,MACLA,EAAI,SAASA,EAAI,OAAO,OAAO,CAAC/K,MAAMA,EAAE,OAAO7E,EAAI,OAAO,GAC1DwS,GAAoBjW,GAAGyD,EAAI,SAAS;AAAA,QACtC,CAAC,GACD,KAAK,MAAM,aAAa,IAAI;AAAA,MAEhC;AAAA,IACF,CAAC,GACD,SAAS,iBAAiB,WAAW,KAAK,sBAAsB,EAAI,GACpE,SAAS,iBAAiB,WAAW,KAAK,iBAAiB,EAAI,GAC/D,KAAK,KAAK,WAAW;AAAA,EACvB;AAAA,EAEQ,YAAY;AAClB,IAAK,KAAK,KAAK,aACX,KAAK,eAAa,OAAO,aAAa,KAAK,WAAW,GAC1D,KAAK,cAAc,OAAO,WAAW,MAAM;;AACzC,OAAAvC,KAAAF,IAAA,KAAK,MAAK,aAAV,QAAAE,EAAA,KAAAF,GAAqB,KAAK,MAAM,MAChC,KAAK,cAAc;AAAA,IACrB,GAAG,EAAE;AAAA,EACP;AAAA,EAEQ,oCAAoC;AAC1C,IAAK,KAAK,+BACV,SAAS,oBAAoB,SAAS,KAAK,4BAA4B,EAAI,GAC3E,KAAK,6BAA6B;AAAA,EACpC;AAAA,EAEQ,gCAAgC2E,GAAqB;AAC3D,SAAK,kCAAA;AACL,UAAM03B,IAAU,CAACre,MAAmB;AAClC,UAAI,CAAC,KAAK,WAAW,qBAAA,KAA0B,KAAK,WAAW,yBAA0B;AACzF,YAAMvd,IAASud,EAAG;AAClB,MAAI,KAAK,WAAW,GAAG,SAASvd,CAAM,KAClCkE,EAAO,SAASlE,CAAM,KAAKA,MAAWkE,KAC1C,KAAK,qBAAA;AAAA,IACP;AACA,SAAK,6BAA6B03B,GAClC,WAAW,MAAM;AACf,MAAI,KAAK,+BAA+BA,KACtC,SAAS,iBAAiB,SAASA,GAAS,EAAI;AAAA,IAEpD,GAAG,CAAC;AAAA,EACN;AAAA,EAEQ,uBAAuB;AAE7B,IADA,KAAK,kCAAA,GACA,KAAK,WAAW,2BACrB,KAAK,WAAW,oBAAA,GAChB,KAAK,OAAO,wBAAwB,EAAK;AAAA,EAC3C;AAAA,EAEQ,qBAAqB13B,GAAqB;;AAChD,KAAA3E,IAAA,KAAK,OAAO,wBAAZ,QAAAA,EAAiC;AAEjC,UAAMmU,IAAO,KAAK,aAAA;AAClB,QAAI,CAACA,EAAK,QAAQ;AAChB,WAAK,WAAW,KAAK,KAAK,EAAE,mBAAmB,CAAC;AAChD;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,UAAU;AAC1B,UAAI,KAAK,WAAW,wBAAwB;AAC1C,aAAK,qBAAA;AACL;AAAA,MACF;AACA,WAAK,wBAAA,GACL,KAAK,yBAAA,GACL,KAAK,WAAW,mBAAmBA,GAAM;AAAA,QACvC,WAAW,CAAClJ,MAAM;AAChB,eAAK,kBAAkBA,CAAC,GACnB,KAAK,WAAW,uBAAA,UAA+B,qBAAA;AAAA,QACtD;AAAA,QACA,eAAe,CAACA,MAAM;AACpB,eAAK,sBAAsBA,CAAC,GACvB,KAAK,WAAW,uBAAA,UAA+B,qBAAA;AAAA,QACtD;AAAA,QACA,QAAQ,CAAC+K,MAAU;AACjB,UAAKsmB,GAAkBtmB,CAAK,EAAE,KAAK,CAAC8kB,MAAO;AACzC,YAAKA,KACL,KAAK,WAAW,KAAK,KAAK,EAAE,sBAAsB,CAAC;AAAA,UACrD,CAAC;AAAA,QACH;AAAA,QACA,SAAS,MAAM,KAAK,qBAAA;AAAA,MAAqB,CAC1C,GACD,KAAK,gCAAgCn2B,CAAM,GAC3C,KAAK,OAAO,wBAAwB,EAAI;AACxC;AAAA,IACF;AAEA,SAAK,uBAAuBA,GAAQwP,CAAI;AAAA,EAC1C;AAAA,EAEQ,0BAA0B;;AAChC,KAAAnU,IAAA,KAAK,aAAa,cAAc,aAAa,MAA7C,QAAAA,EAAgD;AAAA,EAClD;AAAA;AAAA,EAGQ,uBAAuB2E,GAAqBwP,GAAkB;AACpE,UAAMooB,IAAW,KAAK,aAAa,cAAc,aAAa;AAC9D,QAAIA,GAAU;AACZ,MAAAA,EAAS,OAAA,GACT,KAAK,OAAO,wBAAwB,EAAK;AACzC;AAAA,IACF;AAEA,UAAMC,IAAM5vB,EAAE,OAAO,EAAE,OAAO,oCAAoC;AAClE,QAAI6vB,IAAgD;AACpD,UAAMC,IAAiB,MAAM;AAC3B,MAAAF,EAAI,OAAA,GACAC,KAAY,SAAS,oBAAoB,SAASA,GAAY,EAAI,GACtE,KAAK,OAAO,wBAAwB,EAAK;AAAA,IAC3C;AAEA,eAAWxxB,KAAKkJ,GAAM;AACpB,YAAM6B,IAAQC,EAAoBhL,EAAE,GAAG,GACjCokB,IAAMziB,EAAE,OAAO,EAAE,OAAO,mBAAmB,GAC3C0iB,IAAU1iB,EAAE,OAAO,EAAE,OAAO,uBAAuB;AACzD,OAAI3B,EAAE,SAAS,UAAUA,EAAE,SAAS,YAClCqkB,EAAQ;AAAA,QACN1iB;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SAAS,CAACsH,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACF,KAAK,sBAAsBjJ,CAAC,GAC5ByxB,EAAA;AAAA,YACF;AAAA,UAAA;AAAA,UAEF,CAAC,KAAK,KAAK,EAAE,8BAA8B,CAAC;AAAA,QAAA;AAAA,MAC9C,GAGJpN,EAAQ;AAAA,QACN1iB;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,OAAO,KAAK,KAAK,EAAE,4BAA4B,EAAE,OAAAoJ,GAAO;AAAA,YACxD,SAAS,CAAC9B,MAAa;AACrB,cAAAA,EAAE,gBAAA,GACGooB,GAAkBtmB,CAAK,EAAE,KAAK,CAAC8kB,MAAO;AACzC,gBAAKA,MACL4B,EAAA,GACA,KAAK,WAAW,KAAK,KAAK,EAAE,sBAAsB,CAAC;AAAA,cACrD,CAAC;AAAA,YACH;AAAA,UAAA;AAAA,UAEF,CAAC,KAAK,KAAK,EAAE,aAAa,CAAC;AAAA,QAAA;AAAA,MAC7B,GAEFrN,EAAI;AAAA,QACFziB;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,SAAS,MAAM;AACb,mBAAK,kBAAkB3B,CAAC,GACxByxB,EAAA;AAAA,YACF;AAAA,UAAA;AAAA,UAEF;AAAA,YACE9vB,EAAE,QAAQ,EAAE,OAAO,uBAAuB,CAAC3B,EAAE,KAAK,CAAC;AAAA,YACnD2B,EAAE,QAAQ,EAAE,OAAO,qBAAqB,CAACoJ,CAAK,CAAC;AAAA,UAAA;AAAA,QACjD;AAAA,QAEFsZ;AAAA,MAAA,GAEFkN,EAAI,OAAOnN,CAAG;AAAA,IAChB;AAEA,SAAK,aAAa,OAAOmN,CAAG,GAC5BG,GAAsBH,GAAK73B,GAAQ,KAAK,IAAI,GAE5C83B,IAAa,CAACze,MAAmB;AAC/B,MAAI,CAACwe,EAAI,SAASxe,EAAG,MAAc,KAAKA,EAAG,WAAWrZ,KACpD+3B,EAAA;AAAA,IAEJ,GACA,WAAW,MAAM;AACf,MAAID,KAAY,SAAS,iBAAiB,SAASA,GAAY,EAAI;AAAA,IACrE,GAAG,CAAC,GACJ,KAAK,OAAO,wBAAwB,EAAI;AAAA,EAC1C;AAAA,EAEQ,WAAW75B,GAAc;AAC/B,UAAM2L,IAAI3B,EAAE,OAAO,EAAE,OAAO,WAAA,GAAc,CAAChK,CAAI,CAAC;AAChD,SAAK,aAAa,OAAO2L,CAAC,GAC1B,sBAAsB,MAAMA,EAAE,UAAU,IAAI,YAAY,CAAC,GACzD,WAAW,MAAM;AACf,MAAAA,EAAE,UAAU,OAAO,YAAY,GAC/B,WAAW,MAAMA,EAAE,OAAA,GAAU,GAAG;AAAA,IAClC,GAAG,IAAI;AAAA,EACT;AAAA,EAEQ,qBAAqBtD,GAAsB;;AACjD,UAAM+K,IAAQC,EAAoBhL,EAAE,GAAG,GACjC4O,IAAQ,KAAK,SAAS,YAAY,OAAO,GACzCxJ,IAAQwJ,EAAM;AACpB,IAAAxJ,EAAM,MAAM2F,GACZ3F,EAAM,QAAMrQ,IAAAiL,EAAE,UAAF,gBAAAjL,EAAS,WAAUiL,EAAE;AACjC,UAAMxI,IAAM,KAAK,MAAM;AACvB,gBAAK,MAAM,OAAO,CAACzD,MAAM;AACvB,WAAK,gCAAgCA,GAAGyD,GAAKoX,CAAK;AAAA,IACpD,CAAC,GACM;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,gCACN7a,GACAyD,GACAoX,GACM;;AACN,SAAIpX,KAAA,gBAAAA,EAAK,UAAS,SAAS;AACzB,YAAMyS,IAAMlW,EAAE,SAAS,KAAK,CAACoL,MAAMA,EAAE,OAAO3H,EAAI,SAAS,GACnD4P,IAAM6C,KAAA,gBAAAA,EAAK,QAAQzS,EAAI;AAC7B,UAAI4P,GAAK;AACP,cAAMvH,IAAMuH,EAAI,OAAO,UAAU,CAAC/K,MAAMA,EAAE,OAAO7E,EAAI,OAAO;AAC5D,QAAA4P,EAAI,OAAO,OAAOvH,KAAO,IAAIA,IAAM,IAAIuH,EAAI,OAAO,QAAQ,GAAGwH,CAAK;AAClE;AAAA,MACF;AAAA,IACF;AACA,SAAIpX,KAAA,gBAAAA,EAAK,UAAS,WAAW;AAC3B,YAAMyS,IAAMlW,EAAE,SAAS,KAAK,CAACoL,MAAMA,EAAE,OAAO3H,EAAI,SAAS;AACzD,OAAAzC,IAAAkV,KAAA,gBAAAA,EAAK,QAAQ,OAAb,QAAAlV,EAAiB,OAAO,KAAK6Z;AAC7B;AAAA,IACF;AACA,QAAIta,IAAUP,EAAE,SAASA,EAAE,SAAS,SAAS,CAAC;AAC9C,IAAKO,MACHA,IAAUsW,GAAc,GAAG,GAC3B7W,EAAE,SAAS,KAAKO,CAAO,KAEzBW,IAAAX,EAAQ,QAAQ,CAAC,MAAjB,QAAAW,EAAoB,OAAO,KAAK2Z;AAAA,EAClC;AAAA;AAAA,EAGQ,2BAA2B7D,GAAwB;AACzD,UAAMkK,IAAS,SAAS;AACxB,QACEA,MACCA,EAAO,YAAY,WAAWA,EAAO,YAAY,eAClD,KAAK,KAAK,SAASA,CAAM,GACzB;AACA,YAAM0S,IAAa1S,EAAO,aAAa,eAAe;AACtD,UAAI0S,KAAA,QAAAA,EAAY,WAAW,WAAW;AACpC,cAAMrf,IAAQqf,EAAW,MAAM,GAAG,GAC5B7d,IAAUxB,EAAM,CAAC,GACjBwS,IAAUxS,EAAM,CAAC;AACvB,YAAIwB,KAAWgR,KAAW,KAAK,iBAAiBhR,GAASgR,GAAS/P,CAAK;AACrE,iBAAAkK,EAAO,QAAQlK,GACfkK,EAAO,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACnD;AAAA,MAEX;AAAA,IACF;AAEA,UAAMzd,IAAM,KAAK,MAAM;AACvB,SAAIA,KAAA,gBAAAA,EAAK,UAAS,QAAS,QAAO;AAClC,UAAMmX,IAAM9E,EAAkB,KAAK,MAAM,KAAKrS,EAAI,OAAO;AACzD,QAAI,CAACmX,EAAK,QAAO;AACjB,UAAMgjB,IAAS,KAAK,kBAAkB,KAAK,SAAS,IAAIhjB,EAAI,MAAM,IAAI,CAAC;AACvE,WAAKgjB,KACL,KAAK,MAAM,OAAO,CAAC59B,MAAM;AACvB,YAAM,IAAI8V,EAAkB9V,GAAGyD,EAAI,OAAO;AAC1C,MAAI,MAAI,EAAE,MAAM,MAAkCm6B,CAAM,IAAI5mB;AAAA,IAC9D,CAAC,GACM,MALa;AAAA,EAMtB;AAAA,EAEQ,kBAAkBnX,GAAsD;;AAC9E,YAAOmB,IAAAnB,KAAA,gBAAAA,EAAK,OAAO,KAAK,CAACyqB,MAAMA,EAAE,SAAS,WAAnC,gBAAAtpB,EAA2C;AAAA,EACpD;AAAA,EAEQ,iBAAiB+U,GAAiBgR,GAAiB/P,GAAwB;;AACjF,UAAM4D,IAAM9E,EAAkB,KAAK,MAAM,KAAKC,CAAO;AACrD,QAAI,CAAC6E,EAAK,QAAO;AACjB,UAAMwW,KAAQpwB,IAAA,KAAK,SAAS,IAAI4Z,EAAI,MAAM,IAAI,MAAhC,gBAAA5Z,EAAmC,OAAO,KAAK,CAACspB,MAAMA,EAAE,QAAQvD;AAC9E,YAAIqK,KAAA,gBAAAA,EAAO,UAAS,QAAc,MAClC,KAAK,MAAM,OAAO,CAACpxB,MAAM;AACvB,YAAM0U,IAAIoB,EAAkB9V,GAAG+V,CAAO;AACtC,MAAIrB,MAAIA,EAAE,MAAM,MAAkCqS,CAAO,IAAI/P;AAAA,IAC/D,CAAC,GACM;AAAA,EACT;AAAA;AAAA,EAGQ,eAAeqP,GAAiBwX,GAA0B;AAChE,UAAMzb,IAAS,KAAK,OAAO;AAC3B,QAAIA;AACF,aAAIyb,IAAQzb,EAAO,WAAWiE,CAAO,IAChCjE,EAAO,WAAWiE,CAAO,GACvB;AAGT,UAAMnF,IAAS,SAAS;AACxB,QACEA,MACCA,EAAO,YAAY,WAAWA,EAAO,YAAY,eAClD,KAAK,KAAK,SAASA,CAAM;AAEzB,UAAI2c,GAAQ;AACV,cAAMjK,IAAa1S,EAAO,aAAa,eAAe;AACtD,YAAI0S,KAAA,QAAAA,EAAY,WAAW,WAAW;AACpC,gBAAMrf,IAAQqf,EAAW,MAAM,GAAG,GAC5B7d,IAAUxB,EAAM,CAAC,GACjBwS,IAAUxS,EAAM,CAAC;AACvB,cAAIwB,KAAWgR,GAAS;AACtB,kBAAM,IAAIV,EAAQ,MAAM,eAAe,GACjCrP,KAAQ,uBAAI,OAAMqP;AACxB,gBAAI,KAAK,iBAAiBtQ,GAASgR,GAAS/P,CAAK;AAC/C,qBAAAkK,EAAO,QAAQlK,GACfkK,EAAO,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACnD;AAAA,UAEX;AAAA,QACF;AAAA,MAEF,OAAO;AACL,cAAM1b,IAAQ0b,EAAO,kBAAkBA,EAAO,MAAM,QAC9Czb,IAAMyb,EAAO,gBAAgBA,EAAO,MAAM;AAChD,eAAAA,EAAO,QAAQA,EAAO,MAAM,MAAM,GAAG1b,CAAK,IAAI6gB,IAAUnF,EAAO,MAAM,MAAMzb,CAAG,GAC9Eyb,EAAO,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACnD;AAAA,MACT;AAGF,UAAMzd,IAAM,KAAK,MAAM;AACvB,SAAIA,KAAA,gBAAAA,EAAK,UAAS,SAAS;AACzB,UAAIq6B,IAAU;AAkBd,UAjBA,KAAK,MAAM,OAAO,CAAC,MAAM;;AACvB,mBAAW1yB,KAAK,EAAE;AAChB,qBAAWhF,KAAKgF,EAAE,SAAS;AACzB,kBAAM9C,IAAIlC,EAAE,OAAO,KAAK,CAACqO,MAAMA,EAAE,OAAOhR,EAAI,OAAO;AACnD,gBAAI,CAAC6E,EAAG;AACR,kBAAMzI,IAAM,KAAK,SAAS,IAAIyI,EAAE,IAAI,GAC9B5H,KAAMM,IAAAnB,KAAA,gBAAAA,EAAK,mBAAL,gBAAAmB,EAAqB;AACjC,gBAAI,CAACN,EAAK;AACV,kBAAMmyB,IAAM,OAAQvqB,EAAE,MAAkC5H,CAAG,KAAK,EAAE,GAC5Dq9B,IAAal+B,EAAI,eAAgB,SAAS;AAC/C,YAAAyI,EAAE,MAAkC5H,CAAG,IAAIq9B,IACxChmB,GAAuB8a,GAAKxM,CAAO,IACnCwM,IAAMxM,GACVyX,IAAU;AAAA,UACZ;AAAA,MAEJ,CAAC,GACGA,EAAS,QAAO;AAAA,IACtB;AAEA,UAAMjjB,IAAQ,KAAK,SAAS,YAAY,MAAM,GACxCmjB,IAAUjmB,GAAuB,IAAIsO,CAAO;AACjD,WAAAxL,EAAM,MAA8B,UAAUmjB,GAC/C,KAAK,MAAM,OAAO,CAACh+B,MAAM;AACvB,WAAK,gCAAgCA,GAAGyD,GAAKoX,CAAK;AAAA,IACpD,CAAC,GACM;AAAA,EACT;AAAA,EAEQ,wBAAwB;AAC9B,IAAI,KAAK,mBACT,KAAK,iBAAiB,IAAIygB,GAAe;AAAA,MACvC,eAAeM;AAAA,MACf,SAAS,CAAC96B,MAAQ,KAAK,kBAAkBA,CAAG;AAAA,MAC5C,GAAG,KAAK,KAAK;AAAA,IAAA,CACd;AAAA,EACH;AAAA,EAEQ,kBAAkB2B,GAAkB;;AAC1C,UAAMgzB,IAAU,KAAK,MAAM;AAC3B,QAAI/yB,IAAO04B,GAAiB34B,CAAM;AAClC,KAAIzB,IAAA,KAAK,KAAK,OAAV,QAAAA,EAAc,iBAChB0B,IAAO;AAAA,MACL,GAAGA;AAAA,MACH,MAAM,EAAE,GAAG+yB,EAAQ,KAAA;AAAA,IAAK,IAG5B,KAAK,SAAS/yB,CAAI,GAClB,KAAK,MAAM,aAAa,IAAI,GAC5B,KAAK,WAAW,KAAK,KAAK,EAAE,sBAAsB,CAAC;AAAA,EACrD;AAAA,EAEQ,cAAc;AAEpB,SAAK,OAAO,iBAAA,GACE,IAAI8lB,GAAY;AAAA,MAC5B,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG,KAAK,KAAK;AAAA,MACb,qBAAqB;AAAA,IAAA,CACtB,EACK,KAAK,KAAK,IAAI;AAAA,EACtB;AAAA,EAEQ,eAAe;AACrB,SAAK,OAAO,iBAAA,GACE,IAAIyB,GAAa;AAAA,MAC7B,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG,KAAK,KAAK;AAAA,IAAA,CACd,EACK,KAAK,KAAK,IAAI;AAAA,EACtB;AAAA,EAEQ,uBAA4C;AAClD,WAAO;AAAA,MACL,kBAAkBgS,SAA6B,KAAK;AAAA,MACpD,WAAW,KAAK,KAAK;AAAA,IAAA;AAAA,EAEzB;AAAA,EAEQ,oBAAoB;AAC1B,UAAMvV,IAAM,KAAK;AACjB,QAAI,CAACA,EAAK;AACV,UAAM9U,IAAM,KAAK,qBAAA;AACjB,QAAI,CAACsrB,GAAoB,KAAK,KAAK,IAAItrB,CAAG,GAAG;AAC3C,MAAA8U,EAAI,WAAW,EAAI;AACnB;AAAA,IACF;AAEA,IAAAA,EAAI,WAAW,EAAK;AACpB,UAAMhlB,IAAKglB,EAAI;AACf,IAAIhlB,EAAG,cAAcA,EAAG,cAAc,KAAGglB,EAAI,WAAW,EAAI;AAAA,EAC9D;AAAA,EAEQ,yBAAyB;;AAC/B,MAAI1lB,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,mBAAkB,OACpC,KAAK,kBAAA,GACL,KAAK,uBAAuB,IAAI,eAAe,MAAM;AACnD,MAAI,KAAK,mBAAiB,qBAAqB,KAAK,eAAe,GACnE,KAAK,kBAAkB,sBAAsB,MAAM;AACjD,aAAK,kBAAkB,GACvB,KAAK,kBAAA;AAAA,MACP,CAAC;AAAA,IACH,CAAC,GACD,KAAK,qBAAqB,QAAQ,KAAK,IAAI;AAAA,EAC7C;AAAA,EAEQ,2BAA2B;;AACjC,KAAAA,IAAA,KAAK,yBAAL,QAAAA,EAA2B,cAC3B,KAAK,uBAAuB,MACxB,KAAK,oBACP,qBAAqB,KAAK,eAAe,GACzC,KAAK,kBAAkB;AAAA,EAE3B;AAAA,EAEQ,kBAAkB;;AACxB,MAAIA,IAAA,KAAK,KAAK,OAAV,gBAAAA,EAAc,0BAAyB,OAC3C,SAAS,iBAAiB,oBAAoB,KAAK,mBAAmB,GACtE,SAAS,iBAAiB,0BAA0B,KAAK,mBAAmB,GAC5E,KAAK,oBAAA;AAAA,EACP;AAAA,EAEQ,oBAAoB;AAC1B,aAAS,oBAAoB,oBAAoB,KAAK,mBAAmB,GACzE,SAAS,oBAAoB,0BAA0B,KAAK,mBAAmB;AAAA,EACjF;AAAA,EAEA,MAAc,oBAAoB;AAChC,QAAI;AACF,MAAIi7B,GAAA,MAA6B,KAAK,aAAYa,GAAA,IAC7C,MAAMmB,GAAoB,KAAK,IAAI;AAAA,IAC1C,SAAS9O,GAAK;AACZ,cAAQ,KAAK,wBAAwBA,CAAG;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,uBAAuB;AAC7B,SAAK,oBAAoB,CAAC,KAAK,mBAC/B,KAAK,KAAK,UAAU,OAAO,0BAA0B,KAAK,iBAAiB,GAC3E,KAAK,OAAO,uBAAuB,KAAK,iBAAiB;AAAA,EAC3D;AACF;AAGA,SAASwO,GAAsBjgB,GAAoB/X,GAAqB7D,GAAmB;AACzF,QAAM8b,IAAOjY,EAAO,sBAAA,GACdkY,IAAW/b,EAAK,sBAAA,GAChByQ,IAAM,GACN2rB,IAAS;AACf,EAAAxgB,EAAM,MAAM,MAAM,GAAGE,EAAK,SAASC,EAAS,MAAMtL,CAAG;AACrD,QAAMN,IAAIyL,EAAM;AAChB,MAAIkO,IAAOhO,EAAK,OAAOC,EAAS;AAChC,QAAMsgB,IAAYvgB,EAAK,OAAOA,EAAK,QAAQ,KACrCwgB,IAAUvgB,EAAS,OAAOA,EAAS,QAAQ;AACjD,EAAIsgB,KAAaC,MACfxS,IAAOhO,EAAK,QAAQC,EAAS,OAAO5L,IAEtC2Z,IAAO,KAAK,IAAIsS,GAAQ,KAAK,IAAItS,GAAM/N,EAAS,QAAQ5L,IAAIisB,CAAM,CAAC,GACnExgB,EAAM,MAAM,OAAO,GAAGkO,CAAI;AAC5B;AAEO,MAAMyS,KAAmC;AAQzC,SAASnB,GACdC,GACAvrB,GACS;AACT,OAAIurB,KAAA,gBAAAA,EAAI,mBAAkB,GAAM,QAAO;AACvC,QAAMmB,IAASnB,EAAG,gBAAgB;AAClC,MAAImB,MAAW,SAAU,QAAO;AAChC,MAAIA,MAAW,QAAS,QAAO;AAC/B,QAAMC,IAAOpB,EAAG,yBAAyBkB;AACzC,SAAOzsB,EAAI,oBAAoBA,EAAI,aAAa2sB;AAClD;AAEA,eAAejB,GAAkBtmB,GAAiC;AAChE,MAAI;AACF,iBAAM,UAAU,UAAU,UAAUA,CAAK,GAClC;AAAA,EACT,QAAQ;AAAA,EAER;AACA,MAAI;AACF,UAAM6R,IAAK,SAAS,cAAc,UAAU;AAC5C,IAAAA,EAAG,QAAQ7R,GACX6R,EAAG,aAAa,YAAY,MAAM,GAClCA,EAAG,MAAM,WAAW,SACpBA,EAAG,MAAM,OAAO,WAChB,SAAS,KAAK,YAAYA,CAAE,GAC5BA,EAAG,OAAA;AACH,UAAMiT,IAAK,SAAS,YAAY,MAAM;AACtC,oBAAS,KAAK,YAAYjT,CAAE,GACrBiT;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASG,KAAyC;AAChD,QAAMj8B,IAAI;AACV,SAAO,SAAS,qBAAqBA,EAAE,2BAA2B;AACpE;AAEA,eAAei+B,GAAoBv8B,GAAgC;AACjE,QAAM88B,IAAQ98B;AACd,EAAI,OAAO88B,EAAM,qBAAsB,aAAY,MAAMA,EAAM,kBAAA,IACtD,OAAOA,EAAM,2BAA4B,cAAY,MAAMA,EAAM,wBAAA;AAC5E;AAEA,eAAe1B,KAAkC;AAC/C,QAAM98B,IAAI;AACV,EAAI,OAAO,SAAS,kBAAmB,aAAY,MAAM,SAAS,eAAA,IACzD,OAAOA,EAAE,wBAAyB,cAAY,MAAMA,EAAE,qBAAA;AACjE;AAIA,SAASs8B,GACPx7B,GACA2B,GACA8M,GACM;;AACN,IAAIvO,IAAAyB,KAAA,gBAAAA,EAAQ,SAAR,gBAAAzB,EAAc,YAAW,WAAU,KAAK,UAAUuO,EAAE,oBAAoB;AAC9E;AAEA,SAAS8sB,GAAiBlV,GAAuC;AAC/D,QAAMsX,IAAe;AAAA,IACnB,iBAAiB;AAAA,IACjB,wBAAwB;AAAA,IACxB,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,IAAItX,KAAA,gBAAAA,EAAS,WAAU,CAAA;AAAA,EAAC;AAE1B,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,MACP,IAAIA,KAAA,gBAAAA,EAAS,SAAQ,CAAA;AAAA,IAAC;AAAA,IAExB,YAAWA,KAAA,gBAAAA,EAAS,cAAa,CAAA;AAAA,IACjC,QAAQ;AAAA,MACN,GAAGsX;AAAA,MACH,YAAYA,EAAa,cAAc;AAAA,MACvC,YAAYA,EAAa,cAAc;AAAA,IAAA;AAAA,IAEzC,WAAUtX,KAAA,gBAAAA,EAAS,aAAY,CAAA;AAAA,EAAC;AAEpC;"}