{"version":3,"file":"core.umd.cjs","sources":["../../i18n/src/index.ts","../../i18n/src/zh-cn.ts","../../i18n/src/zh-tw.ts","../../i18n/src/en-us.ts","../../i18n/src/ja-jp.ts","../../i18n/src/ko-kr.ts","../../../plugins/docx-editor-schema/src/constants.ts","../../../plugins/docx-editor-schema/src/author-color.ts","../../../plugins/docx-editor-schema/src/revision.ts","../../../node_modules/.pnpm/rfdc@1.4.1/node_modules/rfdc/index.js","../../../plugins/docx-editor-schema/src/walk.ts","../../../plugins/docx-editor-schema/src/format.ts","../../../plugins/docx-editor-schema/src/paragraph.ts","../../../plugins/docx-editor-schema/src/export.ts","../../../plugins/docx-editor-schema/src/keymap.ts","../../../node_modules/.pnpm/eventemitter3@5.0.4/node_modules/eventemitter3/index.js","../../../plugins/docx-editor-state/src/event-bus.ts","../../../plugins/docx-editor-state/src/listener.ts","../../../plugins/docx-editor-state/src/range-manager.ts","../../../plugins/docx-editor-view/src/text-measure.ts","../../../plugins/docx-editor-view/src/list-bullet.ts","../../../plugins/docx-editor-view/src/layout-engine.ts","../../../plugins/docx-editor-view/src/block-painter.ts","../../../plugins/docx-editor-view/src/block-signature.ts","../../../plugins/docx-editor-view/src/canvas-renderer.ts","../../../plugins/docx-editor-view/src/hit-test.ts","../../../plugins/docx-editor-view/src/caret-rect.ts","../../../plugins/docx-editor-view/src/view-i18n.ts","../../../plugins/docx-editor-view/src/context-menu.ts","../../../plugins/docx-editor-view/src/widgets/handle-position.ts","../../../plugins/docx-editor-view/src/assets/components/table-properties-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/table-properties-widget.ts","../../../plugins/docx-editor-view/src/widgets/table-widget.ts","../../../plugins/docx-editor-view/src/widgets/selection-layer.ts","../../../plugins/docx-editor-view/src/widgets/image-widget.ts","../../../plugins/docx-editor-view/src/widgets/chart-widget.ts","../../../plugins/docx-editor-view/src/assets/components/paragraph-layout-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/paragraph-layout-widget.ts","../../../plugins/docx-editor-view/src/assets/components/font-layout-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/font-layout-widget.ts","../../../plugins/docx-editor-view/src/assets/components/hyperlink-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/hyperlink-widget.ts","../../../plugins/docx-editor-view/src/widgets/paragraph-widget.ts","../../../plugins/docx-editor-view/src/widgets/header-footer-widget.ts","../../../plugins/docx-editor-view/src/widgets/ruler-widget.ts","../../../plugins/docx-editor-view/src/widgets/watermark-widget.ts","../../../plugins/docx-editor-view/src/widgets/watermark-system-widget.ts","../../../plugins/docx-editor-view/src/widgets/selection-toolbar-widget.ts","../../../plugins/docx-editor-view/src/widgets/caret-widget.ts","../../../plugins/docx-editor-view/src/render-state.ts","../../../plugins/docx-editor-view/src/layout-query.ts","../../../plugins/docx-editor-view/src/anchor-collector.ts","../../../plugins/docx-editor-view/src/caret-navigation.ts","../../../plugins/docx-editor-view/src/zone-manager.ts","../../../plugins/docx-editor-view/src/draw.ts","../src/command-chain.ts","../../../plugins/docx-editor-transform/src/command-adapt.ts","../../../plugins/docx-editor-transform/src/command.ts","../../../plugins/docx-editor-commands/src/constants.ts","../../../plugins/docx-editor-commands/src/date-picker.ts","../../../plugins/docx-editor-commands/src/date-particle.ts","../../../plugins/docx-editor-commands/src/latex-hershey.ts","../../../plugins/docx-editor-commands/src/latex-symbols.ts","../../../plugins/docx-editor-commands/src/latex-utils.ts","../../../plugins/docx-editor-commands/src/latex-particle.ts","../../../plugins/docx-editor-commands/src/search.ts","../../../plugins/docx-editor-commands/src/block-iframe.ts","../../../plugins/docx-editor-commands/src/block-base.ts","../../../plugins/docx-editor-commands/src/block-particle.ts","../../../plugins/docx-editor-commands/src/control-component.ts","../../../plugins/docx-editor-history/src/history-manager.ts","../../../plugins/docx-editor-history/src/history-component.ts","../src/shortcut.ts","../src/workers/compute.ts","../src/workers/worker-manager.ts","../src/workers/thumbnail-manager.ts","../src/docx-editor.ts","../src/constants.ts","../src/index.ts"],"sourcesContent":["import zhCN from './zh-cn.js'\r\nimport zhTW from './zh-tw.js'\r\nimport enUS from './en-us.js'\r\nimport jaJP from './ja-jp.js'\r\nimport koKR from './ko-kr.js'\r\n\r\nexport const builtinMessages = { zhCN, zhTW, enUS, jaJP, koKR }\r\nexport type BuiltinLocale = keyof typeof builtinMessages\r\nexport type EditorI18n = I18n<BuiltinLocale>\r\n\r\nexport function createEditorI18n(locale: BuiltinLocale = 'zhCN'): EditorI18n {\r\n  return createI18n(builtinMessages, locale, 'zhCN')\r\n}\r\n\r\nexport type Messages = { [key: string]: string | Messages }\r\nexport type Translate = (key: string, params?: Record<string, string | number>) => string\r\n\r\nexport interface I18n<Locale extends string> {\r\n  readonly locale: Locale\r\n  t: Translate\r\n  setLocale(locale: Locale): void\r\n  subscribe(listener: () => void): () => void\r\n}\r\n\r\nfunction lookup(messages: Messages | undefined, key: string): string | undefined {\r\n  let value: string | Messages | undefined = messages\r\n  for (const segment of key.split('.')) {\r\n    if (typeof value !== 'object' || value === null) return undefined\r\n    value = value[segment]\r\n  }\r\n  return typeof value === 'string' ? value : undefined\r\n}\r\n\r\nexport function createI18n<Locale extends string>(\r\n  bundles: Record<Locale, Messages>,\r\n  initialLocale: Locale,\r\n  fallbackLocale: Locale = initialLocale\r\n): I18n<Locale> {\r\n  let locale = initialLocale\r\n  const listeners = new Set<() => void>()\r\n\r\n  return {\r\n    get locale() { return locale },\r\n    t(key, params) {\r\n      const message = lookup(bundles[locale], key) ?? lookup(bundles[fallbackLocale], key) ?? key\r\n      return message.replace(/\\{(\\w+)\\}/g, (_, name: string) => String(params?.[name] ?? ''))\r\n    },\r\n    setLocale(nextLocale) {\r\n      if (locale === nextLocale) return\r\n      locale = nextLocale\r\n      listeners.forEach(listener => listener())\r\n    },\r\n    subscribe(listener) {\r\n      listeners.add(listener)\r\n      return () => listeners.delete(listener)\r\n    }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: '插入图表', settings: '设置', data: '数据', selectType: '选择图表类型', preview: '图表预览', config: '图表配置', clear: '清空', cancel: '取消', confirm: '确定' },\r\n    category: { bar: '柱形图', line: '折线图', pie: '饼图', scatter: '散点图', radar: '雷达图', mixed: '混合图表' },\r\n    preview: { 'bar-basic': '基础柱状图', 'bar-stacked': '堆叠柱状图', 'bar-horizontal': '横向柱状图', 'line-basic': '基础折线图', 'line-smooth': '平滑折线图', 'line-stacked': '堆叠折线图', 'line-area': '堆叠面积图', 'line-step': '阶梯折线图', 'line-dashed': '虚线折线图', 'pie-basic': '基础饼图', 'pie-doughnut': '环形图', 'scatter-basic': '基础散点图', 'radar-basic': '基础雷达图', 'radar-filled': '填充雷达图', 'mixed-line-bar': '折柱混合' },\r\n    config: { showTitle: '显示标题', title: '标题名称', titlePlaceholder: '请输入图表标题', titlePosition: '标题位置', showLegend: '显示图例', legendPosition: '图例位置', xAxisLabel: 'X轴标题', xAxisPlaceholder: '请输入X轴标题', yAxisLabel: 'Y轴标题', yAxisPlaceholder: '请输入Y轴标题', showGrid: '显示网格线', showDataLabel: '显示数据标签', colorScheme: '配色方案' },\r\n    position: { left: '左', center: '中', right: '右', top: '上', bottom: '下' },\r\n    colorScheme: { default: '默认', warm: '暖色调', cool: '冷色调', nature: '自然色' },\r\n    sample: { series: '系列{index}', category: '类别{index}' },\r\n    noData: '暂无数据', data: '数据'\r\n  },\r\n  view: {\r\n    common: {\r\n      cancel: '取消', confirm: '确定', none: '无', leftAlign: '左对齐', rightAlign: '右对齐',\r\n      center: '居中', justify: '两端对齐', distribute: '分散对齐', preview: '预览',\r\n      color: '颜色', spacing: '间距', points: '磅'\r\n    },\r\n    paragraph: {\r\n      format: '段落格式', body: '正文', heading1: '一级标题', heading2: '二级标题',\r\n      heading3: '三级标题', heading4: '四级标题', heading5: '五级标题', heading6: '六级标题',\r\n      cut: '剪切', copy: '复制', paste: '粘贴', fontSettings: '字体...',\r\n      advancedSettings: '段落高级设置', link: '超链接', comment: '插入批注'\r\n    },\r\n    hyperlink: {\r\n      text: '显示文字', address: '链接地址',\r\n      addressPlaceholder: '请输入完整地址（如 https://example.com）',\r\n      textRequired: '请输入显示文字', addressRequired: '请输入链接地址',\r\n      addressInvalid: '链接地址必须使用 http、https、mailto、tel 或 ftp 协议',\r\n      unsupported: '超链接未插入，未能获取具体原因。请重新选择文字后重试，文档未修改。',\r\n      bookmarkSelection: '选区包含书签标记，当前编辑器暂不支持跨书签插入超链接。请调整选区避开书签边界；原文和书签均未修改。',\r\n      fieldSelection: '选区包含 Word 域标记（如目录或页码），暂不支持插入超链接。请选择域以外的普通文字，文档未修改。',\r\n      existingLink: '选区包含已有超链接，当前暂不支持嵌套或替换链接。请选择尚未添加链接的文字，文档未修改。',\r\n      crossContainer: '选区跨越不同文本容器（如段落或单元格）。请在同一段落内选择文字后重试，文档未修改。',\r\n      crossParagraph: '选区包含换行或段落结束标记。请选择同一段落内不含换行的文字，文档未修改。',\r\n      revisions: '选区包含尚未处理的修订。请先审阅并接受或拒绝相关修订，或选择不含修订的文字，文档未修改。',\r\n      tracking: '当前已开启修订模式，暂不支持插入超链接。请关闭修订模式后重试，文档未修改。',\r\n      readOnly: '文档处于只读模式，无法插入超链接。请切换到可编辑模式后重试，文档未修改。',\r\n      disabled: '编辑功能已被禁用，无法插入超链接。请启用编辑后重试，文档未修改。',\r\n      noSelection: '未找到光标位置或文字选区。请关闭弹窗，在正文中放置光标或选择文字后重试，文档未修改。',\r\n      invalidSelection: '文字选区已失效。请关闭弹窗并重新选择文字后重试，文档未修改。',\r\n      nonText: '选区包含图片、表格等非普通文本内容。请只选择普通文字，文档未修改。',\r\n      invalidText: '显示文字必须为非空的普通文本，且不能包含换行或隐藏控制标记。请修改显示文字后重试，文档未修改。'\r\n    },\r\n    table: {\r\n      insert: '插入', insertLeft: '在左侧插入', insertRight: '在右侧插入',\r\n      insertAbove: '在上方插入', insertBelow: '在下方插入', columnUnit: '列', rowUnit: '行',\r\n      insertCell: '单元格(E)...', splitCell: '拆分单元格', mergeCell: '合并单元格',\r\n      delete: '删除', deleteRow: '删除行', deleteColumn: '删除列', deleteTable: '删除整个表格',\r\n      selectAll: '全选表格', horizontalAlign: '水平对齐方式', centerAlign: '居中对齐',\r\n      verticalAlign: '垂直对齐方式', alignTop: '顶端对齐', alignMiddle: '垂直居中',\r\n      alignBottom: '底端对齐', background: '底纹颜色', repeatHeader: '重复表头行',\r\n      properties: '表格属性', select: '选择表格', addColumn: '添加列', addRow: '添加行'\r\n    },\r\n    font: {\r\n      title: '字体', characterSpacing: '字符间距', cjkFont: '中文字体', style: '字形',\r\n      regular: '常规', italic: '倾斜', bold: '加粗', boldItalic: '加粗倾斜', size: '字号',\r\n      effects: '效果', strikethrough: '删除线', underline: '下划线', superscript: '上标',\r\n      subscript: '下标', doubleStrikethrough: '双删除线', hidden: '隐藏',\r\n      previewText: '字体预览文本 ABCabc 123', scale: '缩放', standard: '标准',\r\n      expanded: '加宽', condensed: '紧缩', position: '位置', raised: '提升', lowered: '降低',\r\n      spacingPreview: '字符间距预览 ABCabc 123', unsupported: '间距与位置功能将在后续版本支持'\r\n    },\r\n    paragraphDialog: {\r\n      title: '段落', indentSpacing: '缩进和间距', linePageBreak: '换行和分页',\r\n      cjkLayout: '中文版式', general: '常规', alignment: '对齐方式', outline: '大纲级别',\r\n      bodyText: '正文文本', level1: '1 级', level2: '2 级', level3: '3 级',\r\n      level4: '4 级', level5: '5 级', level6: '6 级', indent: '缩进',\r\n      beforeText: '文本之前', afterText: '文本之后', special: '特殊格式',\r\n      firstLine: '首行缩进', hanging: '悬挂缩进', measure: '度量值', cm: '厘米',\r\n      adjustRightIndent: '如果定义了文档网格，则自动调整右缩进', before: '段前', after: '段后',\r\n      lineSpacing: '行距', single: '单倍行距', oneHalf: '1.5 倍行距', double: '双倍行距',\r\n      atLeast: '最小值', exact: '固定值', multiple: '多倍行距', setting: '设置值', times: '倍',\r\n      alignGrid: '如果定义了文档网格，则与网格对齐', previewText: '段落预览文本',\r\n      pagination: '分页', widow: '孤行控制', keepNext: '与下段同页', breakBefore: '段前分页',\r\n      lineBreak: '换行', noLineNumber: '取消行号', noHyphen: '取消断字',\r\n      unsupported: '该功能将在后续版本支持', cjkWrap: '按中文习惯换行',\r\n      punctuationOverflow: '允许标点溢出边界', wordBreak: '允许西文在单词中间换行',\r\n      compressPunctuation: '允许行首标点压缩', cjkWesternSpacing: '自动调整中文与西文的间距',\r\n      cjkNumberSpacing: '自动调整中文与数字的间距', textAlignment: '文字对齐方式',\r\n      align: '对齐', auto: '自动', baseline: '基线对齐'\r\n    },\r\n    tableDialog: {\r\n      categories: '属性类别', table: '表格', cell: '单元格',\r\n      presetHint: '预设替换整个表格的边框组合，未选中的边将清除。', border: '边框',\r\n      preset: '预设', unchanged: '保持原样', allBorders: '全部边框',\r\n      outsideBorders: '外侧边框', noBorders: '无边框', insideBorders: '内部边框',\r\n      insideHorizontal: '内部横线', insideVertical: '内部竖线', topBorder: '上边框',\r\n      bottomBorder: '下边框', leftBorder: '左边框', rightBorder: '右边框',\r\n      borderPresets: '边框预设', all: '全部', outside: '外侧', inside: '内部',\r\n      colorFormatTitle: '请输入 #RRGGBB 格式的颜色',\r\n      colorFormatClearTitle: '请输入 #RRGGBB 格式的颜色，留空清除',\r\n      borderColor: '边框颜色', cellColor: '单元格底色', chooseColor: '选择{label}（当前{state}）',\r\n      innerWidth: '内框宽度', outerWidth: '外框宽度', innerWidthAria: '内框宽度（像素）',\r\n      outerWidthAria: '外框宽度（像素）', colorHelp: '颜色格式：#RRGGBB；留空保持原样。',\r\n      borderPreview: '边框示意',\r\n      presetPreview: '边框组合示意；虚线仅标示表格范围。未填写的颜色、宽度保持原样。',\r\n      unchangedPreview: '未选择预设，边框组合保持原样；示意不代表混合样式。',\r\n      cellHint: '以下设置仅应用于当前单元格（右键所在格）。', fill: '底色',\r\n      noFill: '无底色', invalidColor: '颜色格式无效', clearFill: '清除底色',\r\n      fillHelp: '颜色格式：#RRGGBB；留空表示无底色。', verticalAlign: '垂直对齐',\r\n      alignCenter: '居中对齐'\r\n    },\r\n    pageNumber: {\r\n      header: '页眉', footer: '页脚', insert: '插入页码', style: '样式:', position: '位置:',\r\n      left: '左侧', center: '居中', right: '右侧', stylePage: '第1页',\r\n      styleTotal: '第1页共x页', styleFirst: '第一页', styleFirstTotal: '第一页共X页'\r\n    },\r\n    fontFamily: {\r\n      SimSun: '宋体', SimHei: '黑体', KaiTi: '楷体', FangSong: '仿宋',\r\n      MicrosoftYaHei: '微软雅黑', DengXian: '等线', STSong: '华文宋体',\r\n      STHeiti: '华文黑体', STKaiti: '华文楷体', STFangsong: '华文仿宋',\r\n      STZhongsong: '华文中宋', STXihei: '华文细黑', STXingkai: '华文行楷',\r\n      STLiti: '华文隶书', STXinwei: '华文新魏', STCaiyun: '华文彩云'\r\n    },\r\n    fontSize: {\r\n      chuhao: '初号', xiaochu: '小初', yihao: '一号', xiaoyi: '小一',\r\n      erhao: '二号', xiaoer: '小二', sanhao: '三号', xiaosan: '小三',\r\n      sihao: '四号', xiaosi: '小四', wuhao: '五号', xiaowu: '小五',\r\n      liuhao: '六号', xiaoliu: '小六', qihao: '七号', bahao: '八号'\r\n    }\r\n  },\r\n  comment: {\r\n    balloon: {\r\n      edit: '编辑批注', delete: '删除批注', resolve: '解决批注', reopen: '重新打开批注',\r\n      placeholder: '请输入批注内容...', save: '保存', cancel: '取消', source: '取自：',\r\n      addReply: '添加回复', replyPlaceholder: '输入回复...', reply: '回复'\r\n    },\r\n    revision: {\r\n      unknownAuthor: '未知', accept: '接受修订', reject: '拒绝修订', insert: '插入：',\r\n      delete: '删除：', format: '格式：', bold: '加粗', italic: '斜体', underline: '下划线',\r\n      strikeout: '删除线', doubleStrikeout: '双删除线', hidden: '隐藏', superscript: '上标',\r\n      subscript: '下标', color: '字体颜色', size: '字号', font: '字体', highlight: '高亮',\r\n      characterScale: '字符缩放', letterSpacing: '字符间距', textDecoration: '装饰线样式',\r\n      rowFlex: '对齐方式', lineHeight: '行距', lineHeightRule: '行距规则', rowMargin: '行间距',\r\n      paragraphIndentLeft: '左缩进', paragraphIndentRight: '右缩进',\r\n      paragraphFirstLineIndent: '首行缩进', indentHanging: '悬挂缩进',\r\n      paragraphSpacingBefore: '段前间距', paragraphSpacingAfter: '段后间距',\r\n      alignLeft: '左对齐', alignCenter: '居中', alignRight: '右对齐',\r\n      alignJustify: '两端对齐', alignDistribute: '分散对齐', undo: '取消', default: '默认',\r\n      property: '{label}: {value}', formatDescription: '设置格式: {details}',\r\n      setFormat: '设置格式', separator: '，', descriptionSeparator: '；'\r\n    }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: '插入圖表', settings: '設定', data: '資料', selectType: '選擇圖表類型', preview: '圖表預覽', config: '圖表設定', clear: '清除', cancel: '取消', confirm: '確定' },\r\n    category: { bar: '直條圖', line: '折線圖', pie: '圓餅圖', scatter: '散佈圖', radar: '雷達圖', mixed: '組合圖' },\r\n    preview: { 'bar-basic': '基本直條圖', 'bar-stacked': '堆疊直條圖', 'bar-horizontal': '橫條圖', 'line-basic': '基本折線圖', 'line-smooth': '平滑折線圖', 'line-stacked': '堆疊折線圖', 'line-area': '堆疊區域圖', 'line-step': '階梯折線圖', 'line-dashed': '虛線折線圖', 'pie-basic': '基本圓餅圖', 'pie-doughnut': '環圈圖', 'scatter-basic': '基本散佈圖', 'radar-basic': '基本雷達圖', 'radar-filled': '填滿雷達圖', 'mixed-line-bar': '折線直條組合圖' },\r\n    config: { showTitle: '顯示標題', title: '標題名稱', titlePlaceholder: '請輸入圖表標題', titlePosition: '標題位置', showLegend: '顯示圖例', legendPosition: '圖例位置', xAxisLabel: 'X 軸標題', xAxisPlaceholder: '請輸入 X 軸標題', yAxisLabel: 'Y 軸標題', yAxisPlaceholder: '請輸入 Y 軸標題', showGrid: '顯示格線', showDataLabel: '顯示資料標籤', colorScheme: '配色方案' },\r\n    position: { left: '左', center: '中', right: '右', top: '上', bottom: '下' },\r\n    colorScheme: { default: '預設', warm: '暖色調', cool: '冷色調', nature: '自然色' },\r\n    sample: { series: '數列{index}', category: '類別{index}' },\r\n    noData: '暫無資料', data: '資料'\r\n  },\r\n  view: {\r\n    common: { cancel: '取消', confirm: '確定', none: '無', leftAlign: '靠左對齊', rightAlign: '靠右對齊', center: '置中', justify: '左右對齊', distribute: '分散對齊', preview: '預覽', color: '顏色', spacing: '間距', points: '點' },\r\n    paragraph: { format: '段落格式', body: '內文', heading1: '標題 1', heading2: '標題 2', heading3: '標題 3', heading4: '標題 4', heading5: '標題 5', heading6: '標題 6', cut: '剪下', copy: '複製', paste: '貼上', fontSettings: '字型...', advancedSettings: '進階段落設定', link: '超連結', comment: '插入批註' },\r\n    hyperlink: {\r\n      text: '顯示文字', address: '連結位址', addressPlaceholder: '請輸入完整位址（例如 https://example.com）',\r\n      textRequired: '請輸入顯示文字', addressRequired: '請輸入連結位址',\r\n      addressInvalid: '連結位址必須使用 http、https、mailto、tel 或 ftp 通訊協定',\r\n      unsupported: '未插入超連結，無法取得具體原因。請重新選取文字後重試，文件未修改。',\r\n      bookmarkSelection: '選取範圍包含書籤標記，目前編輯器尚不支援跨書籤插入超連結。請調整選取範圍以避開書籤邊界；原文和書籤均未修改。',\r\n      fieldSelection: '選取範圍包含 Word 功能變數標記（如目錄或頁碼）。請選取功能變數以外的一般文字，文件未修改。',\r\n      existingLink: '選取範圍包含現有超連結，目前尚不支援巢狀或取代連結。請選取尚未加入連結的文字，文件未修改。',\r\n      crossContainer: '選取範圍跨越不同文字容器（如段落或儲存格）。請在同一段落內選取文字，文件未修改。',\r\n      crossParagraph: '選取範圍包含換行或段落結束標記。請選取同一段落內不含換行的文字，文件未修改。',\r\n      revisions: '選取範圍包含尚未處理的修訂。請先檢閱並接受或拒絕相關修訂，或選取不含修訂的文字，文件未修改。',\r\n      tracking: '目前已開啟追蹤修訂，尚不支援插入超連結。請關閉追蹤修訂後重試，文件未修改。',\r\n      readOnly: '文件處於唯讀模式。請切換至可編輯模式後重試，文件未修改。',\r\n      disabled: '編輯功能已停用。請啟用編輯後重試，文件未修改。',\r\n      noSelection: '找不到游標位置或文字選取範圍。請關閉對話方塊，在內文中放置游標或選取文字後重試，文件未修改。',\r\n      invalidSelection: '文字選取範圍已失效。請關閉對話方塊並重新選取文字，文件未修改。',\r\n      nonText: '選取範圍包含圖片、表格等非一般文字內容。請只選取一般文字，文件未修改。',\r\n      invalidText: '顯示文字必須為非空的一般文字，且不能包含換行或隱藏控制標記。請修改顯示文字後重試，文件未修改。'\r\n    },\r\n    table: { insert: '插入', insertLeft: '在左側插入', insertRight: '在右側插入', insertAbove: '在上方插入', insertBelow: '在下方插入', columnUnit: '欄', rowUnit: '列', insertCell: '儲存格(E)...', splitCell: '分割儲存格', mergeCell: '合併儲存格', delete: '刪除', deleteRow: '刪除列', deleteColumn: '刪除欄', deleteTable: '刪除整個表格', selectAll: '選取整個表格', horizontalAlign: '水平對齊方式', centerAlign: '置中對齊', verticalAlign: '垂直對齊方式', alignTop: '靠上對齊', alignMiddle: '垂直置中', alignBottom: '靠下對齊', background: '網底顏色', repeatHeader: '重複標題列', properties: '表格屬性', select: '選取表格', addColumn: '新增欄', addRow: '新增列' },\r\n    font: { title: '字型', characterSpacing: '字元間距', cjkFont: '中文字型', style: '字型樣式', regular: '標準', italic: '斜體', bold: '粗體', boldItalic: '粗斜體', size: '字級', effects: '效果', strikethrough: '刪除線', underline: '底線', superscript: '上標', subscript: '下標', doubleStrikethrough: '雙刪除線', hidden: '隱藏', previewText: '字型預覽文字 ABCabc 123', scale: '縮放', standard: '標準', expanded: '加寬', condensed: '緊縮', position: '位置', raised: '提高', lowered: '降低', spacingPreview: '字元間距預覽 ABCabc 123', unsupported: '間距與位置功能將於後續版本支援' },\r\n    paragraphDialog: { title: '段落', indentSpacing: '縮排與間距', linePageBreak: '分行與分頁', cjkLayout: '中文排版', general: '一般', alignment: '對齊方式', outline: '大綱階層', bodyText: '內文', level1: '第 1 級', level2: '第 2 級', level3: '第 3 級', level4: '第 4 級', level5: '第 5 級', level6: '第 6 級', indent: '縮排', beforeText: '文字之前', afterText: '文字之後', special: '特殊格式', firstLine: '第一行', hanging: '凸排', measure: '位移量', cm: '公分', adjustRightIndent: '若已定義文件格線，自動調整右側縮排', before: '段落前', after: '段落後', lineSpacing: '行距', single: '單行間距', oneHalf: '1.5 倍行高', double: '雙行間距', atLeast: '至少', exact: '固定行高', multiple: '多倍行高', setting: '設定值', times: '倍', alignGrid: '若已定義文件格線，則貼齊格線', previewText: '段落預覽文字', pagination: '分頁', widow: '孤行控制', keepNext: '與下段同頁', breakBefore: '段落前分頁', lineBreak: '分行', noLineNumber: '取消行號', noHyphen: '不要斷字', unsupported: '此功能將於後續版本支援', cjkWrap: '依中文習慣換行', punctuationOverflow: '允許標點符號超出邊界', wordBreak: '允許西文在單字中間換行', compressPunctuation: '允許壓縮行首標點符號', cjkWesternSpacing: '自動調整中文與西文之間的間距', cjkNumberSpacing: '自動調整中文與數字之間的間距', textAlignment: '文字對齊方式', align: '對齊', auto: '自動', baseline: '基準線對齊' },\r\n    tableDialog: { categories: '屬性類別', table: '表格', cell: '儲存格', presetHint: '預設會取代整個表格的框線組合，未選取的框線將被清除。', border: '框線', preset: '預設', unchanged: '維持原狀', allBorders: '所有框線', outsideBorders: '外框線', noBorders: '無框線', insideBorders: '內框線', insideHorizontal: '內部水平線', insideVertical: '內部垂直線', topBorder: '上框線', bottomBorder: '下框線', leftBorder: '左框線', rightBorder: '右框線', borderPresets: '框線預設', all: '全部', outside: '外側', inside: '內側', colorFormatTitle: '請輸入 #RRGGBB 格式的顏色', colorFormatClearTitle: '請輸入 #RRGGBB 格式的顏色；留白可清除', borderColor: '框線顏色', cellColor: '儲存格底色', chooseColor: '選擇{label}（目前為{state}）', innerWidth: '內框線寬度', outerWidth: '外框線寬度', innerWidthAria: '內框線寬度（像素）', outerWidthAria: '外框線寬度（像素）', colorHelp: '顏色格式：#RRGGBB；留白則維持原狀。', borderPreview: '框線預覽', presetPreview: '框線組合預覽；虛線僅標示表格範圍。未指定的顏色及寬度維持原狀。', unchangedPreview: '未選取預設，框線組合維持原狀；預覽不代表混合樣式。', cellHint: '以下設定僅套用至目前的儲存格（按右鍵的儲存格）。', fill: '底色', noFill: '無底色', invalidColor: '顏色格式無效', clearFill: '清除底色', fillHelp: '顏色格式：#RRGGBB；留白表示無底色。', verticalAlign: '垂直對齊', alignCenter: '置中對齊' },\r\n    pageNumber: { header: '頁首', footer: '頁尾', insert: '插入頁碼', style: '樣式：', position: '位置：', left: '左側', center: '置中', right: '右側', stylePage: '第 1 頁', styleTotal: '第 1 頁，共 x 頁', styleFirst: '第一頁', styleFirstTotal: '第一頁，共 X 頁' },\r\n    fontFamily: { SimSun: '宋體', SimHei: '黑體', KaiTi: '楷體', FangSong: '仿宋', MicrosoftYaHei: '微軟雅黑', DengXian: '等線', STSong: '華文宋體', STHeiti: '華文黑體', STKaiti: '華文楷體', STFangsong: '華文仿宋', STZhongsong: '華文中宋', STXihei: '華文細黑', STXingkai: '華文行楷', STLiti: '華文隸書', STXinwei: '華文新魏', STCaiyun: '華文彩雲' },\r\n    fontSize: { chuhao: '初號', xiaochu: '小初', yihao: '一號', xiaoyi: '小一', erhao: '二號', xiaoer: '小二', sanhao: '三號', xiaosan: '小三', sihao: '四號', xiaosi: '小四', wuhao: '五號', xiaowu: '小五', liuhao: '六號', xiaoliu: '小六', qihao: '七號', bahao: '八號' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: '編輯批註', delete: '刪除批註', resolve: '解決批註', reopen: '重新開啟批註', placeholder: '請輸入批註內容...', save: '儲存', cancel: '取消', source: '取自：', addReply: '新增回覆', replyPlaceholder: '輸入回覆...', reply: '回覆' },\r\n    revision: { unknownAuthor: '未知', accept: '接受修訂', reject: '拒絕修訂', insert: '插入：', delete: '刪除：', format: '格式：', bold: '粗體', italic: '斜體', underline: '底線', strikeout: '刪除線', doubleStrikeout: '雙刪除線', hidden: '隱藏', superscript: '上標', subscript: '下標', color: '字型顏色', size: '字級', font: '字型', highlight: '醒目提示', characterScale: '字元縮放', letterSpacing: '字元間距', textDecoration: '裝飾線樣式', rowFlex: '對齊方式', lineHeight: '行距', lineHeightRule: '行距規則', rowMargin: '行間距', paragraphIndentLeft: '左側縮排', paragraphIndentRight: '右側縮排', paragraphFirstLineIndent: '首行縮排', indentHanging: '凸排', paragraphSpacingBefore: '段前間距', paragraphSpacingAfter: '段後間距', alignLeft: '靠左對齊', alignCenter: '置中', alignRight: '靠右對齊', alignJustify: '左右對齊', alignDistribute: '分散對齊', undo: '取消', default: '預設', property: '{label}：{value}', formatDescription: '設定格式：{details}', setFormat: '設定格式', separator: '，', descriptionSeparator: '；' }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: 'Insert Chart', settings: 'Settings', data: 'Data', selectType: 'Select Chart Type', preview: 'Chart Preview', config: 'Chart Settings', clear: 'Clear', cancel: 'Cancel', confirm: 'OK' },\r\n    category: { bar: 'Column', line: 'Line', pie: 'Pie', scatter: 'Scatter', radar: 'Radar', mixed: 'Combo' },\r\n    preview: { 'bar-basic': 'Basic Column', 'bar-stacked': 'Stacked Column', 'bar-horizontal': 'Horizontal Bar', 'line-basic': 'Basic Line', 'line-smooth': 'Smooth Line', 'line-stacked': 'Stacked Line', 'line-area': 'Stacked Area', 'line-step': 'Stepped Line', 'line-dashed': 'Dashed Line', 'pie-basic': 'Basic Pie', 'pie-doughnut': 'Doughnut', 'scatter-basic': 'Basic Scatter', 'radar-basic': 'Basic Radar', 'radar-filled': 'Filled Radar', 'mixed-line-bar': 'Line and Column' },\r\n    config: { showTitle: 'Show Title', title: 'Title', titlePlaceholder: 'Enter chart title', titlePosition: 'Title Position', showLegend: 'Show Legend', legendPosition: 'Legend Position', xAxisLabel: 'X-Axis Title', xAxisPlaceholder: 'Enter X-axis title', yAxisLabel: 'Y-Axis Title', yAxisPlaceholder: 'Enter Y-axis title', showGrid: 'Show Gridlines', showDataLabel: 'Show Data Labels', colorScheme: 'Color Scheme' },\r\n    position: { left: 'Left', center: 'Center', right: 'Right', top: 'Top', bottom: 'Bottom' },\r\n    colorScheme: { default: 'Default', warm: 'Warm', cool: 'Cool', nature: 'Natural' },\r\n    sample: { series: 'Series {index}', category: 'Category {index}' },\r\n    noData: 'No data', data: 'Data'\r\n  },\r\n  view: {\r\n    common: { cancel: 'Cancel', confirm: 'OK', none: 'None', leftAlign: 'Align Left', rightAlign: 'Align Right', center: 'Center', justify: 'Justify', distribute: 'Distributed', preview: 'Preview', color: 'Color', spacing: 'Spacing', points: 'pt' },\r\n    paragraph: { format: 'Paragraph Formatting', body: 'Body Text', heading1: 'Heading 1', heading2: 'Heading 2', heading3: 'Heading 3', heading4: 'Heading 4', heading5: 'Heading 5', heading6: 'Heading 6', cut: 'Cut', copy: 'Copy', paste: 'Paste', fontSettings: 'Font...', advancedSettings: 'Advanced Paragraph Settings', link: 'Hyperlink', comment: 'Insert Comment' },\r\n    hyperlink: {\r\n      text: 'Display Text', address: 'Link Address', addressPlaceholder: 'Enter a full address (e.g. https://example.com)',\r\n      textRequired: 'Please enter display text', addressRequired: 'Please enter a link address',\r\n      addressInvalid: 'The link address must use http, https, mailto, tel, or ftp protocol',\r\n      unsupported: 'The hyperlink was not inserted and no specific reason is available. Select the text again and retry. The document is unchanged.',\r\n      bookmarkSelection: 'The selection contains bookmark markers. This editor does not yet support inserting hyperlinks across bookmark boundaries. Adjust the selection to avoid them. Text and bookmarks are unchanged.',\r\n      fieldSelection: 'The selection contains Word field markers, such as a table of contents or page number. Select ordinary text outside the field. The document is unchanged.',\r\n      existingLink: 'The selection contains an existing hyperlink. Nested links and replacing links are not yet supported. Select text without a link. The document is unchanged.',\r\n      crossContainer: 'The selection spans different text containers, such as paragraphs or cells. Select text within one paragraph. The document is unchanged.',\r\n      crossParagraph: 'The selection contains a line break or paragraph end. Select text without breaks within one paragraph. The document is unchanged.',\r\n      revisions: 'The selection contains pending revisions. Review and accept or reject them first, or select text without revisions. The document is unchanged.',\r\n      tracking: 'Track Changes is enabled. Hyperlink insertion is not yet supported in this mode. Turn off Track Changes and retry. The document is unchanged.',\r\n      readOnly: 'The document is read-only. Switch to an editable mode and retry. The document is unchanged.',\r\n      disabled: 'Editing is disabled. Enable editing and retry. The document is unchanged.',\r\n      noSelection: 'No caret or text selection was found. Close the dialog, place the caret or select text in the document, and retry. The document is unchanged.',\r\n      invalidSelection: 'The text selection is no longer valid. Close the dialog, select the text again, and retry. The document is unchanged.',\r\n      nonText: 'The selection contains non-text content, such as an image or table. Select ordinary text only. The document is unchanged.',\r\n      invalidText: 'Display text must be nonempty plain text without line breaks or hidden control markers. Edit the display text and retry. The document is unchanged.'\r\n    },\r\n    table: { insert: 'Insert', insertLeft: 'Insert Left', insertRight: 'Insert Right', insertAbove: 'Insert Above', insertBelow: 'Insert Below', columnUnit: 'column(s)', rowUnit: 'row(s)', insertCell: 'Cell (E)...', splitCell: 'Split Cells', mergeCell: 'Merge Cells', delete: 'Delete', deleteRow: 'Delete Row', deleteColumn: 'Delete Column', deleteTable: 'Delete Table', selectAll: 'Select Entire Table', horizontalAlign: 'Horizontal Alignment', centerAlign: 'Center', verticalAlign: 'Vertical Alignment', alignTop: 'Align Top', alignMiddle: 'Align Middle', alignBottom: 'Align Bottom', background: 'Shading Color', repeatHeader: 'Repeat Header Row', properties: 'Table Properties', select: 'Select Table', addColumn: 'Add Column', addRow: 'Add Row' },\r\n    font: { title: 'Font', characterSpacing: 'Character Spacing', cjkFont: 'Chinese Font', style: 'Font Style', regular: 'Regular', italic: 'Italic', bold: 'Bold', boldItalic: 'Bold Italic', size: 'Size', effects: 'Effects', strikethrough: 'Strikethrough', underline: 'Underline', superscript: 'Superscript', subscript: 'Subscript', doubleStrikethrough: 'Double Strikethrough', hidden: 'Hidden', previewText: 'Font preview text ABCabc 123', scale: 'Scale', standard: 'Normal', expanded: 'Expanded', condensed: 'Condensed', position: 'Position', raised: 'Raised', lowered: 'Lowered', spacingPreview: 'Character spacing preview ABCabc 123', unsupported: 'Spacing and position will be supported in a future release' },\r\n    paragraphDialog: { title: 'Paragraph', indentSpacing: 'Indents and Spacing', linePageBreak: 'Line and Page Breaks', cjkLayout: 'Asian Typography', general: 'General', alignment: 'Alignment', outline: 'Outline Level', bodyText: 'Body Text', level1: 'Level 1', level2: 'Level 2', level3: 'Level 3', level4: 'Level 4', level5: 'Level 5', level6: 'Level 6', indent: 'Indentation', beforeText: 'Before text', afterText: 'After text', special: 'Special', firstLine: 'First line', hanging: 'Hanging', measure: 'By', cm: 'cm', adjustRightIndent: 'Automatically adjust right indent when document grid is defined', before: 'Before', after: 'After', lineSpacing: 'Line spacing', single: 'Single', oneHalf: '1.5 lines', double: 'Double', atLeast: 'At least', exact: 'Exactly', multiple: 'Multiple', setting: 'At', times: 'times', alignGrid: 'Snap to grid when document grid is defined', previewText: 'Paragraph preview text', pagination: 'Pagination', widow: 'Widow/Orphan control', keepNext: 'Keep with next', breakBefore: 'Page break before', lineBreak: 'Line breaks', noLineNumber: 'Suppress line numbers', noHyphen: 'Do not hyphenate', unsupported: 'This feature will be supported in a future release', cjkWrap: 'Use Chinese line-breaking rules', punctuationOverflow: 'Allow punctuation to extend beyond margins', wordBreak: 'Allow Latin text to break within words', compressPunctuation: 'Compress punctuation at the start of a line', cjkWesternSpacing: 'Automatically adjust spacing between Chinese and Latin text', cjkNumberSpacing: 'Automatically adjust spacing between Chinese and numbers', textAlignment: 'Text alignment', align: 'Alignment', auto: 'Automatic', baseline: 'Align to baseline' },\r\n    tableDialog: { categories: 'Property Categories', table: 'Table', cell: 'Cell', presetHint: 'Presets replace the entire table border configuration. Unselected edges will be cleared.', border: 'Border', preset: 'Preset', unchanged: 'Keep Existing', allBorders: 'All Borders', outsideBorders: 'Outside Borders', noBorders: 'No Borders', insideBorders: 'Inside Borders', insideHorizontal: 'Inside Horizontal', insideVertical: 'Inside Vertical', topBorder: 'Top Border', bottomBorder: 'Bottom Border', leftBorder: 'Left Border', rightBorder: 'Right Border', borderPresets: 'Border Presets', all: 'All', outside: 'Outside', inside: 'Inside', colorFormatTitle: 'Enter a color in #RRGGBB format', colorFormatClearTitle: 'Enter a color in #RRGGBB format; leave blank to clear', borderColor: 'Border Color', cellColor: 'Cell Background', chooseColor: 'Choose {label} (current: {state})', innerWidth: 'Inner Border Width', outerWidth: 'Outer Border Width', innerWidthAria: 'Inner border width (pixels)', outerWidthAria: 'Outer border width (pixels)', colorHelp: 'Color format: #RRGGBB; leave blank to keep existing.', borderPreview: 'Border Preview', presetPreview: 'Border configuration preview; dashed lines show only the table bounds. Unspecified colors and widths stay unchanged.', unchangedPreview: 'No preset selected; borders stay unchanged. The preview does not represent mixed styles.', cellHint: 'These settings apply only to the current cell (the one right-clicked).', fill: 'Fill', noFill: 'No Fill', invalidColor: 'Invalid color format', clearFill: 'Clear Fill', fillHelp: 'Color format: #RRGGBB; leave blank for no fill.', verticalAlign: 'Vertical Alignment', alignCenter: 'Center' },\r\n    pageNumber: { header: 'Header', footer: 'Footer', insert: 'Insert Page Number', style: 'Style:', position: 'Position:', left: 'Left', center: 'Center', right: 'Right', stylePage: 'Page 1', styleTotal: 'Page 1 of x', styleFirst: 'First Page', styleFirstTotal: 'First Page of X' },\r\n    fontFamily: { SimSun: 'SimSun', SimHei: 'SimHei', KaiTi: 'KaiTi', FangSong: 'FangSong', MicrosoftYaHei: 'Microsoft YaHei', DengXian: 'DengXian', STSong: 'STSong', STHeiti: 'STHeiti', STKaiti: 'STKaiti', STFangsong: 'STFangsong', STZhongsong: 'STZhongsong', STXihei: 'STXihei', STXingkai: 'STXingkai', STLiti: 'STLiti', STXinwei: 'STXinwei', STCaiyun: 'STCaiyun' },\r\n    fontSize: { chuhao: 'Chuhao (42 pt)', xiaochu: 'Xiaochu (36 pt)', yihao: 'Yihao (26 pt)', xiaoyi: 'Xiaoyi (24 pt)', erhao: 'Erhao (22 pt)', xiaoer: 'Xiaoer (18 pt)', sanhao: 'Sanhao (16 pt)', xiaosan: 'Xiaosan (15 pt)', sihao: 'Sihao (14 pt)', xiaosi: 'Xiaosi (12 pt)', wuhao: 'Wuhao (10.5 pt)', xiaowu: 'Xiaowu (9 pt)', liuhao: 'Liuhao (7.5 pt)', xiaoliu: 'Xiaoliu (6.5 pt)', qihao: 'Qihao (5.5 pt)', bahao: 'Bahao (5 pt)' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: 'Edit Comment', delete: 'Delete Comment', resolve: 'Resolve Comment', reopen: 'Reopen Comment', placeholder: 'Enter a comment...', save: 'Save', cancel: 'Cancel', source: 'From:', addReply: 'Add Reply', replyPlaceholder: 'Write a reply...', reply: 'Reply' },\r\n    revision: { unknownAuthor: 'Unknown', accept: 'Accept Change', reject: 'Reject Change', insert: 'Inserted:', delete: 'Deleted:', format: 'Formatting:', bold: 'Bold', italic: 'Italic', underline: 'Underline', strikeout: 'Strikethrough', doubleStrikeout: 'Double Strikethrough', hidden: 'Hidden', superscript: 'Superscript', subscript: 'Subscript', color: 'Font Color', size: 'Font Size', font: 'Font', highlight: 'Highlight', characterScale: 'Character Scale', letterSpacing: 'Character Spacing', textDecoration: 'Text Decoration Style', rowFlex: 'Alignment', lineHeight: 'Line Spacing', lineHeightRule: 'Line Spacing Rule', rowMargin: 'Row Spacing', paragraphIndentLeft: 'Left Indent', paragraphIndentRight: 'Right Indent', paragraphFirstLineIndent: 'First Line Indent', indentHanging: 'Hanging Indent', paragraphSpacingBefore: 'Space Before Paragraph', paragraphSpacingAfter: 'Space After Paragraph', alignLeft: 'Align Left', alignCenter: 'Center', alignRight: 'Align Right', alignJustify: 'Justify', alignDistribute: 'Distributed', undo: 'Cancel', default: 'Default', property: '{label}: {value}', formatDescription: 'Set formatting: {details}', setFormat: 'Set Formatting', separator: ', ', descriptionSeparator: '; ' }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: 'グラフの挿入', settings: '設定', data: 'データ', selectType: 'グラフの種類を選択', preview: 'グラフのプレビュー', config: 'グラフの設定', clear: 'クリア', cancel: 'キャンセル', confirm: 'OK' },\r\n    category: { bar: '縦棒グラフ', line: '折れ線グラフ', pie: '円グラフ', scatter: '散布図', radar: 'レーダーチャート', mixed: '複合グラフ' },\r\n    preview: { 'bar-basic': '基本の縦棒グラフ', 'bar-stacked': '積み上げ縦棒グラフ', 'bar-horizontal': '横棒グラフ', 'line-basic': '基本の折れ線グラフ', 'line-smooth': '平滑線グラフ', 'line-stacked': '積み上げ折れ線グラフ', 'line-area': '積み上げ面グラフ', 'line-step': '階段状の折れ線グラフ', 'line-dashed': '破線の折れ線グラフ', 'pie-basic': '基本の円グラフ', 'pie-doughnut': 'ドーナツグラフ', 'scatter-basic': '基本の散布図', 'radar-basic': '基本のレーダーチャート', 'radar-filled': '塗りつぶしレーダーチャート', 'mixed-line-bar': '折れ線と縦棒の複合グラフ' },\r\n    config: { showTitle: 'タイトルを表示', title: 'タイトル', titlePlaceholder: 'グラフのタイトルを入力', titlePosition: 'タイトルの位置', showLegend: '凡例を表示', legendPosition: '凡例の位置', xAxisLabel: 'X 軸のタイトル', xAxisPlaceholder: 'X 軸のタイトルを入力', yAxisLabel: 'Y 軸のタイトル', yAxisPlaceholder: 'Y 軸のタイトルを入力', showGrid: '目盛線を表示', showDataLabel: 'データラベルを表示', colorScheme: '配色' },\r\n    position: { left: '左', center: '中央', right: '右', top: '上', bottom: '下' },\r\n    colorScheme: { default: '既定', warm: '暖色', cool: '寒色', nature: '自然色' },\r\n    sample: { series: '系列{index}', category: '分類{index}' },\r\n    noData: 'データがありません', data: 'データ'\r\n  },\r\n  view: {\r\n    common: { cancel: 'キャンセル', confirm: 'OK', none: 'なし', leftAlign: '左揃え', rightAlign: '右揃え', center: '中央揃え', justify: '両端揃え', distribute: '均等割り付け', preview: 'プレビュー', color: '色', spacing: '間隔', points: 'pt' },\r\n    paragraph: { format: '段落の書式', body: '本文', heading1: '見出し 1', heading2: '見出し 2', heading3: '見出し 3', heading4: '見出し 4', heading5: '見出し 5', heading6: '見出し 6', cut: '切り取り', copy: 'コピー', paste: '貼り付け', fontSettings: 'フォント...', advancedSettings: '段落の詳細設定', link: 'ハイパーリンク', comment: 'コメントの挿入' },\r\n    hyperlink: {\r\n      text: '表示文字', address: 'リンク先', addressPlaceholder: '完全なアドレスを入力してください（例: https://example.com）',\r\n      textRequired: '表示文字を入力してください', addressRequired: 'リンク先のアドレスを入力してください',\r\n      addressInvalid: 'リンク先は http、https、mailto、tel、ftp のいずれかのプロトコルを使用する必要があります',\r\n      unsupported: 'リンクは挿入されませんでした。具体的な原因を取得できません。文字を選択し直して再試行してください。文書は変更されていません。',\r\n      bookmarkSelection: '選択範囲にブックマークの境界が含まれています。このエディターでは境界をまたぐリンクの挿入にまだ対応していません。境界を避けて選択してください。文字とブックマークは変更されていません。',\r\n      fieldSelection: '選択範囲に目次やページ番号などの Word フィールドが含まれています。フィールド以外の通常の文字を選択してください。文書は変更されていません。',\r\n      existingLink: '選択範囲に既存のリンクが含まれています。リンクの入れ子や置き換えにはまだ対応していません。リンクのない文字を選択してください。文書は変更されていません。',\r\n      crossContainer: '選択範囲が複数の段落やセルなどにまたがっています。同じ段落内の文字を選択してください。文書は変更されていません。',\r\n      crossParagraph: '選択範囲に改行または段落の終端が含まれています。同じ段落内で改行を含まない文字を選択してください。文書は変更されていません。',\r\n      revisions: '選択範囲に未処理の変更履歴が含まれています。確認して承諾または元に戻すか、変更履歴のない文字を選択してください。文書は変更されていません。',\r\n      tracking: '変更履歴の記録が有効です。このモードではリンクの挿入にまだ対応していません。記録を無効にして再試行してください。文書は変更されていません。',\r\n      readOnly: '文書は読み取り専用です。編集可能なモードに切り替えてください。文書は変更されていません。',\r\n      disabled: '編集機能が無効です。編集を有効にして再試行してください。文書は変更されていません。',\r\n      noSelection: 'カーソル位置または文字の選択範囲がありません。ダイアログを閉じ、本文にカーソルを置くか文字を選択してください。文書は変更されていません。',\r\n      invalidSelection: '文字の選択範囲が無効になりました。ダイアログを閉じ、文字を選択し直してください。文書は変更されていません。',\r\n      nonText: '選択範囲に画像や表などが含まれています。通常の文字のみを選択してください。文書は変更されていません。',\r\n      invalidText: '表示文字は空でない通常の文字列にしてください。改行や非表示の制御マーカーは使用できません。表示文字を修正してください。文書は変更されていません。'\r\n    },\r\n    table: { insert: '挿入', insertLeft: '左に挿入', insertRight: '右に挿入', insertAbove: '上に挿入', insertBelow: '下に挿入', columnUnit: '列', rowUnit: '行', insertCell: 'セル(E)...', splitCell: 'セルの分割', mergeCell: 'セルの結合', delete: '削除', deleteRow: '行の削除', deleteColumn: '列の削除', deleteTable: '表全体の削除', selectAll: '表全体を選択', horizontalAlign: '水平方向の配置', centerAlign: '中央揃え', verticalAlign: '垂直方向の配置', alignTop: '上揃え', alignMiddle: '上下中央揃え', alignBottom: '下揃え', background: '網掛けの色', repeatHeader: 'タイトル行の繰り返し', properties: '表のプロパティ', select: '表を選択', addColumn: '列の追加', addRow: '行の追加' },\r\n    font: { title: 'フォント', characterSpacing: '文字間隔', cjkFont: '中国語用フォント', style: 'スタイル', regular: '標準', italic: '斜体', bold: '太字', boldItalic: '太字斜体', size: 'サイズ', effects: '文字飾り', strikethrough: '取り消し線', underline: '下線', superscript: '上付き', subscript: '下付き', doubleStrikethrough: '二重取り消し線', hidden: '隠し文字', previewText: 'フォントのプレビュー ABCabc 123', scale: '倍率', standard: '標準', expanded: '広く', condensed: '狭く', position: '位置', raised: '上げる', lowered: '下げる', spacingPreview: '文字間隔のプレビュー ABCabc 123', unsupported: '文字間隔と位置は今後のバージョンで対応予定です' },\r\n    paragraphDialog: { title: '段落', indentSpacing: 'インデントと行間隔', linePageBreak: '改ページと改行', cjkLayout: '体裁', general: '全般', alignment: '配置', outline: 'アウトライン レベル', bodyText: '本文', level1: 'レベル 1', level2: 'レベル 2', level3: 'レベル 3', level4: 'レベル 4', level5: 'レベル 5', level6: 'レベル 6', indent: 'インデント', beforeText: '左', afterText: '右', special: '最初の行', firstLine: '字下げ', hanging: 'ぶら下げ', measure: '幅', cm: 'cm', adjustRightIndent: '文書グリッドを定義した場合は右インデントを自動調整する', before: '段落前', after: '段落後', lineSpacing: '行間', single: '1 行', oneHalf: '1.5 行', double: '2 行', atLeast: '最小値', exact: '固定値', multiple: '倍数', setting: '間隔', times: '倍', alignGrid: '文書グリッドを定義した場合はグリッド線に合わせる', previewText: '段落のプレビュー', pagination: '改ページ', widow: '改ページ時 1 行残して段落を区切らない', keepNext: '次の段落と分離しない', breakBefore: '段落前で改ページする', lineBreak: '改行', noLineNumber: '行番号を表示しない', noHyphen: 'ハイフネーションしない', unsupported: 'この機能は今後のバージョンで対応予定です', cjkWrap: '中国語の改行規則を使用する', punctuationOverflow: '句読点のぶら下げを許可する', wordBreak: '欧文を単語の途中で改行する', compressPunctuation: '行頭の句読点を詰める', cjkWesternSpacing: '中国語と欧文の間隔を自動調整する', cjkNumberSpacing: '中国語と数字の間隔を自動調整する', textAlignment: '文字の配置', align: '配置', auto: '自動', baseline: 'ベースラインに揃える' },\r\n    tableDialog: { categories: 'プロパティの種類', table: '表', cell: 'セル', presetHint: 'プリセットを適用すると表全体の罫線構成が置き換わり、選択されていない辺の罫線は消去されます。', border: '罫線', preset: 'プリセット', unchanged: '変更しない', allBorders: 'すべての罫線', outsideBorders: '外枠', noBorders: '罫線なし', insideBorders: '内側の罫線', insideHorizontal: '内側の横線', insideVertical: '内側の縦線', topBorder: '上の罫線', bottomBorder: '下の罫線', leftBorder: '左の罫線', rightBorder: '右の罫線', borderPresets: '罫線のプリセット', all: 'すべて', outside: '外側', inside: '内側', colorFormatTitle: '色を #RRGGBB 形式で入力してください', colorFormatClearTitle: '色を #RRGGBB 形式で入力してください。空欄にすると消去します', borderColor: '罫線の色', cellColor: 'セルの背景色', chooseColor: '{label}を選択（現在：{state}）', innerWidth: '内側の罫線の幅', outerWidth: '外枠の幅', innerWidthAria: '内側の罫線の幅（ピクセル）', outerWidthAria: '外枠の幅（ピクセル）', colorHelp: '色の形式：#RRGGBB。空欄の場合は変更しません。', borderPreview: '罫線のプレビュー', presetPreview: '罫線構成のプレビュー。破線は表の範囲のみを示します。未入力の色と幅は変更しません。', unchangedPreview: 'プリセットが選択されていないため、罫線構成は変更しません。プレビューは混在するスタイルを表しません。', cellHint: '以下の設定は現在のセル（右クリックしたセル）にのみ適用されます。', fill: '塗りつぶし', noFill: '塗りつぶしなし', invalidColor: '色の形式が正しくありません', clearFill: '塗りつぶしをクリア', fillHelp: '色の形式：#RRGGBB。空欄の場合は塗りつぶしなしです。', verticalAlign: '垂直方向の配置', alignCenter: '中央揃え' },\r\n    pageNumber: { header: 'ヘッダー', footer: 'フッター', insert: 'ページ番号の挿入', style: 'スタイル:', position: '位置:', left: '左', center: '中央', right: '右', stylePage: '1 ページ', styleTotal: '1 / x ページ', styleFirst: '最初のページ', styleFirstTotal: '最初のページ / 全 X ページ' },\r\n    fontFamily: { SimSun: 'SimSun（宋体）', SimHei: 'SimHei（黒体）', KaiTi: 'KaiTi（楷体）', FangSong: 'FangSong（仿宋）', MicrosoftYaHei: 'Microsoft YaHei', DengXian: 'DengXian', STSong: 'STSong', STHeiti: 'STHeiti', STKaiti: 'STKaiti', STFangsong: 'STFangsong', STZhongsong: 'STZhongsong', STXihei: 'STXihei', STXingkai: 'STXingkai', STLiti: 'STLiti', STXinwei: 'STXinwei', STCaiyun: 'STCaiyun' },\r\n    fontSize: { chuhao: '初号（42 pt）', xiaochu: '小初（36 pt）', yihao: '一号（26 pt）', xiaoyi: '小一（24 pt）', erhao: '二号（22 pt）', xiaoer: '小二（18 pt）', sanhao: '三号（16 pt）', xiaosan: '小三（15 pt）', sihao: '四号（14 pt）', xiaosi: '小四（12 pt）', wuhao: '五号（10.5 pt）', xiaowu: '小五（9 pt）', liuhao: '六号（7.5 pt）', xiaoliu: '小六（6.5 pt）', qihao: '七号（5.5 pt）', bahao: '八号（5 pt）' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: 'コメントを編集', delete: 'コメントを削除', resolve: 'コメントを解決済みにする', reopen: 'コメントを再開', placeholder: 'コメントを入力してください...', save: '保存', cancel: 'キャンセル', source: '引用元：', addReply: '返信を追加', replyPlaceholder: '返信を入力...', reply: '返信' },\r\n    revision: { unknownAuthor: '不明', accept: '変更を採用', reject: '変更を却下', insert: '挿入：', delete: '削除：', format: '書式：', bold: '太字', italic: '斜体', underline: '下線', strikeout: '取り消し線', doubleStrikeout: '二重取り消し線', hidden: '隠し文字', superscript: '上付き', subscript: '下付き', color: 'フォントの色', size: 'フォントサイズ', font: 'フォント', highlight: '蛍光ペン', characterScale: '文字の拡大縮小', letterSpacing: '文字間隔', textDecoration: '文字飾りのスタイル', rowFlex: '配置', lineHeight: '行間', lineHeightRule: '行間の規則', rowMargin: '行の間隔', paragraphIndentLeft: '左インデント', paragraphIndentRight: '右インデント', paragraphFirstLineIndent: '先頭行インデント', indentHanging: 'ぶら下げインデント', paragraphSpacingBefore: '段落前の間隔', paragraphSpacingAfter: '段落後の間隔', alignLeft: '左揃え', alignCenter: '中央揃え', alignRight: '右揃え', alignJustify: '両端揃え', alignDistribute: '均等割り付け', undo: 'キャンセル', default: '既定', property: '{label}：{value}', formatDescription: '書式を設定：{details}', setFormat: '書式を設定', separator: '、', descriptionSeparator: '；' }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: '차트 삽입', settings: '설정', data: '데이터', selectType: '차트 종류 선택', preview: '차트 미리보기', config: '차트 설정', clear: '지우기', cancel: '취소', confirm: '확인' },\r\n    category: { bar: '세로 막대형', line: '꺾은선형', pie: '원형', scatter: '분산형', radar: '방사형', mixed: '혼합형' },\r\n    preview: { 'bar-basic': '기본 세로 막대형', 'bar-stacked': '누적 세로 막대형', 'bar-horizontal': '가로 막대형', 'line-basic': '기본 꺾은선형', 'line-smooth': '부드러운 꺾은선형', 'line-stacked': '누적 꺾은선형', 'line-area': '누적 영역형', 'line-step': '계단형 꺾은선', 'line-dashed': '점선 꺾은선', 'pie-basic': '기본 원형', 'pie-doughnut': '도넛형', 'scatter-basic': '기본 분산형', 'radar-basic': '기본 방사형', 'radar-filled': '채워진 방사형', 'mixed-line-bar': '꺾은선 및 막대 혼합형' },\r\n    config: { showTitle: '제목 표시', title: '제목', titlePlaceholder: '차트 제목 입력', titlePosition: '제목 위치', showLegend: '범례 표시', legendPosition: '범례 위치', xAxisLabel: 'X축 제목', xAxisPlaceholder: 'X축 제목 입력', yAxisLabel: 'Y축 제목', yAxisPlaceholder: 'Y축 제목 입력', showGrid: '눈금선 표시', showDataLabel: '데이터 레이블 표시', colorScheme: '색 구성표' },\r\n    position: { left: '왼쪽', center: '가운데', right: '오른쪽', top: '위', bottom: '아래' },\r\n    colorScheme: { default: '기본값', warm: '따뜻한 색', cool: '차가운 색', nature: '자연색' },\r\n    sample: { series: '계열{index}', category: '범주{index}' },\r\n    noData: '데이터 없음', data: '데이터'\r\n  },\r\n  view: {\r\n    common: { cancel: '취소', confirm: '확인', none: '없음', leftAlign: '왼쪽 맞춤', rightAlign: '오른쪽 맞춤', center: '가운데 맞춤', justify: '양쪽 맞춤', distribute: '균등 분할', preview: '미리보기', color: '색상', spacing: '간격', points: 'pt' },\r\n    paragraph: { format: '단락 서식', body: '본문', heading1: '제목 1', heading2: '제목 2', heading3: '제목 3', heading4: '제목 4', heading5: '제목 5', heading6: '제목 6', cut: '잘라내기', copy: '복사', paste: '붙여넣기', fontSettings: '글꼴...', advancedSettings: '단락 고급 설정', link: '하이퍼링크', comment: '메모 삽입' },\r\n    hyperlink: {\r\n      text: '표시 텍스트', address: '링크 주소', addressPlaceholder: '전체 주소를 입력하세요(예: https://example.com)',\r\n      textRequired: '표시 텍스트를 입력하세요', addressRequired: '링크 주소를 입력하세요',\r\n      addressInvalid: '링크 주소는 http, https, mailto, tel 또는 ftp 프로토콜을 사용해야 합니다',\r\n      unsupported: '링크가 삽입되지 않았으며 구체적인 원인을 확인할 수 없습니다. 텍스트를 다시 선택하고 시도하세요. 문서는 변경되지 않았습니다.',\r\n      bookmarkSelection: '선택 영역에 책갈피 경계가 포함되어 있습니다. 현재 편집기는 책갈피 경계를 가로지르는 링크 삽입을 지원하지 않습니다. 경계를 피하도록 선택 영역을 조정하세요. 텍스트와 책갈피는 변경되지 않았습니다.',\r\n      fieldSelection: '선택 영역에 목차나 페이지 번호 같은 Word 필드가 포함되어 있습니다. 필드 밖의 일반 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      existingLink: '선택 영역에 기존 링크가 포함되어 있습니다. 중첩 링크와 링크 교체는 아직 지원되지 않습니다. 링크가 없는 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      crossContainer: '선택 영역이 여러 단락이나 셀 등 서로 다른 텍스트 영역에 걸쳐 있습니다. 같은 단락 안에서 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      crossParagraph: '선택 영역에 줄 바꿈이나 단락 끝이 포함되어 있습니다. 같은 단락 안에서 줄 바꿈이 없는 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      revisions: '선택 영역에 처리되지 않은 변경 내용이 있습니다. 검토 후 적용하거나 취소하거나, 변경 내용이 없는 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      tracking: '변경 내용 추적이 켜져 있습니다. 이 모드에서는 링크 삽입이 아직 지원되지 않습니다. 추적을 끄고 다시 시도하세요. 문서는 변경되지 않았습니다.',\r\n      readOnly: '문서가 읽기 전용입니다. 편집 가능한 모드로 전환하세요. 문서는 변경되지 않았습니다.',\r\n      disabled: '편집 기능이 비활성화되어 있습니다. 편집을 활성화하고 다시 시도하세요. 문서는 변경되지 않았습니다.',\r\n      noSelection: '커서 위치나 선택 영역을 찾을 수 없습니다. 대화 상자를 닫고 본문에 커서를 놓거나 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      invalidSelection: '텍스트 선택 영역이 더 이상 유효하지 않습니다. 대화 상자를 닫고 텍스트를 다시 선택하세요. 문서는 변경되지 않았습니다.',\r\n      nonText: '선택 영역에 이미지나 표 등 일반 텍스트가 아닌 내용이 있습니다. 일반 텍스트만 선택하세요. 문서는 변경되지 않았습니다.',\r\n      invalidText: '표시 텍스트는 비어 있지 않은 일반 텍스트여야 하며 줄 바꿈이나 숨겨진 제어 표식을 포함할 수 없습니다. 표시 텍스트를 수정하세요. 문서는 변경되지 않았습니다.'\r\n    },\r\n    table: { insert: '삽입', insertLeft: '왼쪽에 삽입', insertRight: '오른쪽에 삽입', insertAbove: '위에 삽입', insertBelow: '아래에 삽입', columnUnit: '열', rowUnit: '행', insertCell: '셀(E)...', splitCell: '셀 분할', mergeCell: '셀 병합', delete: '삭제', deleteRow: '행 삭제', deleteColumn: '열 삭제', deleteTable: '표 전체 삭제', selectAll: '표 전체 선택', horizontalAlign: '가로 맞춤', centerAlign: '가운데 맞춤', verticalAlign: '세로 맞춤', alignTop: '위쪽 맞춤', alignMiddle: '세로 가운데 맞춤', alignBottom: '아래쪽 맞춤', background: '음영 색상', repeatHeader: '머리글 행 반복', properties: '표 속성', select: '표 선택', addColumn: '열 추가', addRow: '행 추가' },\r\n    font: { title: '글꼴', characterSpacing: '문자 간격', cjkFont: '중국어 글꼴', style: '글꼴 스타일', regular: '보통', italic: '기울임꼴', bold: '굵게', boldItalic: '굵은 기울임꼴', size: '글자 크기', effects: '효과', strikethrough: '취소선', underline: '밑줄', superscript: '위 첨자', subscript: '아래 첨자', doubleStrikethrough: '이중 취소선', hidden: '숨김', previewText: '글꼴 미리보기 ABCabc 123', scale: '확대/축소', standard: '표준', expanded: '넓게', condensed: '좁게', position: '위치', raised: '위로', lowered: '아래로', spacingPreview: '문자 간격 미리보기 ABCabc 123', unsupported: '간격 및 위치 기능은 향후 버전에서 지원됩니다' },\r\n    paragraphDialog: { title: '단락', indentSpacing: '들여쓰기 및 간격', linePageBreak: '줄 및 페이지 나누기', cjkLayout: '중국어 조판', general: '일반', alignment: '맞춤', outline: '개요 수준', bodyText: '본문', level1: '수준 1', level2: '수준 2', level3: '수준 3', level4: '수준 4', level5: '수준 5', level6: '수준 6', indent: '들여쓰기', beforeText: '텍스트 앞', afterText: '텍스트 뒤', special: '특수', firstLine: '첫 줄', hanging: '내어쓰기', measure: '기준', cm: 'cm', adjustRightIndent: '문서 눈금이 정의된 경우 오른쪽 들여쓰기 자동 조정', before: '단락 앞', after: '단락 뒤', lineSpacing: '줄 간격', single: '1줄', oneHalf: '1.5줄', double: '2줄', atLeast: '최소', exact: '고정', multiple: '배수', setting: '설정값', times: '배', alignGrid: '문서 눈금이 정의된 경우 눈금에 맞춤', previewText: '단락 미리보기 텍스트', pagination: '페이지 나누기', widow: '문단 보호', keepNext: '다음 단락과 함께', breakBefore: '단락 앞에서 페이지 나누기', lineBreak: '줄 바꿈', noLineNumber: '줄 번호 표시 안 함', noHyphen: '하이픈 넣지 않음', unsupported: '이 기능은 향후 버전에서 지원됩니다', cjkWrap: '중국어 줄 바꿈 규칙 사용', punctuationOverflow: '문장 부호의 여백 넘침 허용', wordBreak: '서양어 단어 중간에서 줄 바꿈 허용', compressPunctuation: '줄 시작 문장 부호 압축 허용', cjkWesternSpacing: '중국어와 서양어 사이 간격 자동 조정', cjkNumberSpacing: '중국어와 숫자 사이 간격 자동 조정', textAlignment: '문자 맞춤', align: '맞춤', auto: '자동', baseline: '기준선에 맞춤' },\r\n    tableDialog: { categories: '속성 범주', table: '표', cell: '셀', presetHint: '미리 설정을 적용하면 표 전체의 테두리 구성이 바뀌며 선택하지 않은 테두리는 지워집니다.', border: '테두리', preset: '미리 설정', unchanged: '변경 안 함', allBorders: '모든 테두리', outsideBorders: '바깥쪽 테두리', noBorders: '테두리 없음', insideBorders: '안쪽 테두리', insideHorizontal: '안쪽 가로선', insideVertical: '안쪽 세로선', topBorder: '위쪽 테두리', bottomBorder: '아래쪽 테두리', leftBorder: '왼쪽 테두리', rightBorder: '오른쪽 테두리', borderPresets: '테두리 미리 설정', all: '모두', outside: '바깥쪽', inside: '안쪽', colorFormatTitle: '#RRGGBB 형식의 색상을 입력하세요', colorFormatClearTitle: '#RRGGBB 형식의 색상을 입력하세요. 비워 두면 지워집니다', borderColor: '테두리 색상', cellColor: '셀 배경색', chooseColor: '{label} 선택(현재: {state})', innerWidth: '안쪽 테두리 두께', outerWidth: '바깥쪽 테두리 두께', innerWidthAria: '안쪽 테두리 두께(픽셀)', outerWidthAria: '바깥쪽 테두리 두께(픽셀)', colorHelp: '색상 형식: #RRGGBB. 비워 두면 변경되지 않습니다.', borderPreview: '테두리 미리보기', presetPreview: '테두리 구성 미리보기. 점선은 표 범위만 나타냅니다. 입력하지 않은 색상과 두께는 변경되지 않습니다.', unchangedPreview: '선택한 미리 설정이 없어 테두리 구성이 유지됩니다. 미리보기는 혼합된 스타일을 나타내지 않습니다.', cellHint: '아래 설정은 현재 셀(마우스 오른쪽 버튼으로 클릭한 셀)에만 적용됩니다.', fill: '채우기', noFill: '채우기 없음', invalidColor: '색상 형식이 올바르지 않습니다', clearFill: '채우기 지우기', fillHelp: '색상 형식: #RRGGBB. 비워 두면 채우지 않습니다.', verticalAlign: '세로 맞춤', alignCenter: '가운데 맞춤' },\r\n    pageNumber: { header: '머리글', footer: '바닥글', insert: '페이지 번호 삽입', style: '스타일:', position: '위치:', left: '왼쪽', center: '가운데', right: '오른쪽', stylePage: '1페이지', styleTotal: '전체 x페이지 중 1페이지', styleFirst: '첫 페이지', styleFirstTotal: '전체 X페이지 중 첫 페이지' },\r\n    fontFamily: { SimSun: 'SimSun(쑹체)', SimHei: 'SimHei(헤이체)', KaiTi: 'KaiTi(카이체)', FangSong: 'FangSong(팡쑹)', MicrosoftYaHei: 'Microsoft YaHei', DengXian: 'DengXian', STSong: 'STSong', STHeiti: 'STHeiti', STKaiti: 'STKaiti', STFangsong: 'STFangsong', STZhongsong: 'STZhongsong', STXihei: 'STXihei', STXingkai: 'STXingkai', STLiti: 'STLiti', STXinwei: 'STXinwei', STCaiyun: 'STCaiyun' },\r\n    fontSize: { chuhao: '초호(42pt)', xiaochu: '소초(36pt)', yihao: '1호(26pt)', xiaoyi: '소1호(24pt)', erhao: '2호(22pt)', xiaoer: '소2호(18pt)', sanhao: '3호(16pt)', xiaosan: '소3호(15pt)', sihao: '4호(14pt)', xiaosi: '소4호(12pt)', wuhao: '5호(10.5pt)', xiaowu: '소5호(9pt)', liuhao: '6호(7.5pt)', xiaoliu: '소6호(6.5pt)', qihao: '7호(5.5pt)', bahao: '8호(5pt)' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: '메모 편집', delete: '메모 삭제', resolve: '메모 해결', reopen: '메모 다시 열기', placeholder: '메모 내용을 입력하세요...', save: '저장', cancel: '취소', source: '출처:', addReply: '답글 추가', replyPlaceholder: '답글 입력...', reply: '답글' },\r\n    revision: { unknownAuthor: '알 수 없음', accept: '변경 내용 수락', reject: '변경 내용 거부', insert: '삽입:', delete: '삭제:', format: '서식:', bold: '굵게', italic: '기울임꼴', underline: '밑줄', strikeout: '취소선', doubleStrikeout: '이중 취소선', hidden: '숨김', superscript: '위 첨자', subscript: '아래 첨자', color: '글꼴 색상', size: '글자 크기', font: '글꼴', highlight: '강조', characterScale: '문자 확대/축소', letterSpacing: '문자 간격', textDecoration: '문자 장식 스타일', rowFlex: '맞춤', lineHeight: '줄 간격', lineHeightRule: '줄 간격 규칙', rowMargin: '행 간격', paragraphIndentLeft: '왼쪽 들여쓰기', paragraphIndentRight: '오른쪽 들여쓰기', paragraphFirstLineIndent: '첫 줄 들여쓰기', indentHanging: '내어쓰기', paragraphSpacingBefore: '단락 앞 간격', paragraphSpacingAfter: '단락 뒤 간격', alignLeft: '왼쪽 맞춤', alignCenter: '가운데 맞춤', alignRight: '오른쪽 맞춤', alignJustify: '양쪽 맞춤', alignDistribute: '균등 분할', undo: '취소', default: '기본값', property: '{label}: {value}', formatDescription: '서식 설정: {details}', setFormat: '서식 설정', separator: ', ', descriptionSeparator: '; ' }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Schema —— 常量\r\n */\r\n\r\nimport type { IEditorOption } from './types'\r\n\r\n/** 当前 Schema 版本号 */\r\nexport const SCHEMA_VERSION = '4.0.0-tree'\r\n\r\n/** 默认编辑器选项 */\r\nexport const DEFAULT_EDITOR_OPTION: Required<Pick<IEditorOption,\r\n  'defaultFont' | 'defaultSize' | 'defaultLineHeight' | 'defaultRowMargin' |\r\n  'pageMode' | 'pageWidth' | 'pageHeight' | 'pageMargins' | 'scale' | 'devicePixelRatio' |\r\n  'historyMaxRecordCount'\r\n>> = {\r\n  defaultFont: 'Microsoft YaHei',\r\n  defaultSize: 16,\r\n  defaultLineHeight: 1.5,\r\n  defaultRowMargin: 5,\r\n  pageMode: 'paging',\r\n  pageWidth: 794,           // A4 @ 96dpi\r\n  pageHeight: 1123,\r\n  pageMargins: [100, 120, 100, 120],\r\n  scale: 1,\r\n  devicePixelRatio: typeof window !== 'undefined' ? (window.devicePixelRatio || 1) : 1,\r\n  historyMaxRecordCount: 100\r\n}\r\n\r\n/** 段落级属性字段名（用于从 run 上剥离/继承） */\r\nexport const PARAGRAPH_ATTR_KEYS = [\r\n  'rowFlex',\r\n  'paragraphStyleId',\r\n  'paragraphFirstLineIndent',\r\n  'paragraphIndentLeft',\r\n  'paragraphSpacingBefore',\r\n  'paragraphSpacingAfter',\r\n  'lineHeight',\r\n  'lineHeightRule',\r\n  'groupIds'\r\n] as const\r\n\r\n/** 段落容器类型 */\r\nexport const PARAGRAPH_CONTAINER_TYPES = new Set(['title', 'list'])\r\n\r\n/** 段落级块类型（占独立段） */\r\nexport const BLOCK_LEVEL_TYPES = new Set([\r\n  'title', 'list', 'table', 'image', 'pageBreak', 'separator', 'block'\r\n])\r\n\r\n/** 列表类型 */\r\nexport const LIST_TYPE = {\r\n  UL: 'ul',\r\n  OL: 'ol'\r\n} as const\r\n\r\n/** 列表样式（项目符号 16 种 + 编号格式 13 种，对齐 WPS 全量） */\r\nexport const LIST_STYLE = {\r\n  // 项目符号\r\n  DISC: 'disc',\r\n  CIRCLE: 'circle',\r\n  SQUARE: 'square',\r\n  EMPTY_SQUARE: 'emptySquare',\r\n  FILLED_DIAMOND: 'filledDiamond',\r\n  DIAMOND: 'diamond',\r\n  ARROW: 'arrow',\r\n  ARROW_FILLED: 'arrowFilled',\r\n  CHECK: 'check',\r\n  CROSS: 'cross',\r\n  BULLET: 'bullet',\r\n  TRIANGLE: 'triangle',\r\n  STAR: 'star',\r\n  HEART: 'heart',\r\n  DASH: 'dash',\r\n  HYPHEN: 'hyphen',\r\n  // 编号格式\r\n  DECIMAL: 'decimal',\r\n  DECIMAL_ZERO: 'decimalZero',\r\n  LOWER_LETTER: 'lowerLetter',\r\n  UPPER_LETTER: 'upperLetter',\r\n  LOWER_ROMAN: 'lowerRoman',\r\n  UPPER_ROMAN: 'upperRoman',\r\n  CHINESE_COUNTING: 'chineseCounting',\r\n  CHINESE_COUNTING_THOUSAND: 'chineseCountingThousand',\r\n  IDEOGRAPH_DIGITAL: 'ideographDigital',\r\n  JAPANESE_COUNTING: 'japaneseCounting',\r\n  KOREAN_COUNTING: 'koreanCounting',\r\n  TAIWANESE_COUNTING: 'taiwaneseCounting'\r\n} as const\r\n\r\n/** 段落对齐方式 */\r\nexport const ROW_FLEX = {\r\n  LEFT: 'left',\r\n  CENTER: 'center',\r\n  RIGHT: 'right',\r\n  JUSTIFY: 'justify',\r\n  ALIGNMENT: 'alignment',\r\n  DISTRIBUTE: 'distribute'\r\n} as const\r\n\r\n/** 标题级别 */\r\nexport const TITLE_LEVEL = {\r\n  FIRST: 'first',\r\n  SECOND: 'second',\r\n  THIRD: 'third',\r\n  FOURTH: 'fourth',\r\n  FIFTH: 'fifth',\r\n  SIXTH: 'sixth'\r\n} as const\r\n\r\n/** 字体族常量（对齐 WPS 常用字体，代码内引用用） */\r\nexport const FONT_FAMILY = {\r\n  SIM_SUN: 'SimSun',\r\n  SIM_HEI: 'SimHei',\r\n  KAI_TI: 'KaiTi',\r\n  FANG_SONG: 'FangSong',\r\n  MICROSOFT_YAHEI: 'Microsoft YaHei',\r\n  DENG_XIAN: 'DengXian',\r\n  ST_SONG: 'STSong',\r\n  ST_HEITI: 'STHeiti',\r\n  ST_KAITI: 'STKaiti',\r\n  ST_FANGSONG: 'STFangsong',\r\n  ST_ZHONGSONG: 'STZhongsong',\r\n  ST_XIHEI: 'STXihei',\r\n  ST_XINGKAI: 'STXingkai',\r\n  ST_LITI: 'STLiti',\r\n  ST_XINWEI: 'STXinwei',\r\n  ST_CAIYUN: 'STCaiyun',\r\n  TIMES_NEW_ROMAN: 'Times New Roman',\r\n  ARIAL: 'Arial',\r\n  CALIBRI: 'Calibri',\r\n  COURIER_NEW: 'Courier New',\r\n  VERDANA: 'Verdana'\r\n} as const\r\n\r\n/**\r\n * 字体映射条目（三层结构）\r\n * - label: 显示名（工具栏下拉显示）\r\n * - value: 存储名（文档里存的，WPS/Office 兼容）\r\n * - css:   CSS font-family 值（带跨平台 fallback，引用系统字体不侵权 + 开源字体兜底）\r\n * - aliases: 文档里可能存的其他名字（中文名、大小写变体等）\r\n */\r\nexport interface FontFamilyEntry {\r\n  label: string\r\n  value: string\r\n  css: string\r\n  aliases?: string[]\r\n}\r\n\r\n/**\r\n * WPS 常用字体完整映射表（16 中文字体 + 5 英文字体）\r\n * CSS fallback 策略：Windows 系统字体 → macOS 对应字体 → 开源字体兜底 → 通用字体族\r\n */\r\nexport const FONT_FAMILY_MAP: FontFamilyEntry[] = [\r\n  { label: '宋体', value: 'SimSun', css: '\"SimSun\", \"Songti SC\", \"Noto Serif CJK SC\", serif', aliases: ['宋体', 'simsun'] },\r\n  { label: '黑体', value: 'SimHei', css: '\"SimHei\", \"STHeiti\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif', aliases: ['黑体', 'simhei'] },\r\n  { label: '楷体', value: 'KaiTi', css: '\"KaiTi\", \"Kaiti SC\", \"STKaiti\", \"LXGW WenKai\", serif', aliases: ['楷体', 'kaiti'] },\r\n  { label: '仿宋', value: 'FangSong', css: '\"FangSong\", \"STFangsong\", \"Noto Serif CJK SC\", serif', aliases: ['仿宋', 'fangsong'] },\r\n  { label: '微软雅黑', value: 'Microsoft YaHei', css: '\"Microsoft YaHei\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif', aliases: ['微软雅黑', 'microsoft yahei'] },\r\n  { label: '等线', value: 'DengXian', css: '\"DengXian\", \"Noto Sans CJK SC\", sans-serif', aliases: ['等线', 'dengxian'] },\r\n  { label: '华文宋体', value: 'STSong', css: '\"STSong\", \"SimSun\", \"Songti SC\", \"Noto Serif CJK SC\", serif', aliases: ['华文宋体'] },\r\n  { label: '华文黑体', value: 'STHeiti', css: '\"STHeiti\", \"SimHei\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif', aliases: ['华文黑体'] },\r\n  { label: '华文楷体', value: 'STKaiti', css: '\"STKaiti\", \"KaiTi\", \"Kaiti SC\", \"LXGW WenKai\", serif', aliases: ['华文楷体'] },\r\n  { label: '华文仿宋', value: 'STFangsong', css: '\"STFangsong\", \"FangSong\", \"Noto Serif CJK SC\", serif', aliases: ['华文仿宋'] },\r\n  { label: '华文中宋', value: 'STZhongsong', css: '\"STZhongsong\", \"STSong\", \"SimSun\", \"Noto Serif CJK SC\", serif', aliases: ['华文中宋'] },\r\n  { label: '华文细黑', value: 'STXihei', css: '\"STXihei\", \"STHeiti\", \"SimHei\", \"Noto Sans CJK SC\", sans-serif', aliases: ['华文细黑'] },\r\n  { label: '华文行楷', value: 'STXingkai', css: '\"STXingkai\", \"STKaiti\", \"KaiTi\", \"LXGW WenKai\", serif', aliases: ['华文行楷'] },\r\n  { label: '华文隶书', value: 'STLiti', css: '\"STLiti\", \"STFangsong\", \"FangSong\", \"Noto Serif CJK SC\", serif', aliases: ['华文隶书'] },\r\n  { label: '华文新魏', value: 'STXinwei', css: '\"STXinwei\", \"STXihei\", \"SimHei\", \"Noto Sans CJK SC\", sans-serif', aliases: ['华文新魏'] },\r\n  { label: '华文彩云', value: 'STCaiyun', css: '\"STCaiyun\", \"STSong\", \"SimSun\", \"Noto Serif CJK SC\", serif', aliases: ['华文彩云'] },\r\n  { label: 'Times New Roman', value: 'Times New Roman', css: '\"Times New Roman\", \"Liberation Serif\", serif' },\r\n  { label: 'Arial', value: 'Arial', css: 'Arial, \"Liberation Sans\", sans-serif' },\r\n  { label: 'Calibri', value: 'Calibri', css: 'Calibri, \"Liberation Sans\", sans-serif' },\r\n  { label: 'Courier New', value: 'Courier New', css: '\"Courier New\", \"Liberation Mono\", monospace' },\r\n  { label: 'Verdana', value: 'Verdana', css: 'Verdana, \"DejaVu Sans\", sans-serif' }\r\n]\r\n\r\n/** 字体下拉选项（显示名列表，有序） */\r\nexport const FONT_FAMILY_LIST: string[] = FONT_FAMILY_MAP.map(e => e.label)\r\n\r\n/** 显示名 → 存储名（工具栏选中后存文档用） */\r\nexport const FONT_FAMILY_VALUE: Record<string, string> = Object.fromEntries(\r\n  FONT_FAMILY_MAP.map(e => [e.label, e.value])\r\n)\r\n\r\n/** 存储名/别名 → 显示名（用于回显，认中文名和英文名） */\r\nexport const FONT_FAMILY_LABEL: Record<string, string> = Object.fromEntries(\r\n  FONT_FAMILY_MAP.flatMap(e => [\r\n    [e.value, e.label],\r\n    ...(e.aliases ?? []).map(a => [a, e.label] as [string, string])\r\n  ])\r\n)\r\n\r\n/** 存储名/别名 → CSS font-family 值（用于渲染，带跨平台 fallback） */\r\nexport const FONT_FAMILY_CSS: Record<string, string> = Object.fromEntries(\r\n  FONT_FAMILY_MAP.flatMap(e => [\r\n    [e.value, e.css],\r\n    ...(e.aliases ?? []).map(a => [a, e.css] as [string, string])\r\n  ])\r\n)\r\n\r\n/**\r\n * WPS 字号表（中文字号名 → pt 值）\r\n * 完整覆盖 WPS 全部预设字号：初号~八号 + 小初~小六\r\n */\r\nexport const FONT_SIZE: Record<string, number> = {\r\n  '初号': 42,\r\n  '小初': 36,\r\n  '一号': 26,\r\n  '小一': 24,\r\n  '二号': 22,\r\n  '小二': 18,\r\n  '三号': 16,\r\n  '小三': 15,\r\n  '四号': 14,\r\n  '小四': 12,\r\n  '五号': 10.5,\r\n  '小五': 9,\r\n  '六号': 7.5,\r\n  '小六': 6.5,\r\n  '七号': 5.5,\r\n  '八号': 5\r\n}\r\n\r\n/**\r\n * 字号下拉选项（有序，中文字号 + 常用数字字号）\r\n * WPS 风格：先列中文字号，再列常用数字字号\r\n */\r\nexport const FONT_SIZE_LIST = [\r\n  '初号', '小初', '一号', '小一', '二号', '小二', '三号', '小三', '四号', '小四',\r\n  '五号', '小五', '六号', '小六', '七号', '八号',\r\n  '5', '5.5', '6.5', '7.5', '8', '9', '10', '10.5', '11', '12', '14', '15', '16',\r\n  '18', '20', '22', '24', '26', '28', '30', '36', '42', '48', '54', '60', '72'\r\n] as const\r\n\r\n/* ========== 纸张方向 / 表格边框 ========== */\r\n\r\n/** 纸张方向 */\r\nexport const PaperDirection = {\r\n  VERTICAL: 'vertical',\r\n  HORIZONTAL: 'horizontal'\r\n} as const\r\n\r\n/** 表格边框类型 */\r\nexport const TableBorder = {\r\n  NONE: 'none',\r\n  OUTSIDE: 'outside',\r\n  ALL: 'all',\r\n  INSIDE: 'inside',\r\n  INSIDE_HORIZONTAL: 'inside-horizontal',\r\n  INSIDE_VERTICAL: 'inside-vertical',\r\n  TOP: 'top',\r\n  BOTTOM: 'bottom',\r\n  LEFT: 'left',\r\n  RIGHT: 'right'\r\n} as const\r\n\r\nexport type TableBorderPreset = typeof TableBorder[keyof typeof TableBorder]\r\n\r\n/* ========== 单位换算（96 DPI） ========== */\r\n\r\n/** 屏幕 DPI 常量 */\r\nexport const DPI = 96\r\n\r\n/**\r\n * 磅（pt）转像素（px）\r\n * @param pt 磅值\r\n * @returns 像素值（保留两位小数）\r\n */\r\nexport function ptToPx(pt: number): number {\r\n  return Math.round(pt * (DPI / 72) * 100) / 100\r\n}\r\n\r\n/**\r\n * 像素（px）转磅（pt）\r\n * @param px 像素值\r\n * @returns 磅值（保留一位小数，0.5 步进）\r\n */\r\nexport function pxToPt(px: number): number {\r\n  return Math.round(px * (72 / DPI) * 2) / 2\r\n}\r\n\r\n/* ========== 纸张大小（对齐 WPS/Office，96 DPI） ========== */\r\n\r\nexport interface PaperSize {\r\n  /** 纸张标识（唯一 key） */\r\n  key: string\r\n  /** 显示名称 */\r\n  label: string\r\n  /** 纸张宽度（px @ 96dpi） */\r\n  width: number\r\n  /** 纸张高度（px @ 96dpi） */\r\n  height: number\r\n  /** 分类 */\r\n  category: 'a-series' | 'b-series' | 'us' | 'cn' | 'envelope' | 'other'\r\n}\r\n\r\n/**\r\n * WPS/Office 纸张预设列表（覆盖 80%+ 常用纸张）\r\n * 像素值按 96 DPI 换算：px = mm * 96 / 25.4\r\n */\r\nexport const PAPER_SIZE_LIST: PaperSize[] = [\r\n  // A 系列（ISO 216）\r\n  { key: 'a0', label: 'A0 (84.1×118.9cm)', width: 3179, height: 4494, category: 'a-series' },\r\n  { key: 'a1', label: 'A1 (59.4×84.1cm)', width: 2245, height: 3179, category: 'a-series' },\r\n  { key: 'a2', label: 'A2 (42×59.4cm)', width: 1587, height: 2245, category: 'a-series' },\r\n  { key: 'a3', label: 'A3 (29.7×42cm)', width: 1123, height: 1587, category: 'a-series' },\r\n  { key: 'a4', label: 'A4 (21×29.7cm)', width: 794, height: 1123, category: 'a-series' },\r\n  { key: 'a5', label: 'A5 (14.8×21cm)', width: 559, height: 794, category: 'a-series' },\r\n  { key: 'a6', label: 'A6 (10.5×14.8cm)', width: 397, height: 559, category: 'a-series' },\r\n  // B 系列（JIS）\r\n  { key: 'b4', label: 'B4 (25.7×36.4cm)', width: 971, height: 1376, category: 'b-series' },\r\n  { key: 'b5', label: 'B5 (18.2×25.7cm)', width: 688, height: 971, category: 'b-series' },\r\n  { key: 'b6', label: 'B6 (12.8×18.2cm)', width: 484, height: 688, category: 'b-series' },\r\n  // 美式\r\n  { key: 'letter', label: 'Letter (21.6×27.9cm)', width: 816, height: 1056, category: 'us' },\r\n  { key: 'legal', label: 'Legal (21.6×35.6cm)', width: 816, height: 1344, category: 'us' },\r\n  { key: 'tabloid', label: 'Tabloid (27.9×43.2cm)', width: 1056, height: 1633, category: 'us' },\r\n  { key: 'executive', label: 'Executive (18.4×26.7cm)', width: 696, height: 1009, category: 'us' },\r\n  { key: 'statement', label: 'Statement (14×21.6cm)', width: 529, height: 816, category: 'us' },\r\n  { key: 'folio', label: 'Folio (21.6×33cm)', width: 816, height: 1247, category: 'us' },\r\n  // 中式\r\n  { key: '16k', label: '16K (19.5×27cm)', width: 737, height: 1020, category: 'cn' },\r\n  { key: '32k', label: '32K (13×19cm)', width: 491, height: 718, category: 'cn' },\r\n  { key: '32k-large', label: '大32K (14×20.3cm)', width: 529, height: 767, category: 'cn' },\r\n  // 信封\r\n  { key: 'env-10', label: '信封 #10 (10.5×24.1cm)', width: 397, height: 910, category: 'envelope' },\r\n  { key: 'env-dl', label: '信封 DL (11×22cm)', width: 416, height: 831, category: 'envelope' },\r\n  { key: 'env-c5', label: '信封 C5 (16.2×22.9cm)', width: 612, height: 865, category: 'envelope' },\r\n  { key: 'env-c6', label: '信封 C6 (11.4×16.2cm)', width: 430, height: 612, category: 'envelope' },\r\n  { key: 'env-monarch', label: '信封 Monarch (9.8×19cm)', width: 370, height: 718, category: 'envelope' },\r\n  // 其他\r\n  { key: 'photo-4x6', label: '照片 4×6 (10.2×15.2cm)', width: 386, height: 574, category: 'other' },\r\n  { key: 'postcard', label: '明信片 (10×14.8cm)', width: 378, height: 559, category: 'other' }\r\n]\r\n\r\n/** 默认纸张大小（A4） */\r\nexport const DEFAULT_PAPER_SIZE: PaperSize = PAPER_SIZE_LIST[4]\r\n\r\n/* ========== 项目符号 / 编号样式 ========== */\r\n\r\n/** 项目符号样式 */\r\nexport const BULLET_STYLES = [\r\n  { style: 'disc', icon: '●', label: '实心圆点' },\r\n  { style: 'circle', icon: '○', label: '空心圆点' },\r\n  { style: 'square', icon: '■', label: '实心方块' },\r\n  { style: 'hollow-square', icon: '□', label: '空心方块' },\r\n  { style: 'diamond', icon: '◆', label: '实心菱形' },\r\n  { style: 'hollow-diamond', icon: '◇', label: '空心菱形' },\r\n  { style: 'arrow', icon: '▶', label: '箭头' },\r\n  { style: 'check', icon: '✓', label: '对勾' }\r\n]\r\n\r\n/** 编号样式 */\r\nexport const NUMBER_STYLES = [\r\n  { style: 'decimal', numFmt: 'decimal', lvlText: '%1.', samples: ['1.', '2.', '3.'], label: '阿拉伯数字' },\r\n  { style: 'decimal-bracket', numFmt: 'decimal', lvlText: '%1)', samples: ['1)', '2)', '3)'], label: '数字右括号' },\r\n  { style: 'decimal-paren', numFmt: 'decimal', lvlText: '(%1)', samples: ['(1)', '(2)', '(3)'], label: '数字括号' },\r\n  { style: 'upper-alpha', numFmt: 'upperLetter', lvlText: '%1.', samples: ['A.', 'B.', 'C.'], label: '大写字母' },\r\n  { style: 'lower-alpha-dot', numFmt: 'lowerLetter', lvlText: '%1.', samples: ['a.', 'b.', 'c.'], label: '小写字母' },\r\n  { style: 'chinese', numFmt: 'chineseCounting', lvlText: '%1、', samples: ['一、', '二、', '三、'], label: '中文数字' },\r\n  { style: 'chinese-bracket', numFmt: 'chineseCounting', lvlText: '（%1）', samples: ['（一）', '（二）', '（三）'], label: '中文括号' },\r\n  { style: 'decimal-circle', numFmt: 'decimalEnclosedCircle', lvlText: '%1', samples: ['①', '②', '③'], label: '圈码' }\r\n]\r\n\r\n/* ========== 行距 / 页边距 / 缩放 ========== */\r\n\r\n/** 行距选项 */\r\nexport const LINE_HEIGHT_OPTIONS = [\r\n  { value: 1, label: '单倍行距' },\r\n  { value: 1.15, label: '1.15 倍行距' },\r\n  { value: 1.5, label: '1.5 倍行距' },\r\n  { value: 2, label: '双倍行距' },\r\n  { value: 2.5, label: '2.5 倍行距' },\r\n  { value: 3, label: '三倍行距' }\r\n]\r\n\r\n/** 页边距预设 */\r\nexport const MARGIN_PRESETS = [\r\n  { name: '普通', margins: [96, 120, 96, 120], style: { margin: '14px 18px' } },\r\n  { name: '窄', margins: [48, 48, 48, 48], style: { margin: '7px 7px' } },\r\n  { name: '适中', margins: [96, 72, 96, 72], style: { margin: '14px 11px' } },\r\n  { name: '宽', margins: [96, 192, 96, 192], style: { margin: '14px 28px' } }\r\n]\r\n\r\n/** 缩放级别 */\r\nexport const ZOOM_LEVELS = [50, 75, 100, 125, 150, 200]\r\n\r\n/* ========== 分割线样式 ========== */\r\n\r\n/** 分割线样式 */\r\nexport const SEPARATOR_STYLES = [\r\n  { name: '极细实线', type: 'solid', width: 0.5, dashArray: [0, 0] },\r\n  { name: '细实线', type: 'solid', width: 1, dashArray: [0, 0] },\r\n  { name: '中实线', type: 'solid', width: 2, dashArray: [0, 0] },\r\n  { name: '粗实线', type: 'solid', width: 3, dashArray: [0, 0] },\r\n  { name: '特粗实线', type: 'solid', width: 4, dashArray: [0, 0] },\r\n  { name: '细点线', type: 'dotted', width: 0.5, dashArray: [1, 1] },\r\n  { name: '点线', type: 'dotted', width: 1, dashArray: [1, 1] },\r\n  { name: '粗点线', type: 'dotted', width: 2, dashArray: [1, 1] },\r\n  { name: '大点线', type: 'dotted', width: 3, dashArray: [2, 2] },\r\n  { name: '细短虚线', type: 'dashed', width: 0.5, dashArray: [3, 2] },\r\n  { name: '短虚线', type: 'dashed', width: 1, dashArray: [3, 2] },\r\n  { name: '粗短虚线', type: 'dashed', width: 2, dashArray: [3, 2] },\r\n  { name: '细长虚线', type: 'dashed', width: 0.5, dashArray: [6, 3] },\r\n  { name: '长虚线', type: 'dashed', width: 1, dashArray: [6, 3] },\r\n  { name: '粗长虚线', type: 'dashed', width: 2, dashArray: [6, 3] },\r\n  { name: '特长虚线', type: 'dashed', width: 1, dashArray: [10, 5] },\r\n  { name: '点划线', type: 'dashed', width: 1, dashArray: [6, 2, 1, 2] },\r\n  { name: '粗点划线', type: 'dashed', width: 2, dashArray: [6, 2, 1, 2] },\r\n  { name: '双点划线', type: 'dashed', width: 1, dashArray: [6, 2, 1, 2, 1, 2] },\r\n  { name: '粗双点划线', type: 'dashed', width: 2, dashArray: [6, 2, 1, 2, 1, 2] },\r\n  { name: '细双线', type: 'double', width: 2, dashArray: [0, 0] },\r\n  { name: '双线', type: 'double', width: 3, dashArray: [0, 0] },\r\n  { name: '粗双线', type: 'double', width: 4, dashArray: [0, 0] },\r\n  { name: '特粗双线', type: 'double', width: 5, dashArray: [0, 0] },\r\n  { name: '三线', type: 'triple', width: 4, dashArray: [0, 0] },\r\n  { name: '细波浪线', type: 'wavy', width: 0.5, dashArray: [0, 0] },\r\n  { name: '波浪线', type: 'wavy', width: 1, dashArray: [0, 0] },\r\n  { name: '粗波浪线', type: 'wavy', width: 2, dashArray: [0, 0] },\r\n  { name: '渐变线', type: 'gradient', width: 2, dashArray: [0, 0] },\r\n  { name: '阴影线', type: 'shadow', width: 2, dashArray: [0, 0] },\r\n  { name: '浮雕线', type: 'emboss', width: 3, dashArray: [0, 0] }\r\n]\r\n\r\n/* ========== 标题级别映射 ========== */\r\n\r\n/** 标题级别映射 */\r\nexport const TITLE_LEVEL_MAP: Record<string, string> = {\r\n  first: '标题1',\r\n  second: '标题2',\r\n  third: '标题3',\r\n  fourth: '标题4',\r\n  fifth: '标题5',\r\n  sixth: '标题6'\r\n}\r\n","const AUTHOR_COLORS = [\r\n  '#409EFF', '#67C23A', '#E6A23C', '#F56C6C',\r\n  '#909399', '#00BCD4', '#9C27B0', '#3F51B5',\r\n  '#FF9800', '#4CAF50', '#009688', '#795548',\r\n  '#FF5722', '#C2185B', '#FFC107', '#607D8B'\r\n]\r\n\r\n/** Stable author colors shared by review text, balloons and connectors. */\r\nexport function getAuthorColor(name: string): string {\r\n  let hash = 0\r\n  for (let i = 0; i < name.length; i++) {\r\n    hash = name.charCodeAt(i) + ((hash << 5) - hash)\r\n  }\r\n  return AUTHOR_COLORS[Math.abs(hash) % AUTHOR_COLORS.length]\r\n}\r\n","import type { IElement, ITextElement } from './types'\r\n\r\nexport interface RevisionMeta {\r\n  revisionId: string\r\n  revisionType: 'insert' | 'delete' | 'format'\r\n  revisionAuthor: string\r\n  revisionDate: string\r\n}\r\n\r\ntype FormatValue = string | number | boolean | null\r\nexport type RevisionFormat = Record<string, FormatValue>\r\n\r\nconst FORMAT_KEYS = [\r\n  'font', 'size', 'bold', 'italic', 'underline', 'strikeout', 'doubleStrikeout',\r\n  'hidden', 'superscript', 'subscript', 'color', 'highlight', 'characterScale',\r\n  'letterSpacing', 'textDecoration', 'characterStyleId', 'paragraphStyleId',\r\n  'paragraphColor', 'rowFlex', 'lineHeight', 'lineHeightRule', 'rowMargin',\r\n  'paragraphIndentLeft', 'paragraphIndentRight', 'paragraphFirstLineIndent',\r\n  'indentHanging', 'paragraphSpacingBefore', 'paragraphSpacingAfter'\r\n] as const\r\n\r\nconst BOOLEAN_TAGS = {\r\n  bold: 'b', italic: 'i', strikeout: 'strike', doubleStrikeout: 'dstrike', hidden: 'vanish'\r\n} as const\r\n\r\nexport function snapshotRevisionFormat(element: IElement): RevisionFormat {\r\n  const source = element as unknown as Record<string, unknown>\r\n  return Object.fromEntries(FORMAT_KEYS.map(key => [key, source[key] ?? null])) as RevisionFormat\r\n}\r\n\r\nexport function clearRevision(element: IElement): void {\r\n  const run = element as ITextElement\r\n  delete run.revisionId\r\n  delete run.revisionType\r\n  delete run.revisionAuthor\r\n  delete run.revisionDate\r\n  delete run.revisionOldRPr\r\n  if (run.extension) {\r\n    // Do not mutate extension objects that may be shared by split runs.\r\n    const extension = { ...run.extension }\r\n    delete extension.revisionOldProps\r\n    delete extension.revisionPrevious\r\n    if (Object.keys(extension).length) run.extension = extension\r\n    else delete run.extension\r\n  }\r\n}\r\n\r\nfunction decodeXml(value: string): string {\r\n  return value.replace(/&quot;/g, '\"').replace(/&apos;/g, \"'\")\r\n    .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&')\r\n}\r\n\r\nfunction escapeXml(value: FormatValue): string {\r\n  return String(value).replace(/&/g, '&amp;').replace(/\"/g, '&quot;')\r\n    .replace(/</g, '&lt;').replace(/>/g, '&gt;')\r\n}\r\n\r\nfunction readRunProperties(xml: string): RevisionFormat {\r\n  const result: RevisionFormat = {}\r\n  const tag = (name: string) => xml.match(new RegExp(`<(?:\\\\w+:)?${name}(?=[\\\\s/>])([^>]*)>`))?.[1]\r\n  const attr = (source: string | undefined, name = 'val') =>\r\n    source?.match(new RegExp(`(?:^|\\\\s)(?:\\\\w+:)?${name}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`))?.[1]\r\n  for (const [key, name] of Object.entries(BOOLEAN_TAGS)) {\r\n    const source = tag(name)\r\n    result[key] = source === undefined ? null : !/^(0|false|off)$/.test(attr(source) ?? '')\r\n  }\r\n  const underline = tag('u')\r\n  result.underline = underline === undefined ? null : attr(underline) !== 'none'\r\n  result.textDecoration = underline === undefined ? null : ({\r\n    single: 'solid', double: 'double', dash: 'dashed', dotted: 'dotted', wave: 'wavy'\r\n  } as Record<string, string>)[attr(underline) ?? 'single'] ?? 'solid'\r\n  const fonts = tag('rFonts')\r\n  const font = attr(fonts, 'eastAsia') ?? attr(fonts, 'ascii') ?? attr(fonts, 'hAnsi')\r\n  result.font = font === undefined ? null : decodeXml(font)\r\n  for (const [key, name, scale] of [\r\n    ['size', 'sz', 0.5], ['characterScale', 'w', 1], ['letterSpacing', 'spacing', 1 / 15]\r\n  ] as const) {\r\n    const value = attr(tag(name))\r\n    result[key] = value !== undefined && Number.isFinite(Number(value)) ? Number(value) * scale : null\r\n  }\r\n  const color = attr(tag('color'))\r\n  result.color = color && color !== 'auto' ? `#${color}` : null\r\n  result.highlight = attr(tag('highlight')) ?? null\r\n  result.characterStyleId = attr(tag('rStyle')) ?? null\r\n  const vertical = attr(tag('vertAlign'))\r\n  result.superscript = vertical === 'superscript' ? true : null\r\n  result.subscript = vertical === 'subscript' ? true : null\r\n  return result\r\n}\r\n\r\nexport function getRevisionOldProps(element: IElement): RevisionFormat {\r\n  const stored = element.extension?.revisionOldProps\r\n  if (stored && typeof stored === 'object' && !Array.isArray(stored)) {\r\n    const source = stored as Record<string, unknown>\r\n    const result: RevisionFormat = {}\r\n    for (const key of FORMAT_KEYS) {\r\n      if (!Object.prototype.hasOwnProperty.call(source, key)) continue\r\n      const value = source[key]\r\n      if (value == null || ['string', 'number', 'boolean'].includes(typeof value)) {\r\n        result[key] = (value ?? null) as FormatValue\r\n      }\r\n    }\r\n    return result\r\n  }\r\n  const xml = (element as ITextElement).revisionOldRPr\r\n  return xml === undefined ? {} : readRunProperties(xml)\r\n}\r\n\r\nfunction serializeRunProperties(format: RevisionFormat): string {\r\n  const parts: string[] = []\r\n  const add = (tag: string, value: FormatValue) => {\r\n    if (value !== null && value !== undefined) parts.push(`<w:${tag} w:val=\"${escapeXml(value)}\"/>`)\r\n  }\r\n  for (const [key, tag] of Object.entries(BOOLEAN_TAGS)) {\r\n    if (format[key] != null) add(tag, format[key] ? 1 : 0)\r\n  }\r\n  if (format.font != null) {\r\n    const font = escapeXml(format.font)\r\n    parts.push(`<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\" w:eastAsia=\"${font}\"/>`)\r\n  }\r\n  if (typeof format.size === 'number') add('sz', format.size * 2)\r\n  if (typeof format.letterSpacing === 'number') add('spacing', Math.round(format.letterSpacing * 15))\r\n  add('w', format.characterScale)\r\n  add('rStyle', format.characterStyleId)\r\n  add('color', typeof format.color === 'string' ? format.color.replace(/^#/, '') : null)\r\n  add('highlight', format.highlight)\r\n  if (format.underline != null) {\r\n    const style = ({ solid: 'single', double: 'double', dashed: 'dash', dotted: 'dotted', wavy: 'wave' } as Record<string, string>)[String(format.textDecoration)] ?? 'single'\r\n    add('u', format.underline ? style : 'none')\r\n  }\r\n  if (format.superscript || format.subscript) add('vertAlign', format.superscript ? 'superscript' : 'subscript')\r\n  return parts.join('')\r\n}\r\n\r\nexport function recordFormatRevision(element: IElement, before: RevisionFormat, meta: RevisionMeta): void {\r\n  const run = element as ITextElement\r\n  // A run has one revision slot: formatting must not replace insertion/deletion identity.\r\n  if (run.revisionType === 'insert' || run.revisionType === 'delete') return\r\n  const after = snapshotRevisionFormat(element)\r\n  const changed = FORMAT_KEYS.filter(key => before[key] !== after[key])\r\n  if (!changed.length) return\r\n  const existing = run.revisionType === 'format'\r\n  const oldProps = existing ? getRevisionOldProps(element) : {}\r\n  for (const key of changed) {\r\n    if (!(key in oldProps)) oldProps[key] = before[key] ?? null\r\n  }\r\n  if (Object.entries(oldProps).every(([key, value]) => after[key] === value)) {\r\n    clearRevision(element)\r\n    return\r\n  }\r\n  if (!existing) {\r\n    Object.assign(run, meta)\r\n    run.revisionOldRPr = serializeRunProperties(before)\r\n  }\r\n  run.extension = { ...run.extension, revisionOldProps: oldProps }\r\n}\r\n\r\nexport function restoreRevisionFormat(element: IElement): void {\r\n  const target = element as unknown as Record<string, unknown>\r\n  for (const [key, value] of Object.entries(getRevisionOldProps(element))) {\r\n    if (value === null) delete target[key]\r\n    else target[key] = value\r\n  }\r\n}\r\n","'use strict'\nmodule.exports = rfdc\n\nfunction copyBuffer (cur) {\n  if (cur instanceof Buffer) {\n    return Buffer.from(cur)\n  }\n\n  return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n}\n\nfunction rfdc (opts) {\n  opts = opts || {}\n  if (opts.circles) return rfdcCircles(opts)\n\n  const constructorHandlers = new Map()\n  constructorHandlers.set(Date, (o) => new Date(o))\n  constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))\n  constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))\n  if (opts.constructorHandlers) {\n    for (const handler of opts.constructorHandlers) {\n      constructorHandlers.set(handler[0], handler[1])\n    }\n  }\n\n  let handler = null\n\n  return opts.proto ? cloneProto : clone\n\n  function cloneArray (a, fn) {\n    const keys = Object.keys(a)\n    const a2 = new Array(keys.length)\n    for (let i = 0; i < keys.length; i++) {\n      const k = keys[i]\n      const cur = a[k]\n      if (typeof cur !== 'object' || cur === null) {\n        a2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        a2[k] = handler(cur, fn)\n      } else if (ArrayBuffer.isView(cur)) {\n        a2[k] = copyBuffer(cur)\n      } else {\n        a2[k] = fn(cur)\n      }\n    }\n    return a2\n  }\n\n  function clone (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, clone)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, clone)\n    }\n    const o2 = {}\n    for (const k in o) {\n      if (Object.hasOwnProperty.call(o, k) === false) continue\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, clone)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        o2[k] = clone(cur)\n      }\n    }\n    return o2\n  }\n\n  function cloneProto (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, cloneProto)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, cloneProto)\n    }\n    const o2 = {}\n    for (const k in o) {\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, cloneProto)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        o2[k] = cloneProto(cur)\n      }\n    }\n    return o2\n  }\n}\n\nfunction rfdcCircles (opts) {\n  const refs = []\n  const refsNew = []\n\n  const constructorHandlers = new Map()\n  constructorHandlers.set(Date, (o) => new Date(o))\n  constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))\n  constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))\n  if (opts.constructorHandlers) {\n    for (const handler of opts.constructorHandlers) {\n      constructorHandlers.set(handler[0], handler[1])\n    }\n  }\n\n  let handler = null\n  return opts.proto ? cloneProto : clone\n\n  function cloneArray (a, fn) {\n    const keys = Object.keys(a)\n    const a2 = new Array(keys.length)\n    for (let i = 0; i < keys.length; i++) {\n      const k = keys[i]\n      const cur = a[k]\n      if (typeof cur !== 'object' || cur === null) {\n        a2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        a2[k] = handler(cur, fn)\n      } else if (ArrayBuffer.isView(cur)) {\n        a2[k] = copyBuffer(cur)\n      } else {\n        const index = refs.indexOf(cur)\n        if (index !== -1) {\n          a2[k] = refsNew[index]\n        } else {\n          a2[k] = fn(cur)\n        }\n      }\n    }\n    return a2\n  }\n\n  function clone (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, clone)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, clone)\n    }\n    const o2 = {}\n    refs.push(o)\n    refsNew.push(o2)\n    for (const k in o) {\n      if (Object.hasOwnProperty.call(o, k) === false) continue\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, clone)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        const i = refs.indexOf(cur)\n        if (i !== -1) {\n          o2[k] = refsNew[i]\n        } else {\n          o2[k] = clone(cur)\n        }\n      }\n    }\n    refs.pop()\n    refsNew.pop()\n    return o2\n  }\n\n  function cloneProto (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, cloneProto)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, cloneProto)\n    }\n    const o2 = {}\n    refs.push(o)\n    refsNew.push(o2)\n    for (const k in o) {\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, cloneProto)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        const i = refs.indexOf(cur)\n        if (i !== -1) {\n          o2[k] = refsNew[i]\n        } else {\n          o2[k] = cloneProto(cur)\n        }\n      }\n    }\n    refs.pop()\n    refsNew.pop()\n    return o2\n  }\n}\n","\r\n/**\r\n * VerveDocs Schema —— 树遍历与路径寻址\r\n *\r\n * 所有遍历严格保持树形语义，不做扁平化。\r\n */\r\n\r\nimport rfdc from 'rfdc'\r\nimport type { IElement, Path, PathSegment, IPosition, ITableElement, ITd, ITr } from './types'\r\n\r\n/* -------------------- 深拷贝 -------------------- */\r\n\r\n/** rfdc 深拷贝实例（关闭原型拷贝与循环引用检测以提升性能） */\r\nconst _clone = rfdc({ proto: false, circles: false })\r\n\r\n/**\r\n * 深拷贝树节点。\r\n * @param node 待拷贝的节点\r\n * @returns 拷贝后的新节点（基本类型直接返回）\r\n */\r\nexport function cloneTree<T>(node: T): T {\r\n  if (node === null || typeof node !== 'object') return node\r\n  return _clone(node)\r\n}\r\n\r\n/* -------------------- 类型守卫 -------------------- */\r\n\r\n/**\r\n * 判断元素是否为段落容器（title/list 且拥有 valueList 数组）。\r\n * @param el 待判断元素\r\n * @returns 是段落容器则返回 true，并收窄类型\r\n */\r\nexport function isParagraphContainer(el: IElement): el is IElement & { valueList: IElement[] } {\r\n  return (el?.type === 'title' || el?.type === 'list') && Array.isArray((el as { valueList?: unknown }).valueList)\r\n}\r\n\r\n/**\r\n * 判断元素是否为表格（type='table' 且拥有 trList 数组）。\r\n * @param el 待判断元素\r\n * @returns 是表格则返回 true，并收窄类型\r\n */\r\nexport function isTable(el: IElement): el is ITableElement {\r\n  return el?.type === 'table' && Array.isArray((el as ITableElement).trList)\r\n}\r\n\r\n/* -------------------- 访问器 -------------------- */\r\n\r\n/** 遍历上下文：携带父节点、路径与索引信息 */\r\nexport interface VisitContext {\r\n  /** 父节点（数组或单个元素，根数组时为 null） */\r\n  parent: IElement[] | IElement | null\r\n  /** 当前节点路径 */\r\n  path: Path\r\n  /** 在父容器中的索引 */\r\n  index: number\r\n}\r\n\r\n/** 访问者函数类型：返回 false 可跳过当前节点的子树 */\r\nexport type Visitor = (node: IElement, ctx: VisitContext) => void | boolean\r\n\r\n/**\r\n * 深度优先遍历（返回 false 可跳过子树）。\r\n * 遍历顺序：elements[i] → 若为段落容器则 valueList[i]；若为 table 则 trList[j].tdList[k].value[m]。\r\n */\r\nexport function walkTree(elements: IElement[], visitor: Visitor, parentPath: Path = []): void {\r\n  for (let i = 0; i < elements.length; i++) {\r\n    const node = elements[i]\r\n    const path: Path = [...parentPath, i]\r\n    const shouldDescend = visitor(node, { parent: elements, path, index: i })\r\n    if (shouldDescend === false) continue\r\n\r\n    if (isParagraphContainer(node)) {\r\n      walkTree(node.valueList, visitor, [...path, 'valueList'])\r\n    } else if (isTable(node)) {\r\n      for (let tr = 0; tr < node.trList.length; tr++) {\r\n        const row = node.trList[tr]\r\n        for (let td = 0; td < row.tdList.length; td++) {\r\n          const cell = row.tdList[td]\r\n          walkTree(cell.value, visitor, [...path, 'trList', tr, 'tdList', td, 'value'])\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/* -------------------- 路径寻址 -------------------- */\r\n\r\n/**\r\n * 根据路径获取节点。\r\n * 路径示例：\r\n *   [3]                                → elements[3]\r\n *   [3, 'valueList', 1]                → elements[3].valueList[1]\r\n *   [5, 'trList', 0, 'tdList', 2, 'value', 1] → table 第 0 行第 2 单元格第 1 子元素\r\n */\r\nexport function getByPath(root: IElement[], path: Path): IElement | null {\r\n  if (path.length === 0) return null\r\n  let current: unknown = root\r\n  for (const seg of path) {\r\n    if (current == null) return null\r\n    if (typeof seg === 'number') {\r\n      if (!Array.isArray(current)) return null\r\n      current = current[seg]\r\n    } else {\r\n      current = (current as Record<string, unknown>)[seg]\r\n    }\r\n  }\r\n  return (current as IElement) ?? null\r\n}\r\n\r\n/**\r\n * 获取路径末段对应的父容器数组。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @returns 父容器数组；若路径非法或末段不是数组索引则返回 null\r\n */\r\nexport function getParentContainer(root: IElement[], path: Path): IElement[] | null {\r\n  if (path.length === 0) return null\r\n  const parentPath = path.slice(0, -1)\r\n  const lastSeg = path[path.length - 1]\r\n  if (typeof lastSeg !== 'number') return null // 末段必须是数组索引\r\n  if (parentPath.length === 0) return root\r\n  let current: unknown = root\r\n  for (const seg of parentPath) {\r\n    if (typeof seg === 'number') {\r\n      if (!Array.isArray(current)) return null\r\n      current = current[seg]\r\n    } else {\r\n      current = (current as Record<string, unknown>)[seg]\r\n    }\r\n  }\r\n  return Array.isArray(current) ? (current as IElement[]) : null\r\n}\r\n\r\n/**\r\n * 在路径指定位置替换节点。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @param node 新节点\r\n * @returns 替换成功返回 true，路径非法返回 false\r\n */\r\nexport function replaceAtPath(root: IElement[], path: Path, node: IElement): boolean {\r\n  const parent = getParentContainer(root, path)\r\n  if (!parent) return false\r\n  const idx = path[path.length - 1] as number\r\n  parent[idx] = node\r\n  return true\r\n}\r\n\r\n/**\r\n * 在路径指定位置插入节点（插入到该索引前）。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @param node 待插入节点\r\n * @returns 插入成功返回 true，路径非法返回 false\r\n */\r\nexport function insertAtPath(root: IElement[], path: Path, node: IElement): boolean {\r\n  const parent = getParentContainer(root, path)\r\n  if (!parent) return false\r\n  const idx = path[path.length - 1] as number\r\n  parent.splice(idx, 0, node)\r\n  return true\r\n}\r\n\r\n/**\r\n * 移除路径指定位置的节点。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @returns 被移除的节点；路径非法返回 null\r\n */\r\nexport function removeAtPath(root: IElement[], path: Path): IElement | null {\r\n  const parent = getParentContainer(root, path)\r\n  if (!parent) return null\r\n  const idx = path[path.length - 1] as number\r\n  const [removed] = parent.splice(idx, 1)\r\n  return removed ?? null\r\n}\r\n\r\n/* -------------------- 位置工具 -------------------- */\r\n\r\n/**\r\n * 判断两条路径是否完全相同。\r\n * @param a 路径 a\r\n * @param b 路径 b\r\n * @returns 相同返回 true\r\n */\r\nexport function isSamePath(a: Path, b: Path): boolean {\r\n  if (a.length !== b.length) return false\r\n  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\r\n  return true\r\n}\r\n\r\n/**\r\n * 比较两条路径的字典序（数字段按数值比较，字符串段按字符串比较）。\r\n * @param a 路径 a\r\n * @param b 路径 b\r\n * @returns a<b 返回负数，a=b 返回 0，a>b 返回正数\r\n */\r\nexport function comparePath(a: Path, b: Path): number {\r\n  const n = Math.min(a.length, b.length)\r\n  for (let i = 0; i < n; i++) {\r\n    const av = a[i]; const bv = b[i]\r\n    if (av === bv) continue\r\n    if (typeof av === 'number' && typeof bv === 'number') return av - bv\r\n    return String(av) < String(bv) ? -1 : 1\r\n  }\r\n  return a.length - b.length\r\n}\r\n\r\n/**\r\n * 比较两个文档位置：先比较路径，路径相同再比较 offset。\r\n * @param a 位置 a\r\n * @param b 位置 b\r\n * @returns a<b 返回负数，a=b 返回 0，a>b 返回正数\r\n */\r\nexport function comparePosition(a: IPosition, b: IPosition): number {\r\n  const c = comparePath(a.path, b.path)\r\n  if (c !== 0) return c\r\n  return a.offset - b.offset\r\n}\r\n\r\n/* -------------------- 表格辅助 -------------------- */\r\n\r\n/**\r\n * 遍历表格所有单元格，对每个单元格调用回调。\r\n * @param table 表格元素\r\n * @param fn 回调函数，接收单元格、行、行索引、列索引\r\n */\r\nexport function forEachCell(\r\n  table: ITableElement,\r\n  fn: (cell: ITd, tr: ITr, trIndex: number, tdIndex: number) => void\r\n) {\r\n  for (let i = 0; i < table.trList.length; i++) {\r\n    const row = table.trList[i]\r\n    for (let j = 0; j < row.tdList.length; j++) {\r\n      fn(row.tdList[j], row, i, j)\r\n    }\r\n  }\r\n}\r\n\r\n/** 计算表格列数（不考虑合并） */\r\nexport function getTableColCount(table: ITableElement): number {\r\n  if (Array.isArray(table.colgroup)) return table.colgroup.length\r\n  return table.trList[0]?.tdList.reduce((sum, td) => sum + (td.colspan || 1), 0) ?? 0\r\n}\r\n\r\n/** 计算某段路径所在的段落容器（title/list/纯段落用父数组表示） */\r\nexport function _pathSegAsKey(seg: PathSegment): string {\r\n  return typeof seg === 'number' ? String(seg) : seg\r\n}\r\n","/**\r\n * VerveDocs Schema —— formatElementTree\r\n *\r\n * 唯一的树归一入口：只做默认值补全、字段规范化，绝不扁平化。\r\n * 输入即输出（原地修改），返回同一引用。\r\n */\r\n\r\nimport type {\r\n  IElement,\r\n  IImageElement,\r\n  IImageGeometry,\r\n  IDocxDocumentMeta,\r\n  IEditorOption,\r\n  IListNumbering,\r\n  IParagraphStyle,\r\n  IBookmark,\r\n  ITitleElement,\r\n  IListElement,\r\n  ITableElement,\r\n  ITd,\r\n  ITr,\r\n  Path,\r\n  PathSegment\r\n} from './types'\r\nimport { DEFAULT_EDITOR_OPTION } from './constants'\r\nimport { isParagraphContainer, isTable, walkTree } from './walk'\r\n\r\n/** 按节引用选择页眉页脚；未定义的引用按 OOXML 继承前节同类引用。 */\r\nexport function resolveHeaderFooterPart(doc: IDocxDocumentMeta, zone: 'header' | 'footer', sectionIndex: number, pageIndex: number, firstPage: boolean): string | undefined {\r\n  const section = doc.sections?.[sectionIndex]\r\n  const kind = firstPage && section?.titlePage ? 'first' : doc.evenAndOddHeaders && (pageIndex + 1) % 2 === 0 ? 'even' : 'default'\r\n  for (let index = sectionIndex; index >= 0; index--) {\r\n    const refs = zone === 'header' ? doc.sections?.[index]?.headers : doc.sections?.[index]?.footers\r\n    if (refs?.[kind] !== undefined) return refs[kind]\r\n  }\r\n  return undefined\r\n}\r\n\r\n/** 格式化树上下文：携带编辑器选项、样式表、编号定义等归一化所需依赖 */\r\nexport interface FormatTreeContext {\r\n  /** 编辑器选项 */\r\n  editorOptions: IEditorOption\r\n  /** 段落样式表 */\r\n  styles?: Record<string, IParagraphStyle>\r\n  /** 列表编号定义表 */\r\n  numbering?: Record<string, IListNumbering>\r\n  /** 供 LaTeX / 公式等扩展使用的转换钩子 */\r\n  laTexToSVG?: (latex: string) => string\r\n  /** 书签标记收集器（遍历时填充，调用方配对 start/end 构建 bookmarks） */\r\n  bookmarkMarkers?: { name: string; position: string; path: Path }[]\r\n  /** 内部路径栈（递归时 push/pop，不暴露给外部） */\r\n  _pathStack?: PathSegment[]\r\n}\r\n\r\n/**\r\n * 归一化编辑器选项，填充默认值。\r\n */\r\nexport function mergeOption(options?: IEditorOption): IEditorOption {\r\n  return { ...DEFAULT_EDITOR_OPTION, ...(options || {}) }\r\n}\r\n\r\n/**\r\n * 递归归一化元素树。\r\n * - 保证段落容器有 valueList\r\n * - 保证 table 有 colgroup / trList / tdList\r\n * - 保证 td 有 padding / borderStyle / verticalAlign\r\n * - 保证 image 有 width/height\r\n * - 补齐 text 的默认字体/字号\r\n */\r\nexport function formatElementTree(\r\n  elements: IElement[],\r\n  ctx: FormatTreeContext\r\n): IElement[] {\r\n  if (!Array.isArray(elements)) return elements\r\n  // 空文档兜底：若 elements 为空数组，插入一个携带默认字体/字号的空 text run，\r\n  // 以保证 layout 能产出一个段落 block（空段兜底会为其生成零宽 caret 承载 inline），\r\n  // 光标可以定位、用户可以直接输入。新字符会拼入该 run 并继承其属性（默认无 bold/highlight）。\r\n  if (elements.length === 0) {\r\n    elements.push({\r\n      type: 'text',\r\n      value: '',\r\n      font: ctx.editorOptions.defaultFont,\r\n      size: ctx.editorOptions.defaultSize\r\n    } as unknown as IElement)\r\n  }\r\n  const stack = ctx._pathStack ??= []\r\n  for (let i = 0; i < elements.length; i++) {\r\n    stack.push(i)\r\n    const ext = (elements[i] as unknown as { extension?: { bookmarkMarker?: { name: string; position: string } } }).extension\r\n    if (ext?.bookmarkMarker && ctx.bookmarkMarkers) {\r\n      ctx.bookmarkMarkers.push({\r\n        name: ext.bookmarkMarker.name,\r\n        position: ext.bookmarkMarker.position,\r\n        path: [...stack]\r\n      })\r\n    }\r\n    normalizeNode(elements[i], ctx)\r\n    stack.pop()\r\n  }\r\n  return elements\r\n}\r\n\r\n/**\r\n * 调整浮动图片坐标：为非 inline/block 的浮动图片叠加页边距和行内 ascent 偏移。\r\n * 仅在导入时调用一次，不随 formatElementTree 自动触发（避免 undo/redo 二次偏移）。\r\n * @param elements 顶层元素数组（原地修改）\r\n * @param editorOptions 编辑器选项（提供 margins/paperDirection/defaultSize）\r\n */\r\nexport function adjustFloatImagePositions(\r\n  elements: IElement[],\r\n  editorOptions: IEditorOption\r\n): void {\r\n  // 坐标由 Java imageLayout 提供；保留旧 API，但禁止二次估算偏移。\r\n  void elements\r\n  void editorOptions\r\n}\r\n\r\n/**\r\n * 单节点归一化分发：按节点类型调用对应的归一化函数。\r\n * @param node 当前节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeNode(node: IElement, ctx: FormatTreeContext): void {\r\n  if (!node || typeof node !== 'object') return\r\n\r\n  switch (node.type) {\r\n    case 'text':\r\n      normalizeText(node as IElement, ctx)\r\n      break\r\n    case 'title':\r\n      normalizeTitle(node as ITitleElement, ctx)\r\n      break\r\n    case 'list':\r\n      normalizeList(node as IListElement, ctx)\r\n      break\r\n    case 'table':\r\n      normalizeTable(node as ITableElement, ctx)\r\n      break\r\n    case 'image':\r\n      normalizeImage(node as IElement, ctx)\r\n      break\r\n    case 'pageBreak':\r\n      normalizePageBreak(node as IElement, ctx)\r\n      break\r\n    default:\r\n      // 兜底：拥有 valueList/tdList/value 数组的容器一律递归\r\n      const anyNode = node as unknown as Record<string, unknown>\r\n      if (Array.isArray(anyNode.valueList)) {\r\n        ctx._pathStack?.push('valueList')\r\n        formatElementTree(anyNode.valueList as IElement[], ctx)\r\n        ctx._pathStack?.pop()\r\n      }\r\n      break\r\n  }\r\n}\r\n\r\n/**\r\n * 归一化 text 节点：补全 value、font、size 默认值并应用段落样式。\r\n * @param node text 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeText(node: IElement, ctx: FormatTreeContext): void {\r\n  const anyNode = node as unknown as Record<string, unknown>\r\n  if (typeof anyNode.value !== 'string') anyNode.value = String(anyNode.value ?? '')\r\n  if (anyNode.font == null) anyNode.font = ctx.editorOptions.defaultFont\r\n  if (anyNode.size == null) anyNode.size = ctx.editorOptions.defaultSize\r\n  applyParagraphStyleId(node, ctx)\r\n}\r\n\r\n/**\r\n * 归一化 title 节点：补全 valueList、level 默认值，递归归一化子节点并下沉段落属性。\r\n * @param node title 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTitle(node: ITitleElement, ctx: FormatTreeContext): void {\r\n  if (!Array.isArray(node.valueList)) node.valueList = []\r\n  if (!node.level) node.level = 'first'\r\n  applyParagraphStyleId(node, ctx)\r\n  ctx._pathStack?.push('valueList')\r\n  formatElementTree(node.valueList, ctx)\r\n  ctx._pathStack?.pop()\r\n  // 段落级属性下沉到 valueList 内每个 run 上（若 run 未指定则继承）\r\n  inheritParagraphAttrsToChildren(node)\r\n}\r\n\r\n/**\r\n * 归一化 list 节点：补全 valueList、listType、listStyle、listLevel 等默认值，\r\n * 关联 numbering 定义，递归归一化子节点并下沉段落属性。\r\n * @param node list 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeList(node: IListElement, ctx: FormatTreeContext): void {\r\n  if (!Array.isArray(node.valueList)) node.valueList = []\r\n  if (!node.listType) node.listType = 'ul'\r\n  if (!node.listStyle) node.listStyle = node.listType === 'ol' ? 'decimal' : 'disc'\r\n  if (typeof node.listLevel !== 'number') node.listLevel = 0\r\n  // 若有 numbering 定义引用，补齐\r\n  if (!node.listNumbering && ctx.numbering) {\r\n    const numId = (node as unknown as { numId?: string }).numId\r\n    if (numId && ctx.numbering[numId]) node.listNumbering = ctx.numbering[numId]\r\n  }\r\n  applyParagraphStyleId(node, ctx)\r\n  ctx._pathStack?.push('valueList')\r\n  formatElementTree(node.valueList, ctx)\r\n  ctx._pathStack?.pop()\r\n  inheritParagraphAttrsToChildren(node)\r\n}\r\n\r\n/**\r\n * 归一化 table 节点：补全 colgroup、trList，递归归一化各行；\r\n * 若 colgroup 为空则用第一行宽度推导。\r\n * @param node table 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTable(node: ITableElement, ctx: FormatTreeContext): void {\r\n  if (!Array.isArray(node.colgroup)) node.colgroup = []\r\n  if (!Array.isArray(node.trList)) node.trList = []\r\n\r\n  for (let ri = 0; ri < node.trList.length; ri++) {\r\n    ctx._pathStack?.push('trList', ri)\r\n    normalizeTr(node.trList[ri], ctx)\r\n    ctx._pathStack?.splice(-2, 2)\r\n  }\r\n\r\n  // 若 colgroup 为空则用第一行宽度推导\r\n  if (node.colgroup.length === 0 && node.trList[0]) {\r\n    node.colgroup = node.trList[0].tdList.map(td => ({ width: td.width || 100 }))\r\n  }\r\n}\r\n\r\n/**\r\n * 归一化表格行：补全 height、tdList 默认值，递归归一化各单元格。\r\n * @param tr 表格行\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTr(tr: ITr, ctx: FormatTreeContext): void {\r\n  if (typeof tr.height !== 'number' || tr.height <= 0) tr.height = 32\r\n  if (!Array.isArray(tr.tdList)) tr.tdList = []\r\n  for (let ci = 0; ci < tr.tdList.length; ci++) {\r\n    ctx._pathStack?.push('tdList', ci)\r\n    normalizeTd(tr.tdList[ci], ctx)\r\n    ctx._pathStack?.splice(-2, 2)\r\n  }\r\n}\r\n\r\n/**\r\n * 归一化单元格：补全 width、colspan、rowspan、verticalAlign、padding、borderStyle 默认值，\r\n * 递归归一化单元格内容。\r\n * @param td 表格单元格\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTd(td: ITd, ctx: FormatTreeContext): void {\r\n  if (typeof td.width !== 'number' || td.width <= 0) td.width = 100\r\n  if (typeof td.colspan !== 'number' || td.colspan <= 0) td.colspan = 1\r\n  if (typeof td.rowspan !== 'number' || td.rowspan <= 0) td.rowspan = 1\r\n  if (!td.verticalAlign) td.verticalAlign = 'middle'\r\n  if (!Array.isArray(td.padding) || td.padding.length !== 4) {\r\n    td.padding = [2, 2, 2, 2]\r\n  }\r\n  if (!Array.isArray(td.value)) td.value = []\r\n  ctx._pathStack?.push('value')\r\n  formatElementTree(td.value, ctx)\r\n  ctx._pathStack?.pop()\r\n}\r\n\r\n/**\r\n * 归一化 image 节点：补全 width、height、rotate 默认值并应用段落样式。\r\n * @param node image 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeImage(node: IElement, ctx: FormatTreeContext): void {\r\n  applyImageLayout(node as IImageElement)\r\n  applyParagraphStyleId(node, ctx)\r\n}\r\n\r\n/** OOXML 的长度单位为 EMU，旋转单位为 1/60000 度。 */\r\nexport function applyImageLayout(image: IImageElement): void {\r\n  const layout = image.imageLayout\r\n  if (!layout) return\r\n  const ext = layout.transform?.children.find(child => child.name === 'ext')\r\n  if (ext?.attributes.cx !== undefined) image.width = Number(ext.attributes.cx) / 9525\r\n  if (ext?.attributes.cy !== undefined) image.height = Number(ext.attributes.cy) / 9525\r\n  image.rotate = Number(layout.transform?.attributes.rot ?? 0) / 60000\r\n  if (layout.anchored === false) image.imgDisplay = 'inline'\r\n  else if (layout.anchored === true) {\r\n    const wrap = layout.positioning?.find(node => node.name.startsWith('wrap'))\r\n    image.imgDisplay = wrap?.name === 'wrapNone'\r\n      ? (layout.anchorAttributes?.behindDoc === '1' || layout.anchorAttributes?.behindDoc === 'true' ? 'float-bottom' : 'float-top')\r\n      : 'surround'\r\n  }\r\n}\r\n\r\n/** 用户调整图片时同时更新 Java 写回使用的几何结构。 */\r\nexport function updateImageLayout(image: IImageElement, changes: {\r\n  width?: number; height?: number; rotate?: number; wrap?: IImageElement['imgDisplay']\r\n}): void {\r\n  const layout = image.imageLayout\r\n  if (!layout) return\r\n  const geometry = (name: string, namespace: string): IImageGeometry => ({ name, namespace, attributes: {}, children: [] })\r\n  const drawing = 'http://schemas.openxmlformats.org/drawingml/2006/main'\r\n  if (changes.width !== undefined || changes.height !== undefined || changes.rotate !== undefined) {\r\n    const transform = layout.transform ??= geometry('xfrm', drawing)\r\n    if (changes.rotate !== undefined) transform.attributes.rot = String(Math.round(changes.rotate * 60000))\r\n    if (changes.width !== undefined || changes.height !== undefined) {\r\n      let ext = transform.children.find(child => child.name === 'ext')\r\n      if (!ext) { ext = geometry('ext', drawing); transform.children.push(ext) }\r\n      if (changes.width !== undefined) ext.attributes.cx = String(Math.round(changes.width * 9525))\r\n      if (changes.height !== undefined) ext.attributes.cy = String(Math.round(changes.height * 9525))\r\n    }\r\n  }\r\n  if (changes.wrap !== undefined) {\r\n    layout.anchored = changes.wrap !== 'inline' && changes.wrap !== 'block'\r\n    layout.anchorAttributes ??= {}\r\n    layout.anchorAttributes.behindDoc = changes.wrap === 'float-bottom' ? '1' : '0'\r\n    layout.positioning = (layout.positioning ?? []).filter(node => !node.name.startsWith('wrap'))\r\n    if (layout.anchored) {\r\n      const wrap = geometry(changes.wrap === 'surround' ? 'wrapSquare' : 'wrapNone', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing')\r\n      if (changes.wrap === 'surround') wrap.attributes.wrapText = 'bothSides'\r\n      layout.positioning.push(wrap)\r\n    }\r\n  }\r\n  applyImageLayout(image)\r\n}\r\n\r\n/**\r\n * 归一化 pageBreak 节点：补全 value 默认值为 'manual' 并应用段落样式。\r\n * @param node pageBreak 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizePageBreak(node: IElement, ctx: FormatTreeContext): void {\r\n  const anyNode = node as unknown as Record<string, unknown>\r\n  if (anyNode.value == null) throw new TypeError('pageBreak.value 缺失，必须由解析来源提供')\r\n  applyParagraphStyleId(node, ctx)\r\n}\r\n\r\n/**\r\n * 应用段落样式表：当节点引用了 paragraphStyleId 时，将样式字段填入节点未显式设置的字段。\r\n * @param node 当前节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction applyParagraphStyleId(node: IElement, ctx: FormatTreeContext): void {\r\n  if (!ctx.styles) return\r\n  const styleId = (node as unknown as { paragraphStyleId?: string }).paragraphStyleId\r\n  if (!styleId) return\r\n  const style = ctx.styles[styleId]\r\n  if (!style) return\r\n  const anyNode = node as unknown as Record<string, unknown>\r\n  const indentationBaseline = anyNode.paragraphIndentationBaseline as Record<string, number | null> | undefined\r\n  // 只在字段未显式设置时应用\r\n  for (const key of Object.keys(style)) {\r\n    if (key === 'id' || key === 'name' || key === 'basedOn') continue\r\n    const axis = key === 'paragraphIndentLeft' ? 'left'\r\n      : key === 'paragraphIndentRight' ? 'right'\r\n      : key === 'paragraphFirstLineIndent' ? 'firstLine' : undefined\r\n    // 后端基线已解析过样式继承；null 也是结果，不能再从原始样式回填。\r\n    if (axis && indentationBaseline && Object.prototype.hasOwnProperty.call(indentationBaseline, axis)) continue\r\n    if (anyNode[key] == null) anyNode[key] = (style as unknown as Record<string, unknown>)[key]\r\n  }\r\n}\r\n\r\n/**\r\n * 将容器上定义的段落级属性下沉到子 runs（子未显式指定时）。\r\n * 只处理段落级字段，不动 font/size/bold 等 run 级属性。\r\n */\r\nfunction inheritParagraphAttrsToChildren(container: ITitleElement | IListElement): void {\r\n  const PARA_KEYS = [\r\n    'rowFlex',\r\n    'paragraphStyleId',\r\n    'paragraphFirstLineIndent',\r\n    'paragraphIndentLeft',\r\n    'paragraphSpacingBefore',\r\n    'paragraphSpacingAfter',\r\n    'lineHeight',\r\n    'lineHeightRule'\r\n  ] as const\r\n  const containerAny = container as unknown as Record<string, unknown>\r\n  for (const child of container.valueList) {\r\n    const childAny = child as unknown as Record<string, unknown>\r\n    for (const key of PARA_KEYS) {\r\n      if (containerAny[key] != null && childAny[key] == null) {\r\n        childAny[key] = containerAny[key]\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 将收集到的 bookmarkMarker 列表配对为 IBookmark[]。\r\n * 同名 start/end 配对，范围落在实际内容上，不把零宽标记作为选区文字。\r\n */\r\nexport function pairBookmarkMarkers(\r\n  markers: { name: string; position: string; path: Path }[],\r\n  elements: IElement[]\r\n): IBookmark[] {\r\n  const leaves: { node: IElement; path: Path }[] = []\r\n  const indices = new Map<string, number>()\r\n  walkTree(elements, (node, { path }) => {\r\n    if (isParagraphContainer(node) || isTable(node)) return\r\n    indices.set(JSON.stringify(path), leaves.length)\r\n    leaves.push({ node, path })\r\n  })\r\n  const isContent = (node: IElement): boolean =>\r\n    !node.extension?.bookmarkMarker && !node.extension?.fieldMarker &&\r\n    (node.type !== 'text' || (!!node.value && !/^[\\u200B\\uFEFF]+$/.test(node.value)))\r\n  const startMap = new Map<string, Path>()\r\n  const bookmarks: IBookmark[] = []\r\n  for (const m of markers) {\r\n    if (m.position === 'start') {\r\n      startMap.set(m.name, m.path)\r\n    } else if (m.position === 'end') {\r\n      const startPath = startMap.get(m.name)\r\n      if (startPath) {\r\n        const start = indices.get(JSON.stringify(startPath))\r\n        const end = indices.get(JSON.stringify(m.path))\r\n        let first: typeof leaves[number] | undefined\r\n        let last: typeof leaves[number] | undefined\r\n        if (start !== undefined && end !== undefined) {\r\n          for (let index = start + 1; index < end; index++) {\r\n            if (!isContent(leaves[index].node)) continue\r\n            first ??= leaves[index]\r\n            last = leaves[index]\r\n          }\r\n        }\r\n        const anchor = { path: first?.path ?? startPath, offset: 0 }\r\n        bookmarks.push({\r\n          name: m.name,\r\n          range: {\r\n            anchor,\r\n            focus: last\r\n              ? { path: last.path, offset: last.node.type === 'text' ? last.node.value.length : 1 }\r\n              : { ...anchor }\r\n          },\r\n          collapsed: !first,\r\n          hidden: m.name.startsWith('_')\r\n        })\r\n        startMap.delete(m.name)\r\n      }\r\n    }\r\n  }\r\n  return bookmarks\r\n}\r\n","/**\r\n * VerveDocs Schema —— 段落解析（辅助 view 层）\r\n *\r\n * 段落切分：将同层的 elements 按\"段落分隔\"划分成段落数组。\r\n * 规则：\r\n *  - title/list/table/image/pageBreak 各自独立成段。\r\n *  - 连续 text 归到同一段，遇到\"段落终止符\"或块级节点即断段。\r\n *  - 段落容器（title/list）自身即为一段，其内 valueList 作为 runs。\r\n *\r\n * 段落终止符：docx-parser 在每个段落末尾插入一个仅由零宽字符\r\n * (`\\u200B` / `\\uFEFF`) 组成的 text run 作为段落结束标记。\r\n *  - 遇到该标记就切段（不并入下一段）。\r\n *  - 空段落载体（`{ type:'text', value:'', ...段落属性 }`）保留为一段的 run，\r\n *    以维持视觉空行与其行高等属性。\r\n *  - 若某段仅由终止符组成（无任何载体），才作为块间分隔符跳过。\r\n */\r\n\r\nimport type { IElement } from './types'\r\nimport { BLOCK_LEVEL_TYPES } from './constants'\r\n\r\nexport interface IParagraphGroup {\r\n  /** 段落类型：normal / title / list / table / image / pageBreak / separator / block */\r\n  kind: 'normal' | 'title' | 'list' | 'table' | 'image' | 'pageBreak' | 'separator' | 'block'\r\n  /** 段落对应的父节点（当 kind !== 'normal' 时即为该节点自身；kind='normal' 时为 null） */\r\n  block: IElement | null\r\n  /** 段落包含的顶层节点在父数组中的索引区间 [start, end)（含 start 不含 end） */\r\n  start: number\r\n  end: number\r\n  /** 段落使用的 runs（对 normal 是原数组切片，对 title/list 是 valueList 切片） */\r\n  runs: IElement[]\r\n  /** runs 在原数组中的起始索引（对 title/list valueList 切片，用于 path 计算；normal 默认 0） */\r\n  runStartIndex?: number\r\n}\r\n\r\n/** 判断某个 text run 是否为\"段落终止符\"（仅由零宽字符构成的 text） */\r\nfunction isParagraphTerminator(el: IElement): boolean {\r\n  if (el.type !== 'text' || el.extension?.bookmarkMarker) return false\r\n  const v = (el as unknown as { value?: string }).value ?? ''\r\n  if (!v) return false\r\n  return /^[\\u200B\\uFEFF]+$/.test(v)\r\n}\r\n\r\n/** Some imports omit the separator after a bookmark marker at the end of a paragraph. */\r\nfunction endsBookmarkParagraph(previous: IElement, next: IElement): boolean {\r\n  return !!previous.extension?.bookmarkMarker &&\r\n    !!previous.sourceParagraphId && !!next.sourceParagraphId &&\r\n    previous.sourceParagraphId !== next.sourceParagraphId\r\n}\r\n\r\n/**\r\n * 将同层 elements 切分为段落数组。\r\n * - 块级节点（title/list/table/image/pageBreak/separator）各自独立成段\r\n * - 普通连续 text 归到同一段，遇到段落终止符或块级节点即断段\r\n * - title/list 内部按零宽分隔符切段以支持段内换行\r\n * @param elements 顶层元素数组\r\n * @returns 段落分组数组\r\n */\r\nexport function splitParagraphs(elements: IElement[]): IParagraphGroup[] {\r\n  const out: IParagraphGroup[] = []\r\n  let i = 0\r\n  while (i < elements.length) {\r\n    const node = elements[i]\r\n    if (node.type === 'columnBreak') {\r\n      out.push({ kind: 'pageBreak', block: node, start: i, end: i + 1, runs: [] })\r\n      i++\r\n      continue\r\n    }\r\n    if (BLOCK_LEVEL_TYPES.has(node.type)) {\r\n      const kind = node.type as IParagraphGroup['kind']\r\n      const valueList = (node as unknown as { valueList?: IElement[] }).valueList ?? []\r\n      // title/list 内部也按零宽分隔符切段（与普通段落一致），支持段内换行\r\n      if (kind === 'title' || kind === 'list') {\r\n        const segs = splitValueList(valueList)\r\n        for (const { runs, startIndex } of segs) {\r\n          out.push({ kind, block: node, start: i, end: i + 1, runs, runStartIndex: startIndex })\r\n        }\r\n      } else {\r\n        out.push({ kind, block: node, start: i, end: i + 1, runs: valueList })\r\n      }\r\n      i++\r\n      continue\r\n    }\r\n    // 普通段落：收集非块级节点，遇到段落终止符即切段\r\n    const start = i\r\n    while (i < elements.length && !BLOCK_LEVEL_TYPES.has(elements[i].type) && elements[i].type !== 'columnBreak') {\r\n      if (i > start && endsBookmarkParagraph(elements[i - 1], elements[i])) break\r\n      if (isParagraphTerminator(elements[i])) {\r\n        i++ // 消费终止符\r\n        break\r\n      }\r\n      i++\r\n    }\r\n    // 段内 runs 保留原切片（含终止符），以保证 ri 与原 elements 索引对齐；\r\n    // 终止符在排版时跳过（不产出 inline），但占位以保持索引一致。\r\n    const runs = elements.slice(start, i)\r\n    // 若段落仅有终止符（无任何载体/内容），视为块间分隔符，跳过\r\n    if (runs.every(isParagraphTerminator)) continue\r\n    out.push({ kind: 'normal', block: null, start, end: i, runs })\r\n  }\r\n  return out\r\n}\r\n\r\n/** 将 valueList 按零宽分隔符切成多段（与顶层 elements 切段逻辑一致） */\r\nfunction splitValueList(valueList: IElement[]): { runs: IElement[]; startIndex: number }[] {\r\n  const result: { runs: IElement[]; startIndex: number }[] = []\r\n  let vi = 0\r\n  while (vi < valueList.length) {\r\n    const vStart = vi\r\n    while (vi < valueList.length) {\r\n      if (vi > vStart && endsBookmarkParagraph(valueList[vi - 1], valueList[vi])) break\r\n      if (isParagraphTerminator(valueList[vi])) {\r\n        vi++\r\n        break\r\n      }\r\n      vi++\r\n    }\r\n    const runs = valueList.slice(vStart, vi)\r\n    if (runs.every(isParagraphTerminator)) continue\r\n    result.push({ runs, startIndex: vStart })\r\n  }\r\n  if (result.length === 0) {\r\n    result.push({ runs: [], startIndex: 0 })\r\n  }\r\n  return result\r\n}\r\n","import type { IDocxDocumentMeta, IElement, IPosition } from './types'\r\nimport { splitParagraphs } from './paragraph'\r\nimport { cloneTree, comparePosition, getByPath, isParagraphContainer, isTable, walkTree } from './walk'\r\n\r\ninterface BookmarkBoundary {\r\n  offset: number\r\n  name: string\r\n  position: 'start' | 'end'\r\n}\r\n\r\n/** Convert editor-only state to the document protocol accepted by DOCX writers. */\r\nexport function toDocxExportDocument(document: IDocxDocumentMeta): IDocxDocumentMeta {\r\n  const result = cloneTree(document)\r\n  const { bookmarks, contentZones } = result\r\n  delete result.bookmarks\r\n  delete result.contentZones\r\n  delete result.meta\r\n  result.header ??= contentZones?.header\r\n  result.footer ??= contentZones?.footer\r\n\r\n  // 将渲染层的链接默认样式写入导出副本，目录链接仍沿用自己的样式。\r\n  const normalizeHyperlinks = (elements: IElement[]) => {\r\n    walkTree(elements, node => {\r\n      if (node.type !== 'hyperlink' ||\r\n        (node.extension?.toc as { role?: string } | undefined)?.role === 'entry') return\r\n      node.color = '#0000FF'\r\n      node.underline = true\r\n      const children = (node as IElement & { valueList?: IElement[] }).valueList\r\n      for (const run of children ?? []) {\r\n        if (run.type !== 'text') continue\r\n        run.color = '#0000FF'\r\n        run.underline = true\r\n      }\r\n    })\r\n  }\r\n  for (const elements of [result.elements, result.header, result.footer,\r\n    ...Object.values(result.headerFooterParts ?? {})]) {\r\n    if (elements) normalizeHyperlinks(elements)\r\n  }\r\n\r\n  const normalizeParagraphRuns = (elements: IElement[]) => {\r\n    for (const group of splitParagraphs(elements)) {\r\n      if (group.kind !== 'normal') continue\r\n      let first = true\r\n      for (const run of group.runs) {\r\n        if (run.extension?.bookmarkMarker || (run.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(run.value))) continue\r\n        if (first) {\r\n          first = false\r\n          continue\r\n        }\r\n        if (run.type !== 'text') continue\r\n        delete run.paragraphStyleId\r\n        delete run.rowFlex\r\n        delete run.paragraphFirstLineIndent\r\n        delete run.paragraphIndentLeft\r\n        delete run.paragraphIndentRight\r\n        delete run.paragraphSpacingBefore\r\n        delete run.paragraphSpacingAfter\r\n        delete run.lineHeight\r\n        delete run.lineHeightRule\r\n        delete run.paragraphColor\r\n      }\r\n    }\r\n  }\r\n  normalizeParagraphRuns(result.elements)\r\n  if (result.header) normalizeParagraphRuns(result.header)\r\n  if (result.footer) normalizeParagraphRuns(result.footer)\r\n  for (const elements of Object.values(result.headerFooterParts ?? {})) normalizeParagraphRuns(elements)\r\n\r\n  if (!bookmarks) return result\r\n\r\n  // Resolve all paths before splitting runs so overlapping ranges keep their positions.\r\n  const boundaries = new Map<IElement, BookmarkBoundary[]>()\r\n  const resolvePoint = (point: IPosition) => {\r\n    const node = getByPath(result.elements, point.path)\r\n    const length = node?.extension?.bookmarkMarker ? 0 : node?.type === 'text' ? node.value.length : 1\r\n    return node && Number.isInteger(point.offset) && point.offset >= 0 && point.offset <= length ? node : null\r\n  }\r\n  const addBoundary = (name: string, position: BookmarkBoundary['position'], point: IPosition) => {\r\n    const node = resolvePoint(point)\r\n    if (!node) {\r\n      throw new Error(`Invalid bookmark position: ${name}`)\r\n    }\r\n    const entries = boundaries.get(node) ?? []\r\n    entries.push({ name, position, offset: point.offset })\r\n    boundaries.set(node, entries)\r\n  }\r\n  for (const bookmark of bookmarks) {\r\n    let { anchor, focus } = bookmark.range\r\n    if (!resolvePoint(anchor) || !resolvePoint(focus)) {\r\n      const starts: IPosition[] = []\r\n      const ends: IPosition[] = []\r\n      walkTree(result.elements, (node, { path }) => {\r\n        const marker = node.extension?.bookmarkMarker as { name?: string; position?: string } | undefined\r\n        if (marker?.name !== bookmark.name) return\r\n        if (marker.position === 'start') starts.push({ path, offset: 0 })\r\n        if (marker.position === 'end') ends.push({ path, offset: 0 })\r\n      })\r\n      if (starts.length !== 1 || ends.length !== 1 || comparePosition(starts[0], ends[0]) >= 0) {\r\n        throw new Error(`Invalid bookmark position: ${bookmark.name}`)\r\n      }\r\n      // Recover both endpoints together; never mix a stale range with imported markers.\r\n      anchor = starts[0]\r\n      focus = ends[0]\r\n    }\r\n    const [start, end] = comparePosition(anchor, focus) <= 0 ? [anchor, focus] : [focus, anchor]\r\n    addBoundary(bookmark.name, 'start', start)\r\n    addBoundary(bookmark.name, 'end', end)\r\n  }\r\n\r\n  const marker = (boundary: BookmarkBoundary): IElement => ({\r\n    type: 'text',\r\n    value: '',\r\n    extension: { bookmarkMarker: { name: boundary.name, position: boundary.position } }\r\n  })\r\n  const convert = (elements: IElement[]): IElement[] => elements.flatMap(node => {\r\n    if (isParagraphContainer(node)) {\r\n      node.valueList = convert(node.valueList)\r\n    } else if (isTable(node)) {\r\n      for (const row of node.trList) {\r\n        for (const cell of row.tdList) cell.value = convert(cell.value)\r\n      }\r\n    }\r\n    const entries = boundaries.get(node)?.sort((a, b) => a.offset - b.offset) ?? []\r\n    // Runtime ranges are authoritative; replace imported markers instead of duplicating them.\r\n    if (node.extension?.bookmarkMarker) return entries.map(marker)\r\n    if (!entries.length) return [node]\r\n    if (node.type !== 'text') {\r\n      return [\r\n        ...entries.filter(entry => entry.offset === 0).map(marker),\r\n        node,\r\n        ...entries.filter(entry => entry.offset !== 0).map(marker)\r\n      ]\r\n    }\r\n    const parts: IElement[] = []\r\n    let offset = 0\r\n    for (const entry of entries) {\r\n      if (entry.offset > offset) parts.push({ ...node, value: node.value.slice(offset, entry.offset) })\r\n      parts.push(marker(entry))\r\n      offset = entry.offset\r\n    }\r\n    if (offset < node.value.length || !node.value.length) {\r\n      parts.push({ ...node, value: node.value.slice(offset) })\r\n    }\r\n    return parts\r\n  })\r\n  result.elements = convert(result.elements)\r\n  return result\r\n}\r\n","/**\r\n * VerveDocs Schema —— 快捷键类型与工具\r\n *\r\n * 定义键盘按键映射常量、快捷键注册接口及平台判断工具函数。\r\n */\r\n\r\n/** 键盘按键映射常量（使用 KeyboardEvent.key 值） */\r\nexport const KeyMap = {\r\n  A: 'a',\r\n  B: 'b',\r\n  C: 'c',\r\n  D: 'd',\r\n  E: 'e',\r\n  F: 'f',\r\n  G: 'g',\r\n  H: 'h',\r\n  I: 'i',\r\n  J: 'j',\r\n  K: 'k',\r\n  L: 'l',\r\n  M: 'm',\r\n  N: 'n',\r\n  O: 'o',\r\n  P: 'p',\r\n  Q: 'q',\r\n  R: 'r',\r\n  S: 's',\r\n  T: 't',\r\n  U: 'u',\r\n  V: 'v',\r\n  W: 'w',\r\n  X: 'x',\r\n  Y: 'y',\r\n  Z: 'z',\r\n  ZERO: '0',\r\n  ONE: '1',\r\n  TWO: '2',\r\n  THREE: '3',\r\n  FOUR: '4',\r\n  FIVE: '5',\r\n  SIX: '6',\r\n  SEVEN: '7',\r\n  EIGHT: '8',\r\n  NINE: '9',\r\n  MINUS: '-',\r\n  EQUAL: '=',\r\n  LEFT_BRACKET: '[',\r\n  RIGHT_BRACKET: ']',\r\n  BACKSLASH: '\\\\',\r\n  SEMICOLON: ';',\r\n  QUOTE: \"'\",\r\n  COMMA: ',',\r\n  PERIOD: '.',\r\n  SLASH: '/',\r\n  LEFT_ANGLE_BRACKET: '<',\r\n  RIGHT_ANGLE_BRACKET: '>',\r\n  ENTER: 'Enter',\r\n  SPACE: ' ',\r\n  TAB: 'Tab',\r\n  BACKSPACE: 'Backspace',\r\n  DELETE: 'Delete',\r\n  ESCAPE: 'Escape',\r\n  ARROW_LEFT: 'ArrowLeft',\r\n  ARROW_RIGHT: 'ArrowRight',\r\n  ARROW_UP: 'ArrowUp',\r\n  ARROW_DOWN: 'ArrowDown'\r\n} as const\r\n\r\n/** 快捷键注册配置接口 */\r\nexport interface IRegisterShortcut {\r\n  /** 按键值（对应 KeyboardEvent.key） */\r\n  key: string\r\n  /** Ctrl/Cmd 组合键（跨平台修饰键） */\r\n  mod?: boolean\r\n  /** Ctrl 键 */\r\n  ctrl?: boolean\r\n  /** Meta（Cmd）键 */\r\n  meta?: boolean\r\n  /** Shift 键 */\r\n  shift?: boolean\r\n  /** Alt 键 */\r\n  alt?: boolean\r\n  /** 是否为全局快捷键（在 document 上监听） */\r\n  isGlobal?: boolean\r\n  /** 是否禁用 */\r\n  disable?: boolean\r\n  /** 命中时执行的回调 */\r\n  callback?: (command: any) => void\r\n}\r\n\r\n/** 判断当前运行环境是否为 Apple 平台（macOS / iOS） */\r\nexport const isApple =\r\n  typeof navigator !== 'undefined' &&\r\n  /Mac|iPod|iPhone|iPad/.test(navigator.platform || navigator.userAgent || '')\r\n\r\n/**\r\n * 判断键盘事件是否按下了跨平台修饰键（macOS 为 Cmd，其他为 Ctrl）\r\n * @param evt 键盘事件\r\n * @returns 是否按下了修饰键\r\n */\r\nexport function isMod(evt: KeyboardEvent): boolean {\r\n  return isApple ? evt.metaKey : evt.ctrlKey\r\n}","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n  , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n  Events.prototype = Object.create(null);\n\n  //\n  // This hack is needed because the `__proto__` property is still inherited in\n  // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n  //\n  if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n  this.fn = fn;\n  this.context = context;\n  this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('The listener must be a function');\n  }\n\n  var listener = new EE(fn, context || emitter, once)\n    , evt = prefix ? prefix + event : event;\n\n  if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n  else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n  else emitter._events[evt] = [emitter._events[evt], listener];\n\n  return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n  if (--emitter._eventsCount === 0) emitter._events = new Events();\n  else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n  this._events = new Events();\n  this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n  var names = []\n    , events\n    , name;\n\n  if (this._eventsCount === 0) return names;\n\n  for (name in (events = this._events)) {\n    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n  }\n\n  if (Object.getOwnPropertySymbols) {\n    return names.concat(Object.getOwnPropertySymbols(events));\n  }\n\n  return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n  var evt = prefix ? prefix + event : event\n    , handlers = this._events[evt];\n\n  if (!handlers) return [];\n  if (handlers.fn) return [handlers.fn];\n\n  for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n    ee[i] = handlers[i].fn;\n  }\n\n  return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n  var evt = prefix ? prefix + event : event\n    , listeners = this._events[evt];\n\n  if (!listeners) return 0;\n  if (listeners.fn) return 1;\n  return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return false;\n\n  var listeners = this._events[evt]\n    , len = arguments.length\n    , args\n    , i;\n\n  if (listeners.fn) {\n    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n    switch (len) {\n      case 1: return listeners.fn.call(listeners.context), true;\n      case 2: return listeners.fn.call(listeners.context, a1), true;\n      case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n    }\n\n    for (i = 1, args = new Array(len -1); i < len; i++) {\n      args[i - 1] = arguments[i];\n    }\n\n    listeners.fn.apply(listeners.context, args);\n  } else {\n    var length = listeners.length\n      , j;\n\n    for (i = 0; i < length; i++) {\n      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n      switch (len) {\n        case 1: listeners[i].fn.call(listeners[i].context); break;\n        case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n        case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n        default:\n          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n            args[j - 1] = arguments[j];\n          }\n\n          listeners[i].fn.apply(listeners[i].context, args);\n      }\n    }\n  }\n\n  return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n  return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n  return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return this;\n  if (!fn) {\n    clearEvent(this, evt);\n    return this;\n  }\n\n  var listeners = this._events[evt];\n\n  if (listeners.fn) {\n    if (\n      listeners.fn === fn &&\n      (!once || listeners.once) &&\n      (!context || listeners.context === context)\n    ) {\n      clearEvent(this, evt);\n    }\n  } else {\n    for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n      if (\n        listeners[i].fn !== fn ||\n        (once && !listeners[i].once) ||\n        (context && listeners[i].context !== context)\n      ) {\n        events.push(listeners[i]);\n      }\n    }\n\n    //\n    // Reset the array, or remove it completely if we have no more listeners.\n    //\n    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n    else clearEvent(this, evt);\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n  var evt;\n\n  if (event) {\n    evt = prefix ? prefix + event : event;\n    if (this._events[evt]) clearEvent(this, evt);\n  } else {\n    this._events = new Events();\n    this._eventsCount = 0;\n  }\n\n  return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n  module.exports = EventEmitter;\n}\n","/**\r\n * VerveDocs State —— EventBus\r\n *\r\n * 轻量事件总线，支持带类型的事件订阅。\r\n * 基于 eventemitter3 实现，保持 on/off/emit/clear API 不变。\r\n */\r\n\r\nimport { EventEmitter } from 'eventemitter3'\r\nimport type { EventHandler, EventBusMap } from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 state 包 API 兼容\r\nexport type { EventHandler, EventBusMap } from '@vervedoc/docx-editor-schema'\r\n\r\n/**\r\n * 轻量事件总线\r\n *\r\n * 支持带类型的事件订阅与派发，泛型 M 描述事件名到 payload 类型的映射。\r\n * 默认泛型为 EventBusMap（用户交互事件），与 Listener（状态变更事件）职责区分。\r\n * 基于 eventemitter3 实现，保持 on/off/emit/clear API 不变。\r\n */\r\nexport class EventBus<M = EventBusMap> {\r\n  /** 底层事件分发器实例 */\r\n  private emitter = new EventEmitter()\r\n\r\n  /**\r\n   * 订阅指定事件\r\n   * @param event 事件名\r\n   * @param handler 事件处理器\r\n   * @returns 取消订阅函数，调用后移除该处理器\r\n   */\r\n  on<K extends keyof M>(event: K, handler: EventHandler<M[K]>): () => void {\r\n    const fn = handler as (...args: any[]) => void\r\n    const e = event as string\r\n    this.emitter.on(e, fn)\r\n    return () => this.emitter.off(e, fn)\r\n  }\r\n\r\n  /**\r\n   * 取消订阅指定事件\r\n   * @param event 事件名\r\n   * @param handler 需要移除的事件处理器\r\n   */\r\n  off<K extends keyof M>(event: K, handler: EventHandler<M[K]>): void {\r\n    this.emitter.off(event as string, handler as (...args: any[]) => void)\r\n  }\r\n\r\n  /**\r\n   * 派发指定事件\r\n   * @param event 事件名\r\n   * @param payload 事件载荷（void 类型事件可省略）\r\n   */\r\n  emit<K extends keyof M>(event: K, ...args: M[K] extends void ? [] : [payload: M[K]]): void {\r\n    this.emitter.emit(event as string, ...(args as any[]))\r\n  }\r\n\r\n  /**\r\n   * 移除所有事件的所有监听器\r\n   */\r\n  clear(): void {\r\n    this.emitter.removeAllListeners()\r\n  }\r\n}\r\n","/**\r\n * VerveDocs State —— Listener\r\n *\r\n * 编辑器生命周期/交互事件的回调注册中心。\r\n * 基于 eventemitter3 实现，保持 on/off/emit API 不变。\r\n *\r\n * 事件名统一使用 camelCase（如 'rangeChange'、'contentChange'）。\r\n * core 层在状态变更时主动 emit 事件，调用方通过 listener.on() 订阅。\r\n * 命名空间方法不带 on 前缀、不带 Change 后缀，以 Listener 结尾。\r\n */\r\n\r\nimport { EventEmitter } from 'eventemitter3'\r\nimport type {\r\n  IPosition,\r\n  IRange,\r\n  IRangeStyle,\r\n  IEditorAbility,\r\n  ListenerMap\r\n} from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 state 包 API 兼容\r\nexport type { IRangeStyle, IEditorAbility, ListenerMap } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 选区事件命名空间 */\r\nexport interface IRangeListener {\r\n  /** 选区变更（光标移动/选区改变） */\r\n  rangeListener(handler: (range: IRange | null) => void): () => void\r\n  /** 格式变更（bold/italic 等回显状态） */\r\n  formatListener(handler: (style: IRangeStyle) => void): () => void\r\n  /** 光标位置变更 */\r\n  positionListener(handler: (pos: IPosition | null) => void): () => void\r\n}\r\n\r\n/** 内容事件命名空间 */\r\nexport interface IContentListener {\r\n  /** 内容变更（文本增删/格式修改等） */\r\n  contentListener(handler: () => void): () => void\r\n  /** 文档保存完成 */\r\n  savedListener(handler: () => void): () => void\r\n}\r\n\r\n/** 能力事件命名空间 */\r\nexport interface IAbilityListener {\r\n  /** 编辑器能力变更（readonly/disabled/canUndo/canRedo） */\r\n  abilityListener(handler: (ability: IEditorAbility) => void): () => void\r\n}\r\n\r\n/** 页面事件命名空间 */\r\nexport interface IPageListener {\r\n  /** 缩放比例变更 */\r\n  pageScaleListener(handler: (scale: number) => void): () => void\r\n  /** 页面尺寸变更（宽高） */\r\n  pageSizeListener(handler: (size: { width: number; height: number }) => void): () => void\r\n  /** 总页数变更 */\r\n  pageCountListener(handler: (count: number) => void): () => void\r\n  /** 当前页码变更 */\r\n  currentPageNoListener(handler: (pageNo: number) => void): () => void\r\n}\r\n\r\n/** 目录事件命名空间 */\r\nexport interface ITocListener {\r\n  /** 目录变更 */\r\n  tocListener(handler: (toc: { id: string; level: number; name: string; number?: string }[]) => void): () => void\r\n}\r\n\r\n/** 区域事件命名空间 */\r\nexport interface IZoneListener {\r\n  /** 编辑区域切换（正文/页眉/页脚） */\r\n  zoneListener(handler: (zone: 'main' | 'header' | 'footer') => void): () => void\r\n}\r\n\r\n/** 生命周期事件命名空间 */\r\nexport interface ILifecycleListener {\r\n  /** 编辑器获得焦点 */\r\n  focusListener(handler: () => void): () => void\r\n  /** 编辑器失去焦点 */\r\n  blurListener(handler: () => void): () => void\r\n  /** 渲染完成后触发（各组件订阅此事件执行渲染联动） */\r\n  afterRenderListener(handler: () => void): () => void\r\n}\r\n\r\n/** 请求事件命名空间（右键菜单等触发的插入请求） */\r\nexport interface IRequestListener {\r\n  /** 请求插入图片 */\r\n  requestInsertImageListener(handler: () => void): () => void\r\n  /** 请求插入超链接 */\r\n  requestInsertHyperlinkListener(handler: () => void): () => void\r\n  /** 请求插入公式 */\r\n  requestInsertFormulaListener(handler: () => void): () => void\r\n\r\n}\r\n\r\n/** 缩略图事件命名空间 */\r\nexport interface IThumbnailListener {\r\n  /** 缩略图变更 */\r\n  thumbnailListener(handler: (images: string[]) => void): () => void\r\n}\r\n\r\n/**\r\n * 编辑器事件监听器\r\n *\r\n * 统一管理编辑器各类事件的订阅、取消订阅与触发。\r\n * 通过命名空间 getter（range/content/ability/page 等）提供分类订阅入口。\r\n */\r\nexport class Listener {\r\n  /** 底层事件分发器实例 */\r\n  private emitter = new EventEmitter()\r\n\r\n  /** 订阅事件，返回取消订阅函数 */\r\n  on<K extends keyof ListenerMap>(event: K, handler: ListenerMap[K]): () => void {\r\n    const fn = handler as (...args: any[]) => void\r\n    this.emitter.on(event, fn)\r\n    return () => this.emitter.off(event, fn)\r\n  }\r\n\r\n  /** 取消订阅事件 */\r\n  off<K extends keyof ListenerMap>(event: K, handler: ListenerMap[K]): void {\r\n    this.emitter.off(event, handler as (...args: any[]) => void)\r\n  }\r\n\r\n  hasListeners(event: keyof ListenerMap): boolean {\r\n    return this.emitter.listenerCount(event) > 0\r\n  }\r\n\r\n  /** 触发事件（core 内部调用） */\r\n  emit<K extends keyof ListenerMap>(event: K, ...args: Parameters<ListenerMap[K]>): void {\r\n    this.emitter.emit(event, ...args)\r\n  }\r\n\r\n  /** 选区事件 */\r\n  get range(): IRangeListener {\r\n    return {\r\n      rangeListener: (handler) => this.on('rangeChange', handler),\r\n      formatListener: (handler) => this.on('formatChange', handler),\r\n      positionListener: (handler) => this.on('positionChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 内容事件 */\r\n  get content(): IContentListener {\r\n    return {\r\n      contentListener: (handler) => this.on('contentChange', handler),\r\n      savedListener: (handler) => this.on('saved', handler)\r\n    }\r\n  }\r\n\r\n  /** 能力事件 */\r\n  get ability(): IAbilityListener {\r\n    return {\r\n      abilityListener: (handler) => this.on('abilityChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 页面事件 */\r\n  get page(): IPageListener {\r\n    return {\r\n      pageScaleListener: (handler) => this.on('pageScaleChange', handler),\r\n      pageSizeListener: (handler) => this.on('pageSizeChange', handler),\r\n      pageCountListener: (handler) => this.on('pageCountChange', handler),\r\n      currentPageNoListener: (handler) => this.on('currentPageNoChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 目录事件 */\r\n  get toc(): ITocListener {\r\n    return {\r\n      tocListener: (handler) => this.on('tocChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 缩略图事件 */\r\n  get thumbnail(): IThumbnailListener {\r\n    return {\r\n      thumbnailListener: (handler) => this.on('thumbnailChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 区域事件 */\r\n  get zone(): IZoneListener {\r\n    return {\r\n      zoneListener: (handler) => this.on('zoneChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 生命周期事件 */\r\n  get lifecycle(): ILifecycleListener {\r\n    return {\r\n      focusListener: (handler) => this.on('focus', handler),\r\n      blurListener: (handler) => this.on('blur', handler),\r\n      afterRenderListener: (handler) => this.on('afterRender', handler)\r\n    }\r\n  }\r\n\r\n  /** 请求事件 */\r\n  get request(): IRequestListener {\r\n    return {\r\n      requestInsertImageListener: (handler) => this.on('requestInsertImage', handler),\r\n      requestInsertHyperlinkListener: (handler) => this.on('requestInsertHyperlink', handler),\r\n      requestInsertFormulaListener: (handler) => this.on('requestInsertFormula', handler)\r\n    }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs State —— RangeManager\r\n *\r\n * 基于树路径的选区/光标模型。\r\n * anchor / focus 均为 IPosition = { path, offset }。\r\n */\r\n\r\nimport type { IPosition, IRange, Path } from '@vervedoc/docx-editor-schema'\r\nimport { comparePosition, isSamePath } from '@vervedoc/docx-editor-schema'\r\nimport type { Listener } from './listener'\r\n\r\n/**\r\n * 选区/光标管理器\r\n *\r\n * 维护编辑器当前选区（anchor/focus 双点模型），\r\n * 并在选区变更时通过 Listener 派发 rangeChange 与 positionChange 事件。\r\n */\r\nexport class RangeManager {\r\n  /** 当前选区，未选中时为 null */\r\n  private _range: IRange | null = null\r\n\r\n  /**\r\n   * 构造选区管理器\r\n   * @param listener 可选的事件监听器，用于在选区变更时派发事件\r\n   */\r\n  constructor(private listener?: Listener) {}\r\n\r\n  /**\r\n   * 获取当前选区\r\n   * @returns 当前选区对象，未选中时返回 null\r\n   */\r\n  getRange(): IRange | null { return this._range }\r\n\r\n  /**\r\n   * 获取选区起点（anchor）\r\n   * @returns anchor 位置，未选中时返回 null\r\n   */\r\n  getAnchor(): IPosition | null { return this._range?.anchor ?? null }\r\n\r\n  /**\r\n   * 获取选区终点（focus，即光标位置）\r\n   * @returns focus 位置，未选中时返回 null\r\n   */\r\n  getFocus(): IPosition | null { return this._range?.focus ?? null }\r\n\r\n  /** 获取按文档顺序排序后的 [start, end] */\r\n  getOrdered(): { start: IPosition; end: IPosition } | null {\r\n    if (!this._range) return null\r\n    const { anchor, focus } = this._range\r\n    return comparePosition(anchor, focus) <= 0\r\n      ? { start: anchor, end: focus }\r\n      : { start: focus, end: anchor }\r\n  }\r\n\r\n  /**\r\n   * 判断选区是否折叠（anchor 与 focus 重合）\r\n   * @returns 折叠（光标状态）返回 true，无选区或存在范围选区时返回 true/false\r\n   */\r\n  isCollapsed(): boolean {\r\n    if (!this._range) return true\r\n    const { anchor, focus } = this._range\r\n    return isSamePath(anchor.path, focus.path) && anchor.offset === focus.offset\r\n  }\r\n\r\n  /**\r\n   * 设置光标位置（折叠选区，anchor = focus）\r\n   * @param pos 光标位置，传 null 清除选区\r\n   */\r\n  setCaret(pos: IPosition | null): void {\r\n    this._range = pos ? { anchor: { ...pos }, focus: { ...pos } } : null\r\n    this.emitChange()\r\n  }\r\n\r\n  /**\r\n   * 设置选区范围\r\n   * @param range 选区对象，传 null 清除选区\r\n   */\r\n  setRange(range: IRange | null): void {\r\n    this._range = range ? { anchor: { ...range.anchor }, focus: { ...range.focus } } : null\r\n    this.emitChange()\r\n  }\r\n\r\n  /**\r\n   * 将选区折叠到起点\r\n   */\r\n  collapseToStart(): void {\r\n    const ordered = this.getOrdered()\r\n    if (!ordered) return\r\n    this.setCaret(ordered.start)\r\n  }\r\n\r\n  /**\r\n   * 将选区折叠到终点\r\n   */\r\n  collapseToEnd(): void {\r\n    const ordered = this.getOrdered()\r\n    if (!ordered) return\r\n    this.setCaret(ordered.end)\r\n  }\r\n\r\n  /**\r\n   * 清除当前选区\r\n   */\r\n  clear(): void {\r\n    this._range = null\r\n    this.emitChange()\r\n  }\r\n\r\n  /**\r\n   * 派发选区变更事件\r\n   * 同时触发 rangeChange 与 positionChange 事件\r\n   */\r\n  private emitChange(): void {\r\n    this.listener?.emit('rangeChange', this._range)\r\n    this.listener?.emit('positionChange', this._range?.focus ?? null)\r\n  }\r\n\r\n  /** 用同一 path 移动 offset */\r\n  moveOffset(delta: number): void {\r\n    if (!this._range) return\r\n    const focus = this._range.focus\r\n    const newOffset = Math.max(0, focus.offset + delta)\r\n    this.setCaret({ path: focus.path.slice() as Path, offset: newOffset })\r\n  }\r\n}\r\n","/**\r\n * VerveDocs View —— TextMeasure\r\n *\r\n * 字形宽度 LRU 缓存 + 段落级 memoization。\r\n * 采用一个隐藏 canvas 的 ctx 做 measureText，主线程即可用。\r\n */\r\n\r\n/**\r\n * LRU 双向链表节点。\r\n */\r\ninterface LruNode<K, V> {\r\n  /** 节点键 */\r\n  key: K\r\n  /** 节点值 */\r\n  value: V\r\n  /** 前驱节点 */\r\n  prev: LruNode<K, V> | null\r\n  /** 后继节点 */\r\n  next: LruNode<K, V> | null\r\n}\r\n\r\n/**\r\n * LRU 缓存：基于双向链表 + Map 实现，最近访问的节点置于链表头部。\r\n */\r\nclass LRU<K, V> {\r\n  /** 节点查找表 */\r\n  private map = new Map<K, LruNode<K, V>>()\r\n  /** 链表头（最近访问） */\r\n  private head: LruNode<K, V> | null = null\r\n  /** 链表尾（最久未访问，淘汰端） */\r\n  private tail: LruNode<K, V> | null = null\r\n  /**\r\n   * 创建容量为 limit 的 LRU 缓存。\r\n   * @param limit 缓存容量上限\r\n   */\r\n  constructor(private limit: number) {}\r\n\r\n  /**\r\n   * 读取键对应的值，并将其置为最近访问。\r\n   * @param key 键\r\n   * @returns 命中返回值，未命中返回 undefined\r\n   */\r\n  get(key: K): V | undefined {\r\n    const node = this.map.get(key)\r\n    if (!node) return undefined\r\n    this.touch(node)\r\n    return node.value\r\n  }\r\n\r\n  /**\r\n   * 写入键值对，已存在则更新值并置为最近访问；超出容量时淘汰尾部。\r\n   * @param key 键\r\n   * @param value 值\r\n   */\r\n  set(key: K, value: V): void {\r\n    let node = this.map.get(key)\r\n    if (node) { node.value = value; this.touch(node); return }\r\n    node = { key, value, prev: null, next: this.head }\r\n    if (this.head) this.head.prev = node\r\n    this.head = node\r\n    if (!this.tail) this.tail = node\r\n    this.map.set(key, node)\r\n    if (this.map.size > this.limit) this.evict()\r\n  }\r\n\r\n  /**\r\n   * 将节点移动到链表头部，标记为最近访问。\r\n   * @param node 待移动节点\r\n   */\r\n  private touch(node: LruNode<K, V>): void {\r\n    if (node === this.head) return\r\n    if (node.prev) node.prev.next = node.next\r\n    if (node.next) node.next.prev = node.prev\r\n    if (node === this.tail) this.tail = node.prev\r\n    node.prev = null\r\n    node.next = this.head\r\n    if (this.head) this.head.prev = node\r\n    this.head = node\r\n  }\r\n\r\n  /**\r\n   * 淘汰链表尾部节点（最久未访问）。\r\n   */\r\n  private evict(): void {\r\n    if (!this.tail) return\r\n    this.map.delete(this.tail.key)\r\n    this.tail = this.tail.prev\r\n    if (this.tail) this.tail.next = null\r\n    else this.head = null\r\n  }\r\n}\r\n\r\n/**\r\n * 字形度量器：基于隐藏 canvas 的 measureText 计算字符宽度，带 LRU 缓存。\r\n */\r\nexport class TextMeasure {\r\n  /** canvas 2d 上下文，用于 measureText */\r\n  private ctx: CanvasRenderingContext2D\r\n  /** 字形宽度 LRU 缓存 */\r\n  private glyphCache = new LRU<string, number>(10000)\r\n\r\n  /**\r\n   * 创建度量器，初始化隐藏 canvas 及其 2d 上下文。\r\n   */\r\n  constructor() {\r\n    const c = typeof document !== 'undefined'\r\n      ? document.createElement('canvas')\r\n      : ({ getContext: () => null } as unknown as HTMLCanvasElement)\r\n    const ctx = c.getContext('2d')\r\n    if (!ctx) throw new Error('[TextMeasure] canvas 2d context unavailable')\r\n    this.ctx = ctx\r\n  }\r\n\r\n  /** 生成 canvas font 字符串 */\r\n  static font(family: string, size: number, bold?: boolean, italic?: boolean): string {\r\n    const w = bold ? '700' : '400'\r\n    const s = italic ? 'italic ' : ''\r\n    return `${s}${w} ${size}px ${family}`\r\n  }\r\n\r\n  /** 单字符宽度 */\r\n  charWidth(ch: string, family: string, size: number, bold?: boolean, italic?: boolean): number {\r\n    const key = `${ch}|${family}|${size}|${bold ? 1 : 0}|${italic ? 1 : 0}`\r\n    const hit = this.glyphCache.get(key)\r\n    if (hit != null) return hit\r\n    this.ctx.font = TextMeasure.font(family, size, bold, italic)\r\n    const w = this.ctx.measureText(ch).width\r\n    this.glyphCache.set(key, w)\r\n    return w\r\n  }\r\n\r\n  /** 整串宽度 */\r\n  textWidth(text: string, family: string, size: number, bold?: boolean, italic?: boolean): number {\r\n    let w = 0\r\n    for (const ch of text) w += this.charWidth(ch, family, size, bold, italic)\r\n    return w\r\n  }\r\n}\r\n\r\n/** 全局共享度量器（浏览器环境） */\r\nlet _sharedMeasure: TextMeasure | null = null\r\n/**\r\n * 获取全局共享的 TextMeasure 实例，首次调用时惰性创建。\r\n * @returns 共享度量器实例\r\n */\r\nexport function getSharedMeasure(): TextMeasure {\r\n  if (!_sharedMeasure) _sharedMeasure = new TextMeasure()\r\n  return _sharedMeasure\r\n}\r\n","/**\r\n * VerveDocs View —— List Bullet & Numbering\r\n *\r\n * 无序符号：直接使用 Wingdings/Symbol 私有区字符，通过字体栈渲染。\r\n *   Windows 自带 Wingdings 字体 → 原生正确显示。\r\n *   其它系统 → 通过字体栈回退到 Segoe UI Symbol / Symbola / Noto 等，\r\n *   或者进一步映射到普通 Unicode（U+27A2 ➢ 等）。\r\n *\r\n * 有序编号：按 numFmt 转换数字，替换 lvlText 里的 %1..%9 占位。\r\n */\r\n\r\nimport type { IListElement, IListNumbering } from '@vervedoc/docx-editor-schema'\r\n\r\n/* ==================== 数字格式转换 ==================== */\r\n\r\n/**\r\n * 将阿拉伯数字转换为罗马数字。\r\n * @param num - 待转换的正整数（仅支持 1..3999，超出范围直接返回原数字字符串）\r\n * @param upper - 是否输出大写罗马数字\r\n * @returns 罗马数字字符串\r\n */\r\nfunction toRoman(num: number, upper: boolean): string {\r\n  if (num <= 0 || num >= 4000) return String(num)\r\n  const map: [number, string][] = [\r\n    [1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'],\r\n    [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'],\r\n    [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']\r\n  ]\r\n  let n = num, out = ''\r\n  for (const [v, s] of map) { while (n >= v) { out += s; n -= v } }\r\n  return upper ? out : out.toLowerCase()\r\n}\r\n\r\n/**\r\n * 将正整数转换为字母序号（1→A, 26→Z, 27→AA）。\r\n * @param num - 待转换的正整数（<=0 时直接返回原数字字符串）\r\n * @param upper - 是否输出大写字母\r\n * @returns 字母序号字符串\r\n */\r\nfunction toLetter(num: number, upper: boolean): string {\r\n  if (num <= 0) return String(num)\r\n  let n = num, out = ''\r\n  while (n > 0) {\r\n    const rem = (n - 1) % 26\r\n    out = String.fromCharCode(65 + rem) + out\r\n    n = Math.floor((n - 1) / 26)\r\n  }\r\n  return upper ? out : out.toLowerCase()\r\n}\r\n\r\n/** 中文小写数字字符表（0..9 对应 零..九） */\r\nconst CN_DIGITS = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']\r\n/** 中文数位单位（个、十、百、千） */\r\nconst CN_UNITS = ['', '十', '百', '千']\r\n/** 中文大分段单位（个、万、亿、兆） */\r\nconst CN_BIG_UNITS = ['', '万', '亿', '兆']\r\n/** 中文大写数字字符表（0..9 对应 零..玖，财务用大写） */\r\nconst CN_UPPER   = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']\r\n\r\n/**\r\n * 将正整数转换为中文小写计数（如 12 → 十二，23 → 二十三）。\r\n * @param num - 待转换的正整数（<=0 时直接返回原数字字符串）\r\n * @returns 中文小写计数字符串\r\n */\r\nfunction toChineseCounting(num: number): string {\r\n  if (num <= 0) return String(num)\r\n  if (num < 10) return CN_DIGITS[num]\r\n  if (num < 20) return num === 10 ? '十' : '十' + CN_DIGITS[num - 10]\r\n  if (num < 100) {\r\n    const t = Math.floor(num / 10), o = num % 10\r\n    return CN_DIGITS[t] + '十' + (o ? CN_DIGITS[o] : '')\r\n  }\r\n  return toChineseCountingLarge(num)\r\n}\r\n\r\n/**\r\n * 将任意大正整数转换为中文计数（支持万、亿、兆等大单位）。\r\n * @param num - 待转换的非负整数\r\n * @returns 中文计数字符串\r\n */\r\nfunction toChineseCountingLarge(num: number): string {\r\n  if (num === 0) return '零'\r\n  let out = ''\r\n  const segs: number[] = []\r\n  let n = num\r\n  while (n > 0) { segs.push(n % 10000); n = Math.floor(n / 10000) }\r\n  for (let s = segs.length - 1; s >= 0; s--) {\r\n    const seg = segs[s]\r\n    if (seg === 0) { if (out && !out.endsWith('零')) out += '零'; continue }\r\n    let segStr = ''\r\n    for (let u = 3; u >= 0; u--) {\r\n      const digit = Math.floor(seg / Math.pow(10, u)) % 10\r\n      if (digit === 0) { if (segStr && !segStr.endsWith('零')) segStr += '零' }\r\n      else segStr += CN_DIGITS[digit] + CN_UNITS[u]\r\n    }\r\n    if (segStr.endsWith('零')) segStr = segStr.slice(0, -1)\r\n    out += segStr + CN_BIG_UNITS[s]\r\n  }\r\n  return out\r\n}\r\n\r\n/**\r\n * 将正整数转换为中文大写计数（财务用，如 12 → 壹拾贰）。\r\n * @param num - 待转换的正整数\r\n * @returns 中文大写计数字符串\r\n */\r\nfunction toChineseUpper(num: number): string {\r\n  return toChineseCounting(num).split('').map(ch => {\r\n    const i = CN_DIGITS.indexOf(ch)\r\n    return i >= 0 ? CN_UPPER[i] : ch\r\n  }).join('')\r\n}\r\n\r\n/**\r\n * 将正整数转换为逐位中文数字（如 123 → 一二三，不进位）。\r\n * @param num - 待转换的正整数\r\n * @returns 逐位中文数字字符串\r\n */\r\nfunction toIdeographDigital(num: number): string {\r\n  return String(num).split('').map(d => CN_DIGITS[Number(d)] ?? d).join('')\r\n}\r\n\r\n/**\r\n * 将正整数格式化为两位前导零十进制（如 1 → 01，10 → 10）。\r\n * @param num - 待格式化的正整数\r\n * @returns 两位十进制字符串\r\n */\r\nfunction toDecimalZero(num: number): string {\r\n  return num < 10 ? '0' + num : String(num)\r\n}\r\n\r\n/**\r\n * 按 OOXML numFmt 编号格式将计数值转换为展示字符串。\r\n * @param num - 当前层级的计数值\r\n * @param numFmt - 编号格式名称（decimal / lowerLetter / upperRoman / chineseCounting 等）\r\n * @returns 格式化后的编号字符串\r\n */\r\nexport function formatCounter(num: number, numFmt: string): string {\r\n  switch (numFmt) {\r\n    case 'decimal':                    return String(num)\r\n    case 'decimalZero':                return toDecimalZero(num)\r\n    case 'decimalEnclosedCircle':\r\n      if (num >= 1 && num <= 20) return String.fromCodePoint(0x2460 + num - 1)\r\n      if (num >= 21 && num <= 35) return String.fromCodePoint(0x3251 + num - 21)\r\n      if (num >= 36 && num <= 50) return String.fromCodePoint(0x32B1 + num - 36)\r\n      return String(num)\r\n    case 'lowerLetter':                return toLetter(num, false)\r\n    case 'upperLetter':                return toLetter(num, true)\r\n    case 'lowerRoman':                 return toRoman(num, false)\r\n    case 'upperRoman':                 return toRoman(num, true)\r\n    case 'chineseCounting':            return toChineseCounting(num)\r\n    case 'chineseCountingThousand':    return toChineseUpper(num)\r\n    case 'ideographDigital':           return toIdeographDigital(num)\r\n    case 'japaneseCounting':\r\n    case 'koreanCounting':\r\n    case 'taiwaneseCounting':          return toChineseCounting(num)\r\n    case 'bullet':                     return ''\r\n    default:                            return String(num)\r\n  }\r\n}\r\n\r\n/* ==================== Wingdings PUA → Unicode 回退表 ==================== */\r\n\r\n/**\r\n * 当系统没有 Wingdings 字体时，把 Wingdings 私有区字符换成能被通用符号字体\r\n * （Segoe UI Symbol / Apple Color Emoji / Symbola）覆盖的 Unicode 字符。\r\n */\r\nconst WINGDINGS_FALLBACK: Record<string, string> = {\r\n  '\\uF020': ' ',\r\n  '\\uF021': '✏',   // 铅笔\r\n  '\\uF022': '✂',   // 剪刀\r\n  '\\uF025': '📞',\r\n  '\\uF029': '📁',\r\n  '\\uF04A': '☺',\r\n  '\\uF04B': '😐',\r\n  '\\uF04C': '☹',\r\n  '\\uF06C': '●',\r\n  '\\uF06D': '❍',\r\n  '\\uF06E': '■',\r\n  '\\uF06F': '□',\r\n  '\\uF070': '◘',\r\n  '\\uF071': '❑',\r\n  '\\uF072': '❒',\r\n  '\\uF073': '⬧',\r\n  '\\uF074': '⬨',\r\n  '\\uF075': '◆',\r\n  '\\uF076': '❖',\r\n  '\\uF077': '⬥',\r\n  '\\uF078': '⧫',\r\n  '\\uF07C': '•',\r\n  '\\uF0A7': '▪',\r\n  '\\uF0A8': '◆',\r\n  '\\uF0A2': '○',\r\n  '\\uF0B7': '•',\r\n  '\\uF0D2': '❑',\r\n  '\\uF0D8': '➢',   // ★★ 常用的中空右箭头（Word \"TAB页\" 项目符号）\r\n  '\\uF0E0': '➔',\r\n  '\\uF0E8': '➢',\r\n  '\\uF0F0': '⇒',\r\n  '\\uF0FC': '✓',\r\n  '\\uF0FB': '✗',\r\n  '\\uF0FE': '❑'\r\n}\r\n\r\n/** 常用符号字体栈：Wingdings 优先，其次系统符号字体，最后 sans-serif */\r\nexport const BULLET_FONT_STACK =\r\n  'Wingdings, \"Segoe UI Symbol\", \"Apple Symbols\", \"Apple Color Emoji\", \"Noto Sans Symbols\", \"Noto Sans Symbols 2\", Symbola, \"DejaVu Sans\", \"Arial Unicode MS\", sans-serif'\r\n\r\n/** 无 Wingdings 字体时的字符栈（跳过 Wingdings） */\r\nexport const BULLET_FONT_STACK_FALLBACK =\r\n  '\"Segoe UI Symbol\", \"Apple Symbols\", \"Apple Color Emoji\", \"Noto Sans Symbols\", \"Noto Sans Symbols 2\", Symbola, \"DejaVu Sans\", \"Arial Unicode MS\", sans-serif'\r\n\r\n/**\r\n * 环境检测：当前浏览器是否安装了 Wingdings 字体。\r\n * 通过测量特定字符宽度对比 sans-serif 判断。缓存结果。\r\n */\r\n/** Wingdings 字体检测结果缓存（null 表示尚未检测） */\r\nlet _hasWingdings: boolean | null = null\r\nexport function detectWingdings(): boolean {\r\n  if (_hasWingdings != null) return _hasWingdings\r\n  if (typeof document === 'undefined') { _hasWingdings = false; return false }\r\n  try {\r\n    const c = document.createElement('canvas')\r\n    const ctx = c.getContext('2d')!\r\n    ctx.font = '20px sans-serif'\r\n    const w1 = ctx.measureText('\\uF0D8').width\r\n    ctx.font = '20px Wingdings, sans-serif'\r\n    const w2 = ctx.measureText('\\uF0D8').width\r\n    _hasWingdings = Math.abs(w1 - w2) > 0.5\r\n  } catch { _hasWingdings = false }\r\n  return _hasWingdings\r\n}\r\n\r\n/** 从 lvlText / listStyle 解析无序符号字符（原始 PUA 或回退 Unicode） */\r\nexport function resolveUnorderedChar(list: IListElement): string {\r\n  const num = list.listNumbering\r\n  const style = (list.listStyle || '').toString()\r\n  const bulletFont = (num as unknown as { font?: string } | undefined)?.font ?? ''\r\n  const isWingdings = /wingdings/i.test(bulletFont)\r\n\r\n  // 1. lvlText 首字符（Word 里就是原始 Wingdings PUA 字符）\r\n  if (num?.lvlText) {\r\n    const trimmed = num.lvlText.trim()\r\n    if (trimmed && !/%[1-9]/.test(trimmed)) {\r\n      const ch = trimmed.charAt(0)\r\n      // 若 numbering 声明了 Wingdings 字体但 lvlText 是 ASCII，则把它当 Wingdings 私有区处理\r\n      if (isWingdings && ch.charCodeAt(0) < 0x80) {\r\n        return String.fromCharCode(0xF000 + ch.charCodeAt(0))\r\n      }\r\n      return ch\r\n    }\r\n  }\r\n\r\n  // 2. numbering 字体为 Wingdings 但 lvlText 为空 → Word 默认使用箭头 U+F0D8（➢）\r\n  if (isWingdings) return '\\uF0D8'\r\n\r\n  // 3. listStyle 命名 → Wingdings PUA 或 Unicode 默认\r\n  const styleMap: Record<string, string> = {\r\n    disc:        '\\uF0B7',\r\n    circle:      '\\uF0A2',\r\n    square:      '\\uF0A7',\r\n    emptySquare: '\\uF0D2',\r\n    filledDiamond: '\\uF0A8',\r\n    diamond:     '\\uF076',\r\n    arrow:       '\\uF0D8',\r\n    arrowFilled: '\\uF0E0',\r\n    check:       '\\uF0FC',\r\n    cross:       '\\uF0FB',\r\n    bullet:      '\\uF0B7',\r\n    triangle:    '▶',\r\n    star:        '★',\r\n    heart:       '♥',\r\n    dash:        '–',\r\n    hyphen:      '-'\r\n  }\r\n  if (styleMap[style]) return styleMap[style]\r\n\r\n  // 4. 层级默认循环\r\n  const level = Math.max(0, list.listLevel ?? 0)\r\n  const fallback = ['\\uF0B7', '\\uF0A2', '\\uF0A7']\r\n  return fallback[level % fallback.length]\r\n}\r\n\r\n/** 若无 Wingdings，就把 PUA 转为通用 Unicode 字符 */\r\nexport function normalizeBulletChar(ch: string, hasWingdings: boolean): string {\r\n  if (hasWingdings) return ch\r\n  return WINGDINGS_FALLBACK[ch] ?? ch\r\n}\r\n\r\n/* ==================== 顶层入口 ==================== */\r\n\r\n/**\r\n * 项目符号解析结果。\r\n * 描述一个列表项最终要绘制的符号/编号文本及其渲染方式。\r\n */\r\nexport interface BulletResult {\r\n  /** 无序符号 or 有序编号，最终要绘制的字符串 */\r\n  text: string\r\n  /** 是否是无序符号（用符号字体栈） */\r\n  isSymbol: boolean\r\n  /** 编号在其\"编号列\"内的对齐方式（来自 numbering.lvlJc） */\r\n  lvlJc?: 'left' | 'center' | 'right'\r\n}\r\n\r\n/**\r\n * 解析列表项的项目符号或编号文本（顶层入口）。\r\n * 无序列表返回符号字符；有序列表根据计数器计算当前编号并替换 lvlText 占位符。\r\n * @param list - 列表元素数据\r\n * @param counters - 跨列表项的编号计数器（按 \"groupId:level\" 索引），可选\r\n * @returns 项目符号解析结果\r\n */\r\nexport function resolveBullet(\r\n  list: IListElement,\r\n  counters?: Map<string, number>\r\n): BulletResult {\r\n  const num: IListNumbering | undefined = list.listNumbering\r\n  const listType = list.listType\r\n  const level = Math.max(0, list.listLevel ?? 0)\r\n\r\n  const isUnordered =\r\n    listType === 'ul' ||\r\n    num?.numFmt === 'bullet' ||\r\n    (num == null && !isOrderedStyle(list.listStyle))\r\n\r\n  if (isUnordered) {\r\n    const raw = resolveUnorderedChar(list)\r\n    const hasWD = detectWingdings()\r\n    const ch = normalizeBulletChar(raw, hasWD)\r\n    return { text: ch, isSymbol: true, lvlJc: num?.lvlJc }\r\n  }\r\n\r\n  const fmt = num?.numFmt ?? list.listStyle ?? 'decimal'\r\n  const start = num?.start ?? 1\r\n  const tpl = num?.lvlText ?? '%1.'\r\n  // 计数隔离键：优先使用 listId（独立列表实例），回退 numId，再回退 listStyle\r\n  const groupId = list.listId ?? num?.numId ?? list.listStyle ?? 'default'\r\n  const numId = groupId\r\n  const key = `${numId}:${level}`\r\n\r\n  let current = start\r\n  if (counters) {\r\n    const prev = counters.get(key)\r\n    current = (prev == null ? start - 1 : prev) + 1\r\n    counters.set(key, current)\r\n    for (const k of counters.keys()) {\r\n      if (!k.startsWith(`${numId}:`)) continue\r\n      const l = Number(k.split(':')[1])\r\n      if (l > level) counters.delete(k)\r\n    }\r\n  }\r\n\r\n  const text = tpl.replace(/%([1-9])/g, (_, d: string) => {\r\n    const lvl = Number(d) - 1\r\n    if (lvl === level) return formatCounter(current, fmt)\r\n    const val = counters?.get(`${numId}:${lvl}`) ?? start\r\n    return formatCounter(val, fmt)\r\n  })\r\n\r\n  return { text, isSymbol: false, lvlJc: num?.lvlJc }\r\n}\r\n\r\n/**\r\n * 判断给定的 listStyle 是否属于有序编号样式。\r\n * @param s - listStyle 字符串\r\n * @returns 若为有序编号样式返回 true，否则 false\r\n */\r\nfunction isOrderedStyle(s?: string): boolean {\r\n  if (!s) return false\r\n  return [\r\n    'decimal', 'decimalZero',\r\n    'lowerLetter', 'upperLetter',\r\n    'lowerRoman', 'upperRoman',\r\n    'chineseCounting', 'chineseCountingThousand',\r\n    'ideographDigital', 'japaneseCounting', 'koreanCounting', 'taiwaneseCounting'\r\n  ].includes(s)\r\n}\r\n","/**\r\n * VerveDocs View —— LayoutEngine\r\n *\r\n * 坐标系约定：\r\n *  - block.rect.x/y = 相对父容器（页面内容原点 或 单元格内容原点）\r\n *  - line.x/y      = 相对块本地（0 起始）\r\n *  - inline.x/y/baseline = 相对块本地\r\n *  - TableRow/Cell rect = 相对 table 本地\r\n *\r\n * 绘制时递归传入偏移量（origin），把局部坐标累加为屏幕坐标。\r\n */\r\n\r\nimport type {\r\n  IElement,\r\n  IImageElement,\r\n  IDocxDocumentMeta,\r\n  IListElement,\r\n  ITableElement,\r\n  Path\r\n} from '@vervedoc/docx-editor-schema'\r\nimport { splitParagraphs, FONT_FAMILY_CSS, resolveHeaderFooterPart } from '@vervedoc/docx-editor-schema'\r\nimport type {\r\n  DocumentLayout, PageLayout, BlockNode, ParagraphBlock,\r\n  ImageBlock, PageBreakBlock, SeparatorBlock, TableBlock, TableRowLayout, TableCellLayout,\r\n  EmbedBlock, ChartBlock, LineBox, InlineBox, Rect\r\n} from './layout-types'\r\nimport { TextMeasure, getSharedMeasure } from './text-measure'\r\nimport { resolveBullet, BULLET_FONT_STACK, BULLET_FONT_STACK_FALLBACK, detectWingdings } from './list-bullet'\r\n\r\n/** 排版引擎配置选项 */\r\nexport interface LayoutOptions {\r\n  /** 页面宽度（CSS 像素） */\r\n  pageWidth: number\r\n  /** 页面高度（CSS 像素） */\r\n  pageHeight: number\r\n  /** 页边距 [top, right, bottom, left] */\r\n  pageMargins: [number, number, number, number]   // top, right, bottom, left\r\n  /** 默认字体族名 */\r\n  defaultFont: string\r\n  /** 默认字号 */\r\n  defaultSize: number\r\n  /** 默认行高倍数 */\r\n  defaultLineHeight: number\r\n  /** 渲染缩放倍数 */\r\n  scale: number\r\n  /** 页首/尾垂直空白（渲染视觉上把纸张与边界隔开） */\r\n  pageGap: number\r\n}\r\n\r\n/** 块 id 自增序列（跨 layout 调用持续递增，保证全局唯一） */\r\nlet _blockSeq = 0\r\n/** 取下一个全局唯一的 block id。 */\r\nfunction nextBlockId(): number { return ++_blockSeq }\r\n\r\ninterface ParagraphInput {\r\n  paragraphKind: ParagraphBlock['paragraphKind']\r\n  block: IElement | null\r\n  runs: IElement[]\r\n  runsParentPath: Path\r\n  startIndex: number\r\n  endIndex: number\r\n  parentPath: Path\r\n  availableWidth: number\r\n  runStartIndex?: number\r\n  exclusions?: { rect: Rect; side: string; topBottom: boolean }[]\r\n}\r\n\r\ninterface ParagraphCache {\r\n  signature: string\r\n  input: ParagraphInput\r\n  layout: ParagraphBlock\r\n}\r\n\r\n/**\r\n * 文档排版引擎：把 IElement[] 排版成分页 DocumentLayout，\r\n * 处理段落折行、列表编号、表格跨行/跨页、图片环绕等。\r\n */\r\nexport class LayoutEngine {\r\n  /** 文本度量器（计算字符/文本宽度） */\r\n  private measure: TextMeasure\r\n  /** 排版选项 */\r\n  private opts: LayoutOptions\r\n  /** 跨列表的多级编号计数器（每次 layout() 重置） */\r\n  private counters = new Map<string, number>()\r\n  private paragraphCache = new Map<string, ParagraphCache>()\r\n  private nextParagraphCache = new Map<string, ParagraphCache>()\r\n  private layoutZone = 'main'\r\n  private diagnostics: NonNullable<DocumentLayout['diagnostics']> = []\r\n  private paragraphInputs = new WeakMap<ParagraphBlock, ParagraphInput>()\r\n\r\n  /**\r\n   * 创建排版引擎。\r\n   * @param options 排版选项\r\n   * @param measure 文本度量器，缺省时使用共享实例\r\n   */\r\n  constructor(options: LayoutOptions, measure?: TextMeasure) {\r\n    this.opts = options\r\n    this.measure = measure ?? getSharedMeasure()\r\n  }\r\n\r\n  /**\r\n   * 更新排版选项（不立即触发重排，由调用方决定何时 layout()）。\r\n   * @param options 新的排版选项\r\n   */\r\n  updateOptions(options: LayoutOptions): void {\r\n    this.opts = options\r\n    this.paragraphCache.clear()\r\n  }\r\n\r\n  /**\r\n   * 顶层入口：把 elements 排版成分页 layout。\r\n   * headerElements / footerElements 为页眉/页脚内容，每页都会渲染一份。\r\n   */\r\n  layout(elements: IElement[], headerElements?: IElement[], footerElements?: IElement[], document?: IDocxDocumentMeta): DocumentLayout {\r\n    this.counters.clear()\r\n    this.diagnostics = []\r\n    this.nextParagraphCache = new Map()\r\n    this.layoutZone = 'main'\r\n    const { pageGap } = this.opts\r\n    let sectionIndex = 0\r\n    let sectionFirstPage = 0\r\n    let pageWidth = this.opts.pageWidth\r\n    let pageHeight = this.opts.pageHeight\r\n    let [mt, mr, mb, ml] = this.opts.pageMargins\r\n    let contentWidth = pageWidth - ml - mr\r\n    let contentHeight = pageHeight - mt - mb\r\n    const setSection = (index: number) => {\r\n      const section = document?.sections?.[index]\r\n      if (section) {\r\n        if (section.pageWidth === undefined || section.pageHeight === undefined || !section.margins) {\r\n          throw new TypeError(`Java sections[${index}] 缺少页面尺寸或页边距`)\r\n        }\r\n        pageWidth = section.pageWidth\r\n        pageHeight = section.pageHeight\r\n        ;[mt, mr, mb, ml] = section.margins\r\n      } else if (document && !document.sections) {\r\n        pageWidth = document.pageWidth ?? this.opts.pageWidth\r\n        pageHeight = document.pageHeight ?? this.opts.pageHeight\r\n        ;[mt, mr, mb, ml] = document.margins ?? this.opts.pageMargins\r\n      }\r\n      contentWidth = pageWidth - ml - mr\r\n      contentHeight = pageHeight - mt - mb\r\n    }\r\n    setSection(0)\r\n    const sectionBreaks = new Set(['continuous', 'nextPage', 'evenPage', 'oddPage'])\r\n    const sectionColumns = (index: number) => {\r\n      const section = document?.sections?.[index]\r\n      const count = section?.columnCount ?? document?.columnCount ?? 1\r\n      const gap = section?.columnGap ?? document?.columnGap ?? 20\r\n      const width = section?.pageWidth !== undefined && section.margins\r\n        ? section.pageWidth - section.margins[1] - section.margins[3] : contentWidth\r\n      return { widths: Array(count).fill((width - gap * (count - 1)) / count) as number[], gap }\r\n    }\r\n    const sectionWidths = (document?.sections ?? [undefined]).map((_, index) => sectionColumns(index).widths[0])\r\n    const columnGroups = new Map<string, { widths: number[]; gap: number }>()\r\n    let columnSection = 0\r\n    for (const element of elements) {\r\n      const data = element as IElement & { columnId?: string; columnCount?: number; columnWidths?: number[]; columnGap?: number }\r\n      if (data.columnId && data.columnCount) {\r\n        const gap = data.columnGap ?? 0\r\n        const width = sectionWidths?.[columnSection] ?? contentWidth\r\n        columnGroups.set(data.columnId, { gap, widths: data.columnWidths ?? Array(data.columnCount).fill((width - gap * (data.columnCount - 1)) / data.columnCount) })\r\n      }\r\n      if (element.type === 'pageBreak' && sectionBreaks.has(element.value)) columnSection++\r\n    }\r\n    const rawBlocks = this.layoutBlocks(elements, [], contentWidth, sectionWidths)\r\n    for (let index = 0; index < rawBlocks.length; index++) {\r\n      const block = rawBlocks[index]\r\n      if (block.kind !== 'paragraph') continue\r\n      const input = this.paragraphInputs.get(block)!\r\n      const columnId = input.runs.find(run => (run as Record<string, unknown>).columnId)?.columnId as string | undefined\r\n      const columns = columnId ? columnGroups.get(columnId) : undefined\r\n      if (columns) rawBlocks[index] = this.layoutParagraph({ ...input, availableWidth: columns.widths[0] })\r\n    }\r\n    const anchorParagraphs = new Map<string, ParagraphBlock>()\r\n    for (const block of rawBlocks) {\r\n      if (block.kind !== 'paragraph') continue\r\n      for (const run of this.paragraphInputs.get(block)?.runs ?? []) {\r\n        if (run.sourceParagraphId && !anchorParagraphs.has(run.sourceParagraphId)) anchorParagraphs.set(run.sourceParagraphId, block)\r\n      }\r\n    }\r\n    // Schedule floating drawings with their Java-identified paragraph, never an adjacent run.\r\n    const attachedImages = new Map<ParagraphBlock, ImageBlock[]>()\r\n    for (let index = rawBlocks.length - 1; index >= 0; index--) {\r\n      const block = rawBlocks[index]\r\n      if (block.kind !== 'image') continue\r\n      const id = (block.block as IImageElement).imageLayout?.anchorParagraphId\r\n      const anchor = id ? anchorParagraphs.get(id) : undefined\r\n      if (!anchor) continue\r\n      attachedImages.set(anchor, [block, ...(attachedImages.get(anchor) ?? [])])\r\n      rawBlocks.splice(index, 1)\r\n    }\r\n    for (let index = rawBlocks.length - 1; index >= 0; index--) {\r\n      const block = rawBlocks[index]\r\n      if (block.kind === 'paragraph') rawBlocks.splice(index + 1, 0, ...(attachedImages.get(block) ?? []))\r\n    }\r\n    const placedAnchors = new Map<string, { paragraph: ParagraphBlock; column: Rect }>()\r\n\r\n    // 页眉/页脚 block 预布局（rect.y 相对各自区域原点）\r\n    this.layoutZone = 'header'\r\n    const headerBlocks = headerElements?.length ? this.layoutBlocks(headerElements, [], contentWidth) : []\r\n    this.layoutZone = 'footer'\r\n    const footerBlocks = footerElements?.length ? this.layoutBlocks(footerElements, [], contentWidth) : []\r\n    this.paragraphCache = this.nextParagraphCache\r\n\r\n    // 页眉内容在上边距区域内靠下排列（底部贴近正文顶部），避免紧贴页面顶部\r\n    let headerOffsetY = 0\r\n    if (headerBlocks.length > 0) {\r\n      const last = headerBlocks[headerBlocks.length - 1]\r\n      const headerContentHeight = last.rect.y + last.rect.height\r\n      headerOffsetY = Math.max(0, mt - headerContentHeight)\r\n    }\r\n    // 页脚内容在下边距区域内靠上排列（顶部贴近正文底部），偏移为 0\r\n    const footerOffsetY = 0\r\n\r\n    // 分页\r\n    const pages: PageLayout[] = []\r\n    let pageIndex = 0\r\n    let cursorY = 0\r\n    let currentBlocks: BlockNode[] = []\r\n    let activeColumns: { widths: number[]; gap: number } | undefined\r\n    let activeColumnId: string | undefined = undefined\r\n    let columnIndex = 0\r\n    let columnTop = 0\r\n    let columnBottom = 0\r\n    const columnX = () => activeColumns ? activeColumns.widths.slice(0, columnIndex).reduce((sum, width) => sum + width + activeColumns!.gap, 0) : 0\r\n    const advanceColumn = () => {\r\n      columnBottom = Math.max(columnBottom, cursorY)\r\n      if (activeColumns && columnIndex + 1 < activeColumns.widths.length) { columnIndex++; cursorY = columnTop }\r\n      else { pushPage(); columnIndex = 0; columnTop = 0; columnBottom = 0 }\r\n    }\r\n\r\n    // 页面承载上限判定的浮点容差：\r\n    // 行高经多次浮点累加（cursorY += rowHeight）后，可能出现微小正偏离\r\n    // （如 903 累加为 903.0000000000001）。若用严格 \">\" 比较，会让\"恰好\r\n    // 填满页面\"的内容被误判为超出，从而提前触发分页。这里引入亚像素级\r\n    // 容差（0.5px，小于半像素，视觉上不可感知），仅当真实超出容差才分页。\r\n    const PAGE_FIT_EPSILON = 0.5\r\n\r\n    const pushPage = () => {\r\n      const previous = pages[pages.length - 1]\r\n      const pageOriginY = previous ? previous.rect.y + previous.rect.height + pageGap : pageGap\r\n      const section = document?.sections?.[sectionIndex]\r\n      const headerPartId = document?.sections ? resolveHeaderFooterPart(document, 'header', sectionIndex, pageIndex, pageIndex === sectionFirstPage) : undefined\r\n      const footerPartId = document?.sections ? resolveHeaderFooterPart(document, 'footer', sectionIndex, pageIndex, pageIndex === sectionFirstPage) : undefined\r\n      this.layoutZone = `header:${headerPartId ?? ''}`\r\n      const pageHeaders = document?.sections ? this.layoutBlocks(headerPartId ? document.headerFooterParts?.[headerPartId] ?? [] : [], [], contentWidth) : headerBlocks\r\n      this.layoutZone = `footer:${footerPartId ?? ''}`\r\n      const pageFooters = document?.sections ? this.layoutBlocks(footerPartId ? document.headerFooterParts?.[footerPartId] ?? [] : [], [], contentWidth) : footerBlocks\r\n      this.layoutZone = 'main'\r\n      const footerHeight = pageFooters.reduce((height, block) => Math.max(height, block.rect.y + block.rect.height), 0)\r\n      const pageRect: Rect = { x: 0, y: pageOriginY, width: pageWidth, height: pageHeight }\r\n      const contentRect: Rect = {\r\n        x: ml,\r\n        y: pageOriginY + mt,\r\n        width: contentWidth,\r\n        height: contentHeight\r\n      }\r\n      const headerRect: Rect = { x: ml, y: pageOriginY, width: contentWidth, height: mt }\r\n      const footerRect: Rect = { x: ml, y: pageOriginY + mt + contentHeight, width: contentWidth, height: mb }\r\n      pages.push({\r\n        index: pageIndex, sectionIndex, headerPartId, footerPartId, rect: pageRect, contentRect, blocks: currentBlocks,\r\n        headerRect,\r\n        headerBlocks: pageHeaders.length\r\n          ? pageHeaders.map(b => ({ ...b, rect: { ...b.rect, y: b.rect.y + (section?.headerDistance ?? headerOffsetY) } }))\r\n          : undefined,\r\n        footerRect,\r\n        footerBlocks: pageFooters.length\r\n          ? pageFooters.map(b => ({ ...b, rect: { ...b.rect, y: b.rect.y + (section?.footerDistance !== undefined ? mb - section.footerDistance - footerHeight : footerOffsetY) } }))\r\n          : undefined\r\n      })\r\n      pageIndex++\r\n      currentBlocks = []\r\n      cursorY = 0\r\n      columnIndex = 0\r\n      columnTop = 0\r\n      columnBottom = 0\r\n    }\r\n\r\n    for (let i = 0; i < rawBlocks.length; i++) {\r\n      let b = rawBlocks[i]\r\n      const source = b.kind === 'paragraph' ? this.paragraphInputs.get(b)?.runs.find(run => run.value !== '\\u200B') : b.block\r\n      const legacyColumnId = (source as { columnId?: string } | undefined)?.columnId\r\n      const sourceColumnId = legacyColumnId ?? `section:${sectionIndex}`\r\n      if (sourceColumnId !== activeColumnId) {\r\n        cursorY = Math.max(cursorY, columnBottom)\r\n        activeColumnId = sourceColumnId\r\n        activeColumns = legacyColumnId ? columnGroups.get(legacyColumnId) : sectionColumns(sectionIndex)\r\n        columnIndex = 0; columnTop = cursorY; columnBottom = cursorY\r\n      }\r\n      if (b.kind === 'paragraph' && activeColumns) {\r\n        const input = this.paragraphInputs.get(b)!\r\n        b = this.layoutParagraph({ ...input, availableWidth: activeColumns.widths[columnIndex] })\r\n      }\r\n      if (b.kind === 'paragraph' && b.paragraphKind !== 'list') {\r\n        const exclusions: NonNullable<ParagraphInput['exclusions']> = []\r\n        for (const placed of currentBlocks) {\r\n          if (placed.kind !== 'image') continue\r\n          const geometry = (placed.block as IImageElement).imageLayout\r\n          if (!geometry?.anchored) continue\r\n          const wrap = geometry.positioning?.find(node => node.name === 'wrapSquare' || node.name === 'wrapTopAndBottom')\r\n          if (!wrap) continue\r\n          const attrs = geometry.anchorAttributes\r\n          const distance = (name: string) => {\r\n            if (attrs?.[name] === undefined) throw new TypeError(`Java anchored image 缺少 ${name}`)\r\n            return Number(attrs[name]) / 9525\r\n          }\r\n          exclusions.push({ rect: { x: placed.rect.x - columnX() - distance('distL'), y: placed.rect.y - cursorY - distance('distT'),\r\n            width: placed.rect.width + distance('distL') + distance('distR'), height: placed.rect.height + distance('distT') + distance('distB') },\r\n            side: wrap.name === 'wrapTopAndBottom' ? '' : wrap.attributes.wrapText, topBottom: wrap.name === 'wrapTopAndBottom' })\r\n        }\r\n        const input = this.paragraphInputs.get(b)\r\n        if (input && exclusions.length) b = this.computeParagraph({ ...input, exclusions })\r\n      }\r\n      if (b.kind === 'pageBreak') {\r\n        if (b.block.type === 'columnBreak') { advanceColumn(); continue }\r\n        const breakType = String(b.block.value)\r\n        const nextSection = sectionBreaks.has(breakType) ? document?.sections?.[sectionIndex + 1] : undefined\r\n        const geometryChanged = nextSection && (nextSection.pageWidth !== pageWidth || nextSection.pageHeight !== pageHeight ||\r\n          nextSection.margins?.some((margin, index) => margin !== [mt, mr, mb, ml][index]))\r\n        if (breakType !== 'continuous' || geometryChanged) pushPage()\r\n        if (sectionBreaks.has(breakType) && document?.sections) {\r\n          sectionIndex++\r\n          if (!document.sections[sectionIndex]) throw new TypeError('Java sections 与正文分节符数量不一致')\r\n          setSection(sectionIndex)\r\n          sectionFirstPage = pageIndex\r\n        }\r\n        if (breakType === 'evenPage' && (pageIndex + 1) % 2 !== 0) pushPage()\r\n        if (breakType === 'oddPage' && (pageIndex + 1) % 2 !== 1) pushPage()\r\n        if (breakType === 'evenPage' || breakType === 'oddPage') sectionFirstPage = pageIndex\r\n        continue\r\n      }\r\n      // 多栏段落按行流入下一栏/页，而非把整个长段落移出页面。\r\n      if (b.kind === 'paragraph' && activeColumns && activeColumns.widths.length > 1 && !b.surroundImage && !attachedImages.has(rawBlocks[i] as ParagraphBlock)) {\r\n        let start = 0\r\n        while (start < b.lines.length) {\r\n          const origin = start === 0 ? 0 : b.lines[start].y\r\n          let end = start\r\n          while (end < b.lines.length && cursorY + b.lines[end].y + b.lines[end].height - origin <= contentHeight + PAGE_FIT_EPSILON) end++\r\n          if (end === start) {\r\n            if (cursorY > columnTop) { advanceColumn(); continue }\r\n            end++\r\n          }\r\n          const lines = b.lines.slice(start, end).map(line => ({ ...line, y: line.y - origin, baseline: line.baseline - origin }))\r\n          const height = end === b.lines.length ? b.rect.height - origin : lines.at(-1)!.y + lines.at(-1)!.height\r\n          currentBlocks.push({ ...b, id: nextBlockId(), bulletText: start === 0 ? b.bulletText : undefined,\r\n            rect: { ...b.rect, x: b.rect.x + columnX(), y: cursorY, height }, lines })\r\n          cursorY += height\r\n          start = end\r\n          if (start < b.lines.length) advanceColumn()\r\n        }\r\n        continue\r\n      }\r\n      let bh = b.rect.height\r\n      const overflow = cursorY + bh - contentHeight\r\n      // 仅当内容真实超出页面承载上限（超出浮点容差）才分页；\r\n      // 恰好填满（|cum - contentHeight| <= epsilon）时留在本页。\r\n      if (overflow > PAGE_FIT_EPSILON && !(b.kind === 'image' && (b.block as IImageElement).imageLayout?.anchored)) {\r\n        // 表格特判：先在当前页放能容纳的行，放不下的行推到下一页，\r\n        // 后续每页重新用整页高度计算能放几行。\r\n        // 跨行（rowspan）格被切割时自动裁剪（见 buildFragment），因此任意行边界都可切割。\r\n        if (b.kind === 'table') {\r\n          const remaining = contentHeight - cursorY\r\n          let frags = this.tryPaginateTableFlow(b, remaining, contentHeight)\r\n          if (!frags && currentBlocks.length > 0) {\r\n            // 当前页剩余空间连首行都放不下：整表推到新页，按整页高度拆分\r\n            pushPage()\r\n            cursorY = 0\r\n            frags = this.tryPaginateTableFlow(b, contentHeight, contentHeight)\r\n          }\r\n          if (frags) {\r\n            for (let fi = 0; fi < frags.length; fi++) {\r\n              const frag = frags[fi]\r\n              if (fi === 0) {\r\n                // 第 1 片：留在当前页（即使当前页尚为空页）\r\n                frag.rect.y = cursorY\r\n                currentBlocks.push(frag)\r\n                cursorY += frag.rect.height\r\n              } else {\r\n                // 第 2 片及以后：结束当前页，开启新页放置\r\n                pushPage()\r\n                frag.rect.y = 0\r\n                currentBlocks.push(frag)\r\n                cursorY = frag.rect.height\r\n              }\r\n            }\r\n            continue\r\n          }\r\n          // 表无法拆分（如单行高于整页）：回退为整表处理。\r\n        }\r\n        if (currentBlocks.length > 0) {\r\n          advanceColumn()\r\n          if (b.kind === 'paragraph' && activeColumns) b = this.layoutParagraph({ ...this.paragraphInputs.get(rawBlocks[i] as ParagraphBlock)!, availableWidth: activeColumns.widths[columnIndex] })\r\n          if (b.kind === 'paragraph' && !activeColumns && b !== rawBlocks[i]) {\r\n            b = rawBlocks[i]\r\n            bh = b.rect.height\r\n          }\r\n        }\r\n      }\r\n      b.rect.y = cursorY\r\n      if (activeColumns) b.rect.x += columnX()\r\n      bh = b.rect.height\r\n      if (b.kind === 'paragraph') {\r\n        for (const [id, anchor] of anchorParagraphs) {\r\n          if (anchor === rawBlocks[i]) placedAnchors.set(id, { paragraph: b, column: { x: columnX(), y: columnTop, width: activeColumns?.widths[columnIndex] ?? contentWidth, height: contentHeight - columnTop } })\r\n        }\r\n      }\r\n      const floating = b.kind === 'image' && (b.block as IImageElement).imageLayout?.anchored\r\n      const image = b.kind === 'image' ? b : b.kind === 'paragraph' ? b.surroundImage : undefined\r\n      if (image && (image.block as IImageElement).imageLayout?.anchored) {\r\n        const geometry = (image.block as IImageElement).imageLayout!\r\n        const horizontal = geometry.positioning?.find(node => node.name === 'positionH')\r\n        const vertical = geometry.positioning?.find(node => node.name === 'positionV')\r\n        const resolve = (node: typeof horizontal, axis: 'x' | 'y'): number => {\r\n          if (!node) throw new TypeError('Java anchored image 缺少定位节点')\r\n          const ref = node.attributes.relativeFrom\r\n          const isX = axis === 'x'\r\n          let origin: number, length: number\r\n          if (ref === 'page') { origin = isX ? -ml : -mt; length = isX ? pageWidth : pageHeight }\r\n          else if (ref === 'margin') { origin = 0; length = isX ? contentWidth : contentHeight }\r\n          else if ((isX && ref === 'column') || (!isX && ref === 'paragraph')) {\r\n            const anchor = geometry.anchorParagraphId ? placedAnchors.get(geometry.anchorParagraphId) : undefined\r\n            if (!anchor) throw new TypeError('Java anchored image 缺少已排版的 anchorParagraphId')\r\n            origin = isX ? anchor.column.x : anchor.paragraph.rect.y + (anchor.paragraph.lines[0]?.y ?? 0)\r\n            length = isX ? anchor.column.width : anchor.paragraph.lines.reduce((height, line) => Math.max(height, line.y + line.height - (anchor.paragraph.lines[0]?.y ?? 0)), 0)\r\n          }\r\n          else if (ref === 'paragraph' || ref === 'line' || ref === 'character' || ref === 'column') {\r\n            throw new TypeError(`尚未支持 OOXML 图片 ${ref} 参考系：需要真实锚点上下文与布局边界`)\r\n          }\r\n          else if (ref === 'leftMargin' || ref === 'topMargin') { origin = isX ? -ml : -mt; length = isX ? ml : mt }\r\n          else if (ref === 'rightMargin' || ref === 'bottomMargin') { origin = isX ? contentWidth : contentHeight; length = isX ? mr : mb }\r\n          else if (ref === 'insideMargin' || ref === 'outsideMargin') {\r\n            const leading = (ref === 'insideMargin') === ((pageIndex + 1) % 2 === 1)\r\n            origin = leading ? (isX ? -ml : -mt) : (isX ? contentWidth : contentHeight)\r\n            length = leading ? (isX ? ml : mt) : (isX ? mr : mb)\r\n          } else throw new TypeError(`不支持的 OOXML 图片定位参考系: ${ref}`)\r\n          const offset = node.children.find(child => child.name === 'posOffset')\r\n          if (offset) return origin + Number(offset.text) / 9525\r\n          const align = node.children.find(child => child.name === 'align')?.text\r\n          const size = isX ? image.rect.width : image.rect.height\r\n          if (align === 'center') return origin + (length - size) / 2\r\n          if (align === 'right' || align === 'bottom') return origin + length - size\r\n          if (align === 'inside' || align === 'outside') return origin + (((align === 'inside') === ((pageIndex + 1) % 2 === 1)) ? 0 : length - size)\r\n          if (align === 'left' || align === 'top') return origin\r\n          throw new TypeError('Java anchored image 缺少 align/posOffset')\r\n        }\r\n        image.rect.x = resolve(horizontal, 'x')\r\n        image.rect.y = resolve(vertical, 'y') - (b.kind === 'paragraph' ? b.rect.y : 0)\r\n        const wrap = geometry.positioning?.find(node => node.name.startsWith('wrap'))\r\n        if (wrap && wrap.name !== 'wrapNone' && b.kind === 'image') {\r\n          const distance = (name: string) => Number(geometry.anchorAttributes?.[name] ?? 0) / 9525\r\n          const top = image.rect.y - distance('distT'), bottom = image.rect.y + image.rect.height + distance('distB')\r\n          const left = image.rect.x - distance('distL'), right = image.rect.x + image.rect.width + distance('distR')\r\n          const intersects = currentBlocks.some(block => block.kind === 'paragraph' && block.lines.some(line =>\r\n            block.rect.y + line.y < bottom && block.rect.y + line.y + line.height > top &&\r\n            (wrap.name === 'wrapTopAndBottom' || (block.rect.x + line.x < right && block.rect.x + line.x + line.width > left))))\r\n          if (intersects) {\r\n            this.diagnostics.push({ code: 'unsupported-floating-image', severity: 'warning', feature: 'anchor-reflow',\r\n              message: '尚未支持浮动图片对已排版段落的回流；此浮动图片暂不显示，原始数据保留用于导出。',\r\n              zone: 'main', path: [...image.parentPath, image.indexInParent], action: 'image-omitted' })\r\n            continue\r\n          }\r\n        }\r\n      }\r\n      currentBlocks.push(b)\r\n      if (!floating) cursorY += bh\r\n    }\r\n    if (currentBlocks.length > 0) pushPage()\r\n    else if (pages.length === 0 || rawBlocks.at(-1)?.block?.type === 'pageBreak' && rawBlocks.at(-1)?.block?.value === 'manual') pushPage()\r\n\r\n    const lastPage = pages[pages.length - 1]\r\n    const totalHeight = lastPage.rect.y + lastPage.rect.height + pageGap\r\n    return { pages, totalHeight, pageWidth: Math.max(...pages.map(page => page.rect.width)), diagnostics: this.diagnostics }\r\n  }\r\n\r\n  /**\r\n   * 将 elements 数组转换为 BlockNode 列表（y 起始为 0，返回后由上层重新分配 y）。\r\n   */\r\n  private layoutBlocks(elements: IElement[], parentPath: Path, availableWidth: number, sectionWidths?: number[]): BlockNode[] {\r\n    let section = 0\r\n    const paragraphs = splitParagraphs(elements)\r\n\r\n    const blocks: BlockNode[] = []\r\n    for (let gi = 0; gi < paragraphs.length; gi++) {\r\n      const g = paragraphs[gi]\r\n      if (g.kind === 'table') {\r\n        blocks.push(this.layoutTable(g.block as ITableElement, parentPath, g.start, availableWidth))\r\n      } else if (g.kind === 'image') {\r\n        const imgEl = g.block as IElement\r\n        const geometry = (imgEl as IImageElement).imageLayout\r\n        if (geometry?.anchored) {\r\n          const issues: { feature: string; reason: string }[] = []\r\n          const issue = (feature: string, reason: string) => issues.push({ feature, reason })\r\n          if (this.layoutZone !== 'main' || parentPath.length) issue('anchor-context', '页眉页脚或表格内浮动图片定位与绕排')\r\n          for (const axis of ['positionH', 'positionV']) {\r\n            const node = geometry.positioning?.find(node => node.name === axis)\r\n            const reference = node?.attributes.relativeFrom\r\n            const hasAnchor = geometry.anchorParagraphId && paragraphs.some(paragraph => paragraph.runs.some(run => run.sourceParagraphId === geometry.anchorParagraphId))\r\n            const supported = axis === 'positionH'\r\n              ? ['page', 'margin', 'leftMargin', 'rightMargin', 'insideMargin', 'outsideMargin', ...(hasAnchor ? ['column'] : [])]\r\n              : ['page', 'margin', 'topMargin', 'bottomMargin', 'insideMargin', 'outsideMargin', ...(hasAnchor ? ['paragraph'] : [])]\r\n            if (!reference || !supported.includes(reference)) issue(`${axis}.${reference ?? 'missing'}`, `${axis} 的 ${reference ?? '缺失'} 参考系（需要真实锚点上下文）`)\r\n            const offset = node?.children.find(child => child.name === 'posOffset')\r\n            const align = node?.children.find(child => child.name === 'align')?.text\r\n            if (offset ? !Number.isFinite(Number(offset.text)) : !['center', 'right', 'bottom', 'inside', 'outside', 'left', 'top'].includes(align ?? '')) {\r\n              issue(`${axis}.position`, `${axis} 缺少有效 align/posOffset`)\r\n            }\r\n          }\r\n          const wrap = geometry.positioning?.find(node => node.name.startsWith('wrap'))\r\n          if (!wrap || !['wrapNone', 'wrapSquare', 'wrapTopAndBottom'].includes(wrap.name)) {\r\n            issue(wrap?.name ?? 'wrap.missing', `${wrap?.name ?? '缺失绕排节点'} 多边形轮廓绕排`)\r\n          }\r\n          if (wrap?.name === 'wrapSquare' && !['left', 'right', 'largest'].includes(wrap.attributes.wrapText)) {\r\n            issue(`wrapSquare.${wrap.attributes.wrapText}`, `${wrap.attributes.wrapText ?? '缺失 wrapText'} 同行排文`)\r\n          }\r\n          if (wrap?.name !== 'wrapNone') {\r\n            const bound = geometry.anchorParagraphId && paragraphs.some(paragraph => paragraph.runs.some(run => run.sourceParagraphId === geometry.anchorParagraphId))\r\n            if (!bound && blocks.some(block => block.kind === 'paragraph')) issue('anchor-reflow', '后置浮动锚点触发前文回流')\r\n            if (paragraphs.some(paragraph => paragraph.kind === 'list')) issue('list-wrap', '浮动图片与列表绕排')\r\n            for (const name of ['distT', 'distB', 'distL', 'distR']) {\r\n              if (geometry.anchorAttributes?.[name] === undefined || !Number.isFinite(Number(geometry.anchorAttributes[name]))) issue(name, `缺少有效 ${name} 绕排距离`)\r\n            }\r\n          }\r\n          if (issues.length) {\r\n            const path: Path = [...parentPath, g.start]\r\n            for (const { feature, reason } of issues) {\r\n              if (!this.diagnostics.some(item => item.zone === this.layoutZone && item.feature === feature && JSON.stringify(item.path) === JSON.stringify(path))) {\r\n                this.diagnostics.push({ code: 'unsupported-floating-image', severity: 'warning', feature,\r\n                  message: `尚未支持 OOXML ${reason}；此浮动图片暂不显示，原始数据保留用于导出，周围内容布局可能与 Office 不一致。`,\r\n                  zone: this.layoutZone, path, action: 'image-omitted' })\r\n              }\r\n            }\r\n            continue\r\n          }\r\n        }\r\n        const imgDisplay = String((imgEl as unknown as Record<string, unknown>).imgDisplay ?? 'block')\r\n        if (imgDisplay === 'surround' || imgDisplay === 'float-top' || imgDisplay === 'float-bottom') {\r\n          const imgBlock = this.layoutImage(imgEl, parentPath, g.start, availableWidth)\r\n          const next = paragraphs[gi + 1]\r\n          if (!(imgEl as IImageElement).imageLayout?.anchored && next && (next.kind === 'normal' || next.kind === 'title' || next.kind === 'list')) {\r\n            const kind: ParagraphBlock['paragraphKind'] = next.kind === 'normal' ? 'normal' : next.kind\r\n            const runsParentPath: Path = (kind === 'normal')\r\n              ? parentPath\r\n              : [...parentPath, next.start, 'valueList']\r\n            const pb = this.layoutParagraph({\r\n              paragraphKind: kind,\r\n              block: next.block,\r\n              runs: next.runs,\r\n              runsParentPath,\r\n              startIndex: next.start,\r\n              endIndex: next.end,\r\n              parentPath,\r\n              availableWidth,\r\n              runStartIndex: next.runStartIndex ?? 0\r\n            })\r\n            pb.surroundImage = imgBlock\r\n            if (imgBlock.rect.height > pb.rect.height) {\r\n              pb.rect.height = imgBlock.rect.height\r\n            }\r\n            blocks.push(pb)\r\n            gi++\r\n            continue\r\n          }\r\n          blocks.push(imgBlock)\r\n        } else {\r\n          blocks.push(this.layoutImage(imgEl, parentPath, g.start, availableWidth))\r\n        }\r\n      } else if (g.kind === 'pageBreak') {\r\n        blocks.push({\r\n          kind: 'pageBreak',\r\n          id: nextBlockId(),\r\n          block: g.block as IElement,\r\n          parentPath,\r\n          indexInParent: g.start,\r\n          rect: { x: 0, y: 0, width: availableWidth, height: 0 }\r\n        } as PageBreakBlock)\r\n        if (sectionWidths && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(String(g.block?.value))) {\r\n          section++\r\n          if (sectionWidths[section] === undefined) throw new TypeError('Java sections 与正文分节符数量不一致')\r\n          availableWidth = sectionWidths[section]\r\n        }\r\n      } else if (g.kind === 'separator') {\r\n        // 分割线：独立块，高度含上下间距（各 6px）+ 线宽 1px\r\n        const sepHeight = 13\r\n        blocks.push({\r\n          kind: 'separator',\r\n          id: nextBlockId(),\r\n          block: g.block as IElement,\r\n          parentPath,\r\n          indexInParent: g.start,\r\n          rect: { x: 0, y: 0, width: availableWidth, height: sepHeight }\r\n        } as SeparatorBlock)\r\n      } else if (g.kind === 'block') {\r\n        const blockEl = g.block as IElement\r\n        const anyEl = blockEl as unknown as Record<string, unknown>\r\n        const metrics = anyEl.metrics as { width?: number; height?: number } | undefined\r\n        const w = Math.max(1, Number(metrics?.width ?? 420))\r\n        const h = Math.max(1, Number(metrics?.height ?? 320))\r\n        const innerBlock = anyEl.block as { type?: string } | undefined\r\n        if (innerBlock?.type === 'chart') {\r\n          blocks.push({\r\n            kind: 'chart',\r\n            id: nextBlockId(),\r\n            block: blockEl,\r\n            parentPath,\r\n            indexInParent: g.start,\r\n            rect: { x: 0, y: 0, width: w, height: h }\r\n          } as ChartBlock)\r\n        } else {\r\n          blocks.push({\r\n            kind: 'block',\r\n            id: nextBlockId(),\r\n            block: blockEl,\r\n            parentPath,\r\n            indexInParent: g.start,\r\n            rect: { x: 0, y: 0, width: w, height: h }\r\n          } as EmbedBlock)\r\n        }\r\n      } else {\r\n        const kind: ParagraphBlock['paragraphKind'] = g.kind === 'normal' ? 'normal' : g.kind\r\n        const runsParentPath: Path = (kind === 'normal')\r\n          ? parentPath\r\n          : [...parentPath, g.start, 'valueList']\r\n        blocks.push(this.layoutParagraph({\r\n          paragraphKind: kind,\r\n          block: g.block,\r\n          runs: g.runs,\r\n          runsParentPath,\r\n          startIndex: g.start,\r\n          endIndex: g.end,\r\n          parentPath,\r\n          availableWidth,\r\n          runStartIndex: g.runStartIndex ?? 0\r\n        }))\r\n      }\r\n    }\r\n    return blocks\r\n  }\r\n\r\n  /**\r\n   * 将单个段落（normal/title/list）排版为 ParagraphBlock：解析段落属性、计算项目符号、\r\n   * 折行、行高、行内定位、rowFlex 对齐，并产出 inline 列表。\r\n   * @param input 段落排版输入（类型/容器/runs/路径/可用宽度等）\r\n   * @returns 段落块（含 lines/inlines 与 rect）\r\n   */\r\n  private layoutParagraph(input: ParagraphInput): ParagraphBlock {\r\n    // Numbered lists depend on preceding counters and must still be evaluated.\r\n    if (input.paragraphKind === 'list') {\r\n      const result = this.computeParagraph(input)\r\n      this.paragraphInputs.set(result, input)\r\n      return result\r\n    }\r\n    const key = JSON.stringify([this.layoutZone, input.runsParentPath, input.startIndex, input.runStartIndex])\r\n    const signature = JSON.stringify(input)\r\n    const cached = this.paragraphCache.get(key)\r\n    // Undo/document replacement may have identical text but different source refs.\r\n    const sameSources = cached?.input.block === input.block &&\r\n      cached.input.runs.length === input.runs.length &&\r\n      input.runs.every((run, index) => run === cached.input.runs[index])\r\n    const layout = cached && sameSources && cached.signature === signature\r\n      ? cached.layout\r\n      : this.computeParagraph(input)\r\n    this.nextParagraphCache.set(key, { signature, input, layout })\r\n    // Pagination, table placement and surrounding images mutate the outer block.\r\n    const result = { ...layout, rect: { ...layout.rect } }\r\n    this.paragraphInputs.set(result, input)\r\n    return result\r\n  }\r\n\r\n  private computeParagraph(input: ParagraphInput): ParagraphBlock {\r\n    const {\r\n      paragraphKind, block, runs, runsParentPath,\r\n      startIndex, endIndex, parentPath, availableWidth,\r\n      runStartIndex = 0\r\n    } = input\r\n\r\n    // 段落属性优先级：block（title/list 容器） > 段内任一 run（docx-parser 会把 pPr 附在 run 上，未必是第 1 个）\r\n    // 段落级属性字段集合\r\n    const PARA_KEYS = [\r\n      'rowFlex',\r\n      'paragraphStyleId',\r\n      'paragraphFirstLineIndent',\r\n      'paragraphIndentLeft',\r\n      'paragraphIndentRight',\r\n      'indentHanging',\r\n      'paragraphSpacingBefore',\r\n      'paragraphSpacingAfter',\r\n      'lineHeight',\r\n      'lineHeightRule'\r\n    ] as const\r\n    const containerAttrs = (block ?? {}) as unknown as Record<string, unknown>\r\n    // 扫描所有 runs，收集段落级属性（第一个非空值胜出）\r\n    const collectedRunAttrs: Record<string, unknown> = {}\r\n    for (const r of runs) {\r\n      const ra = r as unknown as Record<string, unknown>\r\n      for (const k of PARA_KEYS) {\r\n        if (collectedRunAttrs[k] == null && ra[k] != null) {\r\n          collectedRunAttrs[k] = ra[k]\r\n        }\r\n      }\r\n    }\r\n    const attr = (key: string): unknown =>\r\n      containerAttrs[key] != null ? containerAttrs[key] : collectedRunAttrs[key]\r\n\r\n    const rowFlex = (attr('rowFlex') as LineBox['rowFlex']) || 'left'\r\n    const firstIndent = Number(attr('paragraphFirstLineIndent') ?? 0)\r\n    // 段落左右缩进：docx 可能出现负值（\"悬入左边距\"）。若不夹到 0，会使\r\n    // usableWidth > availableWidth，行宽越过 block 边界，超出的字符会被\r\n    // block bitmap 裁掉，表现为文字丢失。此处按可视排版约束夹到 [0, +inf)。\r\n    let indentLeft = Math.max(0, Number(attr('paragraphIndentLeft') ?? 0))\r\n    const indentRight = Math.max(0, Number(attr('paragraphIndentRight') ?? 0))\r\n    // 悬挂缩进：正值表示首行相对后续行左移 hangIndent\r\n    const indentHanging = Number(attr('indentHanging') ?? 0)\r\n    const spacingBefore = Number(attr('paragraphSpacingBefore') ?? 0)\r\n    const spacingAfter = Number(attr('paragraphSpacingAfter') ?? 0)\r\n    const rawLineHeight = Number(attr('lineHeight') ?? this.opts.defaultLineHeight)\r\n    const lineHeightRule = (attr('lineHeightRule') as string) || 'auto'\r\n\r\n    // 项目符号（跟随首个 run 的字体/字号/颜色/粗细）\r\n    let bulletKind: 'symbol' | 'text' | undefined\r\n    let bulletText: string | undefined\r\n    let bulletWidth = 0\r\n    let bulletFont: string | undefined\r\n    let bulletSize: number | undefined\r\n    let bulletColor: string | undefined\r\n    let bulletBold: boolean | undefined\r\n    let bulletX: number | undefined\r\n    // 是否使用 Word 悬挂缩进模型（有 indentHanging 时为 true）\r\n    let useWordHanging = false\r\n    // 悬挂缩进量（编号在文字左侧的偏移）\r\n    let bulletHanging = 0\r\n    // 项目符号/编号：list 段落必定处理；title 段落若带 listNumbering（Word heading 关联多级列表）也一并处理\r\n    const hasNumbering = !!(block as unknown as { listNumbering?: unknown } | undefined)?.listNumbering\r\n    if (block && (paragraphKind === 'list' || (paragraphKind === 'title' && hasNumbering))) {\r\n      const listEl = block as IListElement\r\n      const res = resolveBullet(listEl, this.counters)\r\n      // 层级缩进\r\n      const level = Math.max(0, listEl.listLevel ?? 0)\r\n      const listHanging = Number(listEl.listHanging ?? 24)\r\n      const listBaseIndent = Number(listEl.listIndent ?? listEl.listNumbering?.indentLeft ?? 0)\r\n      // 编号悬挂：仅当 listNumbering 明确定义 indentHanging 时才用 Word 悬挂模型\r\n      bulletHanging = Number(listEl.listNumbering?.indentHanging ?? 0)\r\n      useWordHanging = bulletHanging > 0\r\n      // title 段落（Word heading 关联多级列表）：段落本身已带自己的缩进/对齐，\r\n      // numbering.indentLeft 只作为\"编号列宽提示\"，不应再叠加到段落 indentLeft，\r\n      // 否则整段被推到右侧（源数据里 indentLeft 常带异常大值，如 368px）。\r\n      if (paragraphKind !== 'title') {\r\n        const proposed = listBaseIndent + level * listHanging\r\n        // 保护性上限：新缩进不得占用 > 60% 可用宽度，防止数据异常导致整段跑飞\r\n        const cap = availableWidth * 0.6\r\n        indentLeft = Math.max(indentLeft, Math.min(proposed, cap))\r\n      }\r\n      // 字体/字号/颜色 取自首个 text run\r\n      const firstText = runs.find(r => r.type === 'text') as IElement | undefined\r\n      const fa = firstText as unknown as Record<string, unknown> | undefined\r\n      bulletSize = Number(fa?.size ?? this.opts.defaultSize)\r\n      bulletColor = String(fa?.color ?? '#000000')\r\n      bulletBold = !!fa?.bold\r\n\r\n      if (res.isSymbol) {\r\n        // 无序符号：使用符号字体栈（含 Wingdings）\r\n        bulletKind = 'symbol'\r\n        bulletFont = detectWingdings() ? BULLET_FONT_STACK : BULLET_FONT_STACK_FALLBACK\r\n        bulletText = res.text\r\n      } else {\r\n        // 有序编号：使用文本字体\r\n        bulletKind = 'text'\r\n        const rawBulletFont = String(fa?.font ?? this.opts.defaultFont)\r\n        bulletFont = FONT_FAMILY_CSS[rawBulletFont] ?? rawBulletFont\r\n        bulletText = res.text\r\n      }\r\n      // 度量宽度：符号后加固定间距（half em）\r\n      const symbolGap = bulletSize * 0.4\r\n      const glyphW = this.measure.textWidth(bulletText, bulletFont, bulletSize, bulletBold)\r\n      bulletWidth = glyphW + symbolGap\r\n      // 编号列内对齐（lvlJc）：\r\n      //   useWordHanging（有 indentHanging）：indentLeft = 文字位置，编号在 indentLeft - bulletHanging\r\n      //   否则（无 indentHanging）：indentLeft = 编号位置，文字在 indentLeft + bulletWidth（原行为）\r\n      //   编号绘制 x = firstLine.x + bulletX（bulletX 为负）\r\n      const jc = res.lvlJc\r\n      const hangingOffset = useWordHanging ? bulletHanging : bulletWidth\r\n      if (jc === 'center') {\r\n        const inner = Math.max(0, hangingOffset - symbolGap - glyphW)\r\n        bulletX = -hangingOffset + inner / 2\r\n      } else {\r\n        bulletX = -hangingOffset\r\n      }\r\n    }\r\n\r\n    // 每行可用宽度：Word 悬挂模型下编号在悬挂区不占行宽；否则编号占 bulletWidth\r\n    const bulletWidthForLine = useWordHanging ? 0 : bulletWidth\r\n    const usableWidth = Math.max(20, availableWidth - indentLeft - indentRight - bulletWidthForLine)\r\n    const lines: LineBox[] = []\r\n    let currentInlines: InlineBox[] = []\r\n    let currentLineWidth = 0\r\n    let currentMaxSize = this.opts.defaultSize\r\n    let isFirstLine = true\r\n\r\n    // 首行偏移相对于文本前缩进，负值表示悬挂。\r\n    const firstLineOffset = attr('indentHanging') != null ? -indentHanging : firstIndent\r\n    let flowY = spacingBefore\r\n    const lineRegion = (): { x: number; width: number } => {\r\n      let left = indentLeft + bulletWidthForLine + (isFirstLine ? firstLineOffset : 0)\r\n      let right = availableWidth - indentRight\r\n      for (const exclusion of input.exclusions ?? []) {\r\n        const r = exclusion.rect\r\n        if (flowY >= r.y + r.height || flowY + computeLineHeight(currentMaxSize) <= r.y) continue\r\n        if (exclusion.topBottom || (r.x <= left && r.x + r.width >= right)) {\r\n          flowY = r.y + r.height\r\n          return lineRegion()\r\n        }\r\n        const leftWidth = Math.max(0, r.x - left), rightWidth = Math.max(0, right - r.x - r.width)\r\n        const useLeft = exclusion.side === 'left' || (exclusion.side !== 'right' && leftWidth >= rightWidth)\r\n        if (useLeft) right = Math.min(right, r.x)\r\n        else left = Math.max(left, r.x + r.width)\r\n        if (right - left < currentMaxSize) {\r\n          flowY = r.y + r.height\r\n          return lineRegion()\r\n        }\r\n      }\r\n      return { x: left, width: Math.max(1, right - left) }\r\n    }\r\n    const currentLineMaxWidth = (): number => lineRegion().width\r\n\r\n    // Word 行距 4 种模式：\r\n    //   'auto'    → lineHeight 是倍数（1.0 单倍；1.5 一倍半；2.0 双倍；数值任意）\r\n    //   'exact'   → lineHeight 是像素固定值（不小于字号）\r\n    //   'atLeast' → lineHeight 是像素最小值，字号 > lineHeight 时会自动扩展\r\n    //   'multiple'→ 与 auto 同义（Word 里\"多倍行距\"）\r\n    const computeLineHeight = (size: number): number => {\r\n      const lh = rawLineHeight\r\n      switch (lineHeightRule) {\r\n        case 'exact':    return Math.max(1, lh) // 固定值\r\n        case 'atLeast':  return Math.max(size * 1.15, lh) // 最小值\r\n        case 'multiple':\r\n        case 'auto':\r\n        default: {\r\n          // auto：若给的是\"合理的倍数\"（0.5..5）按倍数处理；否则按 px 处理（部分导出用 px 值 + auto）\r\n          if (lh > 0 && lh <= 5) return size * lh * 1.15\r\n          return Math.max(size, lh)\r\n        }\r\n      }\r\n    }\r\n\r\n    const finalizeLine = (isLastLine: boolean) => {\r\n      const size = currentMaxSize\r\n      const lh = computeLineHeight(size)\r\n      const region = lineRegion()\r\n      const lineXBase = region.x\r\n      // 把 inline.x 从\"相对 line 起点\"平移到\"相对块起点\"\r\n      for (const inl of currentInlines) inl.x += lineXBase\r\n      const line: LineBox = {\r\n        x: lineXBase,\r\n        y: flowY,\r\n        width: region.width,\r\n        height: lh,\r\n        baseline: lh * 0.82,\r\n        inlines: currentInlines,\r\n        rowFlex,\r\n        isLastLine\r\n      }\r\n      lines.push(line)\r\n      flowY += lh\r\n      currentInlines = []\r\n      currentLineWidth = 0\r\n      currentMaxSize = this.opts.defaultSize\r\n      isFirstLine = false\r\n    }\r\n\r\n    const layoutRuns = runs.map(rawRun => {\r\n      if (rawRun.type === 'hyperlink') {\r\n        const vl = (rawRun as unknown as { valueList?: IElement[] }).valueList ?? []\r\n        const text = vl.map(r => r.type === 'tab' ? '\\t' : String(r.value ?? '')).join('')\r\n        const base = (vl.find(r => r.type === 'text' && r.value) as unknown as Record<string, unknown>) ?? {}\r\n        const tocEntry = (rawRun.extension?.toc as { role?: string } | undefined)?.role === 'entry'\r\n        return {\r\n          type: 'text', value: text,\r\n          font: base.font, size: base.size, bold: base.bold, italic: base.italic,\r\n          color: tocEntry ? base.color : '#0000FF', underline: tocEntry ? base.underline : true,\r\n          extension: rawRun.extension\r\n        } as unknown as IElement\r\n      }\r\n      return rawRun\r\n    })\r\n    // Imported PAGEREF results may follow the tab in separate runs, with hidden fields in between.\r\n    const tocPageWidth = (runIndex: number, offset: number): number => {\r\n      let width = 0\r\n      for (let i = runIndex; i < layoutRuns.length; i++) {\r\n        const run = layoutRuns[i]\r\n        if (run.type !== 'text' || run.extension?.fieldMarker || run.extension?.bookmarkMarker) continue\r\n        const text = String(run.value ?? '').slice(i === runIndex ? offset : 0)\r\n        const family = String(run.font ?? this.opts.defaultFont)\r\n        const font = FONT_FAMILY_CSS[family] ?? family\r\n        const size = Number(run.size ?? this.opts.defaultSize)\r\n        for (const ch of text) {\r\n          if (ch === '\\n' || ch === '\\t') return width\r\n          if (ch === '\\u200B' || ch === '\\uFEFF') continue\r\n          width += this.measure.charWidth(ch, font, size, !!run.bold, !!run.italic)\r\n        }\r\n      }\r\n      return width\r\n    }\r\n\r\n    for (let ri = 0; ri < runs.length; ri++) {\r\n      const rawRun = runs[ri]\r\n      const run = layoutRuns[ri]\r\n      if (run.type !== 'text') continue\r\n      const hyperlinkUrl = rawRun.type === 'hyperlink' ? String(rawRun.url ?? rawRun.value ?? '') : undefined\r\n      const anyRun = run as unknown as Record<string, unknown>\r\n      const rawFont = String(anyRun.font ?? this.opts.defaultFont)\r\n      const font = FONT_FAMILY_CSS[rawFont] ?? rawFont\r\n      const size = Number(anyRun.size ?? this.opts.defaultSize)\r\n      const bold = !!anyRun.bold\r\n      const italic = !!anyRun.italic\r\n      const color = String(anyRun.color ?? '#000000')\r\n      const bgColor = anyRun.highlight ? String(anyRun.highlight) : undefined\r\n      const strikeout = !!anyRun.strikeout\r\n      const underline = !!anyRun.underline\r\n      const groupIds = Array.isArray(anyRun.groupIds) ? anyRun.groupIds as string[] : undefined\r\n      const value = String(anyRun.value ?? '')\r\n\r\n      if (!value) continue\r\n      // 跳过段落终止符（零宽字符），不产出 inline，但 ri 仍递进以保持索引对齐\r\n      if (/^[\\u200B\\uFEFF]+$/.test(value)) continue\r\n\r\n      // normal 段落用 elements 原索引（startIndex + ri）作为 path 末段，保证 path 唯一；\r\n      // title/list 的 runsParentPath 已含段索引，ri 是 valueList 切片内索引，需加 runStartIndex 还原原 valueList 索引。\r\n      // 表格单元格内 normal 段落需拼上 runsParentPath（contentPath）以保证 path 全局唯一。\r\n      const runPath: Path = paragraphKind === 'normal'\r\n        ? [...runsParentPath, startIndex + ri]\r\n        : [...runsParentPath, runStartIndex + ri]\r\n      let cursorInRun = 0\r\n\r\n      while (cursorInRun < value.length) {\r\n        const maxLineWidth = currentLineMaxWidth()\r\n        const remaining = maxLineWidth - currentLineWidth\r\n        const tocEntry = (run.extension?.toc as { role?: string } | undefined)?.role === 'entry'\r\n        if (tocEntry && value[cursorInRun] === '\\t') {\r\n          const pageWidth = tocPageWidth(ri, cursorInRun + 1)\r\n          if (currentLineWidth > 0 && remaining < pageWidth + size) {\r\n            finalizeLine(false)\r\n            continue\r\n          }\r\n          const width = Math.max(0, remaining - pageWidth)\r\n          currentInlines.push({\r\n            run, path: runPath, startOffset: cursorInRun, endOffset: cursorInRun + 1,\r\n            text: '\\t', x: currentLineWidth, y: 0, width, height: size,\r\n            font, size, bold, italic, color, baseline: 0\r\n          })\r\n          currentLineWidth += width\r\n          currentMaxSize = Math.max(currentMaxSize, size)\r\n          cursorInRun++\r\n          continue\r\n        }\r\n        // 若当前行已有内容且首个字符放不下 → 先换行再试，避免溢出被裁\r\n        if (currentLineWidth > 0 && value[cursorInRun] !== '\\n') {\r\n          const firstW = this.measure.charWidth(value[cursorInRun], font, size, bold, italic)\r\n          if (firstW > remaining + 0.001) {\r\n            finalizeLine(false)\r\n            continue\r\n          }\r\n        }\r\n        let take = 0\r\n        let takenWidth = 0\r\n        for (let i = cursorInRun; i < value.length; i++) {\r\n          const ch = value[i]\r\n          if (tocEntry && ch === '\\t') break\r\n          const w = this.measure.charWidth(ch, font, size, bold, italic)\r\n          if (ch === '\\n') { take = i - cursorInRun; break }\r\n          if (takenWidth + w > remaining + 0.001 && take > 0) break\r\n          takenWidth += w\r\n          take++\r\n        }\r\n        if (take === 0 && cursorInRun < value.length && value[cursorInRun] === '\\n') {\r\n          // 显式换行\r\n          finalizeLine(false)\r\n          cursorInRun++\r\n          continue\r\n        }\r\n        if (take === 0) {\r\n          // 剩余空间放不下一个字符 → 换行重试\r\n          finalizeLine(false)\r\n          continue\r\n        }\r\n        const segEnd = cursorInRun + take\r\n        const text = value.slice(cursorInRun, segEnd)\r\n        const segWidth = takenWidth\r\n        const inline: InlineBox = {\r\n          run,\r\n          path: runPath,\r\n          startOffset: cursorInRun,\r\n          endOffset: segEnd,\r\n          text,\r\n          x: currentLineWidth, // 暂存为\"相对 line 起点\"，finalizeLine 会平移\r\n          y: 0,\r\n          width: segWidth,\r\n          height: size,\r\n          font,\r\n          size,\r\n          bold,\r\n          italic,\r\n          color,\r\n          bgColor,\r\n          strikeout,\r\n          underline,\r\n          baseline: 0,\r\n          groupIds,\r\n          hyperlink: hyperlinkUrl\r\n        }\r\n        currentInlines.push(inline)\r\n        currentLineWidth += segWidth\r\n        if (size > currentMaxSize) currentMaxSize = size\r\n        cursorInRun = segEnd\r\n        if (cursorInRun < value.length && value[cursorInRun] === '\\n') {\r\n          finalizeLine(false)\r\n          cursorInRun++ // 消费换行符\r\n        } else if (cursorInRun < value.length && currentLineWidth >= maxLineWidth) {\r\n          finalizeLine(false)\r\n        }\r\n      }\r\n    }\r\n    // 空段兜底：若整个段落未产出任何 inline（所有 text run 为空字符串或零宽占位），\r\n    // 为首个空 text run 生成零宽 caret 承载 inline，确保光标可定位、行高不塌陷。\r\n    if (currentInlines.length === 0 && lines.length === 0) {\r\n      let placeholderRun: IElement | null = null\r\n      let placeholderRi = -1\r\n      // 优先选空字符串 run（光标通常落在 rest run），跳过零宽分隔符 run\r\n      for (let ri = 0; ri < runs.length; ri++) {\r\n        if (runs[ri].type !== 'text') continue\r\n        const v = String((runs[ri] as unknown as Record<string, unknown>).value ?? '')\r\n        if (v === '') { placeholderRun = runs[ri]; placeholderRi = ri; break }\r\n      }\r\n      // 退而求其次：用首个 text run（可能是零宽分隔符）\r\n      if (!placeholderRun) {\r\n        for (let ri = 0; ri < runs.length; ri++) {\r\n          if (runs[ri].type === 'text') { placeholderRun = runs[ri]; placeholderRi = ri; break }\r\n        }\r\n      }\r\n      if (placeholderRun) {\r\n        const pr = placeholderRun as unknown as Record<string, unknown>\r\n        const rawFont = String(pr.font ?? this.opts.defaultFont)\r\n        const font = FONT_FAMILY_CSS[rawFont] ?? rawFont\r\n        const size = Number(pr.size ?? this.opts.defaultSize)\r\n        const runPath: Path = paragraphKind === 'normal'\r\n          ? [...runsParentPath, startIndex + placeholderRi]\r\n          : [...runsParentPath, runStartIndex + placeholderRi]\r\n        currentInlines.push({\r\n          run: placeholderRun,\r\n          path: runPath,\r\n          startOffset: 0,\r\n          endOffset: 0,\r\n          text: '',\r\n          x: 0,\r\n          y: 0,\r\n          width: 0,\r\n          height: size,\r\n          font,\r\n          size,\r\n          bold: !!pr.bold,\r\n          italic: !!pr.italic,\r\n          color: String(pr.color ?? '#000000'),\r\n          bgColor: undefined,\r\n          strikeout: false,\r\n          underline: false,\r\n          baseline: 0,\r\n          groupIds: undefined\r\n        })\r\n        currentMaxSize = size\r\n      }\r\n    }\r\n    if (currentInlines.length > 0 || lines.length === 0) finalizeLine(true)\r\n\r\n    // 分配行 y 与 inline y/baseline（相对块本地坐标）\r\n    let yy = spacingBefore\r\n    // 跟踪块内内容实际右边缘（含 rowFlex 平移后的最大 x），用于兜底 bitmap 宽度\r\n    let contentRight = 0\r\n    for (const line of lines) {\r\n      yy = Math.max(yy, line.y)\r\n      line.y = yy\r\n      line.baseline = 0.8 * line.height\r\n      for (const inl of line.inlines) {\r\n        inl.y = yy\r\n        inl.baseline = yy + line.baseline\r\n      }\r\n      applyRowFlex(line, input.exclusions?.length ? line.width : usableWidth)\r\n      for (const inl of line.inlines) {\r\n        const r = inl.x + inl.width\r\n        if (r > contentRight) contentRight = r\r\n      }\r\n      yy += line.height\r\n    }\r\n    yy += spacingAfter\r\n\r\n    // rect.width 必须能覆盖实际内容最大右边缘，避免行末字符被 bitmap 裁掉\r\n    // （浮点误差 / rowFlex 分散对齐 / 负缩进兜底后仍可能微超 availableWidth）\r\n    const rectWidth = Math.max(availableWidth, Math.ceil(contentRight))\r\n    const rect: Rect = { x: 0, y: 0, width: rectWidth, height: yy }\r\n    return {\r\n      kind: 'paragraph',\r\n      id: nextBlockId(),\r\n      paragraphKind,\r\n      block,\r\n      startIndex,\r\n      endIndex,\r\n      parentPath,\r\n\r\n      rect,\r\n      lines,\r\n      bulletKind,\r\n      bulletText,\r\n      bulletWidth,\r\n      bulletFont,\r\n      bulletSize,\r\n      bulletColor,\r\n      bulletBold,\r\n      bulletX\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将图片元素排版为 ImageBlock：根据 width/height/rotate 计算占位尺寸与水平对齐位置。\r\n   * @param el 图片元素\r\n   * @param parentPath 父容器路径\r\n   * @param index 在父容器中的索引\r\n   * @param availableWidth 可用宽度（用于对齐计算）\r\n   * @returns 图片块\r\n   */\r\n  private layoutImage(el: IElement, parentPath: Path, index: number, availableWidth: number): ImageBlock {\r\n    const anyEl = el as unknown as Record<string, unknown>\r\n    const w = Number(anyEl.width)\r\n    const h = Number(anyEl.height)\r\n    const rotate = Number(anyEl.rotate ?? 0) * Math.PI / 180\r\n    const occupiedW = Math.abs(w * Math.cos(rotate)) + Math.abs(h * Math.sin(rotate))\r\n    const occupiedH = Math.abs(w * Math.sin(rotate)) + Math.abs(h * Math.cos(rotate))\r\n    // 水平对齐：rowFlex 决定 x 位置\r\n    const rowFlex = String(anyEl.rowFlex ?? 'left')\r\n    let x = 0\r\n    if (occupiedW < availableWidth) {\r\n      if (rowFlex === 'center') x = (availableWidth - occupiedW) / 2\r\n      else if (rowFlex === 'right') x = availableWidth - occupiedW\r\n    }\r\n    return {\r\n      kind: 'image',\r\n      id: nextBlockId(),\r\n      block: el,\r\n      parentPath,\r\n      indexInParent: index,\r\n      rect: { x, y: 0, width: occupiedW, height: occupiedH }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将表格元素排版为 TableBlock：计算列宽、rowspan 占用矩阵、各行高、单元格内容排版、\r\n   * 跨行 cell 撑高与垂直对齐。\r\n   * @param table 表格元素\r\n   * @param parentPath 父容器路径\r\n   * @param index 在父容器中的索引\r\n   * @param availableWidth 可用宽度\r\n   * @returns 表格块\r\n   */\r\n  private layoutTable(\r\n    table: ITableElement,\r\n    parentPath: Path,\r\n    index: number,\r\n    availableWidth: number\r\n  ): TableBlock {\r\n    // ---------- 列宽计算 ----------\r\n    // 1) 优先使用 colgroup 定义\r\n    let colWidths = table.colgroup.map(c => c.width || 0)\r\n\r\n    // 2) colgroup 缺失或列数不足 → 用首行 tdList 补齐（每个 td 按 colspan 展开）\r\n    if (colWidths.length === 0 || colWidths.every(v => v <= 0)) {\r\n      const firstTr = table.trList[0]\r\n      if (firstTr) {\r\n        const inferred: number[] = []\r\n        for (const td of firstTr.tdList) {\r\n          const span = td.colspan || 1\r\n          const per = (td.width || 0) / span\r\n          for (let k = 0; k < span; k++) inferred.push(per)\r\n        }\r\n        colWidths = inferred\r\n      }\r\n    }\r\n\r\n    const totalDefined = colWidths.reduce((s, v) => s + v, 0)\r\n    // 3) 若 totalDefined 超过 availableWidth 太多，才等比缩放（避免小数误差反复缩放导致数据被改）\r\n    if (totalDefined > availableWidth * 1.02) {\r\n      const k = availableWidth / totalDefined\r\n      colWidths = colWidths.map(v => v * k)\r\n    } else if (totalDefined <= 0) {\r\n      // 兜底：均分\r\n      const n = Math.max(1, colWidths.length || (table.trList[0]?.tdList.length ?? 1))\r\n      colWidths = Array.from({ length: n }, () => availableWidth / n)\r\n    }\r\n    // 表格实际宽度 = 列宽之和（保留自然宽度，不撑满 availableWidth）\r\n    const tableWidth = colWidths.reduce((s, v) => s + v, 0)\r\n\r\n    // ---------- rowspan 网格占用矩阵 ----------\r\n    // occupied[ri][ci] = true 表示该格已被上方 rowspan 覆盖\r\n    const occupied: boolean[][] = table.trList.map(() => new Array(colWidths.length).fill(false))\r\n\r\n    // ---------- 逐行排版 ----------\r\n    const rows: TableRowLayout[] = []\r\n    // 先假设每行最小 = max(tr.height, tr.minHeight)，之后可能被合并单元格撑高\r\n    const rowHeights: number[] = table.trList.map(tr => Math.max(tr.height || 0, tr.minHeight || 0))\r\n    // 收集所有 cellLayouts，后面统一定位\r\n    const rowCells: TableCellLayout[][] = table.trList.map(() => [])\r\n    // 收集跨行单元格：{ startRow, endRow, cellLayout, requiredHeight }\r\n    interface RowspanPending {\r\n      startRow: number\r\n      endRow: number\r\n      layout: TableCellLayout\r\n      contentHeight: number\r\n      padTop: number\r\n      padBottom: number\r\n    }\r\n    const rowspanPending: RowspanPending[] = []\r\n\r\n    for (let ri = 0; ri < table.trList.length; ri++) {\r\n      const tr = table.trList[ri]\r\n      let colCursor = 0\r\n      for (let ci = 0; ci < tr.tdList.length; ci++) {\r\n        // 跳过已被上方 rowspan 覆盖的位置\r\n        while (colCursor < colWidths.length && occupied[ri][colCursor]) colCursor++\r\n        if (colCursor >= colWidths.length) break\r\n\r\n        const td = tr.tdList[ci]\r\n        const colspan = Math.max(1, td.colspan || 1)\r\n        const rowspan = Math.max(1, td.rowspan || 1)\r\n\r\n        // 标记被此 td 覆盖的格子\r\n        for (let rr = ri; rr < Math.min(ri + rowspan, table.trList.length); rr++) {\r\n          for (let cc = colCursor; cc < Math.min(colCursor + colspan, colWidths.length); cc++) {\r\n            if (rr !== ri || cc !== colCursor) occupied[rr][cc] = true\r\n          }\r\n        }\r\n\r\n        const cellWidth = colWidths.slice(colCursor, colCursor + colspan).reduce((s, v) => s + v, 0)\r\n        const cellX = sumUp(colWidths, colCursor)\r\n        const [pt, pr, pb, pl] = td.padding\r\n        const contentWidth = Math.max(10, cellWidth - pl - pr)\r\n        const cellPath: Path = [...parentPath, index, 'trList', ri, 'tdList', ci]\r\n        const contentPath: Path = [...cellPath, 'value']\r\n        const content = this.layoutBlocks(td.value, contentPath, contentWidth)\r\n\r\n        // 内容 y 累加\r\n        let innerY = 0\r\n        for (const cb of content) {\r\n          cb.rect.y = innerY\r\n          innerY += cb.rect.height\r\n        }\r\n        const contentHeight = innerY\r\n\r\n        const layout: TableCellLayout = {\r\n          cell: td,\r\n          cellPath,\r\n          contentPath,\r\n          rect: { x: cellX, y: 0, width: cellWidth, height: 0 },\r\n          content,\r\n          contentPaddingTop: pt,\r\n          contentPaddingLeft: pl,\r\n          verticalOffset: 0\r\n        }\r\n        rowCells[ri].push(layout)\r\n\r\n        if (rowspan === 1) {\r\n          // 单行 cell：直接撑高当前行\r\n          const required = contentHeight + pt + pb\r\n          if (required > rowHeights[ri]) rowHeights[ri] = required\r\n        } else {\r\n          // 跨行 cell：先记录，最后再检查是否需要撑高 endRow\r\n          rowspanPending.push({\r\n            startRow: ri,\r\n            endRow: Math.min(ri + rowspan - 1, table.trList.length - 1),\r\n            layout,\r\n            contentHeight,\r\n            padTop: pt,\r\n            padBottom: pb\r\n          })\r\n        }\r\n        colCursor += colspan\r\n      }\r\n    }\r\n\r\n    // ---------- 处理跨行 cell 的高度需求：若跨行区间累加高度 < 需求，则把差额加到最后一行 ----------\r\n    for (const rp of rowspanPending) {\r\n      let acc = 0\r\n      for (let r = rp.startRow; r <= rp.endRow; r++) acc += rowHeights[r]\r\n      const required = rp.contentHeight + rp.padTop + rp.padBottom\r\n      if (required > acc) {\r\n        rowHeights[rp.endRow] += (required - acc)\r\n      }\r\n    }\r\n\r\n    // ---------- 定位每行 y、每 cell 的最终 rect + 垂直对齐 ----------\r\n    let cursorY = 0\r\n    for (let ri = 0; ri < table.trList.length; ri++) {\r\n      const rowHeight = rowHeights[ri]\r\n      const cellLayouts = rowCells[ri]\r\n      for (const cl of cellLayouts) {\r\n        cl.rect.y = cursorY\r\n        // 高度：单行 = 当前行高；跨行 = 从起始行到结束行的高度累加\r\n        const rowspan = Math.max(1, cl.cell.rowspan || 1)\r\n        let cellH = rowHeight\r\n        if (rowspan > 1) {\r\n          cellH = 0\r\n          for (let r = ri; r < Math.min(ri + rowspan, table.trList.length); r++) cellH += rowHeights[r]\r\n        }\r\n        cl.rect.height = cellH\r\n        // 垂直对齐\r\n        const [pt, , pb] = cl.cell.padding\r\n        const contentHeight = cl.content.reduce((s, b) => s + b.rect.height, 0)\r\n        const inner = Math.max(0, cellH - pt - pb - contentHeight)\r\n        if (cl.cell.verticalAlign === 'middle') cl.verticalOffset = inner / 2\r\n        else if (cl.cell.verticalAlign === 'bottom') cl.verticalOffset = inner\r\n        else cl.verticalOffset = 0\r\n      }\r\n      rows.push({\r\n        rect: { x: 0, y: cursorY, width: tableWidth, height: rowHeight },\r\n        cells: cellLayouts\r\n      })\r\n      cursorY += rowHeight\r\n    }\r\n\r\n    return {\r\n      kind: 'table',\r\n      id: nextBlockId(),\r\n      block: table,\r\n      parentPath,\r\n      indexInParent: index,\r\n      rect: { x: 0, y: 0, width: tableWidth, height: cursorY },\r\n      rows,\r\n      colWidths\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 跨页表格拆分。被 `layout()` 分页循环调用。\r\n   *\r\n   * 逻辑：\r\n   *  - 任意行边界都可切割；跨行（rowspan）格被切割时由 buildFragment 裁剪，\r\n   *    上片保留上半（含内容），下片生成空内容的续接格，边框/背景保持连续。\r\n   *  - 第 1 片最多占用当前页剩余空间 (firstFit)；剩余行逐页推进，\r\n   *    每页用整页高度 (fullHeight) 计算能放几行。\r\n   *\r\n   * 返回的每个片段都是独立 TableBlock，带自己的 rows / colWidths，\r\n   * 其 rect 重建为\"从 0 开始的片段高度\"（y 由上层分页循环重新分配）。\r\n   * 不重复表头，因此不复制表头行。\r\n   *\r\n   * @returns 片段数组（至少 2 片）；null 表示不可拆分（首片连一行都放不下，\r\n   *          或整表本就能容纳）。调用方负责把片段落页。\r\n   */\r\n  private tryPaginateTableFlow(\r\n    b: TableBlock,\r\n    firstFit: number,\r\n    fullHeight: number\r\n  ): TableBlock[] | null {\r\n    const totalRows = b.rows.length\r\n    if (totalRows <= 1) return null\r\n\r\n    // 收集\"表头行\"（从第 0 行起连续被标记为 pagingRepeat 的行）：\r\n    // Word 语义只有从表首开始连续的行才可作为跨页重复表头\r\n    const repeatRows: number[] = []\r\n    for (let i = 0; i < b.rows.length; i++) {\r\n      const tr = (b.block as ITableElement).trList[i]\r\n      if (tr && tr.pagingRepeat) repeatRows.push(i)\r\n      else break\r\n    }\r\n    // 表头行占用的高度（不能小于表头本身，避免第 1 片就装不下）\r\n    const repeatHeight = repeatRows.reduce((s, ri) => s + b.rows[ri].rect.height, 0)\r\n\r\n    // 第 1 片：用当前页剩余空间\r\n    const firstEnd = this.findSliceEnd(b, 0, firstFit)\r\n    if (firstEnd < 0) return null\r\n    // 若第 1 片就已覆盖整张表（能整表容纳），说明本不该走进拆分分支，直接回退。\r\n    if (firstEnd >= totalRows - 1) return null\r\n\r\n    // 先组装全部片段，任一步失败则整体返回 null（事务性，避免半放置）\r\n    const frags: TableBlock[] = [this.buildFragment(b, 0, firstEnd)]\r\n    let startRow = firstEnd + 1\r\n    while (startRow < totalRows) {\r\n      // 后续片段预留表头高度\r\n      const budget = repeatRows.length > 0 ? Math.max(0, fullHeight - repeatHeight) : fullHeight\r\n      const endRow = this.findSliceEnd(b, startRow, budget)\r\n      if (endRow < 0) return null\r\n      frags.push(this.buildFragment(b, startRow, endRow, repeatRows))\r\n      startRow = endRow + 1\r\n    }\r\n    return frags\r\n  }\r\n\r\n  /** 在 [startRow, totalRows) 内，累计行高不超过 fit，找到最大可容纳的行下标；找不到返回 -1。 */\r\n  private findSliceEnd(b: TableBlock, startRow: number, fit: number): number {\r\n    let endRow = -1\r\n    let subAcc = 0\r\n    for (let ri = startRow; ri < b.rows.length; ri++) {\r\n      subAcc += b.rows[ri].rect.height\r\n      if (subAcc > fit) break\r\n      endRow = ri\r\n    }\r\n    return endRow\r\n  }\r\n\r\n  /** 从 TableBlock b 中切出行区间 [s, e]（含两端），重建一个独立 TableBlock 片段。\r\n   *  跨切割点的 rowspan 格做裁剪处理：\r\n   *  - 本片内起始、但延伸出本片的格：高度裁剪到本片底部，并重算垂直偏移；\r\n   *  - 起始于本片之前、延伸进本片的格：在首行补一个空内容的续接格，\r\n   *    使边框 / 背景在续页保持连续（内容只在上半显示一次）。\r\n    *  注意：不修改原表 b 的任何行 / 格对象（后续片段还要复用）。\r\n    *  @param b 表格块\r\n    *  @param s 起始行下标\r\n    *  @param e 结束行下标\r\n    *  @param repeatRowsBefore 需要在片段最前面复制一份的\"表头行\"下标列表（w:tblHeader），仅在非第一片时使用。 */\r\n  private buildFragment(b: TableBlock, s: number, e: number, repeatRowsBefore?: number[]): TableBlock {\r\n    // 先深拷贝主体行\r\n    const bodyRows = b.rows.slice(s, e + 1).map(r => ({\r\n      ...r,\r\n      rect: { ...r.rect },\r\n      cells: r.cells.map(c => ({ ...c, rect: { ...c.rect } }))\r\n    }))\r\n    // 表头重复行（跨页时）：仅当 s>0（非首片）且 repeatRowsBefore 中的行不在当前区间内时才复制\r\n    const headerRows = (s > 0 && repeatRowsBefore && repeatRowsBefore.length > 0)\r\n      ? repeatRowsBefore\r\n          .filter(ri => ri < s) // 首片已经含表头则不重复\r\n          .map(ri => ({\r\n            ...b.rows[ri],\r\n            rect: { ...b.rows[ri].rect },\r\n            cells: b.rows[ri].cells.map(c => ({ ...c, rect: { ...c.rect } }))\r\n          }))\r\n      : []\r\n    const rows = [...headerRows, ...bodyRows]\r\n    // 重建行 rect.y 为片段本地坐标（从 0 重新累加）\r\n    let y = 0\r\n    for (const r of rows) {\r\n      r.rect.y = y\r\n      r.rect.x = b.rect.x\r\n      y += r.rect.height\r\n    }\r\n    const spanHeight = (from: number, to: number): number => {\r\n      let h = 0\r\n      for (let rr = from; rr <= to; rr++) h += b.rows[rr].rect.height\r\n      return h\r\n    }\r\n    const headerOffset = headerRows.length\r\n    // 本片内起始的格：定位到行 y；延伸出本片的裁剪高度\r\n    for (let ri = s; ri <= e; ri++) {\r\n      const r = rows[headerOffset + (ri - s)]\r\n      for (const c of r.cells) {\r\n        c.rect.y = r.rect.y\r\n        const rs = Math.max(1, c.cell.rowspan || 1)\r\n        const end = ri + rs - 1\r\n        if (end > e) {\r\n          c.rect.height = spanHeight(ri, e)\r\n          c.verticalOffset = this.fitVerticalOffset(c, c.rect.height)\r\n        }\r\n      }\r\n    }\r\n    // 重复表头行：定位其内 cell 的 rect.y 到片段本地\r\n    for (let hi = 0; hi < headerOffset; hi++) {\r\n      const r = rows[hi]\r\n      for (const c of r.cells) {\r\n        c.rect.y = r.rect.y\r\n        // 表头行不参与 rowspan 裁剪（表头通常独立），保持原 height\r\n      }\r\n    }\r\n    // 起始于本片之前的 rowspan 格：body 首行补续接格（空内容）\r\n    if (s > 0) {\r\n      const cont: TableCellLayout[] = []\r\n      for (let ri = 0; ri < s; ri++) {\r\n        for (const c of b.rows[ri].cells) {\r\n          const rs = Math.max(1, c.cell.rowspan || 1)\r\n          const end = ri + rs - 1\r\n          if (rs > 1 && end >= s) {\r\n            cont.push({\r\n              ...c,\r\n              rect: { x: c.rect.x, y: 0, width: c.rect.width, height: spanHeight(s, Math.min(e, end)) },\r\n              content: [],\r\n              verticalOffset: 0\r\n            })\r\n          }\r\n        }\r\n      }\r\n      if (cont.length > 0) {\r\n        const bodyFirst = rows[headerOffset]\r\n        bodyFirst.cells = [...cont, ...bodyFirst.cells].sort((a, a2) => a.rect.x - a2.rect.x)\r\n      }\r\n    }\r\n    // 分页处\"封口\"：数据中共享边常只由邻格单侧定义，切开后邻格落在另一页，\r\n    // 因此片段首行缺 top / 末行缺 bottom 时补齐，保证合并格续接处边框连续。\r\n    if (s > 0) {\r\n      // 若有重复表头，封口对象是表头首行；否则是 body 首行\r\n      for (const c of rows[0].cells) this.ensureFragmentEdge(c, 'top')\r\n    }\r\n    if (e < b.rows.length - 1) {\r\n      for (const c of rows[rows.length - 1].cells) this.ensureFragmentEdge(c, 'bottom')\r\n    }\r\n    return {\r\n      kind: 'table',\r\n      id: nextBlockId(),\r\n      block: b.block,\r\n      parentPath: b.parentPath,\r\n      indexInParent: b.indexInParent,\r\n      rect: { x: b.rect.x, y: 0, width: b.rect.width, height: y },\r\n      rows,\r\n      colWidths: b.colWidths\r\n    }\r\n  }\r\n\r\n  /** 片段边界封口：该侧无边框时从本格其他边复制样式补齐（仅改片段副本，不动原数据）。 */\r\n  private ensureFragmentEdge(c: TableCellLayout, side: 'top' | 'bottom'): void {\r\n    // 分页片段不能补造源文档未提供或显式关闭的边框。\r\n    void c\r\n    void side\r\n  }\r\n\r\n  /** 按裁剪后的格高重算垂直偏移（规则同 layoutTable）。 */\r\n  private fitVerticalOffset(c: TableCellLayout, cellH: number): number {\r\n    const [pt, , pb] = c.cell.padding\r\n    const contentHeight = c.content.reduce((acc, blk) => acc + blk.rect.height, 0)\r\n    const inner = Math.max(0, cellH - pt - pb - contentHeight)\r\n    if (c.cell.verticalAlign === 'middle') return inner / 2\r\n    if (c.cell.verticalAlign === 'bottom') return inner\r\n    return 0\r\n  }\r\n\r\n}\r\n\r\n/* -------------------- 工具 -------------------- */\r\n\r\n/**\r\n * 数组前 upto 项求和。\r\n * @param arr 数值数组\r\n * @param upto 求和上界（不含）\r\n * @returns 前 upto 项之和\r\n */\r\nfunction sumUp(arr: number[], upto: number): number {\r\n  let s = 0\r\n  for (let i = 0; i < upto; i++) s += arr[i]\r\n  return s\r\n}\r\n\r\n/**\r\n * 对单行 inline 列表应用水平对齐：left/center/right 直接平移；\r\n * justify/alignment 将剩余空白均分到字符间隙（仅非末行）。\r\n * @param line 行盒\r\n * @param containerWidth 容器可用宽度\r\n */\r\nfunction applyRowFlex(line: LineBox, containerWidth: number): void {\r\n  const used = line.inlines.reduce((s, inl) => s + inl.width, 0)\r\n  const free = containerWidth - used\r\n  if (free <= 0) return\r\n  if (line.rowFlex === 'left') return\r\n  if (line.rowFlex === 'center') {\r\n    const dx = free / 2\r\n    for (const inl of line.inlines) inl.x += dx\r\n    return\r\n  }\r\n  if (line.rowFlex === 'right') {\r\n    for (const inl of line.inlines) inl.x += free\r\n    return\r\n  }\r\n  const isJustify = line.rowFlex === 'justify' || line.rowFlex === 'alignment'\r\n  const isDistribute = line.rowFlex === 'distribute'\r\n  if ((isJustify || isDistribute) && line.inlines.length > 0) {\r\n    if (isJustify && line.isLastLine) return\r\n    // 按\"字符间隙\"分配额外空白（接近 Word 的两端对齐视觉效果）：\r\n    // 全行字符数 N，可拉伸缝隙数 = N - 1，均分 free 到每个字符后。\r\n    // 每个 inline 的宽度按 letterSpacing * charCount 扩展，后续 inline\r\n    // 依次右移；inline 之间不再额外插入间隙，避免出现大块空白。\r\n    // distribute 与 justify 唯一区别：末行也分散对齐。\r\n    let totalChars = 0\r\n    for (const inl of line.inlines) totalChars += inl.text.length\r\n    const gaps = totalChars - 1\r\n    if (gaps <= 0) return\r\n    const extra = free / gaps\r\n    let dx = 0\r\n    for (let i = 0; i < line.inlines.length; i++) {\r\n      const inl = line.inlines[i]\r\n      inl.x += dx\r\n      const n = inl.text.length\r\n      if (n > 0) {\r\n        inl.letterSpacing = extra\r\n        // 若该 inline 是行尾，其最后一个字符后不再有缝隙需要承担\r\n        const isLast = i === line.inlines.length - 1\r\n        const add = isLast ? extra * (n - 1) : extra * n\r\n        inl.width += add\r\n        dx += add\r\n      }\r\n    }\r\n  }\r\n}\r\n","/**\r\n * BlockPainter —— 段落位图绘制纯函数\r\n *\r\n * 从 CanvasRenderer 抽出，无 this 依赖，用于把 paragraph block 绘制到目标 ctx。\r\n */\r\n\r\nimport type { ParagraphBlock, InlineBox } from './layout-types'\r\nimport type { IGroupColor } from '@vervedoc/docx-editor-schema'\r\nimport { getAuthorColor } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 单条文本绘制命令（分桶合并绘制以减少 ctx.font 切换开销） */\r\nexport interface DrawCommand {\r\n  font: string\r\n  color: string\r\n  x: number\r\n  y: number\r\n  text: string\r\n  letterSpacing?: number\r\n}\r\n\r\n/** 段落绘制选项 */\r\nexport interface PaintOptions {\r\n  groupColors?: Record<string, IGroupColor>\r\n  activeGroupId?: string | null\r\n  activeRevision?: { id: string; color: string } | null\r\n}\r\n\r\n/** 绘制上下文类型（HTMLCanvasElement 或 OffscreenCanvas） */\r\nexport type PaintCtx = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D\r\n\r\n/** 由 inline 生成 CSS font 简写 */\r\nexport function fontOf(inl: InlineBox): string {\r\n  const w = inl.bold ? '700' : '400'\r\n  const s = inl.italic ? 'italic ' : ''\r\n  return `${s}${w} ${inl.size}px ${inl.font}`\r\n}\r\n\r\n/** 将绘制命令按 key 推入分桶 */\r\nexport function addBucket(buckets: Map<string, DrawCommand[]>, key: string, cmd: DrawCommand): void {\r\n  let list = buckets.get(key)\r\n  if (!list) { list = []; buckets.set(key, list) }\r\n  list.push(cmd)\r\n}\r\n\r\n/** 将 hex 颜色转为半透明高亮色（批注/修订文本背景） */\r\nexport function groupHighlightColor(color: string, active = false): string {\r\n  const m = color.match(/^#([0-9a-f]{6})$/i)\r\n  if (m) {\r\n    const r = parseInt(m[1].slice(0, 2), 16)\r\n    const g = parseInt(m[1].slice(2, 4), 16)\r\n    const b = parseInt(m[1].slice(4, 6), 16)\r\n    return `rgba(${r},${g},${b},${active ? 0.14 : 0.18})`\r\n  }\r\n  return color\r\n}\r\n\r\n/**\r\n * 将段落块绘制到目标 ctx：项目符号/编号 + 分桶文本 + 背景色 + 下划线/删除线。\r\n * @param ctx 目标 2d 上下文\r\n * @param b 段落块\r\n * @param opts 绘制选项（groupColors / activeGroupId）\r\n */\r\nexport function paintParagraph(ctx: PaintCtx, b: ParagraphBlock, opts: PaintOptions): void {\r\n  // 项目符号 / 编号\r\n  if (b.bulletText) {\r\n    const firstLine = b.lines[0]\r\n    if (firstLine) {\r\n      const size = b.bulletSize ?? 16\r\n      const family = b.bulletFont ?? 'sans-serif'\r\n      const bold = b.bulletBold ? '700' : '400'\r\n      ctx.font = `${bold} ${size}px ${family}`\r\n      ctx.fillStyle = b.bulletColor ?? '#000000'\r\n      ctx.textBaseline = 'alphabetic'\r\n      const bx = firstLine.x + (b.bulletX ?? -(b.bulletWidth ?? 0))\r\n      const by = firstLine.y + firstLine.baseline\r\n      ctx.fillText(b.bulletText, bx, by)\r\n    }\r\n  }\r\n  // 分桶\r\n  const buckets = new Map<string, DrawCommand[]>()\r\n  const bgRects: { x: number; y: number; w: number; h: number; color: string }[] = []\r\n  const strokes: { x1: number; y1: number; x2: number; y2: number; color: string; width: number }[] = []\r\n  const groupColors = opts.groupColors\r\n  const activeColor = opts.activeGroupId ? groupColors?.[opts.activeGroupId]?.color : undefined\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      const hasGroupHighlight = !!(groupColors && inl.groupIds?.some(gid => groupColors[gid]))\r\n      if (opts.activeRevision && inl.run && 'revisionId' in inl.run && inl.run.revisionId === opts.activeRevision.id) {\r\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(opts.activeRevision.color, true) })\r\n      } else if (activeColor && opts.activeGroupId && inl.groupIds?.includes(opts.activeGroupId)) {\r\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(activeColor, true) })\r\n      } else if (hasGroupHighlight) {\r\n        for (const gid of inl.groupIds!) {\r\n          const gc = groupColors![gid]\r\n          if (gc) {\r\n            bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(gc.color, gid === opts.activeGroupId) })\r\n          }\r\n        }\r\n      } else if (inl.bgColor) {\r\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: inl.bgColor })\r\n      }\r\n      const run = inl.run\r\n      const revisionType = run && 'revisionId' in run && run.revisionId && 'revisionType' in run\r\n        ? run.revisionType : undefined\r\n      const inserted = revisionType === 'insert'\r\n      const deleted = revisionType === 'delete'\r\n      const revisionColor = inserted || deleted\r\n        ? getAuthorColor(run && 'revisionAuthor' in run ? String(run.revisionAuthor ?? '') : '')\r\n        : undefined\r\n      const textColor = revisionColor ?? inl.color\r\n      if (inl.text === '\\t' && (run?.extension?.toc as { role?: string } | undefined)?.role === 'entry') {\r\n        ctx.save()\r\n        ctx.strokeStyle = textColor\r\n        ctx.lineWidth = 1\r\n        ctx.setLineDash([1, 3])\r\n        ctx.beginPath()\r\n        ctx.moveTo(inl.x + 3, inl.baseline)\r\n        ctx.lineTo(inl.x + Math.max(3, inl.width - 3), inl.baseline)\r\n        ctx.stroke()\r\n        ctx.restore()\r\n        continue\r\n      }\r\n      const font = fontOf(inl)\r\n      const key = `${font}||${textColor}`\r\n      addBucket(buckets, key, {\r\n        font, color: textColor,\r\n        x: inl.x, y: inl.baseline,\r\n        text: inl.text,\r\n        letterSpacing: inl.letterSpacing\r\n      })\r\n      // Review marks are visual overlays, never persisted as ordinary formatting.\r\n      if (inserted || inl.underline) {\r\n        strokes.push({\r\n          x1: inl.x, y1: inl.baseline + 2, x2: inl.x + inl.width, y2: inl.baseline + 2,\r\n          color: inserted ? revisionColor! : textColor, width: 1\r\n        })\r\n      }\r\n      if (deleted || inl.strikeout) {\r\n        const my = inl.baseline - inl.size * 0.3\r\n        strokes.push({\r\n          x1: inl.x, y1: my, x2: inl.x + inl.width, y2: my,\r\n          color: deleted ? revisionColor! : textColor, width: 1\r\n        })\r\n      }\r\n    }\r\n  }\r\n  for (const r of bgRects) {\r\n    ctx.fillStyle = r.color\r\n    ctx.fillRect(Math.round(r.x), Math.round(r.y), Math.round(r.w), Math.round(r.h))\r\n  }\r\n  ctx.textBaseline = 'alphabetic'\r\n  for (const [key, list] of buckets) {\r\n    const [font, color] = key.split('||')\r\n    ctx.font = font\r\n    ctx.fillStyle = color\r\n    for (const c of list) {\r\n      if (!c.letterSpacing) {\r\n        ctx.fillText(c.text, c.x, c.y)\r\n      } else {\r\n        let cx = c.x\r\n        for (let i = 0; i < c.text.length; i++) {\r\n          const ch = c.text[i]\r\n          ctx.fillText(ch, cx, c.y)\r\n          cx += ctx.measureText(ch).width + c.letterSpacing\r\n        }\r\n      }\r\n    }\r\n  }\r\n  for (const s of strokes) {\r\n    ctx.strokeStyle = s.color\r\n    ctx.lineWidth = s.width\r\n    ctx.beginPath()\r\n    ctx.moveTo(s.x1 + 0.5, s.y1 + 0.5)\r\n    ctx.lineTo(s.x2 + 0.5, s.y2 + 0.5)\r\n    ctx.stroke()\r\n  }\r\n}\r\n","/**\r\n * 块签名（用于跨帧复用 bitmap）\r\n */\r\n\r\nimport type { BlockNode, DocumentLayout, ParagraphBlock } from './layout-types'\r\n\r\nexport function chartTableSignature(b: BlockNode, layout: DocumentLayout): string {\r\n  if (b.kind !== 'chart') return ''\r\n  const source = (b.block as unknown as {\r\n    block?: { chartBlock?: { dataSource?: { type?: string; tableId?: string } } }\r\n  }).block?.chartBlock?.dataSource\r\n  if (source?.type !== 'table') return ''\r\n  for (const page of layout.pages) {\r\n    for (const block of page.blocks) {\r\n      if (block.kind === 'table' && block.block.id === source.tableId) return JSON.stringify(block.block)\r\n    }\r\n  }\r\n  return ''\r\n}\r\n\r\n/**\r\n * 计算块的签名（用于跨帧复用 bitmap）：按块类型拼接关键字段为字符串。\r\n * @param b 块\r\n * @param layout 文档布局（用于 chart-table 签名查找）\r\n * @returns 块签名字符串\r\n */\r\nexport function signBlock(b: BlockNode, layout?: DocumentLayout): string {\r\n  // Include all paint inputs, but not the block's placement on the page.\r\n  // Source objects are mutable, so callers must retain the string, not the object.\r\n  if (b.kind === 'table') {\r\n    const { trList: _rows, ...attrs } = b.block as unknown as Record<string, unknown>\r\n    return JSON.stringify([attrs, b.rect.width, b.rect.height, b.colWidths,\r\n      b.rows.map(row => [row.rect, row.cells.map(cell => {\r\n        const { value: _content, ...cellAttrs } = cell.cell\r\n        return [cellAttrs, cell.rect, cell.contentPaddingTop, cell.contentPaddingLeft,\r\n          cell.verticalOffset, cell.content.map(child => [child.rect, signBlock(child, layout)])]\r\n      })])])\r\n  }\r\n  if (b.kind === 'paragraph') return signParagraph(b)\r\n  if (b.kind === 'image') {\r\n    const img = b.block as unknown as { value?: string; rotate?: number; imgDisplay?: string }\r\n    return `img|${img.value ?? ''}|${b.rect.width}x${b.rect.height}|r${img.rotate ?? 0}|d${img.imgDisplay ?? 'block'}`\r\n  }\r\n  if (b.kind === 'pageBreak') return `pb|${b.parentPath.join('.')}|${b.indexInParent}`\r\n  if (b.kind === 'separator') return JSON.stringify([b.kind, b.block, b.rect.width, b.rect.height])\r\n  if (b.kind === 'block') {\r\n    const el = b.block as unknown as { id?: string }\r\n    return `blk|${el.id ?? ''}|${b.parentPath.join('.')}|${b.indexInParent}|${b.rect.width}x${b.rect.height}`\r\n  }\r\n  if (b.kind === 'chart') {\r\n    const el = b.block as unknown as { id?: string; block?: { chartBlock?: Record<string, unknown> } }\r\n    return `chart|${el.id ?? ''}|${b.rect.width}x${b.rect.height}|${JSON.stringify(el.block?.chartBlock ?? '')}|${layout ? chartTableSignature(b, layout) : ''}`\r\n  }\r\n  return `unk`\r\n}\r\n\r\n/**\r\n * 计算段落块签名：拼接段落属性 + 各 inline 文本/字体/样式 + 项目符号 + 环绕图片关键字段。\r\n * @param b 段落块\r\n * @returns 段落签名字符串\r\n */\r\nexport function signParagraph(b: ParagraphBlock): string {\r\n  const attrs = b.block ?? (b.lines[0]?.inlines[0]?.run) ?? null\r\n  const a = attrs as unknown as Record<string, unknown> | null\r\n  const paraKey = a\r\n    ? `${a.rowFlex ?? ''}|${a.paragraphStyleId ?? ''}|${a.lineHeight ?? ''}|${a.lineHeightRule ?? ''}|${a.paragraphFirstLineIndent ?? ''}|${a.paragraphIndentLeft ?? ''}|${a.paragraphIndentRight ?? ''}|${a.indentHanging ?? ''}|${a.paragraphSpacingBefore ?? ''}|${a.paragraphSpacingAfter ?? ''}`\r\n    : ''\r\n  const runsKey: string[] = []\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      const { run, path: _path, ...paint } = inl\r\n      // Revision colors and decorations are painted from the run, not inline styles.\r\n      const revision = run && 'revisionId' in run && run.revisionId\r\n        ? [run.revisionId, run.revisionType, run.revisionAuthor]\r\n        : null\r\n      runsKey.push(JSON.stringify([line.x, line.y, line.height, line.baseline, paint, revision]))\r\n    }\r\n  }\r\n  const bulletKey = b.bulletText\r\n    ? `~b:${b.bulletKind ?? ''}|${b.bulletText ?? ''}|${b.bulletFont ?? ''}|${b.bulletSize ?? ''}|${b.bulletColor ?? ''}|${b.bulletBold ? 1 : 0}|bx=${b.bulletX ?? ''}|bw=${b.bulletWidth ?? ''}`\r\n    : ''\r\n  const si = b.surroundImage\r\n  const surroundKey = si\r\n    ? `~si:${JSON.stringify(si.rect)}|${signBlock(si)}`\r\n    : ''\r\n  return `p|${b.paragraphKind}|${b.rect.width}x${b.rect.height}|${paraKey}|${runsKey.join('~')}${bulletKey}${surroundKey}`\r\n}\r\n","/**\r\n * VerveDocs View —— CanvasRenderer\r\n *\r\n * 背景 DOM 层 + content/overlay 两层 canvas。\r\n *\r\n * 增量重绘：\r\n *  - 每个 Block 拥有独立 canvas 位图，key = block.id。\r\n *  - 首次或 dirty 时重建该 block bitmap；否则复用。\r\n *  - 主 content canvas 每帧执行：clear + drawImage(bitmap) 到屏幕对应位置。\r\n *  - 因此\"内容变化局部更新\" = 只对 dirty block 重建 bitmap。\r\n *\r\n * 坐标：block/line/inline 均使用块本地坐标；绘制到 bitmap 时以 (0,0) 为起点。\r\n * 主 canvas 落位时 = pageOriginY + block.rect.y - scrollY。\r\n */\r\n\r\nimport type {\r\n  BlockNode, DocumentLayout, PageLayout,\r\n  ParagraphBlock, ImageBlock, TableBlock, SeparatorBlock, ChartBlock\r\n} from './layout-types'\r\nimport type { IGroupColor, IImageElement } from '@vervedoc/docx-editor-schema'\r\nimport type { IChartRenderer } from '@vervedoc/docx-editor-schema'\r\nimport { paintParagraph, type PaintCtx } from './block-painter'\r\nimport { chartTableSignature } from './block-signature'\r\n\r\n\r\n/** CanvasRenderer 渲染器配置选项 */\r\nexport interface RendererOptions {\r\n  /** 设备像素比，用于高 DPI 屏幕清晰渲染 */\r\n  dpr: number\r\n  /** 渲染缩放倍数 */\r\n  scale: number\r\n  /** 页面背景色 */\r\n  pageBg: string\r\n  /** 页面阴影颜色 */\r\n  pageShadow: string\r\n  /** 页面居中时相对 canvas 左侧的水平偏移（外部计算并传入） */\r\n  pageOffsetX: number\r\n  /** 页面 margin（top,right,bottom,left），用于绘制标尺角标 */\r\n  pageMargins: [number, number, number, number]\r\n  /** 是否显示 WPS 风格的四角边距标记 */\r\n  showMarginRuler: boolean\r\n  /** 标尺颜色 */\r\n  rulerColor: string\r\n  /** 批注/修订组颜色映射，用于高亮文档中带 groupIds 的文本 */\r\n  groupColors?: Record<string, IGroupColor>\r\n  /** 当前高亮的 group ID（鼠标悬浮批注气泡时设置） */\r\n  activeGroupId?: string | null\r\n  /** 页码配置（设置后在页眉/页脚中渲染页码） */\r\n  pageNumber?: { style: string; position: 'left' | 'center' | 'right'; zone: 'header' | 'footer' } | null\r\n\r\n}\r\n\r\n\r\n/** 块位图缓存条目：保存已渲染好的位图及其尺寸元信息 */\r\ninterface BlockCache {\r\n  /** 块 id（与 BlockNode.id 对应） */\r\n  id: number\r\n  /** 已渲染好的位图（OffscreenCanvas 时为 ImageBitmap，降级时为 HTMLCanvasElement） */\r\n  bitmap: HTMLCanvasElement | ImageBitmap | null\r\n  /** 位图 CSS 宽度 */\r\n  width: number\r\n  /** 位图 CSS 高度 */\r\n  height: number\r\n  /** 创建该位图时的 dpr（dpr 变化时需重建） */\r\n  dpr: number\r\n}\r\n\r\n/**\r\n * Canvas 渲染器：维护背景 DOM 层 + content/overlay 两层 canvas，\r\n * 负责 block 位图缓存、增量重绘、光标/选区/页眉页脚分隔线绘制。\r\n */\r\nexport class CanvasRenderer {\r\n  /** 背景层 DOM 容器（每页背景 div，z-index:0） */\r\n  private bgLayer: HTMLDivElement\r\n  /** 内容层 canvas（绘制 block 位图） */\r\n  private contentCanvas: HTMLCanvasElement\r\n  /** 覆盖层 canvas（绘制光标、选区高亮、zone 分隔线） */\r\n  private overlayCanvas: HTMLCanvasElement\r\n  /** 内容层 2d 上下文 */\r\n  private contentCtx: CanvasRenderingContext2D\r\n  /** 覆盖层 2d 上下文 */\r\n  private overlayCtx: CanvasRenderingContext2D\r\n  /** 选区层 DOM 容器（选区高亮 div，z-index:3） */\r\n  private selectionLayer: HTMLDivElement\r\n  /** 每页背景 div（页号 → div），带 data-index 供协同光标定位 */\r\n  private pageBgEls = new Map<number, HTMLDivElement>()\r\n  /** 选区高亮 div 池（复用，避免频繁创建） */\r\n  private selectionEls: HTMLDivElement[] = []\r\n\r\n  /** canvas CSS 宽度（视口宽度） */\r\n  private cssWidth = 0\r\n  /** canvas CSS 高度（视口高度） */\r\n  private cssHeight = 0\r\n  /** 渲染器选项 */\r\n  private opts: RendererOptions\r\n  private chartRenderer: IChartRenderer | null = null\r\n\r\n  setChartRenderer(renderer: IChartRenderer | null): void {\r\n    this.chartRenderer = renderer\r\n    for (const key of this.imageCache.keys()) {\r\n      if (key.startsWith('chart|')) this.imageCache.delete(key)\r\n    }\r\n    this.invalidateAll()\r\n  }\r\n\r\n  /** 图片元素缓存（url -> HTMLImageElement） */\r\n  private imageCache = new Map<string, HTMLImageElement>()\r\n  /** block 位图缓存（blockId -> BlockCache） */\r\n  private blockCache = new Map<number, BlockCache>()\r\n  /** 待重建位图的 block id 集合 */\r\n  private dirtyBlocks = new Set<number>()\r\n  /** Built during layout, so hover does not scan the document. */\r\n  private groupBlockIds = new Map<string, Set<number>>()\r\n  private revisionBlockIds = new Map<string, Set<number>>()\r\n  private activeRevision: { id: string; color: string } | null = null\r\n\r\n  /** 当前帧的文档布局（供 drawChartInto 查找表格数据源） */\r\n  private currentLayout: DocumentLayout | null = null\r\n\r\n\r\n  /** 水印 widget（可选，设置后在每页渲染完成后绘制水印） */\r\n  private watermarkWidget: { drawWatermark(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout, scrollY: number): void; drawWatermarkForThumbnail(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout): void } | null = null\r\n\r\n  /**\r\n   * 创建渲染器并挂载三层 canvas 到容器。\r\n   * @param container 宿主 DOM 容器，三层 canvas 绝对定位覆盖其内\r\n   * @param options 渲染选项（缺省字段使用默认值）\r\n   */\r\n  constructor(private container: HTMLElement, options: Partial<RendererOptions> = {}) {\r\n    this.opts = {\r\n      dpr: options.dpr ?? (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),\r\n      scale: options.scale ?? 1,\r\n      pageBg: options.pageBg ?? '#ffffff',\r\n      pageShadow: options.pageShadow ?? 'rgba(0,0,0,0.08)',\r\n      pageOffsetX: options.pageOffsetX ?? 0,\r\n      pageMargins: options.pageMargins ?? [100, 120, 100, 120],\r\n      showMarginRuler: options.showMarginRuler ?? true,\r\n      rulerColor: options.rulerColor ?? '#999999'\r\n    }\r\n\r\n    this.bgLayer = this.createDomLayer('bg', 0)\r\n    this.contentCanvas = this.createLayer('content', 1)\r\n    this.overlayCanvas = this.createLayer('overlay', 2)\r\n    this.selectionLayer = this.createDomLayer('selection', 3)\r\n    this.contentCtx = this.contentCanvas.getContext('2d')!\r\n    this.overlayCtx = this.overlayCanvas.getContext('2d')!\r\n\r\n  }\r\n\r\n  /**\r\n   * 创建一个 canvas 图层并挂载到容器。\r\n   * @param name 图层名（写入 dataset.layer，便于调试与查找）\r\n   * @param z 图层 z-index（越大越上层）\r\n   * @returns 创建好的 canvas 元素\r\n   */\r\n  private createLayer(name: string, z: number): HTMLCanvasElement {\r\n    const c = document.createElement('canvas')\r\n    c.dataset.layer = name\r\n    c.style.position = 'absolute'\r\n    c.style.top = '0'\r\n    c.style.left = '0'\r\n    c.style.zIndex = String(z)\r\n    c.style.pointerEvents = 'none'\r\n    this.container.appendChild(c)\r\n    return c\r\n  }\r\n\r\n  /** 创建一个 DOM 叠加层并挂载到容器 */\r\n  private createDomLayer(name: string, z: number): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.dataset.layer = name\r\n    el.style.position = 'absolute'\r\n    el.style.top = '0'\r\n    el.style.left = '0'\r\n    el.style.zIndex = String(z)\r\n    el.style.pointerEvents = 'none'\r\n    this.container.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 设置 canvas 视口尺寸（CSS 像素），同时按 dpr 调整物理像素与变换矩阵。\r\n   * @param cssWidth CSS 宽度\r\n   * @param cssHeight CSS 高度\r\n   */\r\n  setSize(cssWidth: number, cssHeight: number): void {\r\n    this.cssWidth = cssWidth\r\n    this.cssHeight = cssHeight\r\n    const dpr = this.opts.dpr\r\n    for (const c of [this.contentCanvas, this.overlayCanvas]) {\r\n      c.width = Math.round(cssWidth * dpr)\r\n      c.height = Math.round(cssHeight * dpr)\r\n      c.style.width = `${cssWidth}px`\r\n      c.style.height = `${cssHeight}px`\r\n    }\r\n    for (const ctx of [this.contentCtx, this.overlayCtx]) {\r\n      ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n    }\r\n  }\r\n\r\n  /** 更新可视化选项（页偏移 / margin / 是否显示标尺） */\r\n  updateVisualOptions(patch: Partial<Pick<RendererOptions,\r\n    'pageOffsetX' | 'pageMargins' | 'showMarginRuler' | 'rulerColor' | 'pageBg' | 'pageShadow' | 'scale' | 'groupColors' | 'activeGroupId'\r\n  >>): void {\r\n    Object.assign(this.opts, patch)\r\n  }\r\n\r\n  /** Change only the screen background, preserving layout and all canvas caches. */\r\n  setEyeCare(enabled: boolean): void {\r\n    if (enabled) this.bgLayer.style.setProperty('--vd-eye-care-bg', '#C7EDCC')\r\n    else this.bgLayer.style.removeProperty('--vd-eye-care-bg')\r\n  }\r\n\r\n  /**\r\n   * 渲染单页缩略图到离屏 canvas 并返回 data URL。\r\n   * 创建临时 canvas（页面尺寸 × dpr），绘制白底背景 + 页面内容，输出 PNG data URL。\r\n   * @param page 页面布局信息\r\n   * @param quality PNG 压缩质量（0-1）\r\n   * @returns 缩略图 data URL；页面尺寸为 0 时返回空字符串\r\n   */\r\n  renderPageThumbnail(page: PageLayout, quality = 0.7, pageCount = 1, onForeground?: (image: string) => void): string {\r\n    if (page.rect.width === 0 || page.rect.height === 0) return ''\r\n    const dpr = this.opts.dpr\r\n    const canvas = document.createElement('canvas')\r\n    canvas.width = Math.round(page.rect.width * dpr)\r\n    canvas.height = Math.round(page.rect.height * dpr)\r\n    const ctx = canvas.getContext('2d')!\r\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n\r\n    // 内容区原点（相对于页面左上角）\r\n    const contentOriginX = page.contentRect.x - page.rect.x\r\n    const contentOriginY = page.contentRect.y - page.rect.y\r\n    const aliveIds = new Set<number>()\r\n    for (const b of page.blocks) {\r\n      this.renderBlockOnMain(ctx, b, contentOriginX, contentOriginY, aliveIds)\r\n    }\r\n\r\n    // 页眉\r\n    if (page.headerBlocks && page.headerRect) {\r\n      const hx = page.headerRect.x - page.rect.x\r\n      const hy = page.headerRect.y - page.rect.y\r\n      for (const b of page.headerBlocks) {\r\n        this.renderBlockOnMain(ctx, b, hx, hy, aliveIds)\r\n      }\r\n    }\r\n\r\n    // 页脚\r\n    if (page.footerBlocks && page.footerRect) {\r\n      const fx = page.footerRect.x - page.rect.x\r\n      const fy = page.footerRect.y - page.rect.y\r\n      for (const b of page.footerBlocks) {\r\n        this.renderBlockOnMain(ctx, b, fx, fy, aliveIds)\r\n      }\r\n    }\r\n\r\n    this.drawPageNumberForThumbnail(ctx, page, pageCount)\r\n    this.watermarkWidget?.drawWatermarkForThumbnail(ctx, page)\r\n\r\n    // Keep a transparent content snapshot for background-only Worker composition.\r\n    onForeground?.(canvas.toDataURL('image/png', quality))\r\n    ctx.globalCompositeOperation = 'destination-over'\r\n    ctx.fillStyle = this.opts.pageBg\r\n    ctx.fillRect(0, 0, page.rect.width, page.rect.height)\r\n    const image = canvas.toDataURL('image/png', quality)\r\n    this.trimCache()\r\n    return image\r\n  }\r\n\r\n  /** 标脏（下一帧只重建这些 block 的 bitmap） */\r\n  markDirty(blockIds: number[] | Set<number>): void {\r\n    for (const id of blockIds) this.dirtyBlocks.add(id)\r\n  }\r\n\r\n  /** Retain offscreen document blocks; remove only deleted occurrences. */\r\n  setLayout(layout: DocumentLayout, ids: Set<number>): void {\r\n    this.currentLayout = layout\r\n    this.groupBlockIds.clear()\r\n    this.revisionBlockIds.clear()\r\n    const collect = (blocks: BlockNode[]) => {\r\n      for (const block of blocks) {\r\n        if (block.kind === 'table') {\r\n          for (const row of block.rows) {\r\n            for (const cell of row.cells) collect(cell.content)\r\n          }\r\n        } else if (block.kind === 'paragraph') {\r\n          for (const line of block.lines) {\r\n            for (const inline of line.inlines) {\r\n              const revisionId = inline.run && 'revisionId' in inline.run ? inline.run.revisionId : undefined\r\n              if (typeof revisionId === 'string' && revisionId) {\r\n                let blockIds = this.revisionBlockIds.get(revisionId)\r\n                if (!blockIds) this.revisionBlockIds.set(revisionId, blockIds = new Set())\r\n                blockIds.add(block.id)\r\n              }\r\n              for (const groupId of inline.groupIds ?? []) {\r\n                let blockIds = this.groupBlockIds.get(groupId)\r\n                if (!blockIds) this.groupBlockIds.set(groupId, blockIds = new Set())\r\n                blockIds.add(block.id)\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    for (const page of layout.pages) {\r\n      collect(page.blocks)\r\n      collect(page.headerBlocks ?? [])\r\n      collect(page.footerBlocks ?? [])\r\n    }\r\n    for (const [id, cached] of this.blockCache) {\r\n      if (ids.has(id)) continue\r\n      if (cached.bitmap instanceof ImageBitmap) cached.bitmap.close()\r\n      this.blockCache.delete(id)\r\n    }\r\n    for (const id of this.dirtyBlocks) {\r\n      if (!ids.has(id)) this.dirtyBlocks.delete(id)\r\n    }\r\n  }\r\n\r\n  /** Only the old and new groups need new text bitmaps. */\r\n  setActiveGroup(groupId: string | null): boolean {\r\n    const previous = this.opts.activeGroupId ?? null\r\n    if (previous === groupId) return false\r\n    this.opts.activeGroupId = groupId\r\n    for (const id of [previous, groupId]) {\r\n      if (id === null) continue\r\n      const blocks = this.groupBlockIds.get(id)\r\n      if (blocks) this.markDirty(blocks)\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** Invalidate only the old and new revision's paragraph bitmaps. */\r\n  setActiveRevision(id: string | null, color = '#e60000'): boolean {\r\n    const previous = this.activeRevision\r\n    if ((previous?.id ?? null) === id && (!id || previous?.color === color)) return false\r\n    this.activeRevision = id === null ? null : { id, color }\r\n    for (const revisionId of [previous?.id, id]) {\r\n      if (!revisionId) continue\r\n      const blocks = this.revisionBlockIds.get(revisionId)\r\n      if (blocks) this.markDirty(blocks)\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** Bound retained bitmap memory with least-recently-used eviction. */\r\n  private trimCache(): void {\r\n    let bytes = 0\r\n    const size = (entry: BlockCache) => Math.ceil(entry.width) * Math.ceil(entry.height) * entry.dpr ** 2 * 4\r\n    for (const entry of this.blockCache.values()) bytes += size(entry)\r\n    for (const [id, entry] of this.blockCache) {\r\n      if (bytes <= 64 * 1024 * 1024) break\r\n      bytes -= size(entry)\r\n      if (entry.bitmap instanceof ImageBitmap) entry.bitmap.close()\r\n      this.blockCache.delete(id)\r\n    }\r\n  }\r\n\r\n  /** 全部标脏（用于选项/主题变更） */\r\n  invalidateAll(): void {\r\n    for (const c of this.blockCache.values()) {\r\n      if (c.bitmap instanceof ImageBitmap) c.bitmap.close()\r\n    }\r\n    this.blockCache.clear()\r\n    this.dirtyBlocks.clear()\r\n  }\r\n\r\n  /** 销毁渲染器 */\r\n  destroy(): void {\r\n    for (const c of this.blockCache.values()) {\r\n      if (c.bitmap instanceof ImageBitmap) c.bitmap.close()\r\n    }\r\n    this.pageBgEls.clear()\r\n    this.groupBlockIds.clear()\r\n    this.revisionBlockIds.clear()\r\n    this.blockCache.clear()\r\n    this.dirtyBlocks.clear()\r\n    for (const image of this.imageCache.values()) image.onload = null\r\n    this.imageCache.clear()\r\n    this.selectionEls = []\r\n    this.bgLayer.remove()\r\n    this.selectionLayer.remove()\r\n    this.contentCanvas.remove()\r\n    this.overlayCanvas.remove()\r\n  }\r\n\r\n  /** 更新页码配置 */\r\n  updatePageNumber(cfg: { style: string; position: 'left' | 'center' | 'right'; zone: 'header' | 'footer' } | null): void {\r\n    this.opts.pageNumber = cfg\r\n  }\r\n\r\n  /** 设置水印 widget */\r\n  setWatermarkWidget(widget: { drawWatermark(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout, scrollY: number): void; drawWatermarkForThumbnail(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout): void } | null): void {\r\n    this.watermarkWidget = widget\r\n  }\r\n\r\n\r\n  /** 将数字转为罗马数字字符串 */\r\n  private toRoman(num: number): string {\r\n    const map: [number, string][] = [[1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'], [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'], [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']]\r\n    let result = ''\r\n    for (const [v, s] of map) {\r\n      while (num >= v) { result += s; num -= v }\r\n    }\r\n    return result\r\n  }\r\n\r\n  /** 将数字转为中文数字字符串（支持大写） */\r\n  private toChineseNumber(num: number, uppercase = false): string {\r\n    const digits = uppercase\r\n      ? ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']\r\n      : ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']\r\n    const units = uppercase\r\n      ? ['', '拾', '佰', '仟', '萬', '億']\r\n      : ['', '十', '百', '千', '万', '亿']\r\n    if (num === 0) return digits[0]\r\n    if (num < 10) return digits[num]\r\n    if (num < 20) return (num === 10 ? units[1] : units[1] + digits[num - 10])\r\n    if (num < 100) {\r\n      const tens = Math.floor(num / 10)\r\n      const ones = num % 10\r\n      return digits[tens] + units[1] + (ones > 0 ? digits[ones] : '')\r\n    }\r\n    if (num < 1000) {\r\n      const hundreds = Math.floor(num / 100)\r\n      const rest = num % 100\r\n      let result = digits[hundreds] + units[2]\r\n      if (rest >= 10) {\r\n        result += this.toChineseNumber(rest, uppercase)\r\n      } else if (rest > 0) {\r\n        result += digits[0] + digits[rest]\r\n      }\r\n      return result\r\n    }\r\n    if (num < 10000) {\r\n      const thousands = Math.floor(num / 1000)\r\n      const rest = num % 1000\r\n      let result = digits[thousands] + units[3]\r\n      if (rest >= 100) {\r\n        result += this.toChineseNumber(rest, uppercase)\r\n      } else if (rest > 0) {\r\n        result += digits[0] + this.toChineseNumber(rest, uppercase)\r\n      }\r\n      return result\r\n    }\r\n    return String(num)\r\n  }\r\n\r\n  /**\r\n   * 在页眉/页脚区域绘制页码文本。\r\n   * @param ct 内容 canvas 上下文\r\n   * @param page 页面布局\r\n   * @param scrollY 滚动偏移\r\n   * @param totalPages 总页数\r\n   */\r\n  private drawPageNumber(\r\n    ct: CanvasRenderingContext2D,\r\n    page: { index: number; rect: { x: number; y: number; width: number; height: number }; headerRect?: { x: number; y: number; width: number; height: number } | null; footerRect?: { x: number; y: number; width: number; height: number } | null },\r\n    scrollY: number,\r\n    totalPages: number\r\n  ): void {\r\n    const cfg = this.opts.pageNumber\r\n    if (!cfg) return\r\n    const rect = cfg.zone === 'header' ? page.headerRect : page.footerRect\r\n    if (!rect) return\r\n    const text = this.formatPageNumber(page.index, totalPages, cfg.style)\r\n    ct.save()\r\n    ct.fillStyle = '#333333'\r\n    ct.font = '12px \"Microsoft YaHei\", \"PingFang SC\", sans-serif'\r\n    const metrics = ct.measureText(text)\r\n    const textW = metrics.width\r\n    const textH = 16\r\n    const cx = page.rect.x + this.opts.pageOffsetX\r\n    let x: number\r\n    if (cfg.position === 'left') {\r\n      x = cx + rect.x - page.rect.x + 4\r\n    } else if (cfg.position === 'right') {\r\n      x = cx + rect.x - page.rect.x + rect.width - textW - 4\r\n    } else {\r\n      x = cx + rect.x - page.rect.x + (rect.width - textW) / 2\r\n    }\r\n    const baselineY = cfg.zone === 'header'\r\n      ? rect.y + rect.height - textH - 4 - scrollY\r\n      : rect.y + 4 - scrollY\r\n    ct.fillText(text, x, baselineY + textH)\r\n    ct.restore()\r\n  }\r\n\r\n  /**\r\n   * 为缩略图绘制页码（原点在页面左上角 0,0，无 scrollY/pageOffsetX）。\r\n   */\r\n  private drawPageNumberForThumbnail(\r\n    ct: CanvasRenderingContext2D,\r\n    page: { index: number; rect: { x: number; y: number; width: number; height: number }; headerRect?: { x: number; y: number; width: number; height: number } | null; footerRect?: { x: number; y: number; width: number; height: number } | null },\r\n    totalPages: number\r\n  ): void {\r\n    const cfg = this.opts.pageNumber\r\n    if (!cfg) return\r\n    const rect = cfg.zone === 'header' ? page.headerRect : page.footerRect\r\n    if (!rect) return\r\n    const text = this.formatPageNumber(page.index, totalPages, cfg.style)\r\n    ct.save()\r\n    ct.fillStyle = '#333333'\r\n    ct.font = '12px \"Microsoft YaHei\", \"PingFang SC\", sans-serif'\r\n    const metrics = ct.measureText(text)\r\n    const textW = metrics.width\r\n    const textH = 16\r\n    const relX = rect.x - page.rect.x\r\n    const relY = rect.y - page.rect.y\r\n    let x: number\r\n    if (cfg.position === 'left') {\r\n      x = relX + 4\r\n    } else if (cfg.position === 'right') {\r\n      x = relX + rect.width - textW - 4\r\n    } else {\r\n      x = relX + (rect.width - textW) / 2\r\n    }\r\n    const baselineY = cfg.zone === 'header'\r\n      ? relY + rect.height - textH - 4\r\n      : relY + 4\r\n    ct.fillText(text, x, baselineY + textH)\r\n    ct.restore()\r\n  }\r\n\r\n  /**\r\n   * 将页码索引格式化为字符串（Word 标准格式 + 原有格式）。\r\n   * @param index 页码索引（从 0 开始）\r\n   * @param totalPages 总页数\r\n   * @param style 页码样式\r\n   * @returns 格式化后的页码字符串\r\n   */\r\n  private formatPageNumber(index: number, totalPages: number, style: string): string {\r\n    const n = index + 1\r\n    switch (style) {\r\n      case '第1页': return `第${n}页`\r\n      case '第1页共x页': return `第${n}页共${totalPages}页`\r\n      case '1/x': return `${n}/${totalPages}`\r\n      case '第一页': return `第${this.toChineseNumber(n)}页`\r\n      case '第一页共X页': return `第${this.toChineseNumber(n)}页共${this.toChineseNumber(totalPages)}页`\r\n      case '1, 2, 3 ...': return String(n)\r\n      case 'I, II, III ...': return this.toRoman(n).toUpperCase()\r\n      case 'i, ii, iii ...': return this.toRoman(n).toLowerCase()\r\n      case 'A, B, C ...': return String.fromCharCode(64 + n)\r\n      case 'a, b, c ...': return String.fromCharCode(96 + n)\r\n      case '一, 二, 三 ...': return this.toChineseNumber(n)\r\n      case '壹, 贰, 叁 ...': return this.toChineseNumber(n, true)\r\n      default: return String(n)\r\n    }\r\n  }\r\n\r\n\r\n  /* -------------------- 光标 / 选区（Overlay） -------------------- */\r\n\r\n  /**\r\n\r\n   * 绘制选区高亮（DOM div 池）。传入文档坐标矩形列表，内部应用 scrollY 与 pageOffsetX。\r\n   */\r\n  drawSelection(rects: { x: number; y: number; width: number; height: number }[], scrollY: number): void {\r\n    for (let i = 0; i < rects.length; i++) {\r\n      const r = rects[i]\r\n      let el = this.selectionEls[i]\r\n      if (!el) {\r\n        el = document.createElement('div')\r\n        el.className = 'vd-selection'\r\n        el.style.position = 'absolute'\r\n        el.style.background = 'rgba(77, 146, 255, 0.3)'\r\n        el.style.pointerEvents = 'none'\r\n        this.selectionLayer.appendChild(el)\r\n        this.selectionEls[i] = el\r\n      }\r\n      el.style.display = 'block'\r\n      el.style.left = `${Math.round(r.x + this.opts.pageOffsetX)}px`\r\n      el.style.top = `${Math.round(r.y - scrollY)}px`\r\n      el.style.width = `${Math.round(r.width)}px`\r\n      el.style.height = `${Math.round(r.height)}px`\r\n    }\r\n    for (let i = rects.length; i < this.selectionEls.length; i++) {\r\n      this.selectionEls[i].style.display = 'none'\r\n    }\r\n  }\r\n\r\n  /** 清除 overlay canvas 上的光标/zone，并隐藏选区 div */\r\n  clearOverlay(): void {\r\n    this.overlayCtx.clearRect(0, 0, this.cssWidth, this.cssHeight)\r\n    for (const el of this.selectionEls) el.style.display = 'none'\r\n  }\r\n\r\n  /** 绘制页眉/页脚编辑区域的虚线边框（参照 Word：紧贴可输入内容区域的矩形边框） */\r\n  drawZoneBorder(\r\n    layout: DocumentLayout,\r\n    scrollY: number,\r\n    zone: 'header' | 'footer',\r\n    pageOffsetX: number\r\n  ): void {\r\n    const ov = this.overlayCtx\r\n    ov.save()\r\n    ov.strokeStyle = this.opts.rulerColor\r\n    ov.lineWidth = 1\r\n    ov.setLineDash([4, 3])\r\n    for (const page of layout.pages) {\r\n      const rect = zone === 'header' ? page.headerRect : page.footerRect\r\n      if (!rect) continue\r\n      const pageBottom = page.rect.y + page.rect.height\r\n      if (pageBottom < scrollY || page.rect.y > scrollY + this.cssHeight) continue\r\n\r\n      const blocks = zone === 'header' ? page.headerBlocks : page.footerBlocks\r\n      // 虚线矩形紧贴可输入内容区域，并留出 4px 视觉间距：\r\n      // - 页眉：顶部在内容上方 4px，底部对齐边距区域下沿（正文顶部）\r\n      // - 页脚：顶部对齐边距区域上沿（正文底部），底部在内容下方 4px\r\n      const PADDING = 20\r\n      let top: number\r\n      let bottom: number\r\n      if (zone === 'header') {\r\n        bottom = rect.y + rect.height\r\n        if (blocks && blocks.length > 0) {\r\n          const contentTop = Math.min(...blocks.map(b => b.rect.y))\r\n          top = rect.y + contentTop - PADDING\r\n        } else {\r\n          top = rect.y\r\n        }\r\n      } else {\r\n        top = rect.y\r\n        if (blocks && blocks.length > 0) {\r\n          const contentBottom = Math.max(...blocks.map(b => b.rect.y + b.rect.height))\r\n          bottom = rect.y + contentBottom + PADDING\r\n        } else {\r\n          bottom = rect.y + rect.height\r\n        }\r\n      }\r\n\r\n      const x = Math.round(rect.x + pageOffsetX) + 0.5\r\n      const y = Math.round(top - scrollY) + 0.5\r\n      const w = Math.round(rect.width) - 1\r\n      const h = Math.max(0, Math.round(bottom - top) - 1)\r\n\r\n      // 只绘制三边虚线（靠近正文的一侧由贯穿整页的分隔虚线代替，避免重叠）：\r\n      // - 页眉：上 + 左 + 右（不画底部）\r\n      // - 页脚：下 + 左 + 右（不画顶部）\r\n      ov.beginPath()\r\n      if (zone === 'header') {\r\n        // 上边\r\n        ov.moveTo(x, y)\r\n        ov.lineTo(x + w, y)\r\n        // 左边\r\n        ov.moveTo(x, y)\r\n        ov.lineTo(x, y + h)\r\n        // 右边\r\n        ov.moveTo(x + w, y)\r\n        ov.lineTo(x + w, y + h)\r\n      } else {\r\n        // 下边\r\n        ov.moveTo(x, y + h)\r\n        ov.lineTo(x + w, y + h)\r\n        // 左边\r\n        ov.moveTo(x, y)\r\n        ov.lineTo(x, y + h)\r\n        // 右边\r\n        ov.moveTo(x + w, y)\r\n        ov.lineTo(x + w, y + h)\r\n      }\r\n      ov.stroke()\r\n\r\n      // 贯穿整页宽度的分隔虚线（页眉：正文顶部；页脚：正文底部）\r\n      const fullLineStartX = Math.round(page.rect.x + pageOffsetX) + 0.5\r\n      const fullLineEndX = fullLineStartX + Math.round(page.rect.width) - 1\r\n      const dividerY = zone === 'header'\r\n        ? Math.round(bottom - scrollY) + 0.5\r\n        : Math.round(top - scrollY) + 0.5\r\n      ov.beginPath()\r\n      ov.moveTo(fullLineStartX, dividerY)\r\n      ov.lineTo(fullLineEndX, dividerY)\r\n      ov.stroke()\r\n    }\r\n    ov.restore()\r\n  }\r\n\r\n\r\n  /**\r\n   * 渲染一帧。\r\n   *   - 视口过滤：只处理与视口相交的页\r\n   *   - block bitmap：按需构建（首次 / dirty）\r\n   *   - 主 canvas：clear + drawImage\r\n   */\r\n  render(layout: DocumentLayout, scrollY: number, viewportHeight: number, dirtyRect?: { x: number; y: number; width: number; height: number } | null): void {\r\n    this.currentLayout = layout\r\n    const ct = this.contentCtx\r\n    const w = this.cssWidth\r\n    const h = this.cssHeight\r\n    const pageCount = layout.pages.length\r\n    const aliveIds = new Set<number>()\r\n\r\n    // 脏区域合成：无重排局部变更时只清 + 重画脏区域，不重画 bg，跳过 GC\r\n    if (dirtyRect) {\r\n      if (dirtyRect.width <= 0 || dirtyRect.height <= 0) return\r\n\r\n      // Expand to physical pixel boundaries; rounding just the origin can leave\r\n      // partially cleared rows when a fractional-height header intersects a table.\r\n      const dpr = this.opts.dpr\r\n      const dx = Math.floor((dirtyRect.x + this.opts.pageOffsetX) * dpr) / dpr\r\n      const dy = Math.floor((dirtyRect.y - scrollY) * dpr) / dpr\r\n      const dw = Math.ceil((dirtyRect.x + dirtyRect.width + this.opts.pageOffsetX) * dpr) / dpr - dx\r\n      const dh = Math.ceil((dirtyRect.y + dirtyRect.height - scrollY) * dpr) / dpr - dy\r\n      const dTop = dirtyRect.y\r\n      const dBottom = dirtyRect.y + dirtyRect.height\r\n\r\n      ct.clearRect(dx, dy, dw, dh)\r\n      ct.save()\r\n      ct.beginPath()\r\n      ct.rect(dx, dy, dw, dh)\r\n      ct.clip()\r\n      for (const page of layout.pages) {\r\n        const pageBottom = page.rect.y + page.rect.height\r\n        if (pageBottom < dTop || page.rect.y > dBottom ||\r\n            pageBottom < scrollY || page.rect.y > scrollY + viewportHeight) continue\r\n        this.renderPageContent(ct, page, scrollY, pageCount, aliveIds)\r\n      }\r\n      ct.restore()\r\n      this.trimCache()\r\n      return\r\n    }\r\n\r\n    // 全量\r\n\r\n    ct.clearRect(0, 0, w, h)\r\n    const viewTop = scrollY\r\n    const viewBottom = scrollY + viewportHeight\r\n\r\n    this.renderBgDom(layout, scrollY, viewportHeight)\r\n\r\n    for (const page of layout.pages) {\r\n      const pageBottom = page.rect.y + page.rect.height\r\n      if (pageBottom < viewTop || page.rect.y > viewBottom) continue\r\n      this.renderPageContent(ct, page, scrollY, pageCount, aliveIds)\r\n    }\r\n\r\n    this.trimCache()\r\n  }\r\n\r\n  /** 渲染每页背景 DOM div（带 data-index 供协同光标定位） */\r\n  private renderBgDom(layout: DocumentLayout, scrollY: number, viewportHeight: number): void {\r\n    const viewTop = scrollY\r\n    const viewBottom = scrollY + viewportHeight\r\n    const alive = new Set<number>()\r\n    for (const page of layout.pages) {\r\n      const pageBottom = page.rect.y + page.rect.height\r\n      if (pageBottom < viewTop || page.rect.y > viewBottom) continue\r\n      alive.add(page.index)\r\n      let el = this.pageBgEls.get(page.index)\r\n      if (!el) {\r\n        el = document.createElement('div')\r\n        el.className = 'vd-page-bg'\r\n        el.dataset.index = String(page.index)\r\n        el.style.position = 'absolute'\r\n        el.style.boxShadow = `0 4px 12px ${this.opts.pageShadow}`\r\n        el.style.pointerEvents = 'none'\r\n        this.bgLayer.appendChild(el)\r\n        this.pageBgEls.set(page.index, el)\r\n      }\r\n      el.style.background = `var(--vd-eye-care-bg, ${this.opts.pageBg})`\r\n      el.style.left = `${Math.round(page.rect.x + this.opts.pageOffsetX)}px`\r\n      el.style.top = `${Math.round(page.rect.y - scrollY)}px`\r\n      el.style.width = `${page.rect.width}px`\r\n      el.style.height = `${page.rect.height}px`\r\n      if (this.opts.showMarginRuler) {\r\n        this.renderMarginRuler(el, page)\r\n      }\r\n    }\r\n    for (const [idx, el] of this.pageBgEls) {\r\n      if (!alive.has(idx)) { el.remove(); this.pageBgEls.delete(idx) }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 绘制 WPS 风格四角边距标尺（SVG，DOM）。内容区四角的角标朝外伸入页边距。\r\n   * 用签名缓存避免每帧重建 SVG。\r\n   */\r\n  private renderMarginRuler(el: HTMLDivElement, page: PageLayout): void {\r\n    const { width: pw, height: ph } = page.rect\r\n    const ml = page.contentRect.x - page.rect.x\r\n    const mt = page.contentRect.y - page.rect.y\r\n    const mr = pw - ml - page.contentRect.width\r\n    const mb = ph - mt - page.contentRect.height\r\n    const color = this.opts.rulerColor\r\n    const L = 20\r\n    const sig = `${pw}|${ph}|${ml}|${mr}|${mt}|${mb}|${color}`\r\n    if (el.dataset.rulerSig === sig) return\r\n    el.dataset.rulerSig = sig\r\n    const corners = [\r\n      `${ml - L},${mt} ${ml},${mt} ${ml},${mt - L}`,\r\n      `${pw - mr + L},${mt} ${pw - mr},${mt} ${pw - mr},${mt - L}`,\r\n      `${ml - L},${ph - mb} ${ml},${ph - mb} ${ml},${ph - mb + L}`,\r\n      `${pw - mr + L},${ph - mb} ${pw - mr},${ph - mb} ${pw - mr},${ph - mb + L}`\r\n    ]\r\n    el.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"position:absolute;inset:0;width:100%;height:100%;pointer-events:none\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1\">${corners.map(p => `<polyline points=\"${p}\"/>`).join('')}</svg>`\r\n  }\r\n\r\n  /** 渲染单页内容：blocks + 页眉 + 页脚 + 页码 + 水印 */\r\n  private renderPageContent(ct: CanvasRenderingContext2D, page: PageLayout, scrollY: number, pageCount: number, aliveIds: Set<number>): void {\r\n    const contentOriginX = page.contentRect.x + this.opts.pageOffsetX\r\n    const contentOriginY = page.contentRect.y - scrollY\r\n    const layer = (block: BlockNode): number => block.kind === 'image'\r\n      ? ((block.block as IImageElement).imgDisplay === 'float-bottom' ? -1 : (block.block as IImageElement).imageLayout?.anchored ? 1 : 0) : 0\r\n    for (const b of [...page.blocks].sort((a, b) => layer(a) - layer(b))) {\r\n      this.renderBlockOnMain(ct, b, contentOriginX, contentOriginY, aliveIds)\r\n    }\r\n    if (page.headerBlocks && page.headerRect) {\r\n      const hx = page.headerRect.x + this.opts.pageOffsetX\r\n      const hy = page.headerRect.y - scrollY\r\n      for (const b of page.headerBlocks) {\r\n        this.renderBlockOnMain(ct, b, hx, hy, aliveIds)\r\n      }\r\n    }\r\n    if (page.footerBlocks && page.footerRect) {\r\n      const fx = page.footerRect.x + this.opts.pageOffsetX\r\n      const fy = page.footerRect.y - scrollY\r\n      for (const b of page.footerBlocks) {\r\n        this.renderBlockOnMain(ct, b, fx, fy, aliveIds)\r\n      }\r\n    }\r\n    this.drawPageNumber(ct, page, scrollY, pageCount)\r\n    this.watermarkWidget?.drawWatermark(ct, page, scrollY)\r\n  }\r\n\r\n  /**\r\n   * 渲染单个 block 到主 content canvas：按需构建/复用位图，再 drawImage 落位。\r\n   * @param ctx 主 canvas 2d 上下文\r\n   * @param b 待渲染块\r\n   * @param originX 块所属内容区在 canvas 上的 x 原点\r\n   * @param originY 块所属内容区在 canvas 上的 y 原点（已应用 scrollY）\r\n   * @param aliveIds 收集本帧使用中的 block id，用于 GC 旧位图\r\n   */\r\n  private renderBlockOnMain(\r\n    ctx: CanvasRenderingContext2D,\r\n    b: BlockNode,\r\n    originX: number,\r\n    originY: number,\r\n    aliveIds: Set<number>\r\n  ): void {\r\n    aliveIds.add(b.id)\r\n    if (b.kind === 'pageBreak') return\r\n    if (b.kind === 'block') return\r\n    const bx = originX + b.rect.x\r\n    const by = originY + b.rect.y\r\n\r\n    // 分割线：直接在主 canvas 上按样式画线（简单图形，不走 bitmap 缓存）\r\n    if (b.kind === 'separator') {\r\n      this.drawSeparator(ctx, b, bx, by)\r\n      return\r\n    }\r\n\r\n    // table 不做整表 bitmap（cell 内容可能常变），直接递归绘制到主 canvas\r\n    if (b.kind === 'table') {\r\n      this.drawTable(ctx, b, bx, by, aliveIds)\r\n      return\r\n    }\r\n\r\n    // 其它块使用 block bitmap 缓存\r\n    const cache = this.blockCache.get(b.id)\r\n    const needRebuild = !cache || this.dirtyBlocks.has(b.id) ||\r\n      Math.round(cache.width) !== Math.round(b.rect.width) ||\r\n      Math.round(cache.height) !== Math.round(b.rect.height) ||\r\n      cache.dpr !== this.opts.dpr\r\n\r\n    let bitmap: HTMLCanvasElement | ImageBitmap | null\r\n    if (needRebuild) {\r\n      if (cache?.bitmap instanceof ImageBitmap) cache.bitmap.close()\r\n      bitmap = this.buildBlockBitmap(b)\r\n      this.blockCache.set(b.id, {\r\n        id: b.id,\r\n        bitmap,\r\n        width: b.rect.width,\r\n        height: b.rect.height,\r\n        dpr: this.opts.dpr\r\n      })\r\n      this.dirtyBlocks.delete(b.id)\r\n    } else {\r\n      bitmap = cache!.bitmap\r\n      this.blockCache.delete(b.id)\r\n      this.blockCache.set(b.id, cache!)\r\n    }\r\n    if (bitmap) {\r\n      ctx.drawImage(bitmap, Math.round(bx), Math.round(by), b.rect.width, b.rect.height)\r\n    }\r\n  }\r\n\r\n\r\n  /** 绘制分割线，按元素上的 lineType/lineWidth/dashArray/color 渲染 */\r\n  private drawSeparator(ctx: CanvasRenderingContext2D, b: SeparatorBlock, bx: number, by: number): void {\r\n    const anyBlock = b.block as unknown as Record<string, unknown>\r\n    const lineType = (anyBlock.lineType as string) || 'solid'\r\n    const lineWidth = Number(anyBlock.lineWidth ?? 1)\r\n    const dashArray = Array.isArray(anyBlock.dashArray) ? (anyBlock.dashArray as number[]) : [0, 0]\r\n    const color = (anyBlock.color as string) || '#9e9e9e'\r\n    const x0 = Math.round(bx)\r\n    const x1 = Math.round(bx + b.rect.width)\r\n    const cy = by + Math.round(b.rect.height / 2)\r\n\r\n    ctx.save()\r\n    ctx.strokeStyle = color\r\n    ctx.lineWidth = lineWidth\r\n    ctx.lineCap = 'butt'\r\n\r\n    if (lineType === 'wavy') {\r\n      // 波浪线：用正弦近似，振幅随线宽\r\n      const amp = Math.max(1.5, lineWidth * 1.5)\r\n      const wave = 6\r\n      ctx.beginPath()\r\n      for (let x = x0; x <= x1; x += 1) {\r\n        const y = cy + amp * Math.sin(((x - x0) / wave) * Math.PI)\r\n        if (x === x0) { ctx.moveTo(x, y) } else { ctx.lineTo(x, y) }\r\n      }\r\n      ctx.stroke()\r\n    } else if (lineType === 'double' || lineType === 'triple') {\r\n      const gap = Math.max(2, lineWidth + 1.5)\r\n      const lines = lineType === 'triple' ? [-gap, 0, gap] : [-gap / 2, gap / 2]\r\n      ctx.setLineDash(dashArray)\r\n      for (const off of lines) {\r\n        ctx.beginPath()\r\n        ctx.moveTo(x0, Math.round(cy + off) + 0.5)\r\n        ctx.lineTo(x1, Math.round(cy + off) + 0.5)\r\n        ctx.stroke()\r\n      }\r\n    } else if (lineType === 'shadow') {\r\n      // 阴影线：主线下方画一条浅色偏移线\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy) + 0.5)\r\n      ctx.stroke()\r\n      ctx.strokeStyle = 'rgba(0,0,0,0.25)'\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy + 1.5) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy + 1.5) + 0.5)\r\n      ctx.stroke()\r\n    } else if (lineType === 'emboss') {\r\n      // 浮雕线：上亮下暗\r\n      ctx.strokeStyle = 'rgba(255,255,255,0.8)'\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy - 0.75) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy - 0.75) + 0.5)\r\n      ctx.stroke()\r\n      ctx.strokeStyle = 'rgba(0,0,0,0.5)'\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy + 0.75) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy + 0.75) + 0.5)\r\n      ctx.stroke()\r\n    } else if (lineType === 'gradient') {\r\n      // 渐变线：左透明右实色\r\n      const grad = ctx.createLinearGradient(x0, 0, x1, 0)\r\n      grad.addColorStop(0, 'rgba(158,158,158,0)')\r\n      grad.addColorStop(1, color)\r\n      ctx.strokeStyle = grad\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy) + 0.5)\r\n      ctx.stroke()\r\n    } else {\r\n      // solid / dotted / dashed\r\n      ctx.setLineDash(dashArray)\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy) + 0.5)\r\n      ctx.stroke()\r\n    }\r\n    ctx.restore()\r\n  }\r\n\r\n  /**\r\n   * 为单个 block 构建独立位图（paragraph/image）。\r\n   * 优先使用 OffscreenCanvas + transferToImageBitmap（零拷贝），不支持时降级 HTMLCanvasElement。\r\n   * @param b 待构建块（仅处理 paragraph/image，其它类型返回空位图）\r\n   * @returns 渲染好块内容的 ImageBitmap 或 canvas 元素\r\n   */\r\n  private buildBlockBitmap(b: BlockNode): HTMLCanvasElement | ImageBitmap {\r\n    const dpr = this.opts.dpr\r\n    const w = Math.max(1, Math.ceil(b.rect.width))\r\n    const h = Math.max(1, Math.ceil(b.rect.height))\r\n    const pw = Math.max(1, Math.round(w * dpr))\r\n    const ph = Math.max(1, Math.round(h * dpr))\r\n\r\n    let ctx: PaintCtx\r\n    let off: OffscreenCanvas | null = null\r\n    let c: HTMLCanvasElement | null = null\r\n    if (typeof OffscreenCanvas !== 'undefined') {\r\n      off = new OffscreenCanvas(pw, ph)\r\n      ctx = off.getContext('2d')!\r\n    } else {\r\n      c = document.createElement('canvas')\r\n      c.width = pw\r\n      c.height = ph\r\n      ctx = c.getContext('2d')!\r\n    }\r\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n\r\n    if (b.kind === 'paragraph') {\r\n      if (b.surroundImage) {\r\n        const si = b.surroundImage\r\n        const sx = si.rect.x\r\n        const sy = 0\r\n        const mode = String((si.block as unknown as { imgDisplay?: string }).imgDisplay ?? 'surround')\r\n        if (mode === 'float-bottom') {\r\n          this.drawImageInto(ctx, si, sx, sy)\r\n          this.drawParagraphInto(ctx, b)\r\n        } else {\r\n          this.drawParagraphInto(ctx, b)\r\n          if (mode === 'surround') {\r\n            ctx.clearRect(sx, sy, si.rect.width, si.rect.height)\r\n          }\r\n          this.drawImageInto(ctx, si, sx, sy)\r\n        }\r\n      } else {\r\n        this.drawParagraphInto(ctx, b)\r\n      }\r\n    }\r\n    else if (b.kind === 'image') this.drawImageInto(ctx, b, 0, 0)\r\n    else if (b.kind === 'chart') this.drawChartInto(ctx, b, 0, 0)\r\n\r\n    if (off) return off.transferToImageBitmap()\r\n    return c!\r\n  }\r\n\r\n  /**\r\n   * 将段落块绘制到目标 ctx：委托共享纯函数 paintParagraph。\r\n   * @param ctx 目标 2d 上下文\r\n   * @param b 段落块\r\n   */\r\n  private drawParagraphInto(ctx: PaintCtx, b: ParagraphBlock): void {\r\n    paintParagraph(ctx, b, { groupColors: this.opts.groupColors, activeGroupId: this.opts.activeGroupId, activeRevision: this.activeRevision })\r\n  }\r\n\r\n\r\n  /**\r\n   * 将图片块绘制到目标 ctx：异步加载图片，加载完成后触发重绘；支持 90/180/270 旋转。\r\n   * @param ctx 目标 2d 上下文\r\n   * @param b 图片块\r\n   * @param x 绘制左上角 x\r\n   * @param y 绘制左上角 y\r\n   */\r\n  private drawImageInto(ctx: PaintCtx, b: ImageBlock, x: number, y: number): void {\r\n    const url = String((b.block as unknown as { value?: string }).value ?? '')\r\n    if (!url) return\r\n    let img = this.imageCache.get(url)\r\n    if (!img) {\r\n      img = new Image()\r\n      img.crossOrigin = 'anonymous'\r\n      img.onload = () => {\r\n        // 图片加载完成 → 使该 block 失效 + 触发全局重绘\r\n        this.invalidateAll()\r\n        this.container.dispatchEvent(new CustomEvent('vervedocs:image-loaded', { detail: { url } }))\r\n      }\r\n      img.src = url\r\n      this.imageCache.set(url, img)\r\n    }\r\n    const image = b.block as IImageElement\r\n    const transform = image.imageLayout?.transform?.attributes\r\n    const rotate = Number(transform?.rot ?? (image.rotate ?? 0) * 60000) / 60000\r\n    if (img.complete && img.naturalWidth > 0) {\r\n      const crop = image.imageLayout?.crop?.attributes\r\n      const l = Number(crop?.l ?? 0) / 100000\r\n      const t = Number(crop?.t ?? 0) / 100000\r\n      const r = Number(crop?.r ?? 0) / 100000\r\n      const bottom = Number(crop?.b ?? 0) / 100000\r\n      const dw = image.width\r\n      const dh = image.height\r\n      ctx.save()\r\n      try {\r\n        ctx.translate(x + b.rect.width / 2, y + b.rect.height / 2)\r\n        ctx.rotate((rotate * Math.PI) / 180)\r\n        ctx.scale(transform?.flipH === '1' || transform?.flipH === 'true' ? -1 : 1,\r\n          transform?.flipV === '1' || transform?.flipV === 'true' ? -1 : 1)\r\n        ctx.beginPath()\r\n        ctx.rect(-dw / 2, -dh / 2, dw, dh)\r\n        ctx.clip()\r\n        const scaledWidth = dw / (1 - l - r)\r\n        const scaledHeight = dh / (1 - t - bottom)\r\n        ctx.drawImage(img, -dw / 2 - l * scaledWidth, -dh / 2 - t * scaledHeight, scaledWidth, scaledHeight)\r\n      } finally {\r\n        ctx.restore()\r\n      }\r\n    } else {\r\n      ctx.strokeStyle = '#cccccc'\r\n      ctx.strokeRect(x + 0.5, y + 0.5, b.rect.width - 1, b.rect.height - 1)\r\n      ctx.fillStyle = '#f5f5f5'\r\n      ctx.fillRect(x, y, b.rect.width, b.rect.height)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将图表块绘制到目标 ctx：从 chartBlock 数据生成 dataUrl，加载为 Image 后 drawImage。\r\n   * 数据源变更时由 signBlock 触发 bitmap 重建。\r\n   */\r\n  private drawChartInto(ctx: PaintCtx, b: ChartBlock, x: number, y: number): void {\r\n    const el = b.block as unknown as {\r\n      id?: string\r\n      block?: { chartBlock?: Record<string, unknown> }\r\n    }\r\n    const chartBlock = el.block?.chartBlock\r\n    if (!chartBlock) return\r\n\r\n    const renderer = this.chartRenderer\r\n    if (!renderer) {\r\n      ctx.strokeStyle = '#cccccc'\r\n      ctx.strokeRect(x + 0.5, y + 0.5, b.rect.width - 1, b.rect.height - 1)\r\n      ctx.fillStyle = '#f5f5f5'\r\n      ctx.fillRect(x, y, b.rect.width, b.rect.height)\r\n      ctx.fillStyle = '#999'\r\n      ctx.font = '14px sans-serif'\r\n      ctx.textAlign = 'center'\r\n      ctx.textBaseline = 'middle'\r\n      ctx.fillText('图表插件未加载', x + b.rect.width / 2, y + b.rect.height / 2)\r\n      return\r\n    }\r\n\r\n    const dependency = this.currentLayout ? chartTableSignature(b, this.currentLayout) : ''\r\n    const cacheKey = `chart|${el.id ?? ''}|${b.rect.width}x${b.rect.height}|${JSON.stringify(chartBlock)}|${dependency}`\r\n    let img = this.imageCache.get(cacheKey)\r\n    if (!img) {\r\n      const option = this.getChartOption(chartBlock, renderer)\r\n      const width = Math.max(10, Math.round(b.rect.width))\r\n      const height = Math.max(10, Math.round(b.rect.height))\r\n      const dataUrl = renderer.renderToDataUrl(option, width, height, 2)\r\n      img = new Image()\r\n      img.onload = () => {\r\n        this.invalidateAll()\r\n        this.container.dispatchEvent(new CustomEvent('vervedocs:chart-loaded', { detail: { id: el.id } }))\r\n      }\r\n      img.src = dataUrl\r\n      this.imageCache.set(cacheKey, img)\r\n    }\r\n\r\n    if (img.complete && img.naturalWidth > 0) {\r\n      try {\r\n        ctx.drawImage(img, x, y, b.rect.width, b.rect.height)\r\n      } catch { /* ignore */ }\r\n    } else {\r\n      ctx.strokeStyle = '#cccccc'\r\n      ctx.strokeRect(x + 0.5, y + 0.5, b.rect.width - 1, b.rect.height - 1)\r\n      ctx.fillStyle = '#f5f5f5'\r\n      ctx.fillRect(x, y, b.rect.width, b.rect.height)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 根据图表数据源生成图表配置选项。\r\n   * manual 数据直接使用；table 数据从布局中查找对应表格元素提取。\r\n   */\r\n  private getChartOption(chartBlock: Record<string, unknown>, renderer: IChartRenderer): any {\r\n    const { dataSource, chartType, config, subtype } = chartBlock as {\r\n      dataSource: { type: string; manualData?: any; tableId?: string; range?: any }\r\n      chartType: string\r\n      config?: any\r\n      subtype?: string\r\n    }\r\n\r\n    if (dataSource?.type === 'manual' && dataSource.manualData) {\r\n      return renderer!.generateOption(chartType, dataSource.manualData, config, subtype)\r\n    }\r\n\r\n    if (dataSource?.type === 'table' && dataSource.tableId && this.currentLayout) {\r\n      for (const page of this.currentLayout.pages) {\r\n        for (const blk of page.blocks) {\r\n          if (blk.kind === 'table') {\r\n            const tableEl = blk.block as unknown as { type?: string; id?: string }\r\n            if (tableEl.type === 'table' && tableEl.id === dataSource.tableId) {\r\n              const tableData = renderer!.extractTableData(tableEl, dataSource.range)\r\n              return renderer!.generateOption(chartType, tableData, config, subtype)\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    return {\r\n      type: 'bar',\r\n      data: { labels: [], datasets: [] },\r\n      options: { plugins: { title: { display: true, text: '暂无数据' } } }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 绘制表格块到主 canvas：依次绘制单元格背景色、单元格内容、统一边框（共享边去重）与斜线。\r\n   * @param ctx 主 canvas 2d 上下文\r\n   * @param b 表格块\r\n   * @param bx 表格左上角在 canvas 上的 x\r\n   * @param by 表格左上角在 canvas 上的 y\r\n   * @param aliveIds 收集本帧使用中的 block id，用于 GC\r\n   */\r\n  private drawTable(\r\n    ctx: CanvasRenderingContext2D,\r\n    b: TableBlock,\r\n    bx: number,\r\n    by: number,\r\n    aliveIds: Set<number>\r\n  ): void {\r\n    // 1) 先绘制所有单元格背景色（如有）\r\n    for (const row of b.rows) {\r\n      for (const cell of row.cells) {\r\n        const bg = (cell.cell as unknown as { backgroundColor?: string }).backgroundColor\r\n        if (bg) {\r\n          const cx = Math.round(bx + cell.rect.x)\r\n          const cy = Math.round(by + cell.rect.y)\r\n          const cw = Math.round(cell.rect.width)\r\n          const ch = Math.round(cell.rect.height)\r\n          ctx.fillStyle = bg\r\n          ctx.fillRect(cx, cy, cw, ch)\r\n        }\r\n      }\r\n    }\r\n    // 2) 绘制单元格内容（不含边框）\r\n    for (const row of b.rows) {\r\n      for (const cell of row.cells) {\r\n        const cx = bx + cell.rect.x\r\n        const cy = by + cell.rect.y\r\n        const contentX = cx + cell.contentPaddingLeft\r\n        const contentY = cy + cell.contentPaddingTop + cell.verticalOffset\r\n        for (const cb of cell.content) {\r\n          this.renderBlockOnMain(ctx, cb, contentX, contentY, aliveIds)\r\n        }\r\n      }\r\n    }\r\n    // 3) 统一绘制边框（每条网格边只画一次，避免共享边被重复描绘制造成\"边框加深/重影\"）\r\n    // 用\"边端点 + 方向\"做去重：相邻两个 cell 的共享边、跨行格下探边都会折叠为一条。\r\n    // 像素对齐沿用 strokeSide（奇数宽 +0.5）。\r\n    type BorderSide = { width: number; color: string; style: string; officeType?: string; source?: string; sizeEighthPoints?: number }\r\n    type Edge = { x1: number; y1: number; x2: number; y2: number; side: BorderSide }\r\n    const edges: Edge[] = []\r\n    const edgeKey = (x1: number, y1: number, x2: number, y2: number): string => {\r\n      // 归一化端点（保证横边/竖边方向唯一），保留 0.5px 精度避免浮点抖动\r\n      const a1 = Math.round(x1 * 2) / 2, b1 = Math.round(y1 * 2) / 2\r\n      const a2 = Math.round(x2 * 2) / 2, b2 = Math.round(y2 * 2) / 2\r\n      if (a1 === a2 && b1 === b2) return ''\r\n      // 竖边：x 相同，按 y 排序；横边：y 相同，按 x 排序\r\n      if (a1 === a2) return `V${a1}:${Math.min(b1, b2)}-${Math.max(b1, b2)}`\r\n      return `H${b1}:${Math.min(a1, a2)}-${Math.max(a1, a2)}`\r\n    }\r\n    const drawOnce = (\r\n      x1: number, y1: number, x2: number, y2: number,\r\n      side?: BorderSide\r\n    ) => {\r\n      // 该侧无边框定义 → 不画且不占用去重 key（否则会挡住邻格共享边的绘制）\r\n      if (!side || side.style === 'none' || side.width <= 0) return\r\n      if (edgeKey(x1, y1, x2, y2)) edges.push({ x1, y1, x2, y2, side })\r\n    }\r\n    // 每个 cell 四条边都尝试绘制（数据中共享边可能只由某一侧的格子定义，\r\n    // 例如附表5：水平分隔线只定义在上格的 bottom，下格无 top），\r\n    // 共享边由先遍历到的格子画出，后到的经 drawnEdges 去重跳过。\r\n    for (const row of b.rows) {\r\n      for (const cell of row.cells) {\r\n        const cx = bx + cell.rect.x\r\n        const cy = by + cell.rect.y\r\n        const cw = cell.rect.width\r\n        const ch = cell.rect.height\r\n        const bs = cell.cell.borderStyle ?? {}\r\n        // borderTypes: [top,right,bottom,left]，值为 0 表示隐藏该侧（三线表等场景）\r\n        const bt = (cell.cell as unknown as { borderTypes?: number[] }).borderTypes\r\n        const showTop    = !bt || bt[0] !== 0\r\n        const showRight  = !bt || bt[1] !== 0\r\n        const showBottom = !bt || bt[2] !== 0\r\n        const showLeft   = !bt || bt[3] !== 0\r\n        if (showTop)    drawOnce(cx, cy, cx + cw, cy, bs.top)              // 顶边\r\n        if (showBottom) drawOnce(cx, cy + ch, cx + cw, cy + ch, bs.bottom) // 底边\r\n        if (showLeft)   drawOnce(cx, cy, cx, cy + ch, bs.left)             // 左边\r\n        if (showRight)  drawOnce(cx + cw, cy, cx + cw, cy + ch, bs.right)  // 右边\r\n        // slashTypes: 单元格斜线（斜表头）\r\n        const slashes = (cell.cell as unknown as { slashTypes?: string[] }).slashTypes\r\n        if (slashes && slashes.length > 0) {\r\n          const side = bs.top ?? bs.bottom ?? bs.left ?? bs.right\r\n          const color = side?.color ?? '#000000'\r\n          const width = side?.width ?? 1\r\n          ctx.save()\r\n          ctx.strokeStyle = color\r\n          ctx.lineWidth = width\r\n          for (const s of slashes) {\r\n            ctx.beginPath()\r\n            if (s === 'forward') {\r\n              // '/'：左下 -> 右上\r\n              ctx.moveTo(cx + 0.5, cy + ch + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + 0.5)\r\n            } else if (s === 'backward') {\r\n              // '\\'：左上 -> 右下\r\n              ctx.moveTo(cx + 0.5, cy + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + ch + 0.5)\r\n            } else if (s === 'cross') {\r\n              // '×'：两条对角线\r\n              ctx.moveTo(cx + 0.5, cy + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + ch + 0.5)\r\n              ctx.moveTo(cx + 0.5, cy + ch + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + 0.5)\r\n            }\r\n            ctx.stroke()\r\n          }\r\n          ctx.restore()\r\n        }\r\n      }\r\n    }\r\n    const groups = new Map<string, Edge[]>()\r\n    for (const edge of edges) {\r\n      const vertical = edge.x1 === edge.x2\r\n      const key = `${vertical ? 'V' : 'H'}:${Math.round((vertical ? edge.x1 : edge.y1) * 2) / 2}`\r\n      const group = groups.get(key) ?? []\r\n      group.push(edge)\r\n      groups.set(key, group)\r\n    }\r\n    const rank: Record<string, number> = { solid: 1, single: 1, thick: 2, double: 3, dotted: 4, dashed: 5, dotDash: 6, dotDotDash: 7, triple: 8, thinThickSmallGap: 9, thickThinSmallGap: 10, thinThickThinSmallGap: 11, thinThickMediumGap: 12, thickThinMediumGap: 13, thinThickThinMediumGap: 14, thinThickLargeGap: 15, thickThinLargeGap: 16, thinThickThinLargeGap: 17, wave: 18, doubleWave: 19, dashSmallGap: 20, dashDotStroked: 21, threeDEmboss: 22, threeDEngrave: 23, outset: 24, inset: 25 }\r\n    const borderRank = (side: BorderSide) => rank[side.officeType ?? side.style] ?? 1\r\n    const borderWeight = (side: BorderSide) => (side.sizeEighthPoints ?? side.width * 6) * borderRank(side)\r\n    const brightness = (color: string): number => {\r\n      const rgb = Number.parseInt(color.replace('#', ''), 16)\r\n      return (rgb >> 16 & 255) + 2 * (rgb >> 8 & 255) + (rgb & 255)\r\n    }\r\n    const secondaryBrightness = (color: string): number => {\r\n      const rgb = Number.parseInt(color.slice(1), 16)\r\n      return (rgb >> 16 & 255) + 2 * (rgb >> 8 & 255)\r\n    }\r\n    for (const group of groups.values()) {\r\n      const vertical = group[0].x1 === group[0].x2\r\n      const start = (edge: Edge) => vertical ? Math.min(edge.y1, edge.y2) : Math.min(edge.x1, edge.x2)\r\n      const end = (edge: Edge) => vertical ? Math.max(edge.y1, edge.y2) : Math.max(edge.x1, edge.x2)\r\n      const points = [...new Set(group.flatMap(edge => [start(edge), end(edge)]))].sort((a, b) => a - b)\r\n      for (let index = 1; index < points.length; index++) {\r\n        const a = points[index - 1], b = points[index]\r\n        const candidates = group.filter(edge => start(edge) <= a && end(edge) >= b)\r\n        candidates.sort((a, b) => Number(b.side.source === 'cell') - Number(a.side.source === 'cell')\r\n          || borderWeight(b.side) - borderWeight(a.side)\r\n          || borderRank(b.side) - borderRank(a.side) || brightness(a.side.color) - brightness(b.side.color)\r\n          || secondaryBrightness(a.side.color) - secondaryBrightness(b.side.color)\r\n          || (Number.parseInt(a.side.color.slice(1), 16) >> 8 & 255) - (Number.parseInt(b.side.color.slice(1), 16) >> 8 & 255))\r\n        const winner = candidates[0]\r\n        if (!winner) continue\r\n        if (vertical) strokeSide(ctx, winner.x1, a, winner.x1, b, winner.side)\r\n        else strokeSide(ctx, a, winner.y1, b, winner.y1, winner.side)\r\n      }\r\n    }\r\n  }\r\n\r\n  /* -------------------- 边距标尺（WPS 风格） -------------------- */\r\n\r\n\r\n}\r\n\r\n/* -------------------- 工具 -------------------- */\r\n\r\n/**\r\n\r\n * 绘制一条带样式的边：支持 solid/dashed/dotted/double，并对奇数宽度做 0.5px 像素对齐。\r\n * @param ctx 目标 2d 上下文\r\n * @param x1 起点 x\r\n * @param y1 起点 y\r\n * @param x2 终点 x\r\n * @param y2 终点 y\r\n * @param side 边样式（宽/色/风格）\r\n */\r\nfunction strokeSide(\r\n  ctx: CanvasRenderingContext2D,\r\n  x1: number, y1: number, x2: number, y2: number,\r\n  side: { width: number; color: string; style: string }\r\n): void {\r\n  if (!side || side.style === 'none' || side.width <= 0) return\r\n  const w = side.width\r\n  // 像素对齐：奇数宽度用 +0.5，偶数宽度用 +0\r\n  const halfOffset = (w % 2 === 1) ? 0.5 : 0\r\n  ctx.save()\r\n  ctx.strokeStyle = side.color\r\n  ctx.lineWidth = w\r\n  // dashed / dotted 样式\r\n  switch (side.style) {\r\n    case 'dashed': ctx.setLineDash([Math.max(2, w * 3), Math.max(2, w * 2)]); break\r\n    case 'dotted': ctx.setLineDash([w, Math.max(2, w * 2)]); break\r\n    case 'double': {\r\n      // 双线：绘制两条平行线（简单实现）\r\n      const gap = Math.max(1, w)\r\n      ctx.lineWidth = 1\r\n      const off = halfOffset\r\n      ctx.beginPath()\r\n      if (y1 === y2) {\r\n        ctx.moveTo(Math.round(x1), Math.round(y1) + off - gap / 2)\r\n        ctx.lineTo(Math.round(x2), Math.round(y2) + off - gap / 2)\r\n        ctx.moveTo(Math.round(x1), Math.round(y1) + off + gap / 2)\r\n        ctx.lineTo(Math.round(x2), Math.round(y2) + off + gap / 2)\r\n      } else {\r\n        ctx.moveTo(Math.round(x1) + off - gap / 2, Math.round(y1))\r\n        ctx.lineTo(Math.round(x2) + off - gap / 2, Math.round(y2))\r\n        ctx.moveTo(Math.round(x1) + off + gap / 2, Math.round(y1))\r\n        ctx.lineTo(Math.round(x2) + off + gap / 2, Math.round(y2))\r\n      }\r\n      ctx.stroke()\r\n      ctx.restore()\r\n      return\r\n    }\r\n    default: ctx.setLineDash([])\r\n  }\r\n  ctx.beginPath()\r\n  ctx.moveTo(Math.round(x1) + halfOffset, Math.round(y1) + halfOffset)\r\n  ctx.lineTo(Math.round(x2) + halfOffset, Math.round(y2) + halfOffset)\r\n  ctx.stroke()\r\n  ctx.restore()\r\n}\r\n","/**\r\n * VerveDocs View —— HitTest\r\n *\r\n * 屏幕坐标 -> IPosition。\r\n * 新坐标系：block/table/cell 均使用相对父容器坐标；命中时递归传入原点。\r\n */\r\n\r\nimport type { IPosition, Path } from '@vervedoc/docx-editor-schema'\r\nimport type { BlockNode, DocumentLayout, LineBox, ParagraphBlock, TableBlock } from './layout-types'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\nimport { getSharedMeasure } from './text-measure'\r\n\r\n/**\r\n * 命中测试主入口：根据文档坐标（未减 scrollY）返回对应位置。\r\n * @param layout 文档布局\r\n * @param docX 文档 X 坐标\r\n * @param docY 文档 Y 坐标\r\n * @param zone 当前编辑区域，默认 'main'；'header'/'footer' 时仅命中对应区域块\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nexport function hitTest(layout: DocumentLayout, docX: number, docY: number, zone: Zone = 'main'): IPosition | null {\r\n  for (const page of layout.pages) {\r\n    if (docY < page.rect.y || docY > page.rect.y + page.rect.height) continue\r\n    let blocks: BlockNode[]\r\n    let originX: number\r\n    let originY: number\r\n    if (zone === 'header' && page.headerBlocks && page.headerRect) {\r\n      if (docY < page.headerRect.y || docY > page.headerRect.y + page.headerRect.height) return null\r\n      blocks = page.headerBlocks\r\n      originX = page.headerRect.x\r\n      originY = page.headerRect.y\r\n    } else if (zone === 'footer' && page.footerBlocks && page.footerRect) {\r\n      if (docY < page.footerRect.y || docY > page.footerRect.y + page.footerRect.height) return null\r\n      blocks = page.footerBlocks\r\n      originX = page.footerRect.x\r\n      originY = page.footerRect.y\r\n    } else {\r\n      blocks = page.blocks\r\n      originX = page.contentRect.x\r\n      originY = page.contentRect.y\r\n    }\r\n    const p = hitBlocks(blocks, docX, docY, originX, originY)\r\n    if (p) return p\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在指定原点偏移下遍历块列表进行命中测试。\r\n * @param blocks 块节点列表\r\n * @param x 文档 X 坐标\r\n * @param y 文档 Y 坐标\r\n * @param ox 父容器原点 X\r\n * @param oy 父容器原点 Y\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nfunction hitBlocks(blocks: BlockNode[], x: number, y: number, ox: number, oy: number): IPosition | null {\r\n  for (const b of blocks) {\r\n    const bx = ox + b.rect.x\r\n    const by = oy + b.rect.y\r\n    if (y < by || y > by + b.rect.height) continue\r\n    if (b.kind === 'paragraph') {\r\n      if (b.surroundImage) {\r\n        const si = b.surroundImage\r\n        const six = bx + si.rect.x\r\n        if (x >= six && x <= six + si.rect.width && y >= by && y <= by + si.rect.height) {\r\n          const p: Path = [...si.parentPath, si.indexInParent]\r\n          return { path: p, offset: 0 }\r\n        }\r\n      }\r\n      const r = hitParagraph(b, x - bx, y - by, b)\r\n      if (r) return r\r\n    } else if (b.kind === 'table') {\r\n      const r = hitTable(b, x, y, bx, by)\r\n      if (r) return r\r\n    } else if (b.kind === 'image') {\r\n      const p: Path = [...b.parentPath, b.indexInParent]\r\n      return { path: p, offset: 0 }\r\n    } else if (b.kind === 'block') {\r\n      const p: Path = [...b.parentPath, b.indexInParent]\r\n      return { path: p, offset: 0 }\r\n    } else if (b.kind === 'chart') {\r\n      const p: Path = [...b.parentPath, b.indexInParent]\r\n      return { path: p, offset: 0 }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在段落内进行命中测试，返回所在行的命中位置。\r\n * @param b 段落块\r\n * @param lx 相对块本地 X 坐标\r\n * @param ly 相对块本地 Y 坐标\r\n * @param _pb 段落块（保留参数，当前未使用）\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nfunction hitParagraph(b: ParagraphBlock, lx: number, ly: number, _pb: ParagraphBlock): IPosition | null {\r\n  for (const line of b.lines) {\r\n    if (ly < line.y || ly > line.y + line.height) continue\r\n    return hitLine(line, lx)\r\n  }\r\n  const last = b.lines[b.lines.length - 1]\r\n  if (last) return hitLine(last, lx)\r\n  return null\r\n}\r\n\r\n/**\r\n * 在单行内进行命中测试，按字符宽度逐字定位光标偏移。\r\n * @param line 行盒\r\n * @param lx 相对块本地 X 坐标\r\n * @returns 命中位置；空行返回 null\r\n */\r\nfunction hitLine(line: LineBox, lx: number): IPosition | null {\r\n  if (line.inlines.length === 0) return null\r\n  const measure = getSharedMeasure()\r\n  for (const inl of line.inlines) {\r\n    if (lx >= inl.x && lx <= inl.x + inl.width) {\r\n      if (inl.text === '\\t' && (inl.run.extension?.toc as { role?: string } | undefined)?.role === 'entry') {\r\n        return { path: inl.path, offset: lx < inl.x + inl.width / 2 ? inl.startOffset : inl.endOffset }\r\n      }\r\n      let cursor = inl.x\r\n      const ls = inl.letterSpacing ?? 0\r\n      for (let i = 0; i < inl.text.length; i++) {\r\n        const ch = inl.text[i]\r\n        const cw = measure.charWidth(ch, inl.font, inl.size, inl.bold, inl.italic) + ls\r\n        if (lx < cursor + cw / 2) return { path: inl.path, offset: inl.startOffset + i }\r\n        cursor += cw\r\n      }\r\n      return { path: inl.path, offset: inl.endOffset }\r\n    }\r\n  }\r\n  const first = line.inlines[0]\r\n  const last = line.inlines[line.inlines.length - 1]\r\n  if (lx < first.x) return { path: first.path, offset: first.startOffset }\r\n  return { path: last.path, offset: last.endOffset }\r\n}\r\n\r\n/**\r\n * 在表格内进行命中测试，递归进入命中的单元格内容。\r\n * @param b 表格块\r\n * @param x 文档 X 坐标\r\n * @param y 文档 Y 坐标\r\n * @param tbx 表格原点 X\r\n * @param tby 表格原点 Y\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nfunction hitTable(b: TableBlock, x: number, y: number, tbx: number, tby: number): IPosition | null {\r\n  for (const row of b.rows) {\r\n    const ry = tby + row.rect.y\r\n    if (y < ry || y > ry + row.rect.height) continue\r\n    for (const cell of row.cells) {\r\n      const cx = tbx + cell.rect.x\r\n      if (x < cx || x > cx + cell.rect.width) continue\r\n      const contentOX = cx + cell.contentPaddingLeft\r\n      const contentOY = ry + cell.contentPaddingTop + cell.verticalOffset\r\n      const r = hitBlocks(cell.content, x, y, contentOX, contentOY)\r\n      if (r) return r\r\n      return { path: cell.contentPath.concat(0), offset: 0 }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n","/**\r\n * VerveDocs View —— CaretRect\r\n *\r\n * 由 IPosition -> 屏幕坐标的光标矩形（文档坐标系，未减 scrollY）。\r\n * 用于绘制光标闪烁与选区。\r\n */\r\n\r\nimport type { IPosition, Path } from '@vervedoc/docx-editor-schema'\r\nimport { isSamePath, comparePosition } from '@vervedoc/docx-editor-schema'\r\nimport type {\r\n  BlockNode, DocumentLayout, ParagraphBlock, TableBlock, InlineBox\r\n} from './layout-types'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\nimport { getSharedMeasure } from './text-measure'\r\n\r\n/**\r\n * 光标矩形（文档坐标系，未减 scrollY），用于绘制光标闪烁。\r\n */\r\nexport interface CaretRect {\r\n  /** 文档坐标（未减 scrollY） */\r\n  x: number\r\n  y: number\r\n  /** 光标高度 = line.height */\r\n  height: number\r\n}\r\n\r\n/**\r\n * 选区矩形（文档坐标系，未减 scrollY），用于绘制选区高亮。\r\n */\r\nexport interface SelectionRect {\r\n  /** 文档坐标 X（未减 scrollY） */\r\n  x: number\r\n  /** 文档坐标 Y（未减 scrollY） */\r\n  y: number\r\n  /** 矩形宽度 */\r\n  width: number\r\n  /** 矩形高度 = line.height */\r\n  height: number\r\n}\r\n\r\n/**\r\n * 定位光标矩形：根据位置返回光标在文档坐标系中的矩形。\r\n * @param layout 文档布局\r\n * @param pos 光标位置\r\n * @param zone 当前编辑区域，默认 'main'；'header'/'footer' 时在对应区域块中定位\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nexport function locateCaret(layout: DocumentLayout, pos: IPosition, zone: Zone = 'main'): CaretRect | null {\r\n  for (const page of layout.pages) {\r\n    let blocks: BlockNode[]\r\n    let originX: number\r\n    let originY: number\r\n    if (zone === 'header' && page.headerBlocks && page.headerRect) {\r\n      blocks = page.headerBlocks\r\n      originX = page.headerRect.x\r\n      originY = page.headerRect.y\r\n    } else if (zone === 'footer' && page.footerBlocks && page.footerRect) {\r\n      blocks = page.footerBlocks\r\n      originX = page.footerRect.x\r\n      originY = page.footerRect.y\r\n    } else {\r\n      blocks = page.blocks\r\n      originX = page.contentRect.x\r\n      originY = page.contentRect.y\r\n    }\r\n    const r = locateInBlocks(blocks, pos, originX, originY)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在指定原点偏移下遍历块列表定位光标矩形。\r\n * @param blocks 块节点列表\r\n * @param pos 光标位置\r\n * @param ox 父容器原点 X\r\n * @param oy 父容器原点 Y\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nfunction locateInBlocks(blocks: BlockNode[], pos: IPosition, ox: number, oy: number): CaretRect | null {\r\n  for (const b of blocks) {\r\n    const bx = ox + b.rect.x\r\n    const by = oy + b.rect.y\r\n    if (b.kind === 'paragraph') {\r\n      const r = locateInParagraph(b, pos, bx, by)\r\n      if (r) return r\r\n    } else if (b.kind === 'table') {\r\n      const r = locateInTable(b, pos, bx, by)\r\n      if (r) return r\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在段落内定位光标矩形，按行和 inline 匹配位置。\r\n * @param b 段落块\r\n * @param pos 光标位置\r\n * @param bx 段落原点 X\r\n * @param by 段落原点 Y\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nfunction locateInParagraph(b: ParagraphBlock, pos: IPosition, bx: number, by: number): CaretRect | null {\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      if (!isSamePath(inl.path, pos.path)) continue\r\n      if (pos.offset < inl.startOffset || pos.offset > inl.endOffset) continue\r\n      const localX = charOffsetToX(inl, pos.offset - inl.startOffset)\r\n      // 光标高度按行高，顶部对齐行顶\r\n      return {\r\n        x: bx + localX,\r\n        y: by + line.y,\r\n        height: line.height\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n\r\n/**\r\n * 在表格内定位光标矩形，递归进入匹配的单元格内容。\r\n * @param b 表格块\r\n * @param pos 光标位置\r\n * @param tbx 表格原点 X\r\n * @param tby 表格原点 Y\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nfunction locateInTable(b: TableBlock, pos: IPosition, tbx: number, tby: number): CaretRect | null {\r\n  for (const row of b.rows) {\r\n    for (const cell of row.cells) {\r\n      // 光标 path 必须以 cell.contentPath 为前缀\r\n      if (!pathStartsWith(pos.path, cell.contentPath)) continue\r\n      const cx = tbx + cell.rect.x\r\n      const cy = tby + row.rect.y\r\n      const contentOX = cx + cell.contentPaddingLeft\r\n      const contentOY = cy + cell.contentPaddingTop + cell.verticalOffset\r\n      const r = locateInBlocks(cell.content, pos, contentOX, contentOY)\r\n      if (r) return r\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 判断路径 path 是否以 prefix 为前缀。\r\n * @param path 待判断路径\r\n * @param prefix 前缀路径\r\n * @returns 是前缀返回 true，否则返回 false\r\n */\r\nfunction pathStartsWith(path: Path, prefix: Path): boolean {\r\n  if (path.length < prefix.length) return false\r\n  for (let i = 0; i < prefix.length; i++) {\r\n    if (path[i] !== prefix[i]) return false\r\n  }\r\n  return true\r\n}\r\n\r\n/**\r\n * 在 inline 内部按 offset 求 x（相对块本地）。\r\n * 使用真实 measureText 度量（与 layout 阶段一致），避免估算错位。\r\n */\r\nfunction charOffsetToX(inl: InlineBox, offsetInInline: number): number {\r\n  if (offsetInInline <= 0) return inl.x\r\n  if (offsetInInline >= inl.text.length) return inl.x + inl.width\r\n  const measure = getSharedMeasure()\r\n  let x = inl.x\r\n  const ls = inl.letterSpacing ?? 0\r\n  for (let i = 0; i < offsetInInline; i++) {\r\n    x += measure.charWidth(inl.text[i], inl.font, inl.size, inl.bold, inl.italic) + ls\r\n  }\r\n  return x\r\n}\r\n\r\n/* -------------------- 选区矩形 -------------------- */\r\n\r\n/**\r\n * 计算从 start 到 end（文档顺序）的选区矩形列表（文档坐标，未减 scrollY）。\r\n * 遍历所有 inline，收集与 [start, end] 相交的部分，同行 inline 合并为一个矩形。\r\n * @param layout 文档布局\r\n * @param start 选区起点\r\n * @param end 选区终点\r\n * @param zone 当前编辑区域，默认 'main'；'header'/'footer' 时在对应区域块中收集\r\n * @returns 选区矩形列表\r\n */\r\nexport function computeSelectionRects(layout: DocumentLayout, start: IPosition, end: IPosition, zone: Zone = 'main'): SelectionRect[] {\r\n  const rects: SelectionRect[] = []\r\n  for (const page of layout.pages) {\r\n    let blocks: BlockNode[]\r\n    let originX: number\r\n    let originY: number\r\n    if (zone === 'header' && page.headerBlocks && page.headerRect) {\r\n      blocks = page.headerBlocks\r\n      originX = page.headerRect.x\r\n      originY = page.headerRect.y\r\n    } else if (zone === 'footer' && page.footerBlocks && page.footerRect) {\r\n      blocks = page.footerBlocks\r\n      originX = page.footerRect.x\r\n      originY = page.footerRect.y\r\n    } else {\r\n      blocks = page.blocks\r\n      originX = page.contentRect.x\r\n      originY = page.contentRect.y\r\n    }\r\n    collectSelectionInBlocks(blocks, originX, originY, start, end, rects)\r\n  }\r\n  return rects\r\n}\r\n\r\n/**\r\n * 在指定原点偏移下遍历块列表收集选区矩形。\r\n * @param blocks 块节点列表\r\n * @param ox 父容器原点 X\r\n * @param oy 父容器原点 Y\r\n * @param start 选区起点\r\n * @param end 选区终点\r\n * @param rects 收集结果数组\r\n */\r\nfunction collectSelectionInBlocks(\r\n  blocks: BlockNode[], ox: number, oy: number,\r\n  start: IPosition, end: IPosition, rects: SelectionRect[]\r\n): void {\r\n  for (const b of blocks) {\r\n    const bx = ox + b.rect.x\r\n    const by = oy + b.rect.y\r\n    if (b.kind === 'paragraph') {\r\n      collectSelectionInParagraph(b, bx, by, start, end, rects)\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const cx = bx + cell.rect.x + cell.contentPaddingLeft\r\n          const cy = by + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n          collectSelectionInBlocks(cell.content, cx, cy, start, end, rects)\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 在段落内收集选区矩形，同行 inline 合并为一个矩形。\r\n * @param b 段落块\r\n * @param bx 段落原点 X\r\n * @param by 段落原点 Y\r\n * @param start 选区起点\r\n * @param end 选区终点\r\n * @param rects 收集结果数组\r\n */\r\nfunction collectSelectionInParagraph(\r\n  b: ParagraphBlock, bx: number, by: number,\r\n  start: IPosition, end: IPosition, rects: SelectionRect[]\r\n): void {\r\n  for (const line of b.lines) {\r\n    // 同行选中片段合并：记录当前合并段的 [leftX, rightX]\r\n    let segLeft: number | null = null\r\n    let segRight = 0\r\n    const flush = () => {\r\n      if (segLeft != null) {\r\n        rects.push({ x: segLeft, y: by + line.y, width: segRight - segLeft, height: line.height })\r\n        segLeft = null\r\n      }\r\n    }\r\n    for (const inl of line.inlines) {\r\n      const inlStart: IPosition = { path: inl.path, offset: inl.startOffset }\r\n      const inlEnd: IPosition = { path: inl.path, offset: inl.endOffset }\r\n      // 不相交\r\n      if (comparePosition(inlEnd, start) <= 0) continue\r\n      if (comparePosition(inlStart, end) >= 0) { flush(); continue }\r\n      // 裁剪起点\r\n      let clipStartOff: number\r\n      if (comparePosition(inlStart, start) >= 0) {\r\n        clipStartOff = inl.startOffset\r\n      } else {\r\n        clipStartOff = isSamePath(inl.path, start.path) ? start.offset : inl.startOffset\r\n      }\r\n      // 裁剪终点\r\n      let clipEndOff: number\r\n      if (comparePosition(inlEnd, end) <= 0) {\r\n        clipEndOff = inl.endOffset\r\n      } else {\r\n        clipEndOff = isSamePath(inl.path, end.path) ? end.offset : inl.endOffset\r\n      }\r\n      const x1 = bx + charOffsetToX(inl, clipStartOff - inl.startOffset)\r\n      const x2 = bx + charOffsetToX(inl, clipEndOff - inl.startOffset)\r\n      if (segLeft == null) {\r\n        segLeft = x1\r\n        segRight = x2\r\n      } else {\r\n        // 同行连续 inline 合并（若有间隙也合并，视觉为整块高亮）\r\n        if (x1 <= segRight) segRight = Math.max(segRight, x2)\r\n        else { flush(); segLeft = x1; segRight = x2 }\r\n      }\r\n    }\r\n    flush()\r\n  }\r\n}\r\n","export type ViewTranslate = (key: string, params?: Record<string, string | number>) => string\r\n\r\n// Defaults are local to the view layer; option values and command values are never translated.\r\nexport const viewText: Record<string, string> = {\r\n  'view.common.cancel': '取消',\r\n  'view.common.confirm': '确定',\r\n  'view.common.none': '无',\r\n  'view.common.leftAlign': '左对齐',\r\n  'view.common.rightAlign': '右对齐',\r\n  'view.common.center': '居中',\r\n  'view.common.justify': '两端对齐',\r\n  'view.common.distribute': '分散对齐',\r\n  'view.common.preview': '预览',\r\n  'view.common.color': '颜色',\r\n  'view.common.spacing': '间距',\r\n  'view.common.points': '磅',\r\n  'view.paragraph.format': '段落格式',\r\n  'view.paragraph.body': '正文',\r\n  'view.paragraph.heading1': '一级标题',\r\n  'view.paragraph.heading2': '二级标题',\r\n  'view.paragraph.heading3': '三级标题',\r\n  'view.paragraph.heading4': '四级标题',\r\n  'view.paragraph.heading5': '五级标题',\r\n  'view.paragraph.heading6': '六级标题',\r\n  'view.paragraph.cut': '剪切',\r\n  'view.paragraph.copy': '复制',\r\n  'view.paragraph.paste': '粘贴',\r\n  'view.paragraph.fontSettings': '字体...',\r\n  'view.paragraph.advancedSettings': '段落高级设置',\r\n  'view.paragraph.link': '超链接',\r\n  'view.hyperlink.text': '显示文字',\r\n  'view.hyperlink.address': '链接地址',\r\n  'view.hyperlink.addressPlaceholder': '请输入完整地址（如 https://example.com）',\r\n  'view.hyperlink.textRequired': '请输入显示文字',\r\n  'view.hyperlink.addressRequired': '请输入链接地址',\r\n  'view.hyperlink.addressInvalid': '链接地址必须使用 http、https、mailto、tel 或 ftp 协议',\r\n  'view.hyperlink.unsupported': '超链接未插入，未能获取具体原因。请重新选择文字后重试，文档未修改。',\r\n  'view.hyperlink.bookmarkSelection': '选区包含书签标记，当前编辑器暂不支持跨书签插入超链接。请调整选区避开书签边界；原文和书签均未修改。',\r\n  'view.hyperlink.fieldSelection': '选区包含 Word 域标记（如目录或页码），暂不支持插入超链接。请选择域以外的普通文字，文档未修改。',\r\n  'view.hyperlink.existingLink': '选区包含已有超链接，当前暂不支持嵌套或替换链接。请选择尚未添加链接的文字，文档未修改。',\r\n  'view.hyperlink.crossContainer': '选区跨越不同文本容器（如段落或单元格）。请在同一段落内选择文字后重试，文档未修改。',\r\n  'view.hyperlink.crossParagraph': '选区包含换行或段落结束标记。请选择同一段落内不含换行的文字，文档未修改。',\r\n  'view.hyperlink.revisions': '选区包含尚未处理的修订。请先审阅并接受或拒绝相关修订，或选择不含修订的文字，文档未修改。',\r\n  'view.hyperlink.tracking': '当前已开启修订模式，暂不支持插入超链接。请关闭修订模式后重试，文档未修改。',\r\n  'view.hyperlink.readOnly': '文档处于只读模式，无法插入超链接。请切换到可编辑模式后重试，文档未修改。',\r\n  'view.hyperlink.disabled': '编辑功能已被禁用，无法插入超链接。请启用编辑后重试，文档未修改。',\r\n  'view.hyperlink.noSelection': '未找到光标位置或文字选区。请关闭弹窗，在正文中放置光标或选择文字后重试，文档未修改。',\r\n  'view.hyperlink.invalidSelection': '文字选区已失效。请关闭弹窗并重新选择文字后重试，文档未修改。',\r\n  'view.hyperlink.nonText': '选区包含图片、表格等非普通文本内容。请只选择普通文字，文档未修改。',\r\n  'view.hyperlink.invalidText': '显示文字必须为非空的普通文本，且不能包含换行或隐藏控制标记。请修改显示文字后重试，文档未修改。',\r\n  'view.paragraph.comment': '插入批注',\r\n  'view.table.insert': '插入',\r\n  'view.table.insertLeft': '在左侧插入',\r\n  'view.table.insertRight': '在右侧插入',\r\n  'view.table.insertAbove': '在上方插入',\r\n  'view.table.insertBelow': '在下方插入',\r\n  'view.table.columnUnit': '列',\r\n  'view.table.rowUnit': '行',\r\n  'view.table.insertCell': '单元格(E)...',\r\n  'view.table.splitCell': '拆分单元格',\r\n  'view.table.mergeCell': '合并单元格',\r\n  'view.table.delete': '删除',\r\n  'view.table.deleteRow': '删除行',\r\n  'view.table.deleteColumn': '删除列',\r\n  'view.table.deleteTable': '删除整个表格',\r\n  'view.table.selectAll': '全选表格',\r\n  'view.table.horizontalAlign': '水平对齐方式',\r\n  'view.table.centerAlign': '居中对齐',\r\n  'view.table.verticalAlign': '垂直对齐方式',\r\n  'view.table.alignTop': '顶端对齐',\r\n  'view.table.alignMiddle': '垂直居中',\r\n  'view.table.alignBottom': '底端对齐',\r\n  'view.table.background': '底纹颜色',\r\n  'view.table.repeatHeader': '重复表头行',\r\n  'view.table.properties': '表格属性',\r\n  'view.table.select': '选择表格',\r\n  'view.table.addColumn': '添加列',\r\n  'view.table.addRow': '添加行',\r\n  'view.font.title': '字体',\r\n  'view.font.characterSpacing': '字符间距',\r\n  'view.font.cjkFont': '中文字体',\r\n  'view.font.style': '字形',\r\n  'view.font.regular': '常规',\r\n  'view.font.italic': '倾斜',\r\n  'view.font.bold': '加粗',\r\n  'view.font.boldItalic': '加粗倾斜',\r\n  'view.font.size': '字号',\r\n  'view.font.effects': '效果',\r\n  'view.font.strikethrough': '删除线',\r\n  'view.font.underline': '下划线',\r\n  'view.font.superscript': '上标',\r\n  'view.font.subscript': '下标',\r\n  'view.font.doubleStrikethrough': '双删除线',\r\n  'view.font.hidden': '隐藏',\r\n  'view.font.previewText': '字体预览文本 ABCabc 123',\r\n  'view.font.scale': '缩放',\r\n  'view.font.standard': '标准',\r\n  'view.font.expanded': '加宽',\r\n  'view.font.condensed': '紧缩',\r\n  'view.font.position': '位置',\r\n  'view.font.raised': '提升',\r\n  'view.font.lowered': '降低',\r\n  'view.font.spacingPreview': '字符间距预览 ABCabc 123',\r\n  'view.font.unsupported': '间距与位置功能将在后续版本支持',\r\n  'view.paragraphDialog.title': '段落',\r\n  'view.paragraphDialog.indentSpacing': '缩进和间距',\r\n  'view.paragraphDialog.linePageBreak': '换行和分页',\r\n  'view.paragraphDialog.cjkLayout': '中文版式',\r\n  'view.paragraphDialog.general': '常规',\r\n  'view.paragraphDialog.alignment': '对齐方式',\r\n  'view.paragraphDialog.outline': '大纲级别',\r\n  'view.paragraphDialog.bodyText': '正文文本',\r\n  'view.paragraphDialog.level1': '1 级',\r\n  'view.paragraphDialog.level2': '2 级',\r\n  'view.paragraphDialog.level3': '3 级',\r\n  'view.paragraphDialog.level4': '4 级',\r\n  'view.paragraphDialog.level5': '5 级',\r\n  'view.paragraphDialog.level6': '6 级',\r\n  'view.paragraphDialog.indent': '缩进',\r\n  'view.paragraphDialog.beforeText': '文本之前',\r\n  'view.paragraphDialog.afterText': '文本之后',\r\n  'view.paragraphDialog.special': '特殊格式',\r\n  'view.paragraphDialog.firstLine': '首行缩进',\r\n  'view.paragraphDialog.hanging': '悬挂缩进',\r\n  'view.paragraphDialog.measure': '度量值',\r\n  'view.paragraphDialog.cm': '厘米',\r\n  'view.paragraphDialog.adjustRightIndent': '如果定义了文档网格，则自动调整右缩进',\r\n  'view.paragraphDialog.before': '段前',\r\n  'view.paragraphDialog.after': '段后',\r\n  'view.paragraphDialog.lineSpacing': '行距',\r\n  'view.paragraphDialog.single': '单倍行距',\r\n  'view.paragraphDialog.oneHalf': '1.5 倍行距',\r\n  'view.paragraphDialog.double': '双倍行距',\r\n  'view.paragraphDialog.atLeast': '最小值',\r\n  'view.paragraphDialog.exact': '固定值',\r\n  'view.paragraphDialog.multiple': '多倍行距',\r\n  'view.paragraphDialog.setting': '设置值',\r\n  'view.paragraphDialog.times': '倍',\r\n  'view.paragraphDialog.alignGrid': '如果定义了文档网格，则与网格对齐',\r\n  'view.paragraphDialog.previewText': '段落预览文本',\r\n  'view.paragraphDialog.pagination': '分页',\r\n  'view.paragraphDialog.widow': '孤行控制',\r\n  'view.paragraphDialog.keepNext': '与下段同页',\r\n  'view.paragraphDialog.breakBefore': '段前分页',\r\n  'view.paragraphDialog.lineBreak': '换行',\r\n  'view.paragraphDialog.noLineNumber': '取消行号',\r\n  'view.paragraphDialog.noHyphen': '取消断字',\r\n  'view.paragraphDialog.unsupported': '该功能将在后续版本支持',\r\n  'view.paragraphDialog.cjkWrap': '按中文习惯换行',\r\n  'view.paragraphDialog.punctuationOverflow': '允许标点溢出边界',\r\n  'view.paragraphDialog.wordBreak': '允许西文在单词中间换行',\r\n  'view.paragraphDialog.compressPunctuation': '允许行首标点压缩',\r\n  'view.paragraphDialog.cjkWesternSpacing': '自动调整中文与西文的间距',\r\n  'view.paragraphDialog.cjkNumberSpacing': '自动调整中文与数字的间距',\r\n  'view.paragraphDialog.textAlignment': '文字对齐方式',\r\n  'view.paragraphDialog.align': '对齐',\r\n  'view.paragraphDialog.auto': '自动',\r\n  'view.paragraphDialog.baseline': '基线对齐',\r\n  'view.tableDialog.categories': '属性类别',\r\n  'view.tableDialog.table': '表格',\r\n  'view.tableDialog.cell': '单元格',\r\n  'view.tableDialog.presetHint': '预设替换整个表格的边框组合，未选中的边将清除。',\r\n  'view.tableDialog.border': '边框',\r\n  'view.tableDialog.preset': '预设',\r\n  'view.tableDialog.unchanged': '保持原样',\r\n  'view.tableDialog.allBorders': '全部边框',\r\n  'view.tableDialog.outsideBorders': '外侧边框',\r\n  'view.tableDialog.noBorders': '无边框',\r\n  'view.tableDialog.insideBorders': '内部边框',\r\n  'view.tableDialog.insideHorizontal': '内部横线',\r\n  'view.tableDialog.insideVertical': '内部竖线',\r\n  'view.tableDialog.topBorder': '上边框',\r\n  'view.tableDialog.bottomBorder': '下边框',\r\n  'view.tableDialog.leftBorder': '左边框',\r\n  'view.tableDialog.rightBorder': '右边框',\r\n  'view.tableDialog.borderPresets': '边框预设',\r\n  'view.tableDialog.all': '全部',\r\n  'view.tableDialog.outside': '外侧',\r\n  'view.tableDialog.inside': '内部',\r\n  'view.tableDialog.colorFormatTitle': '请输入 #RRGGBB 格式的颜色',\r\n  'view.tableDialog.colorFormatClearTitle': '请输入 #RRGGBB 格式的颜色，留空清除',\r\n  'view.tableDialog.borderColor': '边框颜色',\r\n  'view.tableDialog.cellColor': '单元格底色',\r\n  'view.tableDialog.chooseColor': '选择{label}（当前{state}）',\r\n  'view.tableDialog.innerWidth': '内框宽度',\r\n  'view.tableDialog.outerWidth': '外框宽度',\r\n  'view.tableDialog.innerWidthAria': '内框宽度（像素）',\r\n  'view.tableDialog.outerWidthAria': '外框宽度（像素）',\r\n  'view.tableDialog.colorHelp': '颜色格式：#RRGGBB；留空保持原样。',\r\n  'view.tableDialog.borderPreview': '边框示意',\r\n  'view.tableDialog.presetPreview': '边框组合示意；虚线仅标示表格范围。未填写的颜色、宽度保持原样。',\r\n  'view.tableDialog.unchangedPreview': '未选择预设，边框组合保持原样；示意不代表混合样式。',\r\n  'view.tableDialog.cellHint': '以下设置仅应用于当前单元格（右键所在格）。',\r\n  'view.tableDialog.fill': '底色',\r\n  'view.tableDialog.noFill': '无底色',\r\n  'view.tableDialog.invalidColor': '颜色格式无效',\r\n  'view.tableDialog.clearFill': '清除底色',\r\n  'view.tableDialog.fillHelp': '颜色格式：#RRGGBB；留空表示无底色。',\r\n  'view.tableDialog.verticalAlign': '垂直对齐',\r\n  'view.tableDialog.alignCenter': '居中对齐',\r\n  'view.pageNumber.header': '页眉',\r\n  'view.pageNumber.footer': '页脚',\r\n  'view.pageNumber.insert': '插入页码',\r\n  'view.pageNumber.style': '样式:',\r\n  'view.pageNumber.position': '位置:',\r\n  'view.pageNumber.left': '左侧',\r\n  'view.pageNumber.center': '居中',\r\n  'view.pageNumber.right': '右侧',\r\n  'view.pageNumber.stylePage': '第1页',\r\n  'view.pageNumber.styleTotal': '第1页共x页',\r\n  'view.pageNumber.styleFirst': '第一页',\r\n  'view.pageNumber.styleFirstTotal': '第一页共X页',\r\n  'view.fontFamily.SimSun': '宋体',\r\n  'view.fontFamily.SimHei': '黑体',\r\n  'view.fontFamily.KaiTi': '楷体',\r\n  'view.fontFamily.FangSong': '仿宋',\r\n  'view.fontFamily.MicrosoftYaHei': '微软雅黑',\r\n  'view.fontFamily.DengXian': '等线',\r\n  'view.fontFamily.STSong': '华文宋体',\r\n  'view.fontFamily.STHeiti': '华文黑体',\r\n  'view.fontFamily.STKaiti': '华文楷体',\r\n  'view.fontFamily.STFangsong': '华文仿宋',\r\n  'view.fontFamily.STZhongsong': '华文中宋',\r\n  'view.fontFamily.STXihei': '华文细黑',\r\n  'view.fontFamily.STXingkai': '华文行楷',\r\n  'view.fontFamily.STLiti': '华文隶书',\r\n  'view.fontFamily.STXinwei': '华文新魏',\r\n  'view.fontFamily.STCaiyun': '华文彩云',\r\n  'view.fontSize.chuhao': '初号',\r\n  'view.fontSize.xiaochu': '小初',\r\n  'view.fontSize.yihao': '一号',\r\n  'view.fontSize.xiaoyi': '小一',\r\n  'view.fontSize.erhao': '二号',\r\n  'view.fontSize.xiaoer': '小二',\r\n  'view.fontSize.sanhao': '三号',\r\n  'view.fontSize.xiaosan': '小三',\r\n  'view.fontSize.sihao': '四号',\r\n  'view.fontSize.xiaosi': '小四',\r\n  'view.fontSize.wuhao': '五号',\r\n  'view.fontSize.xiaowu': '小五',\r\n  'view.fontSize.liuhao': '六号',\r\n  'view.fontSize.xiaoliu': '小六',\r\n  'view.fontSize.qihao': '七号',\r\n  'view.fontSize.bahao': '八号'\r\n}\r\n\r\nexport function viewTranslate(translate: ViewTranslate | undefined, key: string, params?: Record<string, string | number>): string {\r\n  const fallback = viewText[key] ?? key\r\n  const result = translate?.(key, params)\r\n  const text = !result || result === key ? fallback : result\r\n  return text.replace(/\\{(\\w+)}/g, (_, name: string) => String(params?.[name] ?? `{${name}}`))\r\n}\r\n\r\n// Translate template text nodes and display-only attributes, leaving form values intact.\r\nconst textKeys = new WeakMap<Text, string>()\r\n\r\nexport function translatePanel(root: HTMLElement, translate: ViewTranslate | undefined, prefix: string): void {\r\n  const entries = Object.entries(viewText)\r\n  const preferred = entries.filter(([key]) => key.startsWith(prefix) || key.startsWith('view.common.'))\r\n  const byText = new Map([...entries, ...preferred].map(([key, value]) => [value, key]))\r\n  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\r\n  while (walker.nextNode()) {\r\n    const node = walker.currentNode as Text\r\n    const raw = node.textContent ?? ''\r\n    const text = raw.trim()\r\n    const key = textKeys.get(node) ?? byText.get(text)\r\n    if (key) {\r\n      textKeys.set(node, key)\r\n      node.textContent = raw.replace(text, () => viewTranslate(translate, key))\r\n    }\r\n  }\r\n  for (const el of [root, ...Array.from(root.querySelectorAll<HTMLElement>('*'))]) {\r\n    const keyedText = el.dataset.i18nKey\r\n    if (keyedText) el.textContent = viewTranslate(translate, keyedText)\r\n    for (const attr of ['title', 'aria-label', 'placeholder']) {\r\n      const marker = `i18n${attr === 'aria-label' ? 'AriaLabel' : attr[0].toUpperCase() + attr.slice(1)}`\r\n      const raw = el.getAttribute(attr)\r\n      const key = el.dataset[marker] ?? (raw && byText.get(raw))\r\n      if (key) {\r\n        el.dataset[marker] = key\r\n        el.setAttribute(attr, viewTranslate(translate, key))\r\n      }\r\n    }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs View —— 表格右键菜单\r\n *\r\n * 纯 DOM 实现，无框架依赖。支持子菜单、图标、快捷键、分隔线。\r\n */\r\n\r\nimport './assets/css/context-menu.css'\r\nimport { viewTranslate, type ViewTranslate } from './view-i18n'\r\n\r\n/** CSS 类名前缀，所有菜单相关样式均以此为前缀 */\r\nconst PREFIX = 'ce-table-context-menu'\r\n\r\n/**\r\n * 菜单项内嵌数字输入框配置。\r\n * 用于在菜单项右侧展示一个带单位的数字输入控件（如行高、列宽）。\r\n */\r\nexport interface MenuItemInput {\r\n  /** 输入框初始值 */\r\n  defaultValue: number\r\n  /** 单位文本（如 \"px\"、\"%\"） */\r\n  unit: string\r\n  /** 允许的最小值，默认 1 */\r\n  min?: number\r\n  /** 允许的最大值，默认 99 */\r\n  max?: number\r\n}\r\n\r\n/**\r\n * 菜单项内嵌颜色选择器配置。\r\n * 用于在菜单项右侧展示一个原生 color input 及可选的\"无\"清除按钮。\r\n */\r\nexport interface MenuItemColorPicker {\r\n  /** 初始颜色值（如 \"#ffffff\"），默认白色 */\r\n  defaultColor?: string\r\n  /** 是否展示\"无\"清除按钮，点击后以空字符串触发 onClick */\r\n  allowClear?: boolean\r\n}\r\n\r\n/**\r\n * 右键菜单项描述。\r\n * 支持图标、快捷键、子菜单、内嵌输入框、内嵌颜色选择器、危险态、禁用态等。\r\n */\r\nexport interface MenuItem {\r\n  /** 显示文本；值为 \"---\" 时渲染为分隔线 */\r\n  label: string\r\n  /** material-symbols-outlined 图标名，可选 */\r\n  icon?: string\r\n  /** 快捷键提示文本（仅展示，不绑定按键），可选 */\r\n  shortcut?: string\r\n  /** 是否为危险操作（红色高亮），可选 */\r\n  danger?: boolean\r\n  /** 是否禁用该项，可选 */\r\n  disabled?: boolean\r\n  /** 子菜单项数组，存在时显示右箭头并悬停展开 */\r\n  submenu?: MenuItem[]\r\n  /** 内嵌数字输入框配置，可选 */\r\n  input?: MenuItemInput\r\n  /** 内嵌颜色选择器配置，可选 */\r\n  colorPicker?: MenuItemColorPicker\r\n  /** 点击回调；参数为输入框/颜色选择器的当前值（无控件时为 undefined） */\r\n  onClick?: (value?: number | string) => void\r\n}\r\n\r\n/** material-symbols-outlined 图标名映射表，供外部通过 getIcons() 引用 */\r\nconst SVG = {\r\n  insertRowAbove: 'table_rows',\r\n  insertRowBelow: 'table_rows',\r\n  insertColLeft: 'view_column',\r\n  insertColRight: 'view_column',\r\n  deleteRow: 'delete',\r\n  deleteCol: 'delete',\r\n  splitCell: 'splitscreen',\r\n  selectAll: 'select_all',\r\n  alignLeft: 'format_align_left',\r\n  alignCenter: 'format_align_center',\r\n  alignRight: 'format_align_right',\r\n  link: 'link',\r\n  tableProp: 'settings',\r\n  mergeCell: 'merge',\r\n  valignTop: 'vertical_align_top',\r\n  valignMiddle: 'vertical_align_center',\r\n  valignBottom: 'vertical_align_bottom',\r\n  cellBackground: 'format_color_fill',\r\n  repeatHeader: 'repeat',\r\n  deleteTable: 'delete',\r\n  arrow: 'chevron_right'\r\n}\r\n\r\n/**\r\n * 表格右键菜单控制器。\r\n * 纯 DOM 实现，负责菜单/子菜单的构建、定位、显隐与外部点击关闭。\r\n */\r\nexport class ContextMenu {\r\n  /** 主菜单根元素 */\r\n  private menuEl: HTMLDivElement | null = null\r\n  /** 子菜单根元素 */\r\n  private submenuEl: HTMLDivElement | null = null\r\n  /** 子菜单延迟隐藏定时器句柄 */\r\n  private hideTimer: number | null = null\r\n\r\n  constructor(private translate?: ViewTranslate) {}\r\n\r\n  /**\r\n   * 在指定坐标显示主菜单。\r\n   * @param x - 菜单左上角横坐标（px）\r\n   * @param y - 菜单左上角纵坐标（px）\r\n   * @param items - 菜单项描述数组\r\n   * @returns 无返回值\r\n   */\r\n  show(x: number, y: number, items: MenuItem[]): void {\r\n    this.showContent(x, y, this.buildMenu(items, false))\r\n  }\r\n\r\n  /** Display custom menu content with the same positioning and dismissal lifecycle. */\r\n  showContent(x: number, y: number, content: HTMLDivElement): void {\r\n    this.hide()\r\n    this.menuEl = content\r\n    this.menuEl.style.left = `${x}px`\r\n    this.menuEl.style.top = `${y}px`\r\n    document.body.appendChild(this.menuEl)\r\n    this.adjustPosition(this.menuEl, x, y)\r\n    document.addEventListener('mousedown', this.onOutsideDown, { capture: true })\r\n    document.addEventListener('scroll', this.onScroll, { capture: true })\r\n  }\r\n\r\n  /**\r\n   * 关闭并销毁主菜单与子菜单，移除所有全局事件监听。\r\n   * @returns 无返回值\r\n   */\r\n  hide(): void {\r\n    if (this.menuEl) { this.menuEl.remove(); this.menuEl = null }\r\n    if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n    document.removeEventListener('mousedown', this.onOutsideDown, { capture: true })\r\n    document.removeEventListener('scroll', this.onScroll, { capture: true })\r\n  }\r\n\r\n  /**\r\n   * 根据菜单项描述构建菜单根 div。\r\n   * @param items - 菜单项描述数组\r\n   * @param isSub - 是否为子菜单（影响是否追加子菜单修饰类）\r\n   * @returns 构建完成的菜单根 HTMLDivElement\r\n   */\r\n  private buildMenu(items: MenuItem[], isSub: boolean): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = PREFIX + (isSub ? ` ${PREFIX}--sub` : '')\r\n    for (const item of items) {\r\n      if (item.label === '---') {\r\n        const div = document.createElement('div')\r\n        div.className = `${PREFIX}__divider`\r\n        el.appendChild(div)\r\n        continue\r\n      }\r\n      el.appendChild(this.buildItem(item))\r\n    }\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 构建单个菜单项元素，包含图标、文本、快捷键、子菜单箭头、输入框、颜色选择器等。\r\n   * @param item - 菜单项描述\r\n   * @returns 构建完成的菜单项 HTMLDivElement\r\n   */\r\n  private buildItem(item: MenuItem): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = `${PREFIX}__item${item.danger ? ' danger' : ''}${item.disabled ? ' disabled' : ''}${item.input ? ` ${PREFIX}__item--with-input` : ''}`\r\n\r\n    const main = document.createElement('span')\r\n    main.className = `${PREFIX}__main`\r\n\r\n    if (item.icon) {\r\n      const icon = document.createElement('span')\r\n      icon.className = `material-symbols-outlined ${PREFIX}__icon`\r\n      icon.textContent = item.icon\r\n      main.appendChild(icon)\r\n    }\r\n\r\n    const label = document.createElement('span')\r\n    label.className = `${PREFIX}__label`\r\n    label.textContent = item.label\r\n    main.appendChild(label)\r\n    el.appendChild(main)\r\n\r\n    const meta = document.createElement('span')\r\n    meta.className = `${PREFIX}__meta`\r\n\r\n    if (item.shortcut) {\r\n      const sc = document.createElement('span')\r\n      sc.className = `${PREFIX}__shortcut`\r\n      sc.textContent = item.shortcut\r\n      meta.appendChild(sc)\r\n    }\r\n\r\n    if (item.submenu) {\r\n      const arrow = document.createElement('span')\r\n      arrow.className = `material-symbols-outlined ${PREFIX}__arrow`\r\n      arrow.textContent = SVG.arrow\r\n      meta.appendChild(arrow)\r\n    }\r\n\r\n    el.appendChild(meta)\r\n\r\n    let inputValue: number | undefined\r\n\r\n    if (item.input) {\r\n      const wrap = document.createElement('span')\r\n      wrap.className = `${PREFIX}__input-wrap`\r\n\r\n      const input = document.createElement('input')\r\n      input.type = 'number'\r\n      input.setAttribute('aria-label', item.label)\r\n      input.className = `${PREFIX}__input`\r\n      input.value = String(item.input.defaultValue)\r\n      const min = item.input.min ?? 1\r\n      const max = item.input.max ?? 99\r\n      input.min = String(min)\r\n      input.max = String(max)\r\n      inputValue = item.input.defaultValue\r\n\r\n      input.addEventListener('mousedown', (e) => {\r\n        e.stopPropagation()\r\n      })\r\n      input.addEventListener('click', (e) => {\r\n        e.stopPropagation()\r\n      })\r\n      input.addEventListener('input', () => {\r\n        const v = parseInt(input.value, 10)\r\n        inputValue = isNaN(v) ? item.input!.defaultValue : Math.max(min, Math.min(max, v))\r\n      })\r\n      input.addEventListener('keydown', (e) => {\r\n        e.stopPropagation()\r\n        if (e.key === 'Enter') {\r\n          if (!item.disabled && item.onClick) {\r\n            item.onClick(inputValue)\r\n            this.hide()\r\n          }\r\n        }\r\n      })\r\n\r\n      wrap.appendChild(input)\r\n\r\n      const unit = document.createElement('span')\r\n      unit.className = `${PREFIX}__input-unit`\r\n      unit.textContent = item.input.unit\r\n      wrap.appendChild(unit)\r\n\r\n      meta.appendChild(wrap)\r\n    }\r\n\r\n    let colorValue: string | undefined\r\n\r\n    if (item.colorPicker) {\r\n      const wrap = document.createElement('span')\r\n      wrap.className = `${PREFIX}__color-wrap`\r\n\r\n      const colorInput = document.createElement('input')\r\n      colorInput.type = 'color'\r\n      colorInput.setAttribute('aria-label', item.label)\r\n      colorInput.className = `${PREFIX}__color-input`\r\n      colorInput.value = item.colorPicker.defaultColor ?? '#ffffff'\r\n      colorValue = colorInput.value\r\n\r\n      colorInput.addEventListener('mousedown', (e) => { e.stopPropagation() })\r\n      colorInput.addEventListener('click', (e) => { e.stopPropagation() })\r\n      colorInput.addEventListener('input', () => { colorValue = colorInput.value })\r\n      colorInput.addEventListener('change', () => {\r\n        if (!item.disabled && item.onClick) {\r\n          item.onClick(colorValue)\r\n          this.hide()\r\n        }\r\n      })\r\n      wrap.appendChild(colorInput)\r\n\r\n      if (item.colorPicker.allowClear) {\r\n        const clear = document.createElement('span')\r\n        clear.className = `${PREFIX}__color-clear`\r\n        clear.textContent = viewTranslate(this.translate, 'view.common.none')\r\n        clear.addEventListener('mousedown', (e) => { e.stopPropagation() })\r\n        clear.addEventListener('click', (e) => {\r\n          e.stopPropagation()\r\n          if (!item.disabled && item.onClick) {\r\n            item.onClick('')\r\n            this.hide()\r\n          }\r\n        })\r\n        wrap.appendChild(clear)\r\n      }\r\n\r\n      meta.appendChild(wrap)\r\n    }\r\n\r\n    if (!item.disabled && item.onClick && !item.colorPicker) {\r\n      el.addEventListener('click', () => {\r\n        item.onClick!(inputValue ?? colorValue)\r\n        this.hide()\r\n      })\r\n    }\r\n\r\n    if (!item.disabled && item.submenu) {\r\n      el.addEventListener('mouseenter', () => {\r\n        if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null }\r\n        this.showSubmenu(el, item.submenu!)\r\n      })\r\n      el.addEventListener('mouseleave', () => {\r\n        this.hideTimer = window.setTimeout(() => {\r\n          if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n        }, 200)\r\n      })\r\n    }\r\n\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 在指定父菜单项右侧展开其子菜单，并绑定悬停保持/离开延迟隐藏。\r\n   * @param parentEl - 触发展开的父菜单项元素\r\n   * @param items - 子菜单项描述数组\r\n   * @returns 无返回值\r\n   */\r\n  private showSubmenu(parentEl: HTMLDivElement, items: MenuItem[]): void {\r\n    if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n    this.submenuEl = this.buildMenu(items, true)\r\n    this.submenuEl.addEventListener('mouseenter', () => {\r\n      if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null }\r\n    })\r\n    this.submenuEl.addEventListener('mouseleave', () => {\r\n      this.hideTimer = window.setTimeout(() => {\r\n        if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n      }, 200)\r\n    })\r\n    const rect = parentEl.getBoundingClientRect()\r\n    const x = rect.right\r\n    const y = rect.top\r\n    this.submenuEl.style.left = `${x}px`\r\n    this.submenuEl.style.top = `${y}px`\r\n    document.body.appendChild(this.submenuEl)\r\n    this.adjustPosition(this.submenuEl, x, y)\r\n  }\r\n\r\n  /**\r\n   * 校正菜单位置，避免其超出视口右边界或下边界。\r\n   * @param el - 待校正的菜单元素\r\n   * @param x - 期望的横坐标（px）\r\n   * @param y - 期望的纵坐标（px）\r\n   * @returns 无返回值\r\n   */\r\n  private adjustPosition(el: HTMLDivElement, x: number, y: number): void {\r\n    const rect = el.getBoundingClientRect()\r\n    const vw = window.innerWidth\r\n    const vh = window.innerHeight\r\n    if (x + rect.width > vw || x < 4) {\r\n      el.style.left = `${Math.max(4, Math.min(vw - rect.width - 4, x < 4 ? 4 : vw - rect.width - 4))}px`\r\n    }\r\n    if (y + rect.height > vh || y < 4) {\r\n      el.style.top = `${Math.max(4, Math.min(vh - rect.height - 4, y < 4 ? 4 : vh - rect.height - 4))}px`\r\n    }\r\n  }\r\n\r\n  /** 全局 mousedown 监听器：点击发生在菜单外部时关闭菜单 */\r\n  private onOutsideDown = (e: MouseEvent): void => {\r\n    const target = e.target as Node\r\n    if (this.menuEl?.contains(target)) return\r\n    if (this.submenuEl?.contains(target)) return\r\n    this.hide()\r\n  }\r\n\r\n  /** 全局 scroll 监听器：页面滚动时关闭菜单，避免错位 */\r\n  private onScroll = (): void => {\r\n    this.hide()\r\n  }\r\n\r\n  /**\r\n   * 获取内置 material-symbols-outlined 图标名映射表。\r\n   * @returns 图标名映射对象\r\n   */\r\n  static getIcons() { return SVG }\r\n}\r\n","/** Body-mounted handles must stay inside both the editor and the browser viewport. */\r\nexport function positionHandle(\r\n  handle: HTMLElement,\r\n  x: number,\r\n  y: number,\r\n  size: number,\r\n  viewport: DOMRect\r\n): boolean {\r\n  const left = Math.round(x)\r\n  const top = Math.round(y)\r\n  const visible = left >= Math.max(0, viewport.left) &&\r\n    top >= Math.max(0, viewport.top) &&\r\n    left + size <= Math.min(window.innerWidth, viewport.right) &&\r\n    top + size <= Math.min(window.innerHeight, viewport.bottom)\r\n\r\n  handle.style.boxSizing = 'border-box'\r\n  handle.style.left = `${left}px`\r\n  handle.style.top = `${top}px`\r\n  handle.style.display = visible ? 'flex' : 'none'\r\n  return visible\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask tp-mask\\\">\\r\\n  <form class=\\\"pw-panel tp-panel\\\" role=\\\"dialog\\\" aria-modal=\\\"true\\\" aria-labelledby=\\\"tp-title\\\" novalidate>\\r\\n    <div class=\\\"pw-panel-title\\\" id=\\\"tp-title\\\">表格属性</div>\\r\\n    <div class=\\\"tp-tabs\\\" role=\\\"tablist\\\" aria-label=\\\"属性类别\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"tp-table-tab\\\" role=\\\"tab\\\" aria-selected=\\\"true\\\" aria-controls=\\\"tp-table-pane\\\" data-tab=\\\"table\\\">表格</button>\\r\\n      <button type=\\\"button\\\" id=\\\"tp-cell-tab\\\" role=\\\"tab\\\" aria-selected=\\\"false\\\" aria-controls=\\\"tp-cell-pane\\\" data-tab=\\\"cell\\\" tabindex=\\\"-1\\\">单元格</button>\\r\\n    </div>\\r\\n    <div class=\\\"tp-body\\\">\\r\\n      <section id=\\\"tp-table-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-table-tab\\\" data-pane=\\\"table\\\">\\r\\n        <p class=\\\"tp-hint\\\">预设替换整个表格的边框组合，未选中的边将清除。</p>\\r\\n        <fieldset class=\\\"tp-group\\\">\\r\\n          <legend>边框</legend>\\r\\n          <div class=\\\"tp-border-layout\\\">\\r\\n            <div class=\\\"tp-settings\\\">\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-type\\\">预设</label>\\r\\n              <select id=\\\"tp-type\\\" name=\\\"type\\\" class=\\\"pw-ctrl\\\"><option value=\\\"\\\">保持原样</option><option value=\\\"all\\\">全部边框</option><option value=\\\"outside\\\">外侧边框</option><option value=\\\"none\\\">无边框</option><option value=\\\"inside\\\">内部边框</option><option value=\\\"inside-horizontal\\\">内部横线</option><option value=\\\"inside-vertical\\\">内部竖线</option><option value=\\\"top\\\">上边框</option><option value=\\\"bottom\\\">下边框</option><option value=\\\"left\\\">左边框</option><option value=\\\"right\\\">右边框</option></select>\\r\\n              <div class=\\\"tp-presets\\\" role=\\\"group\\\" aria-label=\\\"边框预设\\\">\\r\\n                <button type=\\\"button\\\" data-preset=\\\"all\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"all\\\" aria-hidden=\\\"true\\\"></span>全部</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"outside\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"outside\\\" aria-hidden=\\\"true\\\"></span>外侧</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"none\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"none\\\" aria-hidden=\\\"true\\\"></span>无边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"inside\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside\\\" aria-hidden=\\\"true\\\"></span>内部</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"inside-horizontal\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside-horizontal\\\" aria-hidden=\\\"true\\\"></span>内部横线</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"inside-vertical\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside-vertical\\\" aria-hidden=\\\"true\\\"></span>内部竖线</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"top\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"top\\\" aria-hidden=\\\"true\\\"></span>上边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"bottom\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"bottom\\\" aria-hidden=\\\"true\\\"></span>下边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"left\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"left\\\" aria-hidden=\\\"true\\\"></span>左边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"right\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"right\\\" aria-hidden=\\\"true\\\"></span>右边框</button>\\r\\n              </div>\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-color\\\">颜色</label>\\r\\n              <div class=\\\"tp-color-field\\\" data-empty=\\\"true\\\">\\r\\n                <input id=\\\"tp-color\\\" type=\\\"text\\\" name=\\\"color\\\" class=\\\"pw-ctrl\\\" placeholder=\\\"保持原样\\\" pattern=\\\"#[0-9a-fA-F]{6}\\\" title=\\\"请输入 #RRGGBB 格式的颜色\\\" aria-describedby=\\\"tp-color-help\\\">\\r\\n                <input type=\\\"color\\\" value=\\\"#000000\\\" data-color-picker=\\\"color\\\" aria-label=\\\"选择边框颜色（当前保持原样）\\\" aria-describedby=\\\"tp-color-help\\\">\\r\\n              </div>\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-width\\\">内框宽度</label>\\r\\n              <div class=\\\"tp-with-unit\\\"><input id=\\\"tp-width\\\" name=\\\"width\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"any\\\" placeholder=\\\"保持原样\\\" aria-label=\\\"内框宽度（像素）\\\"><span>px</span></div>\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-external-width\\\">外框宽度</label>\\r\\n              <div class=\\\"tp-with-unit\\\"><input id=\\\"tp-external-width\\\" name=\\\"externalWidth\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"any\\\" placeholder=\\\"保持原样\\\" aria-label=\\\"外框宽度（像素）\\\"><span>px</span></div>\\r\\n              <p id=\\\"tp-color-help\\\" class=\\\"tp-field-help\\\">颜色格式：#RRGGBB；留空保持原样。</p>\\r\\n            </div>\\r\\n            <div class=\\\"tp-preview-box\\\">\\r\\n              <span class=\\\"tp-label\\\">预览</span>\\r\\n              <div class=\\\"tp-preview-stage\\\" aria-hidden=\\\"true\\\"><div class=\\\"tp-border-icon tp-border-preview\\\" data-preview data-border=\\\"all\\\"><span></span><span></span><span></span><span></span></div></div>\\r\\n              <p class=\\\"tp-hint\\\" data-preview-caption aria-live=\\\"polite\\\">边框示意</p>\\r\\n            </div>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n      </section>\\r\\n      <section id=\\\"tp-cell-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-cell-tab\\\" data-pane=\\\"cell\\\" hidden>\\r\\n        <p class=\\\"tp-hint\\\">以下设置仅应用于当前单元格（右键所在格）。</p>\\r\\n        <fieldset class=\\\"tp-group\\\">\\r\\n          <legend>底色</legend>\\r\\n          <div class=\\\"tp-cell-fill\\\">\\r\\n            <label class=\\\"tp-label\\\" for=\\\"tp-background\\\">颜色</label>\\r\\n            <div class=\\\"tp-color-field\\\" data-empty=\\\"true\\\">\\r\\n              <input id=\\\"tp-background\\\" type=\\\"text\\\" name=\\\"backgroundColor\\\" class=\\\"pw-ctrl\\\" placeholder=\\\"无底色\\\" pattern=\\\"#[0-9a-fA-F]{6}\\\" title=\\\"请输入 #RRGGBB 格式的颜色，留空清除\\\" aria-describedby=\\\"tp-background-help\\\">\\r\\n              <input type=\\\"color\\\" value=\\\"#000000\\\" data-color-picker=\\\"backgroundColor\\\" aria-label=\\\"选择单元格底色（当前无底色）\\\" aria-describedby=\\\"tp-background-help\\\">\\r\\n            </div>\\r\\n            <button type=\\\"button\\\" data-clear-background>清除底色</button>\\r\\n          </div>\\r\\n          <p id=\\\"tp-background-help\\\" class=\\\"tp-hint\\\">颜色格式：#RRGGBB；留空表示无底色。</p>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"tp-group\\\">\\r\\n          <legend>垂直对齐</legend>\\r\\n          <div class=\\\"tp-cell-align\\\">\\r\\n            <label class=\\\"tp-label\\\" for=\\\"tp-vertical-align\\\">对齐方式</label>\\r\\n            <select id=\\\"tp-vertical-align\\\" name=\\\"verticalAlign\\\" class=\\\"pw-ctrl\\\"><option value=\\\"top\\\">顶端对齐</option><option value=\\\"middle\\\">居中对齐</option><option value=\\\"bottom\\\">底端对齐</option></select>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n      </section>\\r\\n    </div>\\r\\n    <div class=\\\"tp-actions\\\">\\r\\n      <button type=\\\"submit\\\" class=\\\"tp-primary\\\">确定</button>\\r\\n      <button type=\\\"button\\\" data-cancel>取消</button>\\r\\n    </div>\\r\\n  </form>\\r\\n</div>\\r\\n\"","import '../../assets/css/paragraph-layout-widget.css'\r\nimport panelHtml from '../../assets/components/table-properties-widget.html?raw'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { translatePanel, viewTranslate, type ViewTranslate } from '../../view-i18n'\r\n\r\ninterface Deps {\r\n  onCommand: (cmd: string, ...args: any[]) => any\r\n  focusInput: () => void\r\n  translate?: ViewTranslate\r\n}\r\n\r\nexport class TablePropertiesWidget {\r\n  private root: HTMLElement | null = null\r\n  private initial: Record<string, string> = {}\r\n  private target: IPosition | null = null\r\n\r\n  constructor(private deps: Deps) {}\r\n\r\n  show(target: IPosition): void {\r\n    this.hide()\r\n    this.target = { path: [...target.path], offset: target.offset }\r\n    const cmd = this.deps.onCommand\r\n    const selection = cmd('getRange')\r\n    cmd('executeReplaceRange', { anchor: this.target, focus: this.target })\r\n    const borders = cmd('getTableBorders')\r\n    const cell = cmd('getCellProperties')\r\n    cmd('executeReplaceRange', selection)\r\n    if (!borders || !cell) return\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.deps.translate, 'view.tableDialog.')\r\n    document.body.appendChild(this.root)\r\n    this.initial = {}\r\n    for (const [name, value] of Object.entries({ ...borders, ...cell })) {\r\n      const input = this.root.querySelector<HTMLInputElement | HTMLSelectElement>(`[name=\"${name}\"]`)!\r\n      input.value = value === undefined ? '' : String(value)\r\n      if (name === 'color' || name === 'backgroundColor') {\r\n        input.value = input.value.replace(/^#([\\da-f])([\\da-f])([\\da-f])$/i, '#$1$1$2$2$3$3')\r\n      }\r\n      this.initial[name] = input.value\r\n    }\r\n    this.root.querySelectorAll<HTMLButtonElement>('[data-tab]').forEach(tab => {\r\n      tab.addEventListener('click', () => this.selectTab(tab.dataset.tab!))\r\n      tab.addEventListener('keydown', event => {\r\n        const tabs = Array.from(this.root!.querySelectorAll<HTMLButtonElement>('[data-tab]'))\r\n        const index = tabs.indexOf(tab)\r\n        let next: number\r\n        if (event.key === 'ArrowRight') next = (index + 1) % tabs.length\r\n        else if (event.key === 'ArrowLeft') next = (index + tabs.length - 1) % tabs.length\r\n        else if (event.key === 'Home') next = 0\r\n        else if (event.key === 'End') next = tabs.length - 1\r\n        else return\r\n        event.preventDefault()\r\n        this.selectTab(tabs[next].dataset.tab!)\r\n        tabs[next].focus()\r\n      })\r\n    })\r\n    this.root.querySelectorAll<HTMLButtonElement>('[data-preset]').forEach(button => {\r\n      button.addEventListener('click', () => {\r\n        this.root!.querySelector<HTMLSelectElement>('[name=\"type\"]')!.value = button.dataset.preset!\r\n        this.updatePreview()\r\n      })\r\n    })\r\n    this.root.querySelectorAll<HTMLInputElement>('[data-color-picker]').forEach(picker => {\r\n      const input = this.root!.querySelector<HTMLInputElement>(`[name=\"${picker.dataset.colorPicker}\"]`)!\r\n      const selectColor = () => {\r\n        input.value = picker.value\r\n        this.updatePreview()\r\n      }\r\n      picker.addEventListener('input', selectColor)\r\n      picker.addEventListener('change', selectColor)\r\n    })\r\n    this.root.querySelector('[data-clear-background]')!.addEventListener('click', () => {\r\n      const input = this.root!.querySelector<HTMLInputElement>('[name=\"backgroundColor\"]')!\r\n      input.value = ''\r\n      this.updatePreview()\r\n      input.focus()\r\n    })\r\n    this.root.addEventListener('input', () => this.updatePreview())\r\n    this.root.addEventListener('change', () => this.updatePreview())\r\n    this.updatePreview()\r\n    this.root.querySelector('[data-cancel]')!.addEventListener('click', () => this.close())\r\n    this.root.addEventListener('keydown', event => {\r\n      if (event.key === 'Escape') { event.preventDefault(); this.close() }\r\n      if (event.key === 'Tab' && this.root) {\r\n        const controls = Array.from(this.root.querySelectorAll<HTMLElement>('input, select, button'))\r\n          .filter(control => control.tabIndex >= 0 && !control.closest('[hidden]'))\r\n        const first = controls[0]\r\n        const last = controls[controls.length - 1]\r\n        if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus() }\r\n        else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus() }\r\n      }\r\n      event.stopPropagation()\r\n    })\r\n    this.root.querySelector('form')!.addEventListener('submit', event => {\r\n      event.preventDefault()\r\n      const invalid = Array.from(this.root!.querySelectorAll<HTMLInputElement>('input'))\r\n        .find(input => !input.validity.valid)\r\n      if (invalid) {\r\n        this.selectTab(invalid.closest<HTMLElement>('[data-pane]')!.dataset.pane!)\r\n        invalid.focus()\r\n        invalid.reportValidity()\r\n        return\r\n      }\r\n      this.apply()\r\n      this.close()\r\n    })\r\n    this.root.querySelector<HTMLElement>('[data-tab=\"table\"]')!.focus()\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (!this.root) return\r\n    translatePanel(this.root, this.deps.translate, 'view.tableDialog.')\r\n    this.updatePreview()\r\n  }\r\n\r\n  private selectTab(name: string): void {\r\n    this.root!.querySelectorAll<HTMLElement>('[data-tab]').forEach(tab => {\r\n      const selected = tab.dataset.tab === name\r\n      tab.setAttribute('aria-selected', String(selected))\r\n      tab.tabIndex = selected ? 0 : -1\r\n    })\r\n    this.root!.querySelectorAll<HTMLElement>('[data-pane]').forEach(pane => {\r\n      pane.hidden = pane.dataset.pane !== name\r\n    })\r\n  }\r\n\r\n  private updatePreview(): void {\r\n    const value = (name: string) => this.root!.querySelector<HTMLInputElement | HTMLSelectElement>(`[name=\"${name}\"]`)!.value\r\n    this.root!.querySelectorAll<HTMLInputElement>('[data-color-picker]').forEach(picker => {\r\n      const color = value(picker.dataset.colorPicker!)\r\n      const valid = /^#[\\da-f]{6}$/i.test(color)\r\n      picker.value = valid ? color : '#000000'\r\n      picker.parentElement!.dataset.empty = String(color === '')\r\n      const t = (key: string) => viewTranslate(this.deps.translate, `view.tableDialog.${key}`)\r\n      const label = picker.dataset.colorPicker === 'color' ? t('borderColor') : t('cellColor')\r\n      const state = color === '' ? (picker.dataset.colorPicker === 'color' ? t('unchanged') : t('noFill')) : (valid ? color : t('invalidColor'))\r\n      picker.setAttribute('aria-label', viewTranslate(this.deps.translate, 'view.tableDialog.chooseColor', { label, state }))\r\n    })\r\n    const type = value('type')\r\n    this.root!.querySelectorAll<HTMLElement>('[data-preset]').forEach(button => {\r\n      button.setAttribute('aria-pressed', String(button.dataset.preset === type))\r\n    })\r\n    const preview = this.root!.querySelector<HTMLElement>('[data-preview]')!\r\n    preview.dataset.border = type || 'all'\r\n    preview.style.setProperty('--tp-line-color', /^#[\\da-f]{6}$/i.test(value('color')) ? value('color') : 'var(--tp-muted)')\r\n    for (const [name, property] of [['width', '--tp-inner-width'], ['externalWidth', '--tp-outer-width']]) {\r\n      const width = value(name)\r\n      preview.style.setProperty(property, `${width === '' ? 1 : Math.min(8, Math.max(0, Number(width)))}px`)\r\n    }\r\n    this.root!.querySelector<HTMLElement>('[data-preview-caption]')!.textContent = viewTranslate(this.deps.translate,\r\n      type ? 'view.tableDialog.presetPreview' : 'view.tableDialog.unchangedPreview')\r\n  }\r\n\r\n  private apply(): void {\r\n    if (!this.root || !this.target) return\r\n    const cmd = this.deps.onCommand\r\n    cmd('executeReplaceRange', { anchor: this.target, focus: this.target })\r\n    const patch: Record<string, string | number> = {}\r\n    for (const name of ['type', 'color', 'width', 'externalWidth']) {\r\n      const value = this.root.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value\r\n      if (value !== '' && value !== this.initial[name]) {\r\n        patch[name] = name === 'width' || name === 'externalWidth' ? Number(value) : value\r\n      }\r\n    }\r\n    if (Object.keys(patch).length) cmd('executeSetTableBorders', patch)\r\n    for (const [name, command] of [['verticalAlign', 'executeSetCellVerticalAlign'], ['backgroundColor', 'executeSetCellBackground']]) {\r\n      const value = this.root.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value\r\n      if (value !== this.initial[name]) cmd(command, value)\r\n    }\r\n  }\r\n\r\n  private close(): void {\r\n    this.hide()\r\n    this.deps.focusInput()\r\n  }\r\n\r\n  hide(): void {\r\n    this.root?.remove()\r\n    this.root = null\r\n    this.target = null\r\n  }\r\n}\r\n","/**\r\n * TableWidget —— 表格交互 widget\r\n *\r\n * 从 Draw 分离的表格 UI 交互逻辑：\r\n *  - 表格选择手柄（左上角全选按钮）\r\n *  - 表格添加列按钮（右侧中间 + 号）\r\n *  - 表格右键上下文菜单\r\n *\r\n * 生命周期：create() → update() / showContextMenu() → destroy()\r\n */\r\n\r\nimport type { BlockNode, DocumentLayout, TableBlock } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { ContextMenu, type MenuItem } from '../context-menu'\r\nimport { positionHandle } from './handle-position'\r\nimport { TablePropertiesWidget } from './layout/table-properties-widget'\r\nimport { viewText, viewTranslate, type ViewTranslate } from '../view-i18n'\r\n\r\n/** 边框热区半宽（像素），鼠标距离边框小于该值时视为命中边框可拖拽 */\r\nconst BORDER_HOT = 4\r\n\r\n/**\r\n * 表格边框拖拽状态\r\n *\r\n * 记录当前正在拖拽的列/行信息，用于拖拽过程中计算新尺寸。\r\n */\r\ninterface DragState {\r\n  /** 拖拽类型：列或行 */\r\n  type: 'col' | 'row'\r\n  /** 表格在父节点中的索引 */\r\n  tableIndex: number\r\n  /** 被拖拽边框对应的列/行索引 */\r\n  index: number\r\n  /** 拖拽起始时的客户端坐标（clientX 或 clientY） */\r\n  startClient: number\r\n  /** 拖拽起始时该列/行的原始尺寸（像素） */\r\n  origSize: number\r\n}\r\n\r\n/**\r\n * TableWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface TableWidgetDeps {\r\n  translate?: ViewTranslate\r\n  /** Whether editing interactions are currently allowed. */\r\n  canEdit: () => boolean\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n  /** 根据客户端坐标命中测试，返回位置信息或 null */\r\n  hit: (clientX: number, clientY: number) => IPosition | null\r\n  /** 让编辑器输入区获取焦点 */\r\n  focusInput: () => void\r\n  /** 设置鼠标光标样式 */\r\n  setCursor: (cursor: string) => void\r\n}\r\n\r\n/**\r\n * 表格交互 widget\r\n *\r\n * 提供表格选择手柄、添加列/行按钮、右键上下文菜单以及边框拖拽调整列宽行高功能。\r\n */\r\nexport class TableWidget {\r\n  /** 表格左上角的全选手柄 DOM 元素 */\r\n  private handle: HTMLDivElement | null = null\r\n  /** 表格右侧中间的添加列手柄 DOM 元素 */\r\n  private addColHandle: HTMLDivElement | null = null\r\n  /** 表格底部中间的添加行手柄 DOM 元素 */\r\n  private addRowHandle: HTMLDivElement | null = null\r\n  /** 右键上下文菜单实例 */\r\n  private contextMenu: ContextMenu\r\n  /** 当前边框拖拽状态，未拖拽时为 null */\r\n  private dragState: DragState | null = null\r\n  /** 标记光标样式是否已被修改，用于在离开边框时恢复 */\r\n  private cursorChanged = false\r\n\r\n  /**\r\n   * 构造 TableWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  private panel: TablePropertiesWidget\r\n\r\n  constructor(private deps: TableWidgetDeps) {\r\n    this.contextMenu = new ContextMenu(deps.translate)\r\n    this.panel = new TablePropertiesWidget({\r\n      onCommand: (cmd, ...args) => {\r\n        if (this.deps.canEdit()) this.deps.onCommand(cmd, ...args)\r\n      },\r\n      focusInput: () => this.deps.focusInput(),\r\n      translate: deps.translate\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    this.contextMenu.hide()\r\n    for (const [el, key] of [[this.handle, 'select'], [this.addColHandle, 'addColumn'], [this.addRowHandle, 'addRow']] as const) {\r\n      if (!el) continue\r\n      el.title = viewTranslate(this.deps.translate, `view.table.${key}`)\r\n      el.setAttribute('aria-label', el.title)\r\n    }\r\n    this.panel.refreshTranslations()\r\n  }\r\n\r\n  /* -------------------- 创建 -------------------- */\r\n\r\n  /**\r\n   * 创建表格交互所需的全部手柄 DOM 并挂载到 document.body\r\n   */\r\n  create(): void {\r\n    this.handle = this.createHandle()\r\n    this.addColHandle = this.createAddColHandle()\r\n    this.addRowHandle = this.createAddRowHandle()\r\n  }\r\n\r\n  /**\r\n   * 创建表格左上角全选手柄\r\n   *\r\n   * @returns 创建并挂载好的手柄 DOM 元素\r\n   */\r\n  private createHandle(): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-table-handle'\r\n    el.title = viewTranslate(this.deps.translate, 'view.table.select')\r\n    el.setAttribute('aria-label', el.title)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'drag_indicator'\r\n    icon.style.cssText = 'font-size:16px;color:#606266;'\r\n    el.appendChild(icon)\r\n    Object.assign(el.style, {\r\n      position: 'fixed',\r\n      width: '24px',\r\n      height: '24px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '3px',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      color: '#606266',\r\n      boxShadow: '0 1px 4px rgba(0,0,0,.15)'\r\n    } as CSSStyleDeclaration)\r\n    el.addEventListener('mousedown', (e) => {\r\n      e.preventDefault()\r\n      e.stopPropagation()\r\n      if (!this.deps.canEdit()) return\r\n      this.deps.onCommand('executeSelectTable')\r\n    })\r\n    document.body.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 创建表格右侧中间的添加列手柄\r\n   *\r\n   * @returns 创建并挂载好的手柄 DOM 元素\r\n   */\r\n  private createAddColHandle(): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-table-add-col'\r\n    el.title = viewTranslate(this.deps.translate, 'view.table.addColumn')\r\n    el.setAttribute('aria-label', el.title)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'add'\r\n    icon.style.cssText = 'font-size:16px;color:#606266;'\r\n    el.appendChild(icon)\r\n    Object.assign(el.style, {\r\n      position: 'fixed',\r\n      width: '24px',\r\n      height: '24px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '3px',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      color: '#606266',\r\n      boxShadow: '0 1px 4px rgba(0,0,0,.15)'\r\n    } as CSSStyleDeclaration)\r\n    el.addEventListener('mouseenter', () => {\r\n      el.style.background = '#409eff'\r\n      el.style.color = '#fff'\r\n      el.style.borderColor = '#409eff'\r\n    })\r\n    el.addEventListener('mouseleave', () => {\r\n      el.style.background = '#fff'\r\n      el.style.color = '#606266'\r\n      el.style.borderColor = '#dcdfe6'\r\n    })\r\n    el.addEventListener('mousedown', (e) => {\r\n      e.preventDefault()\r\n      e.stopPropagation()\r\n      if (!this.deps.canEdit()) return\r\n      this.deps.onCommand('executeInsertTableCol', 'right')\r\n    })\r\n    document.body.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 创建表格底部中间的添加行手柄\r\n   *\r\n   * @returns 创建并挂载好的手柄 DOM 元素\r\n   */\r\n  private createAddRowHandle(): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-table-add-row'\r\n    el.title = viewTranslate(this.deps.translate, 'view.table.addRow')\r\n    el.setAttribute('aria-label', el.title)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'add'\r\n    icon.style.cssText = 'font-size:16px;color:#606266;'\r\n    el.appendChild(icon)\r\n    Object.assign(el.style, {\r\n      position: 'fixed',\r\n      width: '24px',\r\n      height: '24px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '3px',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      color: '#606266',\r\n      boxShadow: '0 1px 4px rgba(0,0,0,.15)'\r\n    } as CSSStyleDeclaration)\r\n    el.addEventListener('mouseenter', () => {\r\n      el.style.background = '#409eff'\r\n      el.style.color = '#fff'\r\n      el.style.borderColor = '#409eff'\r\n    })\r\n    el.addEventListener('mouseleave', () => {\r\n      el.style.background = '#fff'\r\n      el.style.color = '#606266'\r\n      el.style.borderColor = '#dcdfe6'\r\n    })\r\n    el.addEventListener('mousedown', (e) => {\r\n      e.preventDefault()\r\n      e.stopPropagation()\r\n      if (!this.deps.canEdit()) return\r\n      this.deps.onCommand('executeInsertTableRow', 'below')\r\n    })\r\n    document.body.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /* -------------------- 更新手柄位置 -------------------- */\r\n\r\n  /**\r\n   * 根据当前选区更新手柄位置\r\n   *\r\n   * 当光标位于表格内时，显示全选、添加列、添加行手柄；否则隐藏全部手柄。\r\n   */\r\n  update(): void {\r\n    if (!this.deps.canEdit()) { this.resetInteraction(); return }\r\n    if (!this.handle) return\r\n    for (const [el, key] of [[this.handle, 'select'], [this.addColHandle, 'addColumn'], [this.addRowHandle, 'addRow']] as const) {\r\n      if (!el) continue\r\n      el.title = viewTranslate(this.deps.translate, `view.table.${key}`)\r\n      el.setAttribute('aria-label', el.title)\r\n    }\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) { this.hideHandles(); return }\r\n\r\n    const pos = range.getFocus()\r\n    const isTable = pos && pos.path.length >= 5 && pos.path[1] === 'trList'\r\n    if (!isTable) {\r\n      this.hideHandles()\r\n      return\r\n    }\r\n\r\n    const tableIndex = pos!.path[0] as number\r\n    // Match the focused cell so a paginated table uses the correct fragment.\r\n    const matchesTable = (b: BlockNode) =>\r\n      b.kind === 'table' && b.indexInParent === tableIndex &&\r\n      b.rows.some(row => row.cells.some(cell =>\r\n        cell.cellPath.every((part, index) => part === pos!.path[index])))\r\n    const page = layout.pages.find(p =>\r\n      p.blocks.some(matchesTable)\r\n    )\r\n    if (!page) { this.hideHandles(); return }\r\n\r\n    const block = page.blocks.find(matchesTable)\r\n    if (!block || block.kind !== 'table') { this.hideHandles(); return }\r\n\r\n    const rect = this.deps.getContainerRect()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n    const tableX = rect.left + pageOffsetX + page.contentRect.x + block.rect.x\r\n    const tableY = rect.top - scrollY + page.contentRect.y + block.rect.y\r\n    if (tableX + block.rect.width <= rect.left || tableX >= rect.right ||\r\n        tableY + block.rect.height <= rect.top || tableY >= rect.bottom) {\r\n      this.hideHandles()\r\n      return\r\n    }\r\n    positionHandle(this.handle, tableX - 31, tableY - 25, 24, rect)\r\n\r\n    if (this.addColHandle) {\r\n      const colX = tableX + block.rect.width + 4\r\n      const colY = tableY + block.rect.height / 2 - 12\r\n      positionHandle(this.addColHandle, colX, colY, 24, rect)\r\n    }\r\n\r\n    if (this.addRowHandle) {\r\n      const rowX = tableX + block.rect.width / 2 - 12\r\n      const rowY = tableY + block.rect.height + 4\r\n      positionHandle(this.addRowHandle, rowX, rowY, 24, rect)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 隐藏全部手柄\r\n   */\r\n  private hideHandles(): void {\r\n    if (this.handle) this.handle.style.display = 'none'\r\n    if (this.addColHandle) this.addColHandle.style.display = 'none'\r\n    if (this.addRowHandle) this.addRowHandle.style.display = 'none'\r\n  }\r\n\r\n  private resetInteraction(): void {\r\n    this.hideHandles()\r\n    this.hideContextMenu()\r\n    this.panel.hide()\r\n    if (this.dragState || this.cursorChanged) this.deps.setCursor('default')\r\n    this.dragState = null\r\n    this.cursorChanged = false\r\n  }\r\n\r\n  /* -------------------- 右键菜单 -------------------- */\r\n\r\n  /**\r\n   * 在指定客户端坐标处显示表格右键上下文菜单\r\n   *\r\n   * 菜单包含插入、拆分/合并单元格、删除、对齐方式、底纹颜色、表格属性等操作。\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中表格并显示菜单返回 true，否则返回 false\r\n   */\r\n  showContextMenu(clientX: number, clientY: number): boolean {\r\n    if (!this.deps.canEdit()) return false\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return false\r\n\r\n    const pos = this.deps.hit(clientX, clientY)\r\n    if (!pos) return false\r\n\r\n    const isTable = pos.path.length >= 5 && pos.path[1] === 'trList'\r\n    if (!isTable) return false\r\n\r\n    const selected = range.getRange()\r\n    const inSameTable = selected && [selected.anchor, selected.focus].every(p =>\r\n      p.path[0] === pos.path[0] && p.path[1] === 'trList'\r\n    )\r\n    const insideSelection = inSameTable &&\r\n      Number(pos.path[2]) >= Math.min(Number(selected.anchor.path[2]), Number(selected.focus.path[2])) &&\r\n      Number(pos.path[2]) <= Math.max(Number(selected.anchor.path[2]), Number(selected.focus.path[2])) &&\r\n      Number(pos.path[4]) >= Math.min(Number(selected.anchor.path[4]), Number(selected.focus.path[4])) &&\r\n      Number(pos.path[4]) <= Math.max(Number(selected.anchor.path[4]), Number(selected.focus.path[4]))\r\n    if (!insideSelection) range.setCaret(pos)\r\n    this.deps.focusInput()\r\n\r\n    const icons = ContextMenu.getIcons()\r\n    const fire = (cmd: string, ...args: any[]) => {\r\n      if (this.deps.canEdit()) this.deps.onCommand(cmd, ...args)\r\n    }\r\n\r\n    const items: MenuItem[] = [\r\n      {\r\n        label: '插入',\r\n        icon: icons.insertRowAbove,\r\n        submenu: [\r\n          { label: '在左侧插入', icon: icons.insertColLeft, input: { defaultValue: 1, unit: '列', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableCol', 'left', v ?? 1) },\r\n          { label: '在右侧插入', icon: icons.insertColRight, input: { defaultValue: 1, unit: '列', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableCol', 'right', v ?? 1) },\r\n          { label: '在上方插入', icon: icons.insertRowAbove, input: { defaultValue: 1, unit: '行', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableRow', 'above', v ?? 1) },\r\n          { label: '在下方插入', icon: icons.insertRowBelow, input: { defaultValue: 1, unit: '行', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableRow', 'below', v ?? 1) },\r\n          { label: '---' },\r\n          { label: '单元格(E)...', onClick: () => fire('executeInsertTableCell') },\r\n        ]\r\n      },\r\n      { label: '拆分单元格', icon: icons.splitCell, onClick: () => fire('executeSplitTableCell') },\r\n      { label: '合并单元格', icon: icons.mergeCell, onClick: () => fire('executeMergeTableCells') },\r\n      {\r\n        label: '删除',\r\n        icon: icons.deleteRow,\r\n        danger: true,\r\n        submenu: [\r\n          { label: '删除行', icon: icons.deleteRow, danger: true, onClick: () => fire('executeDeleteTableRow') },\r\n          { label: '删除列', icon: icons.deleteCol, danger: true, onClick: () => fire('executeDeleteTableCol') },\r\n          { label: '---' },\r\n          { label: '删除整个表格', icon: icons.deleteTable, danger: true, onClick: () => fire('executeDeleteTable') },\r\n        ]\r\n      },\r\n      { label: '---' },\r\n      { label: '全选表格', icon: icons.selectAll, onClick: () => fire('executeSelectTable') },\r\n      { label: '---' },\r\n      {\r\n        label: '水平对齐方式',\r\n        icon: icons.alignLeft,\r\n        submenu: [\r\n          { label: '左对齐', icon: icons.alignLeft, onClick: () => fire('executeRowFlex', 'left') },\r\n          { label: '居中对齐', icon: icons.alignCenter, onClick: () => fire('executeRowFlex', 'center') },\r\n          { label: '右对齐', icon: icons.alignRight, onClick: () => fire('executeRowFlex', 'right') },\r\n        ]\r\n      },\r\n      {\r\n        label: '垂直对齐方式',\r\n        icon: icons.valignMiddle,\r\n        submenu: [\r\n          { label: '顶端对齐', icon: icons.valignTop, onClick: () => fire('executeSetCellVerticalAlign', 'top') },\r\n          { label: '垂直居中', icon: icons.valignMiddle, onClick: () => fire('executeSetCellVerticalAlign', 'middle') },\r\n          { label: '底端对齐', icon: icons.valignBottom, onClick: () => fire('executeSetCellVerticalAlign', 'bottom') },\r\n        ]\r\n      },\r\n      {\r\n        label: '底纹颜色',\r\n        icon: icons.cellBackground,\r\n        colorPicker: { defaultColor: '#ffffff', allowClear: true },\r\n        onClick: (v) => fire('executeSetCellBackground', String(v ?? ''))\r\n      },\r\n      { label: '重复表头行', icon: icons.repeatHeader, onClick: () => fire('executeToggleRepeatHeader') },\r\n      { label: '---' },\r\n      { label: '超链接', icon: icons.link, shortcut: 'Ctrl+K', onClick: () => fire('executeHyperlink') },\r\n      { label: '表格属性', icon: icons.tableProp, onClick: () => { if (this.deps.canEdit()) this.panel.show(pos) } },\r\n    ]\r\n\r\n    const labels = new Map(Object.entries(viewText)\r\n      .filter(([key]) => key.startsWith('view.table.') || key === 'view.paragraph.link' || key.startsWith('view.common.'))\r\n      .map(([key, text]) => [text, key]))\r\n    const localize = (menu: MenuItem[]) => menu.forEach(item => {\r\n      const key = labels.get(item.label)\r\n      if (key) item.label = viewTranslate(this.deps.translate, key)\r\n      if (item.input) {\r\n        const unitKey = labels.get(item.input.unit)\r\n        if (unitKey) item.input.unit = viewTranslate(this.deps.translate, unitKey)\r\n      }\r\n      if (item.submenu) localize(item.submenu)\r\n    })\r\n    localize(items)\r\n    this.contextMenu.show(clientX, clientY, items)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 隐藏右键上下文菜单\r\n   */\r\n  hideContextMenu(): void {\r\n    this.contextMenu.hide()\r\n  }\r\n\r\n  /* -------------------- 边框拖拽 -------------------- */\r\n\r\n  /**\r\n   * 根据屏幕坐标查找命中的表格块\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中的表格块及其屏幕起点坐标，未命中返回 null\r\n   */\r\n  private findTableAtScreen(clientX: number, clientY: number): { block: TableBlock; screenX: number; screenY: number } | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      for (const b of page.blocks) {\r\n        if (b.kind !== 'table') continue\r\n        const sx = rect.left + pageOffsetX + page.contentRect.x + b.rect.x\r\n        const sy = rect.top - scrollY + page.contentRect.y + b.rect.y\r\n        if (clientX >= sx && clientX <= sx + b.rect.width && clientY >= sy && clientY <= sy + b.rect.height) {\r\n          return { block: b, screenX: sx, screenY: sy }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 检测指定坐标是否命中表格边框（列边框或行边框）\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中边框时返回类型、索引、原始尺寸和表格索引，否则返回 null\r\n   */\r\n  private detectBorder(clientX: number, clientY: number): { type: 'col' | 'row'; index: number; origSize: number; tableIndex: number } | null {\r\n    const info = this.findTableAtScreen(clientX, clientY)\r\n    if (!info) return null\r\n    const { block, screenX, screenY } = info\r\n\r\n    for (let i = 0; i < block.colWidths.length; i++) {\r\n      const borderX = screenX + block.colWidths.slice(0, i + 1).reduce((a, b) => a + b, 0)\r\n      if (Math.abs(clientX - borderX) <= BORDER_HOT) {\r\n        return { type: 'col', index: i, origSize: block.colWidths[i], tableIndex: block.indexInParent }\r\n      }\r\n    }\r\n\r\n    for (let i = 0; i < block.rows.length; i++) {\r\n      const row = block.rows[i]\r\n      const borderY = screenY + row.rect.y + row.rect.height\r\n      if (Math.abs(clientY - borderY) <= BORDER_HOT) {\r\n        return { type: 'row', index: i, origSize: row.rect.height, tableIndex: block.indexInParent }\r\n      }\r\n    }\r\n\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 处理鼠标按下事件，若命中表格边框则进入拖拽状态\r\n   *\r\n   * @param e 鼠标事件\r\n   * @returns 命中边框并进入拖拽返回 true，否则返回 false\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    if (!this.deps.canEdit()) { this.resetInteraction(); return false }\r\n    if (this.dragState) return true\r\n    const border = this.detectBorder(e.clientX, e.clientY)\r\n    if (!border) return false\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    this.dragState = {\r\n      type: border.type,\r\n      tableIndex: border.tableIndex,\r\n      index: border.index,\r\n      startClient: border.type === 'col' ? e.clientX : e.clientY,\r\n      origSize: border.origSize\r\n    }\r\n    this.deps.setCursor(border.type === 'col' ? 'col-resize' : 'row-resize')\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 处理鼠标移动事件\r\n   *\r\n   * 拖拽中：根据偏移量计算并应用新的列宽/行高；\r\n   * 非拖拽：检测是否悬停在边框上以更新光标样式。\r\n   *\r\n   * @param e 鼠标事件\r\n   */\r\n  handleMouseMove(e: MouseEvent): boolean {\r\n    if (!this.deps.canEdit()) { this.resetInteraction(); return false }\r\n    if (this.dragState) {\r\n      e.preventDefault()\r\n      const delta = this.dragState.type === 'col' ? e.clientX - this.dragState.startClient : e.clientY - this.dragState.startClient\r\n      const newSize = Math.max(20, this.dragState.origSize + delta)\r\n      if (this.dragState.type === 'col') {\r\n        this.deps.onCommand('executeSetTableColWidth', this.dragState.tableIndex, this.dragState.index, newSize)\r\n      } else {\r\n        this.deps.onCommand('executeSetTableRowHeight', this.dragState.tableIndex, this.dragState.index, newSize)\r\n      }\r\n      return true\r\n    }\r\n\r\n    const border = this.detectBorder(e.clientX, e.clientY)\r\n    if (border) {\r\n      this.deps.setCursor(border.type === 'col' ? 'col-resize' : 'row-resize')\r\n      this.cursorChanged = true\r\n      return true\r\n    } else if (this.cursorChanged) {\r\n      this.deps.setCursor('default')\r\n      this.cursorChanged = false\r\n    }\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理鼠标释放事件，结束边框拖拽并恢复光标\r\n   *\r\n   * @param _e 鼠标事件（未使用）\r\n   */\r\n  handleMouseUp(_e: MouseEvent): void {\r\n    if (!this.dragState) return\r\n    this.dragState = null\r\n    this.deps.setCursor('default')\r\n    this.cursorChanged = false\r\n  }\r\n\r\n  /* -------------------- 销毁 -------------------- */\r\n\r\n  /**\r\n   * 销毁 widget，隐藏手柄和菜单并移除所有手柄 DOM\r\n   */\r\n  destroy(): void {\r\n    this.panel.hide()\r\n    this.hideHandles()\r\n    this.hideContextMenu()\r\n    if (this.handle) { this.handle.remove(); this.handle = null }\r\n    if (this.addColHandle) { this.addColHandle.remove(); this.addColHandle = null }\r\n    if (this.addRowHandle) { this.addRowHandle.remove(); this.addRowHandle = null }\r\n  }\r\n}\r\n","import type { Rect } from '../layout-types'\r\n\r\n/** Keep selection chrome clipped to the same viewport as the document canvas. */\r\nexport function createSelectionLayer(container: HTMLElement, name: string): HTMLDivElement {\r\n  const layer = document.createElement('div')\r\n  layer.className = `vervedocs-${name}-selection-layer`\r\n  layer.style.cssText = 'position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:100;display:none;'\r\n  container.appendChild(layer)\r\n  return layer\r\n}\r\n\r\nexport function updateSelectionLayer(\r\n  layer: HTMLElement,\r\n  bounds: Rect,\r\n  viewport: Pick<Rect, 'width' | 'height'>\r\n): boolean {\r\n  const visible = bounds.x < viewport.width && bounds.y < viewport.height &&\r\n    bounds.x + bounds.width > 0 && bounds.y + bounds.height > 0\r\n  layer.style.display = visible ? 'block' : 'none'\r\n  return visible\r\n}\r\n\r\n/** Place the toolbar beside the object only when it fits inside the editor. */\r\nexport function positionSelectionToolbar(toolbar: HTMLElement, bounds: Rect, layer: HTMLElement): void {\r\n  const padding = 4\r\n  const gap = 6\r\n  toolbar.style.display = 'flex'\r\n  toolbar.style.maxWidth = `${Math.max(0, layer.clientWidth - padding * 2)}px`\r\n  const width = toolbar.offsetWidth\r\n  const height = toolbar.offsetHeight\r\n  const x = Math.max(padding, Math.min(\r\n    bounds.x + bounds.width / 2 - width / 2,\r\n    layer.clientWidth - width - padding\r\n  ))\r\n  let y = bounds.y - height - gap\r\n  if (y < padding) y = bounds.y + bounds.height + gap\r\n  if (y < padding || y + height > layer.clientHeight - padding) {\r\n    toolbar.style.display = 'none'\r\n    return\r\n  }\r\n  toolbar.style.left = `${Math.round(x)}px`\r\n  toolbar.style.top = `${Math.round(y)}px`\r\n}\r\n","/**\r\n * ImageWidget —— 图片交互 widget\r\n *\r\n * 从 Draw 分离的图片 UI 交互逻辑：\r\n *  - 点击图片选中（高亮边框 + 八方向缩放手柄）\r\n *  - 拖拽手柄缩放图片\r\n *  - 悬浮工具栏（删除、重置大小、对齐方式、替换图片）\r\n *\r\n * 生命周期：create() → handleMouseDown() / update() → destroy()\r\n */\r\n\r\nimport type { DocumentLayout, ImageBlock } from '../layout-types'\r\nimport type { Path } from '@vervedoc/docx-editor-schema'\r\nimport { createSelectionLayer, positionSelectionToolbar, updateSelectionLayer } from './selection-layer'\r\n\r\n\r\n/**\r\n * ImageWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、容器信息以及触发命令等。\r\n */\r\nexport interface ImageWidgetDeps {\r\n  /** 选框裁剪层的挂载容器 */\r\n  getContainer: () => HTMLElement\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n  /** 拖拽过程中实时更新图片尺寸的回调（不写入文档，仅刷新显示） */\r\n  onUpdateImageSizeLive: (path: Path, width: number, height: number) => void\r\n}\r\n\r\n/**\r\n * 当前选中的图片信息\r\n *\r\n * 记录选中图片的路径、块数据以及所在页面的屏幕起点坐标，用于定位选中框和手柄。\r\n */\r\ninterface ImageSelection {\r\n  /** 图片在文档中的路径 */\r\n  path: Path\r\n  /** 图片块数据 */\r\n  block: ImageBlock\r\n  /** 图片所在页面的屏幕起点横坐标（像素） */\r\n  pageOriginX: number\r\n  /** 图片所在页面的屏幕起点纵坐标（像素） */\r\n  pageOriginY: number\r\n}\r\n\r\n/** 缩放手柄边长（像素） */\r\nconst HANDLE_SIZE = 8\r\n/** 缩放手柄中心偏移量（像素），用于将手柄中心对齐到图片边缘 */\r\nconst HANDLE_OFFSET = HANDLE_SIZE / 2\r\n/** 八方向缩放手柄的位置定义，x/y 为 0~1 的比例坐标 */\r\nconst HANDLES = [\r\n  { dir: 'nw', x: 0, y: 0 },\r\n  { dir: 'n', x: 0.5, y: 0 },\r\n  { dir: 'ne', x: 1, y: 0 },\r\n  { dir: 'e', x: 1, y: 0.5 },\r\n  { dir: 'se', x: 1, y: 1 },\r\n  { dir: 's', x: 0.5, y: 1 },\r\n  { dir: 'sw', x: 0, y: 1 },\r\n  { dir: 'w', x: 0, y: 0.5 },\r\n] as const\r\n\r\n/**\r\n * 图片交互 widget\r\n *\r\n * 提供图片选中高亮、八方向缩放手柄、悬浮工具栏（重置大小、旋转、对齐、\r\n * 环绕方式、替换、保存、删除等）以及拖拽缩放功能。\r\n */\r\nexport class ImageWidget {\r\n  private selectionLayer: HTMLDivElement | null = null\r\n  /** 选中高亮边框 DOM 元素 */\r\n  private selectionBox: HTMLDivElement | null = null\r\n  /** 八方向缩放手柄 DOM 元素数组 */\r\n  private handleEls: HTMLDivElement[] = []\r\n  /** 悬浮工具栏 DOM 元素 */\r\n  private toolbar: HTMLDivElement | null = null\r\n  /** 当前选中的图片信息，未选中时为 null */\r\n  private selection: ImageSelection | null = null\r\n\r\n  /** 拖拽缩放状态，未拖拽时为 null */\r\n  private dragging: { dir: string; startX: number; startY: number; origW: number; origH: number; lastW: number; lastH: number } | null = null\r\n\r\n  /**\r\n   * 构造 ImageWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ImageWidgetDeps) {}\r\n\r\n  /**\r\n   * 创建选中框、八方向缩放手柄和悬浮工具栏，统一挂载到编辑区裁剪层\r\n   */\r\n  create(): void {\r\n    this.selectionLayer = createSelectionLayer(this.deps.getContainer(), 'image')\r\n    this.selectionBox = document.createElement('div')\r\n    this.selectionBox.style.cssText = 'position:absolute;border:1.5px solid #409eff;pointer-events:none;z-index:100;box-sizing:border-box;'\r\n    this.selectionLayer.appendChild(this.selectionBox)\r\n\r\n    for (const h of HANDLES) {\r\n      const el = document.createElement('div')\r\n      el.dataset.dir = h.dir\r\n      el.style.cssText = `position:absolute;pointer-events:auto;width:${HANDLE_SIZE}px;height:${HANDLE_SIZE}px;background:#fff;border:1.5px solid #409eff;border-radius:50%;z-index:101;cursor:${this.cursorFor(h.dir)};box-sizing:border-box;`\r\n      el.addEventListener('mousedown', (e) => this.onHandleMouseDown(e, h.dir))\r\n      this.selectionLayer.appendChild(el)\r\n      this.handleEls.push(el)\r\n    }\r\n\r\n    this.toolbar = this.createToolbar()\r\n    this.selectionLayer.appendChild(this.toolbar)\r\n  }\r\n\r\n  /**\r\n   * 根据手柄方向返回对应的鼠标光标样式\r\n   *\r\n   * @param dir 手柄方向（nw/n/ne/e/se/s/sw/w）\r\n   * @returns 对应的 CSS 光标样式\r\n   */\r\n  private cursorFor(dir: string): string {\r\n    const map: Record<string, string> = {\r\n      nw: 'nwse-resize', n: 'ns-resize', ne: 'nesw-resize', e: 'ew-resize',\r\n      se: 'nwse-resize', s: 'ns-resize', sw: 'nesw-resize', w: 'ew-resize',\r\n    }\r\n    return map[dir] || 'default'\r\n  }\r\n\r\n  /**\r\n   * 创建图片悬浮工具栏\r\n   *\r\n   * 工具栏包含重置大小、旋转、预览、对齐方式、环绕方式、替换、保存、删除等按钮。\r\n   *\r\n   * @returns 创建好的工具栏 DOM 元素\r\n   */\r\n  private createToolbar(): HTMLDivElement {\r\n    const bar = document.createElement('div')\r\n    bar.style.cssText = 'position:absolute;pointer-events:auto;box-sizing:border-box;overflow-x:auto;display:none;z-index:102;background:#f5f5f5;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,0.15);padding:4px 6px;align-items:center;gap:2px;font-family:sans-serif;'\r\n\r\n    const mkBtn = (icon: string, title: string, onClick: () => void): HTMLButtonElement => {\r\n      const btn = document.createElement('button')\r\n      btn.title = title\r\n      btn.style.cssText = 'border:none;background:transparent;cursor:pointer;padding:5px;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background .15s;'\r\n      const sp = document.createElement('span')\r\n      sp.className = 'material-symbols-outlined'\r\n      sp.textContent = icon\r\n      sp.style.cssText = 'font-size:18px;color:#333;'\r\n      btn.appendChild(sp)\r\n      btn.addEventListener('mouseenter', () => { btn.style.background = '#e0e0e0' })\r\n      btn.addEventListener('mouseleave', () => { btn.style.background = 'transparent' })\r\n      btn.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n      btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); onClick() })\r\n      return btn\r\n    }\r\n    const mkSep = (): HTMLDivElement => {\r\n      const sep = document.createElement('div')\r\n      sep.style.cssText = 'width:1px;height:20px;background:#ccc;margin:0 3px;'\r\n      return sep\r\n    }\r\n\r\n    bar.appendChild(mkBtn('restore', '重置大小', () => this.fire('executeResetImageSize')))\r\n    bar.appendChild(mkBtn('rotate_right', '旋转 90°', () => this.fire('executeRotateImage')))\r\n    bar.appendChild(mkBtn('zoom_in', '预览', () => this.showPreview()))\r\n    bar.appendChild(mkSep())\r\n    bar.appendChild(mkBtn('format_align_left', '左对齐', () => this.fire('executeImageAlign', 'left')))\r\n    bar.appendChild(mkBtn('format_align_center', '居中对齐', () => this.fire('executeImageAlign', 'center')))\r\n    bar.appendChild(mkBtn('format_align_right', '右对齐', () => this.fire('executeImageAlign', 'right')))\r\n    bar.appendChild(mkSep())\r\n    bar.appendChild(mkBtn('wrap_text', '文字环绕', () => this.fire('executeImageWrap', 'surround')))\r\n    bar.appendChild(mkBtn('flip_to_front', '浮于文字上方', () => this.fire('executeImageWrap', 'float-top')))\r\n    bar.appendChild(mkBtn('flip_to_back', '浮于文字下方', () => this.fire('executeImageWrap', 'float-bottom')))\r\n    bar.appendChild(mkSep())\r\n    bar.appendChild(mkBtn('image', '替换图片', () => this.fire('executeReplaceImage')))\r\n    bar.appendChild(mkBtn('download', '保存图片', () => this.fire('executeSaveImage')))\r\n    const delBtn = mkBtn('delete', '删除图片', () => this.fire('executeDeleteImage'))\r\n    const delIcon = delBtn.querySelector('.material-symbols-outlined') as HTMLElement\r\n    delBtn.addEventListener('mouseenter', () => { delIcon.style.color = '#e53935' })\r\n    delBtn.addEventListener('mouseleave', () => { delIcon.style.color = '#333' })\r\n    bar.appendChild(delBtn)\r\n\r\n    return bar\r\n  }\r\n\r\n  /**\r\n   * 触发针对当前选中图片的编辑器命令\r\n   *\r\n   * @param cmd 命令名称\r\n   * @param args 命令参数\r\n   */\r\n  private fire(cmd: string, ...args: any[]): void {\r\n    if (!this.selection) return\r\n    this.deps.onCommand(cmd, this.selection.path, ...args)\r\n  }\r\n\r\n  /**\r\n   * 显示图片预览遮罩层\r\n   *\r\n   * 创建全屏黑色遮罩并居中展示当前选中图片的原始大小，支持点击遮罩或按 Esc 关闭。\r\n   */\r\n  private showPreview(): void {\r\n    if (!this.selection) return\r\n    const src = String((this.selection.block.block as unknown as { value?: string }).value ?? '')\r\n    if (!src) return\r\n    const rotate = Number((this.selection.block.block as unknown as { rotate?: number }).rotate ?? 0) % 360\r\n\r\n    const overlay = document.createElement('div')\r\n    Object.assign(overlay.style, {\r\n      position: 'fixed', inset: '0', zIndex: '10000',\r\n      background: 'rgba(0,0,0,.75)',\r\n      display: 'flex', alignItems: 'center', justifyContent: 'center',\r\n      cursor: 'zoom-out'\r\n    } as CSSStyleDeclaration)\r\n\r\n    const img = document.createElement('img')\r\n    img.src = src\r\n    Object.assign(img.style, {\r\n      maxWidth: '90vw', maxHeight: '90vh',\r\n      objectFit: 'contain',\r\n      boxShadow: '0 8px 32px rgba(0,0,0,.5)',\r\n      borderRadius: '4px',\r\n      transform: `rotate(${rotate}deg)`\r\n    } as CSSStyleDeclaration)\r\n    overlay.appendChild(img)\r\n\r\n    const close = () => overlay.remove()\r\n    overlay.addEventListener('mousedown', (e) => { if (e.target === overlay) close() })\r\n    const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') { close(); document.removeEventListener('keydown', onKey) } }\r\n    document.addEventListener('keydown', onKey)\r\n    document.body.appendChild(overlay)\r\n  }\r\n\r\n\r\n  /**\r\n   * 处理 mousedown，返回 true 表示点击了图片（已拦截），false 表示未处理\r\n   *\r\n   * @param e 鼠标事件\r\n   * @returns 点击命中图片返回 true，否则返回 false\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    this.clearSelection()\r\n    const hit = this.findImageAt(e.clientX, e.clientY)\r\n    if (!hit) return false\r\n\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    this.selectImage(hit)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 根据屏幕坐标查找命中的图片\r\n   *\r\n   * 同时支持独立图片块和段落环绕图片。\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中的图片选中信息，未命中返回 null\r\n   */\r\n  private findImageAt(clientX: number, clientY: number): ImageSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'image') {\r\n          const bx = pageOriginX + b.rect.x\r\n          const by = pageOriginY + b.rect.y\r\n          if (clientX >= bx && clientX <= bx + b.rect.width && clientY >= by && clientY <= by + b.rect.height) {\r\n            const path = [...b.parentPath, b.indexInParent] as Path\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        } else if (b.kind === 'paragraph' && b.surroundImage) {\r\n          const si = b.surroundImage\r\n          const bx = pageOriginX + b.rect.x + si.rect.x\r\n          const by = pageOriginY + b.rect.y\r\n          if (clientX >= bx && clientX <= bx + si.rect.width && clientY >= by && clientY <= by + si.rect.height) {\r\n            const path = [...si.parentPath, si.indexInParent] as Path\r\n            return { path, block: si, pageOriginX: pageOriginX + b.rect.x, pageOriginY: pageOriginY + b.rect.y }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 选中指定图片并刷新选中 UI\r\n   *\r\n   * @param sel 图片选中信息\r\n   */\r\n  private selectImage(sel: ImageSelection): void {\r\n    this.selection = sel\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 清除当前选中状态，隐藏选中框、手柄和工具栏\r\n   */\r\n  private clearSelection(): void {\r\n    this.selection = null\r\n    if (this.selectionLayer) this.selectionLayer.style.display = 'none'\r\n  }\r\n\r\n  /**\r\n   * 刷新选中状态\r\n   *\r\n   * 根据当前选中图片路径重新查找布局中的图片块，若已不存在则清除选中。\r\n   */\r\n  update(): void {\r\n    if (!this.selection) return\r\n    const hit = this.findImageByPath(this.selection.path)\r\n    if (!hit) { this.clearSelection(); return }\r\n    this.selection = hit\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 根据路径查找图片块\r\n   *\r\n   * @param path 图片路径\r\n   * @returns 命中的图片选中信息，未找到返回 null\r\n   */\r\n  private findImageByPath(path: Path): ImageSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'image') {\r\n          const bp = [...b.parentPath, b.indexInParent] as Path\r\n          if (bp.length === path.length && bp.every((seg, i) => seg === path[i])) {\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        } else if (b.kind === 'paragraph' && b.surroundImage) {\r\n          const si = b.surroundImage\r\n          const bp = [...si.parentPath, si.indexInParent] as Path\r\n          if (bp.length === path.length && bp.every((seg, i) => seg === path[i])) {\r\n            return { path, block: si, pageOriginX: pageOriginX + b.rect.x, pageOriginY: pageOriginY + b.rect.y }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 更新选中框、八方向手柄和悬浮工具栏的位置与显示状态\r\n   */\r\n  private updateSelectionUI(): void {\r\n    if (!this.selection || !this.selectionBox || !this.selectionLayer) return\r\n    const { block, pageOriginX, pageOriginY } = this.selection\r\n    const viewport = this.deps.getContainerRect()\r\n    const x = pageOriginX + block.rect.x - viewport.left\r\n    const y = pageOriginY + block.rect.y - viewport.top\r\n    const w = block.rect.width\r\n    const h = block.rect.height\r\n    const bounds = { x, y, width: w, height: h }\r\n    if (!updateSelectionLayer(this.selectionLayer, bounds, viewport)) return\r\n    this.selectionBox.style.left = `${Math.round(x)}px`\r\n    this.selectionBox.style.top = `${Math.round(y)}px`\r\n    this.selectionBox.style.width = `${Math.round(w)}px`\r\n    this.selectionBox.style.height = `${Math.round(h)}px`\r\n\r\n    for (let i = 0; i < this.handleEls.length; i++) {\r\n      const el = this.handleEls[i]\r\n      const hd = HANDLES[i]\r\n      el.style.left = `${Math.round(x + w * hd.x - HANDLE_OFFSET)}px`\r\n      el.style.top = `${Math.round(y + h * hd.y - HANDLE_OFFSET)}px`\r\n    }\r\n\r\n    // 悬浮工具栏：定位在图片上方居中，空间不足时放下方\r\n    if (this.toolbar) {\r\n      positionSelectionToolbar(this.toolbar, bounds, this.selectionLayer)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 处理缩放手柄的 mousedown 事件，进入拖拽缩放状态\r\n   *\r\n   * @param e 鼠标事件\r\n   * @param dir 手柄方向\r\n   */\r\n  private onHandleMouseDown(e: MouseEvent, dir: string): void {\r\n    if (!this.selection) return\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    const { block } = this.selection\r\n    this.dragging = { dir, startX: e.clientX, startY: e.clientY, origW: block.rect.width, origH: block.rect.height, lastW: block.rect.width, lastH: block.rect.height }\r\n    window.addEventListener('mousemove', this.onDragMove)\r\n    window.addEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放过程中的 mousemove 处理（箭头函数绑定）\r\n   *\r\n   * 根据手柄方向和鼠标偏移量按图片原始宽高比计算新的宽高，并实时刷新显示。\r\n   *\r\n   * @param e 鼠标事件\r\n   */\r\n  private onDragMove = (e: MouseEvent): void => {\r\n    if (!this.dragging || !this.selection) return\r\n    const dx = e.clientX - this.dragging.startX\r\n    const dy = e.clientY - this.dragging.startY\r\n    const { dir, origW, origH } = this.dragging\r\n    let w = origW\r\n    let h = origH\r\n    const ratio = origW / origH\r\n    if (dir.includes('e')) w = Math.max(20, origW + dx)\r\n    if (dir.includes('w')) w = Math.max(20, origW - dx)\r\n    if (dir.includes('s')) h = Math.max(20, origH + dy)\r\n    if (dir.includes('n')) h = Math.max(20, origH - dy)\r\n    if (dir === 'n' || dir === 's') w = h * ratio\r\n    if (dir === 'e' || dir === 'w') h = w / ratio\r\n    this.dragging.lastW = w\r\n    this.dragging.lastH = h\r\n    this.deps.onUpdateImageSizeLive(this.selection.path, w, h)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放结束的 mouseup 处理（箭头函数绑定）\r\n   *\r\n   * 将最终尺寸写入文档并清理拖拽状态和事件监听。\r\n   */\r\n  private onDragEnd = (): void => {\r\n    if (this.dragging && this.selection) {\r\n      this.deps.onCommand('executeUpdateImageSize', this.selection.path, this.dragging.lastW, this.dragging.lastH)\r\n    }\r\n    this.dragging = null\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 销毁 widget，清除选中、移除事件监听并清理所有 DOM\r\n   */\r\n  destroy(): void {\r\n    this.clearSelection()\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n    if (this.selectionLayer) { this.selectionLayer.remove(); this.selectionLayer = null }\r\n    this.selectionBox = null\r\n    this.handleEls = []\r\n    this.toolbar = null\r\n    this.dragging = null\r\n  }\r\n}\r\n","/**\r\n * ChartWidget —— 图表交互 widget\r\n *\r\n * 图表以 canvas drawImage 方式渲染（同图片），交互层独立：\r\n *  - 点击图表选中（高亮边框 + 八方向缩放手柄）\r\n *  - 拖拽手柄缩放图表\r\n *  - 悬浮工具栏（编辑图表、删除）\r\n *  - 点击或\"编辑\"按钮 → emit chartClick 事件 → 弹出编辑面板\r\n */\r\n\r\nimport type { DocumentLayout, ChartBlock } from '../layout-types'\r\nimport type { EventBus } from '@vervedoc/docx-editor-state'\r\nimport type { Path } from '@vervedoc/docx-editor-schema'\r\nimport { createSelectionLayer, positionSelectionToolbar, updateSelectionLayer } from './selection-layer'\r\n\r\n\r\n/** ChartWidget 的依赖注入接口 */\r\nexport interface ChartWidgetDeps {\r\n  /** 选框裁剪层的挂载容器 */\r\n  getContainer: () => HTMLElement\r\n  /** 获取当前文档布局 */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量 */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量 */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n  /** 拖拽过程中实时更新图表尺寸（不写入文档，仅刷新显示） */\r\n  onUpdateChartSizeLive: (path: Path, width: number, height: number) => void\r\n  /** 获取事件总线（用于发射 chartClick 事件） */\r\n  getEventBus: () => EventBus | undefined\r\n}\r\n\r\n/** 当前选中的图表信息 */\r\ninterface ChartSelection {\r\n  /** 图表在文档中的路径 */\r\n  path: Path\r\n  /** 图表块数据 */\r\n  block: ChartBlock\r\n  /** 图表所在页面的屏幕起点横坐标 */\r\n  pageOriginX: number\r\n  /** 图表所在页面的屏幕起点纵坐标 */\r\n  pageOriginY: number\r\n}\r\n\r\n/** 缩放手柄边长 */\r\nconst HANDLE_SIZE = 8\r\n/** 缩放手柄中心偏移量 */\r\nconst HANDLE_OFFSET = HANDLE_SIZE / 2\r\n/** 八方向缩放手柄定义 */\r\nconst HANDLES = [\r\n  { dir: 'nw', x: 0, y: 0 },\r\n  { dir: 'n', x: 0.5, y: 0 },\r\n  { dir: 'ne', x: 1, y: 0 },\r\n  { dir: 'e', x: 1, y: 0.5 },\r\n  { dir: 'se', x: 1, y: 1 },\r\n  { dir: 's', x: 0.5, y: 1 },\r\n  { dir: 'sw', x: 0, y: 1 },\r\n  { dir: 'w', x: 0, y: 0.5 },\r\n] as const\r\n\r\n/**\r\n * 图表交互 widget\r\n *\r\n * 提供图表选中高亮、八方向缩放手柄、悬浮工具栏（编辑、删除）以及拖拽缩放功能。\r\n */\r\nexport class ChartWidget {\r\n  private selectionLayer: HTMLDivElement | null = null\r\n  /** 选中高亮边框 DOM */\r\n  private selectionBox: HTMLDivElement | null = null\r\n  /** 缩放手柄 DOM 数组 */\r\n  private handleEls: HTMLDivElement[] = []\r\n  /** 悬浮工具栏 DOM */\r\n  private toolbar: HTMLDivElement | null = null\r\n  /** 当前选中的图表信息 */\r\n  private selection: ChartSelection | null = null\r\n  /** 拖拽缩放状态 */\r\n  private dragging: { dir: string; startX: number; startY: number; origW: number; origH: number; lastW: number; lastH: number } | null = null\r\n\r\n  /**\r\n   * 创建 ChartWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ChartWidgetDeps) {}\r\n\r\n  /**\r\n   * 创建选中框、缩放手柄和工具栏，统一挂载到编辑区裁剪层\r\n   */\r\n  create(): void {\r\n    this.selectionLayer = createSelectionLayer(this.deps.getContainer(), 'chart')\r\n    this.selectionBox = document.createElement('div')\r\n    this.selectionBox.style.cssText = 'position:absolute;border:1.5px solid #409eff;pointer-events:none;z-index:100;box-sizing:border-box;'\r\n    this.selectionLayer.appendChild(this.selectionBox)\r\n\r\n    for (const h of HANDLES) {\r\n      const el = document.createElement('div')\r\n      el.dataset.dir = h.dir\r\n      el.style.cssText = `position:absolute;pointer-events:auto;width:${HANDLE_SIZE}px;height:${HANDLE_SIZE}px;background:#fff;border:1.5px solid #409eff;border-radius:50%;z-index:101;cursor:${this.cursorFor(h.dir)};box-sizing:border-box;`\r\n      el.addEventListener('mousedown', (e) => this.onHandleMouseDown(e, h.dir))\r\n      this.selectionLayer.appendChild(el)\r\n      this.handleEls.push(el)\r\n    }\r\n\r\n    this.toolbar = this.createToolbar()\r\n    this.selectionLayer.appendChild(this.toolbar)\r\n  }\r\n\r\n  /**\r\n   * 根据手柄方向返回对应的鼠标光标样式\r\n   */\r\n  private cursorFor(dir: string): string {\r\n    const map: Record<string, string> = {\r\n      nw: 'nwse-resize', n: 'ns-resize', ne: 'nesw-resize', e: 'ew-resize',\r\n      se: 'nwse-resize', s: 'ns-resize', sw: 'nesw-resize', w: 'ew-resize',\r\n    }\r\n    return map[dir] || 'default'\r\n  }\r\n\r\n  /**\r\n   * 创建图表悬浮工具栏（编辑图表、删除）\r\n   */\r\n  private createToolbar(): HTMLDivElement {\r\n    const bar = document.createElement('div')\r\n    bar.style.cssText = 'position:absolute;pointer-events:auto;box-sizing:border-box;overflow-x:auto;display:none;z-index:102;background:#f5f5f5;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,0.15);padding:4px 6px;align-items:center;gap:2px;font-family:sans-serif;'\r\n\r\n    const mkBtn = (icon: string, title: string, onClick: () => void): HTMLButtonElement => {\r\n      const btn = document.createElement('button')\r\n      btn.title = title\r\n      btn.style.cssText = 'border:none;background:transparent;cursor:pointer;padding:5px;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background .15s;'\r\n      const sp = document.createElement('span')\r\n      sp.className = 'material-symbols-outlined'\r\n      sp.textContent = icon\r\n      sp.style.cssText = 'font-size:18px;color:#333;'\r\n      btn.appendChild(sp)\r\n      btn.addEventListener('mouseenter', () => { btn.style.background = '#e0e0e0' })\r\n      btn.addEventListener('mouseleave', () => { btn.style.background = 'transparent' })\r\n      btn.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n      btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); onClick() })\r\n      return btn\r\n    }\r\n    const mkSep = (): HTMLDivElement => {\r\n      const sep = document.createElement('div')\r\n      sep.style.cssText = 'width:1px;height:20px;background:#ccc;margin:0 3px;'\r\n      return sep\r\n    }\r\n\r\n    bar.appendChild(mkBtn('edit', '编辑图表', () => this.editChart()))\r\n    bar.appendChild(mkSep())\r\n    const delBtn = mkBtn('delete', '删除图表', () => this.deleteChart())\r\n    const delIcon = delBtn.querySelector('.material-symbols-outlined') as HTMLElement\r\n    delBtn.addEventListener('mouseenter', () => { delIcon.style.color = '#e53935' })\r\n    delBtn.addEventListener('mouseleave', () => { delIcon.style.color = '#333' })\r\n    bar.appendChild(delBtn)\r\n\r\n    return bar\r\n  }\r\n\r\n  /**\r\n   * 编辑当前选中的图表：emit chartClick 事件\r\n   */\r\n  private editChart(): void {\r\n    if (!this.selection) return\r\n    const el = this.selection.block.block as unknown as {\r\n      id?: string\r\n      block?: { chartBlock?: Record<string, unknown> }\r\n    }\r\n    const chartBlock = el.block?.chartBlock\r\n    this.deps.getEventBus()?.emit('chartClick', {\r\n      chartId: el.id ?? '',\r\n      chartType: String(chartBlock?.chartType ?? ''),\r\n      dataSource: chartBlock?.dataSource,\r\n      config: chartBlock?.config,\r\n      subtype: String(chartBlock?.subtype ?? '')\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 删除当前选中的图表\r\n   */\r\n  private deleteChart(): void {\r\n    if (!this.selection) return\r\n    this.deps.onCommand('executeDeleteBlock', this.selection.path)\r\n    this.clearSelection()\r\n  }\r\n\r\n  /**\r\n   * 处理 mousedown，返回 true 表示点击了图表（已拦截）\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    this.clearSelection()\r\n    const hit = this.findChartAt(e.clientX, e.clientY)\r\n    if (!hit) return false\r\n\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    this.selectChart(hit)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 根据屏幕坐标查找命中的图表\r\n   */\r\n  private findChartAt(clientX: number, clientY: number): ChartSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'chart') {\r\n          const bx = pageOriginX + b.rect.x\r\n          const by = pageOriginY + b.rect.y\r\n          if (clientX >= bx && clientX <= bx + b.rect.width && clientY >= by && clientY <= by + b.rect.height) {\r\n            const path = [...b.parentPath, b.indexInParent] as Path\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 选中指定图表并刷新选中 UI\r\n   */\r\n  private selectChart(sel: ChartSelection): void {\r\n    this.selection = sel\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 清除当前选中状态\r\n   */\r\n  private clearSelection(): void {\r\n    this.selection = null\r\n    if (this.selectionLayer) this.selectionLayer.style.display = 'none'\r\n  }\r\n\r\n  /**\r\n   * 刷新选中状态：按当前 path 重新查找图表块\r\n   */\r\n  update(): void {\r\n    if (!this.selection) return\r\n    const hit = this.findChartByPath(this.selection.path)\r\n    if (!hit) { this.clearSelection(); return }\r\n    this.selection = hit\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 根据路径查找图表块\r\n   */\r\n  private findChartByPath(path: Path): ChartSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'chart') {\r\n          const bp = [...b.parentPath, b.indexInParent] as Path\r\n          if (bp.length === path.length && bp.every((seg, i) => seg === path[i])) {\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 更新选中框、手柄和工具栏的位置\r\n   */\r\n  private updateSelectionUI(): void {\r\n    if (!this.selection || !this.selectionBox || !this.selectionLayer) return\r\n    const { block, pageOriginX, pageOriginY } = this.selection\r\n    const viewport = this.deps.getContainerRect()\r\n    const x = pageOriginX + block.rect.x - viewport.left\r\n    const y = pageOriginY + block.rect.y - viewport.top\r\n    const w = block.rect.width\r\n    const h = block.rect.height\r\n    const bounds = { x, y, width: w, height: h }\r\n    if (!updateSelectionLayer(this.selectionLayer, bounds, viewport)) return\r\n    this.selectionBox.style.left = `${Math.round(x)}px`\r\n    this.selectionBox.style.top = `${Math.round(y)}px`\r\n    this.selectionBox.style.width = `${Math.round(w)}px`\r\n    this.selectionBox.style.height = `${Math.round(h)}px`\r\n\r\n    for (let i = 0; i < this.handleEls.length; i++) {\r\n      const el = this.handleEls[i]\r\n      const hd = HANDLES[i]\r\n      el.style.left = `${Math.round(x + w * hd.x - HANDLE_OFFSET)}px`\r\n      el.style.top = `${Math.round(y + h * hd.y - HANDLE_OFFSET)}px`\r\n    }\r\n\r\n    if (this.toolbar) {\r\n      positionSelectionToolbar(this.toolbar, bounds, this.selectionLayer)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 处理缩放手柄的 mousedown 事件\r\n   */\r\n  private onHandleMouseDown(e: MouseEvent, dir: string): void {\r\n    if (!this.selection) return\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    const { block } = this.selection\r\n    this.dragging = { dir, startX: e.clientX, startY: e.clientY, origW: block.rect.width, origH: block.rect.height, lastW: block.rect.width, lastH: block.rect.height }\r\n    window.addEventListener('mousemove', this.onDragMove)\r\n    window.addEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放过程中的 mousemove 处理\r\n   */\r\n  private onDragMove = (e: MouseEvent): void => {\r\n    if (!this.dragging || !this.selection) return\r\n    const dx = e.clientX - this.dragging.startX\r\n    const dy = e.clientY - this.dragging.startY\r\n    const { dir, origW, origH } = this.dragging\r\n    let w = origW\r\n    let h = origH\r\n    const ratio = origW / origH\r\n    if (dir.includes('e')) w = Math.max(20, origW + dx)\r\n    if (dir.includes('w')) w = Math.max(20, origW - dx)\r\n    if (dir.includes('s')) h = Math.max(20, origH + dy)\r\n    if (dir.includes('n')) h = Math.max(20, origH - dy)\r\n    if (dir === 'n' || dir === 's') w = h * ratio\r\n    if (dir === 'e' || dir === 'w') h = w / ratio\r\n    this.dragging.lastW = w\r\n    this.dragging.lastH = h\r\n    this.deps.onUpdateChartSizeLive(this.selection.path, w, h)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放结束的 mouseup 处理\r\n   */\r\n  private onDragEnd = (): void => {\r\n    if (this.dragging && this.selection) {\r\n      this.deps.onCommand('executeUpdateChartSize', this.selection.path, this.dragging.lastW, this.dragging.lastH)\r\n    }\r\n    this.dragging = null\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 销毁 widget，清除选中、移除事件监听并清理所有 DOM\r\n   */\r\n  destroy(): void {\r\n    this.clearSelection()\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n    if (this.selectionLayer) { this.selectionLayer.remove(); this.selectionLayer = null }\r\n    this.selectionBox = null\r\n    this.handleEls = []\r\n    this.toolbar = null\r\n    this.dragging = null\r\n  }\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask\\\">\\r\\n  <div class=\\\"pw-panel pw-paragraph-panel\\\">\\r\\n    <div class=\\\"pw-panel-title\\\">段落</div>\\r\\n\\r\\n    <div class=\\\"pw-tabs\\\">\\r\\n      <div class=\\\"pw-tab pw-tab-active\\\" data-tab=\\\"indent\\\">缩进和间距</div>\\r\\n      <div class=\\\"pw-tab\\\" data-tab=\\\"break\\\">换行和分页</div>\\r\\n      <div class=\\\"pw-tab\\\" data-tab=\\\"cjk\\\">中文版式</div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"pw-panel-body\\\">\\r\\n      <!-- ===== Tab 1：缩进和间距 ===== -->\\r\\n      <div class=\\\"pw-pane pw-pane-active\\\" data-pane=\\\"indent\\\">\\r\\n\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>常规</legend>\\r\\n          <div class=\\\"pw-grid\\\">\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-align\\\">对齐方式</label>\\r\\n              <select id=\\\"pw-align\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"left\\\">左对齐</option>\\r\\n                <option value=\\\"center\\\">居中对齐</option>\\r\\n                <option value=\\\"right\\\">右对齐</option>\\r\\n                <option value=\\\"justify\\\">两端对齐</option>\\r\\n                <option value=\\\"distribute\\\">分散对齐</option>\\r\\n              </select>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-outline\\\">大纲级别</label>\\r\\n              <select id=\\\"pw-outline\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"\\\">正文文本</option>\\r\\n                <option value=\\\"first\\\">1 级</option>\\r\\n                <option value=\\\"second\\\">2 级</option>\\r\\n                <option value=\\\"third\\\">3 级</option>\\r\\n                <option value=\\\"fourth\\\">4 级</option>\\r\\n                <option value=\\\"fifth\\\">5 级</option>\\r\\n                <option value=\\\"sixth\\\">6 级</option>\\r\\n              </select>\\r\\n            </div>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>缩进</legend>\\r\\n          <div class=\\\"pw-grid\\\">\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-indent-left\\\">文本之前</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-indent-left\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.01\\\">\\r\\n              <span class=\\\"pw-unit\\\">厘米</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-special\\\">特殊格式</label>\\r\\n              <select id=\\\"pw-special\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"none\\\">无</option>\\r\\n                <option value=\\\"firstLine\\\">首行缩进</option>\\r\\n                <option value=\\\"hanging\\\">悬挂缩进</option>\\r\\n              </select>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-indent-right\\\">文本之后</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-indent-right\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.01\\\">\\r\\n              <span class=\\\"pw-unit\\\">厘米</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-special-value\\\">度量值</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-special-value\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.01\\\" disabled>\\r\\n              <span class=\\\"pw-unit\\\">厘米</span>\\r\\n            </div>\\r\\n          </div>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" disabled> 如果定义了文档网格，则自动调整右缩进</label>\\r\\n        </fieldset>\\r\\n\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>间距</legend>\\r\\n          <div class=\\\"pw-grid\\\">\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-spacing-before\\\">段前</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-spacing-before\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.5\\\">\\r\\n              <span class=\\\"pw-unit\\\">磅</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-lh-type\\\">行距</label>\\r\\n              <select id=\\\"pw-lh-type\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"single\\\">单倍行距</option>\\r\\n                <option value=\\\"1.5\\\">1.5 倍行距</option>\\r\\n                <option value=\\\"double\\\">双倍行距</option>\\r\\n                <option value=\\\"atLeast\\\">最小值</option>\\r\\n                <option value=\\\"exact\\\">固定值</option>\\r\\n                <option value=\\\"multiple\\\">多倍行距</option>\\r\\n              </select>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-spacing-after\\\">段后</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-spacing-after\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.5\\\">\\r\\n              <span class=\\\"pw-unit\\\">磅</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-lh-value\\\">设置值</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-lh-value\\\" class=\\\"pw-ctrl\\\" value=\\\"1.00\\\" min=\\\"0\\\" step=\\\"0.05\\\" disabled>\\r\\n              <span class=\\\"pw-unit\\\" id=\\\"pw-lh-unit\\\">磅</span>\\r\\n            </div>\\r\\n          </div>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" disabled> 如果定义了文档网格，则与网格对齐</label>\\r\\n        </fieldset>\\r\\n\\r\\n        <div class=\\\"pw-preview-box\\\">\\r\\n          <div class=\\\"pw-preview-label\\\">预览</div>\\r\\n          <div class=\\\"pw-preview\\\" id=\\\"pw-preview\\\">段落预览文本</div>\\r\\n        </div>\\r\\n      </div>\\r\\n\\r\\n      <!-- ===== Tab 2：换行和分页 ===== -->\\r\\n      <div class=\\\"pw-pane\\\" data-pane=\\\"break\\\">\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>分页</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-widow\\\" disabled> 孤行控制</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-keep-next\\\" disabled> 与下段同页</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-page-break-before\\\" disabled> 段前分页</label>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>换行</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-suppress-line-num\\\" disabled> 取消行号</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-suppress-auto-hyphen\\\" disabled> 取消断字</label>\\r\\n        </fieldset>\\r\\n        <div class=\\\"pw-placeholder\\\">该功能将在后续版本支持</div>\\r\\n      </div>\\r\\n\\r\\n      <!-- ===== Tab 3：中文版式 ===== -->\\r\\n      <div class=\\\"pw-pane\\\" data-pane=\\\"cjk\\\">\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>换行</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-word-wrap\\\" disabled> 按中文习惯换行</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-overflow-punct\\\" disabled> 允许标点溢出边界</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-allow-break-word\\\" disabled> 允许西文在单词中间换行</label>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>字符间距</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-compress-punct\\\" disabled> 允许行首标点压缩</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-auto-space-cjk-west\\\" disabled> 自动调整中文与西文的间距</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-auto-space-cjk-num\\\" disabled> 自动调整中文与数字的间距</label>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>文字对齐方式</legend>\\r\\n          <div class=\\\"pw-field\\\">\\r\\n            <label class=\\\"pw-field-label\\\" for=\\\"pw-text-align\\\">对齐</label>\\r\\n            <select id=\\\"pw-text-align\\\" class=\\\"pw-ctrl\\\" disabled>\\r\\n              <option value=\\\"auto\\\">自动</option>\\r\\n              <option value=\\\"top\\\">顶端对齐</option>\\r\\n              <option value=\\\"center\\\">居中</option>\\r\\n              <option value=\\\"baseline\\\">基线对齐</option>\\r\\n              <option value=\\\"bottom\\\">底端对齐</option>\\r\\n            </select>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n        <div class=\\\"pw-placeholder\\\">该功能将在后续版本支持</div>\\r\\n      </div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"pw-panel-actions\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"pw-cancel\\\">取消</button>\\r\\n      <button type=\\\"button\\\" id=\\\"pw-ok\\\">确定</button>\\r\\n    </div>\\r\\n  </div>\\r\\n</div>\\r\\n\"","/**\r\n * ParagraphLayoutWidget —— 段落设置弹出面板（对齐 Word 标准）\r\n *\r\n * 结构在 paragraph-layout-widget.html，样式在 paragraph-layout-widget.css，\r\n * 本模块负责注入资源、填充当前值、绑定事件、应用命令。\r\n * CSS 由 cssInjectedByJsPlugin 自动注入，HTML 通过 ?raw 导入字符串。\r\n */\r\nimport '../../assets/css/paragraph-layout-widget.css'\r\nimport panelHtml from '../../assets/components/paragraph-layout-widget.html?raw'\r\nimport { translatePanel, viewTranslate } from '../../view-i18n'\r\nimport type { ViewTranslate } from '../../view-i18n'\r\n\r\n/** 每厘米对应的像素数（96 DPI） */\r\nconst PX_PER_CM = 96 / 2.54\r\n\r\n/** 命令调用签名：可返回值（用于 getter） */\r\ntype CommandFn = (cmd: string, ...args: any[]) => any\r\n\r\n/** 段落设置弹出面板依赖 */\r\nexport interface ParagraphLayoutWidgetDeps {\r\n  /** 触发编辑器命令 / 读取状态 */\r\n  onCommand: CommandFn\r\n  translate?: ViewTranslate\r\n}\r\n\r\n/**\r\n * 段落设置弹出面板。\r\n *\r\n * show() 显示面板并填充当前段落值，hide() 关闭。\r\n * 确定按钮应用缩进、行距、对齐、大纲级别等命令。\r\n */\r\nexport class ParagraphLayoutWidget {\r\n  /** 面板根元素（.pw-panel-mask） */\r\n  private root: HTMLElement | null = null\r\n  /** 命令回调 */\r\n  private onCommand: CommandFn | null = null\r\n  private translate?: ViewTranslate\r\n\r\n  /** 注入依赖 */\r\n  setDeps(deps: ParagraphLayoutWidgetDeps): void {\r\n    this.onCommand = deps.onCommand\r\n    this.translate = deps.translate\r\n  }\r\n\r\n  /**\r\n   * 显示段落设置面板。\r\n   */\r\n  show(): void {\r\n    this.hide()\r\n\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.translate, 'view.paragraphDialog.')\r\n    document.body.appendChild(this.root)\r\n\r\n    this.bindTabs()\r\n    this.bindIndentSpacing()\r\n    this.root.querySelectorAll<HTMLInputElement>('input[type=\"number\"]').forEach(input => {\r\n      input.addEventListener('blur', () => {\r\n        if (input.value !== '' && Number.isFinite(input.valueAsNumber)) {\r\n          input.value = input.valueAsNumber.toFixed(2)\r\n        }\r\n      })\r\n    })\r\n    this.fillValues()\r\n    this.root.querySelector('#pw-cancel')!.addEventListener('click', () => this.hide())\r\n    this.root.querySelector('#pw-ok')!.addEventListener('click', () => {\r\n      this.apply()\r\n      this.hide()\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (!this.root) return\r\n    translatePanel(this.root, this.translate, 'view.paragraphDialog.')\r\n    this.syncLhDisabled()\r\n    this.updatePreview()\r\n  }\r\n\r\n  /**\r\n   * 关闭面板。\r\n   */\r\n  hide(): void {\r\n    if (this.root) { this.root.remove(); this.root = null }\r\n  }\r\n\r\n  /** 绑定 Tab 切换 */\r\n  private bindTabs(): void {\r\n    const tabs = this.root!.querySelectorAll<HTMLElement>('.pw-tab')\r\n    const panes = this.root!.querySelectorAll<HTMLElement>('.pw-pane')\r\n    tabs.forEach(tab => {\r\n      tab.addEventListener('click', () => {\r\n        const key = tab.dataset.tab\r\n        tabs.forEach(t => t.classList.toggle('pw-tab-active', t === tab))\r\n        panes.forEach(p => p.classList.toggle('pw-pane-active', p.dataset.pane === key))\r\n      })\r\n    })\r\n  }\r\n\r\n  /** 绑定缩进和间距 Tab 的联动交互 */\r\n  private bindIndentSpacing(): void {\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\r\n    const lhUnit = this.root!.querySelector<HTMLElement>('#pw-lh-unit')!\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\r\n\r\n    const updateLh = () => {\r\n      const t = lhType.value\r\n      lhValue.disabled = t === 'single' || t === '1.5' || t === 'double'\r\n      if (t === 'single') { lhValue.value = '1.00' }\r\n      else if (t === '1.5') { lhValue.value = '1.50' }\r\n      else if (t === 'double') { lhValue.value = '2.00' }\r\n      lhUnit.textContent = (t === 'atLeast' || t === 'exact') ? viewTranslate(this.translate, 'view.common.points') : viewTranslate(this.translate, 'view.paragraphDialog.times')\r\n      this.updatePreview()\r\n    }\r\n\r\n    const updateSpecial = () => {\r\n      const s = special.value\r\n      specialValue.disabled = s === 'none'\r\n      if (s === 'none') { specialValue.value = '0.00' }\r\n      this.updatePreview()\r\n    }\r\n\r\n    lhType.addEventListener('change', updateLh)\r\n    special.addEventListener('change', updateSpecial)\r\n    lhValue.addEventListener('input', () => this.updatePreview())\r\n    specialValue.addEventListener('input', () => this.updatePreview())\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!\r\n    align.addEventListener('change', () => this.updatePreview())\r\n  }\r\n\r\n  /** 从编辑器读取当前段落状态并填充表单 */\r\n  private fillValues(): void {\r\n    if (!this.onCommand) return\r\n    const cmd = this.onCommand\r\n    const displayNumber = (value: number) => value.toFixed(2)\r\n\r\n    let style: any = null\r\n    try { style = cmd('getRangeStyle') } catch { /* noop */ }\r\n    if (!style) {\r\n      this.root!.querySelectorAll<HTMLInputElement>('input[type=\"number\"]').forEach(input => {\r\n        input.value = Number(input.value).toFixed(2)\r\n      })\r\n      return\r\n    }\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!\r\n    align.value = style.rowFlex === 'alignment' ? 'justify' : (style.rowFlex || 'left')\r\n\r\n    const outline = this.root!.querySelector<HTMLSelectElement>('#pw-outline')!\r\n    outline.value = style.level || ''\r\n\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\r\n    const lh = Number(style.lineHeight ?? 1.5)\r\n    const rule: string = style.lineHeightRule || 'auto'\r\n    if (rule === 'exact') { lhType.value = 'exact'; lhValue.value = displayNumber(lh * 72 / 96) }\r\n    else if (rule === 'atLeast') { lhType.value = 'atLeast'; lhValue.value = displayNumber(lh * 72 / 96) }\r\n    else if (lh === 1) { lhType.value = 'single'; lhValue.value = displayNumber(1) }\r\n    else if (lh === 1.5) { lhType.value = '1.5'; lhValue.value = displayNumber(1.5) }\r\n    else if (lh === 2) { lhType.value = 'double'; lhValue.value = displayNumber(2) }\r\n    else { lhType.value = 'multiple'; lhValue.value = displayNumber(lh) }\r\n    this.syncLhDisabled()\r\n\r\n    const spacingAfter = this.root!.querySelector<HTMLInputElement>('#pw-spacing-after')!\r\n    let spAfter: number\r\n    try { spAfter = Number(cmd('getParagraphSpacingAfter')) || 0 } catch { spAfter = Number(style.rowMargin ?? 0) }\r\n    spacingAfter.value = displayNumber(spAfter)\r\n\r\n    const spacingBefore = this.root!.querySelector<HTMLInputElement>('#pw-spacing-before')!\r\n    try { spacingBefore.value = displayNumber(Number(cmd('getParagraphSpacingBefore')) || 0) } catch { /* noop */ }\r\n\r\n    const indentLeft = this.root!.querySelector<HTMLInputElement>('#pw-indent-left')!\r\n    const indentRight = this.root!.querySelector<HTMLInputElement>('#pw-indent-right')!\r\n    try { indentLeft.value = displayNumber((Number(cmd('getParagraphIndentLeft')) || 0) / PX_PER_CM) } catch { /* noop */ }\r\n    try { indentRight.value = displayNumber((Number(cmd('getParagraphIndentRight')) || 0) / PX_PER_CM) } catch { /* noop */ }\r\n\r\n    let indentPx = 0\r\n    try { indentPx = Number(cmd('getFirstLineIndent')) || 0 } catch { /* noop */ }\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\r\n    if (indentPx === 0) {\r\n      special.value = 'none'; specialValue.value = displayNumber(0)\r\n    } else if (indentPx > 0) {\r\n      special.value = 'firstLine'; specialValue.value = displayNumber(indentPx / PX_PER_CM)\r\n    } else {\r\n      special.value = 'hanging'; specialValue.value = displayNumber(Math.abs(indentPx) / PX_PER_CM)\r\n    }\r\n    this.syncSpecialDisabled()\r\n    this.root!.querySelectorAll<HTMLInputElement>('input[type=\"number\"]').forEach(input => {\r\n      input.value = Number(input.value).toFixed(2)\r\n    })\r\n\r\n    this.updatePreview()\r\n  }\r\n\r\n  /** 同步行距设置值禁用态 */\r\n  private syncLhDisabled(): void {\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\r\n    const lhUnit = this.root!.querySelector<HTMLElement>('#pw-lh-unit')!\r\n    const t = lhType.value\r\n    lhValue.disabled = t === 'single' || t === '1.5' || t === 'double'\r\n    lhUnit.textContent = (t === 'atLeast' || t === 'exact') ? viewTranslate(this.translate, 'view.common.points') : viewTranslate(this.translate, 'view.paragraphDialog.times')\r\n  }\r\n\r\n  /** 同步特殊格式度量值禁用态 */\r\n  private syncSpecialDisabled(): void {\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\r\n    specialValue.disabled = special.value === 'none'\r\n  }\r\n\r\n  /** 实时更新预览区 */\r\n  private updatePreview(): void {\r\n    const preview = this.root!.querySelector<HTMLElement>('#pw-preview')!\r\n    if (!preview) return\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!.value\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!.value\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!.value\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!.value\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!.value\r\n\r\n    const alignMap: Record<string, string> = {\r\n      left: 'left', center: 'center', right: 'right',\r\n      justify: 'justify', distribute: 'justify'\r\n    }\r\n    preview.style.textAlign = alignMap[align] || 'left'\r\n\r\n    let lh: number\r\n    if (lhType === 'single') lh = 1\r\n    else if (lhType === '1.5') lh = 1.5\r\n    else if (lhType === 'double') lh = 2\r\n    else lh = Number(lhValue) || 1.5\r\n    if (lhType === 'atLeast' || lhType === 'exact') {\r\n      preview.style.lineHeight = `${lh * 96 / 72}px`\r\n    } else {\r\n      preview.style.lineHeight = String(lh)\r\n    }\r\n\r\n    let indent = 0\r\n    if (special === 'firstLine') indent = Number(specialValue) || 0\r\n    else if (special === 'hanging') indent = -(Number(specialValue) || 0)\r\n    preview.style.textIndent = `${indent * PX_PER_CM}px`\r\n\r\n    preview.textContent = viewTranslate(this.translate, 'view.paragraphDialog.previewText')\r\n  }\r\n\r\n  /** 确定按钮：应用所有设置到编辑器 */\r\n  private apply(): void {\r\n    if (!this.onCommand) return\r\n    const cmd = this.onCommand\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!.value\r\n    cmd('executeSetRowFlex', align)\r\n\r\n    const outline = this.root!.querySelector<HTMLSelectElement>('#pw-outline')!.value\r\n    cmd('executeSetTitle', outline || null)\r\n\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!.value\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!.value\r\n    let lh: number\r\n    let rule: 'auto' | 'exact' | 'atLeast'\r\n    if (lhType === 'single') { lh = 1; rule = 'auto' }\r\n    else if (lhType === '1.5') { lh = 1.5; rule = 'auto' }\r\n    else if (lhType === 'double') { lh = 2; rule = 'auto' }\r\n    else if (lhType === 'atLeast') { lh = (Number(lhValue) || 1) * 96 / 72; rule = 'atLeast' }\r\n    else if (lhType === 'exact') { lh = (Number(lhValue) || 1) * 96 / 72; rule = 'exact' }\r\n    else { lh = Number(lhValue) || 1; rule = 'auto' }\r\n    cmd('executeSetLineHeight', lh, rule)\r\n\r\n    const spacingBefore = this.root!.querySelector<HTMLInputElement>('#pw-spacing-before')!.value\r\n    cmd('executeSetParagraphSpacingBefore', Number(spacingBefore) || 0)\r\n\r\n    const spacingAfter = this.root!.querySelector<HTMLInputElement>('#pw-spacing-after')!.value\r\n    cmd('executeSetParagraphSpacingAfter', Number(spacingAfter) || 0)\r\n\r\n    const indentLeft = this.root!.querySelector<HTMLInputElement>('#pw-indent-left')!.value\r\n    const indentRight = this.root!.querySelector<HTMLInputElement>('#pw-indent-right')!.value\r\n    cmd('executeSetParagraphIndentLeft', (Number(indentLeft) || 0) * PX_PER_CM)\r\n    cmd('executeSetParagraphIndentRight', (Number(indentRight) || 0) * PX_PER_CM)\r\n\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!.value\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!.value\r\n    let indentPx = 0\r\n    if (special === 'firstLine') indentPx = (Number(specialValue) || 0) * PX_PER_CM\r\n    else if (special === 'hanging') indentPx = -(Number(specialValue) || 0) * PX_PER_CM\r\n    cmd('executeSetFirstLineIndent', indentPx)\r\n  }\r\n}\r\n","export default \"<div class=\\\"fw-panel-mask\\\">\\r\\n  <div class=\\\"fw-panel\\\">\\r\\n    <div class=\\\"fw-panel-title\\\">字体</div>\\r\\n\\r\\n    <div class=\\\"fw-tabs\\\">\\r\\n      <div class=\\\"fw-tab fw-tab-active\\\" data-tab=\\\"font\\\">字体</div>\\r\\n      <div class=\\\"fw-tab\\\" data-tab=\\\"spacing\\\">字符间距</div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"fw-panel-body\\\">\\r\\n      <!-- ===== Tab 1：字体 ===== -->\\r\\n      <div class=\\\"fw-pane fw-pane-active\\\" data-pane=\\\"font\\\">\\r\\n        <fieldset class=\\\"fw-group\\\">\\r\\n          <legend>字体</legend>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">中文字体</span>\\r\\n            <select id=\\\"fw-font-cjk\\\" class=\\\"fw-input\\\"></select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n\\r\\n            <span class=\\\"fw-label\\\">字形</span>\\r\\n            <select id=\\\"fw-style\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"regular\\\">常规</option>\\r\\n              <option value=\\\"italic\\\">倾斜</option>\\r\\n              <option value=\\\"bold\\\">加粗</option>\\r\\n              <option value=\\\"bold-italic\\\">加粗倾斜</option>\\r\\n            </select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">字号</span>\\r\\n            <select id=\\\"fw-size\\\" class=\\\"fw-input\\\"></select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">颜色</span>\\r\\n            <input type=\\\"color\\\" id=\\\"fw-color\\\" class=\\\"fw-color\\\" value=\\\"#000000\\\">\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <fieldset class=\\\"fw-group\\\">\\r\\n          <legend>效果</legend>\\r\\n          <div class=\\\"fw-check-grid\\\">\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-strikeout\\\"> 删除线</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-underline\\\"> 下划线</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-superscript\\\"> 上标</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-subscript\\\"> 下标</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-double-strikeout\\\"> 双删除线</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-hidden\\\"> 隐藏</label>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <div class=\\\"fw-preview-box\\\">\\r\\n          <div class=\\\"fw-preview-label\\\">预览</div>\\r\\n          <div class=\\\"fw-preview\\\" id=\\\"fw-preview\\\">字体预览文本 ABCabc 123</div>\\r\\n        </div>\\r\\n      </div>\\r\\n\\r\\n      <!-- ===== Tab 2：字符间距 ===== -->\\r\\n      <div class=\\\"fw-pane\\\" data-pane=\\\"spacing\\\">\\r\\n        <fieldset class=\\\"fw-group\\\">\\r\\n          <legend>间距</legend>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">缩放</span>\\r\\n            <select id=\\\"fw-scale\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"100\\\">100%</option>\\r\\n              <option value=\\\"90\\\">90%</option>\\r\\n              <option value=\\\"80\\\">80%</option>\\r\\n              <option value=\\\"66\\\">66%</option>\\r\\n              <option value=\\\"50\\\">50%</option>\\r\\n              <option value=\\\"200\\\">200%</option>\\r\\n              <option value=\\\"150\\\">150%</option>\\r\\n            </select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">间距</span>\\r\\n            <select id=\\\"fw-spacing-type\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"normal\\\">标准</option>\\r\\n              <option value=\\\"expanded\\\">加宽</option>\\r\\n              <option value=\\\"condensed\\\">紧缩</option>\\r\\n            </select>\\r\\n            <input type=\\\"number\\\" id=\\\"fw-spacing-value\\\" class=\\\"fw-input fw-sm\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.1\\\">\\r\\n            <span class=\\\"fw-unit\\\">磅</span>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">位置</span>\\r\\n            <select id=\\\"fw-position-type\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"normal\\\">标准</option>\\r\\n              <option value=\\\"raised\\\">提升</option>\\r\\n              <option value=\\\"lowered\\\">降低</option>\\r\\n            </select>\\r\\n            <input type=\\\"number\\\" id=\\\"fw-position-value\\\" class=\\\"fw-input fw-sm\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.1\\\">\\r\\n            <span class=\\\"fw-unit\\\">磅</span>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <div class=\\\"fw-preview-box\\\">\\r\\n          <div class=\\\"fw-preview-label\\\">预览</div>\\r\\n          <div class=\\\"fw-preview\\\" id=\\\"fw-preview-spacing\\\">字符间距预览 ABCabc 123</div>\\r\\n        </div>\\r\\n\\r\\n        <div class=\\\"fw-placeholder\\\">间距与位置功能将在后续版本支持</div>\\r\\n      </div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"fw-panel-actions\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"fw-cancel\\\">取消</button>\\r\\n      <button type=\\\"button\\\" id=\\\"fw-ok\\\">确定</button>\\r\\n    </div>\\r\\n  </div>\\r\\n</div>\\r\\n\"","/**\r\n * FontLayoutWidget —— 字体设置弹出面板（对齐 Word 标准）\r\n *\r\n * 结构在 font-layout-widget.html，样式在 font-layout-widget.css，\r\n * 本模块负责注入资源、填充当前值、绑定事件、应用命令。\r\n */\r\nimport '../../assets/css/font-layout-widget.css'\r\nimport panelHtml from '../../assets/components/font-layout-widget.html?raw'\r\nimport { translatePanel, viewText, viewTranslate, type ViewTranslate } from '../../view-i18n'\r\nimport {\r\n  FONT_FAMILY_MAP,\r\n  FONT_FAMILY_LABEL,\r\n  FONT_SIZE,\r\n  FONT_SIZE_LIST\r\n} from '@vervedoc/docx-editor-schema'\r\n\r\n/** 命令调用签名：可返回值（用于 getter） */\r\ntype CommandFn = (cmd: string, ...args: any[]) => any\r\n\r\n/** 字体设置弹出面板依赖 */\r\nexport interface FontLayoutWidgetDeps {\r\n  /** 触发编辑器命令 / 读取状态 */\r\n  onCommand: CommandFn\r\n  translate?: ViewTranslate\r\n}\r\n\r\n/**\r\n * 字体设置弹出面板。\r\n *\r\n * show() 显示面板并填充当前字体值，hide() 关闭。\r\n * 确定按钮应用字体、字号、字形、颜色、效果等命令。\r\n */\r\nexport class FontLayoutWidget {\r\n  /** 面板根元素 */\r\n  private root: HTMLElement | null = null\r\n  /** 命令回调 */\r\n  private onCommand: CommandFn | null = null\r\n  private translate?: ViewTranslate\r\n\r\n  /** 注入依赖 */\r\n  setDeps(deps: FontLayoutWidgetDeps): void {\r\n    this.onCommand = deps.onCommand\r\n    this.translate = deps.translate\r\n  }\r\n\r\n  /** 显示字体设置面板 */\r\n  show(): void {\r\n    this.hide()\r\n\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.translate, 'view.font.')\r\n    document.body.appendChild(this.root)\r\n\r\n    this.fillFontOptions()\r\n    this.fillSizeOptions()\r\n    this.bindTabs()\r\n    this.bindPreview()\r\n    this.fillValues()\r\n    this.root.querySelector('#fw-cancel')!.addEventListener('click', () => this.hide())\r\n    this.root.querySelector('#fw-ok')!.addEventListener('click', () => {\r\n      this.apply()\r\n      this.hide()\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (this.root) translatePanel(this.root, this.translate, 'view.font.')\r\n  }\r\n\r\n  /** 关闭面板 */\r\n  hide(): void {\r\n    if (this.root) { this.root.remove(); this.root = null }\r\n  }\r\n\r\n  /** 填充中文字体下拉选项 */\r\n  private fillFontOptions(): void {\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!\r\n    const opts = FONT_FAMILY_MAP.map(e => {\r\n      const o = document.createElement('option')\r\n      o.value = e.value\r\n      const key = `view.fontFamily.${e.value.replace(/\\s/g, '')}`\r\n      o.textContent = key in viewText ? viewTranslate(this.translate, key) : e.label\r\n      return o\r\n    })\r\n    cjk.append(...opts)\r\n  }\r\n\r\n  /** 填充字号下拉选项 */\r\n  private fillSizeOptions(): void {\r\n    const size = this.root!.querySelector<HTMLSelectElement>('#fw-size')!\r\n    for (const item of FONT_SIZE_LIST) {\r\n      const o = document.createElement('option')\r\n      o.value = String(item)\r\n      const sizeKeys = ['chuhao', 'xiaochu', 'yihao', 'xiaoyi', 'erhao', 'xiaoer', 'sanhao', 'xiaosan', 'sihao', 'xiaosi', 'wuhao', 'xiaowu', 'liuhao', 'xiaoliu', 'qihao', 'bahao']\r\n      const index = FONT_SIZE_LIST.indexOf(item)\r\n      o.textContent = index < sizeKeys.length ? viewTranslate(this.translate, `view.fontSize.${sizeKeys[index]}`) : String(item)\r\n      size.appendChild(o)\r\n    }\r\n  }\r\n\r\n  /** 绑定 Tab 切换 */\r\n  private bindTabs(): void {\r\n    const tabs = this.root!.querySelectorAll<HTMLElement>('.fw-tab')\r\n    const panes = this.root!.querySelectorAll<HTMLElement>('.fw-pane')\r\n    tabs.forEach(tab => {\r\n      tab.addEventListener('click', () => {\r\n        const key = tab.dataset.tab\r\n        tabs.forEach(t => t.classList.toggle('fw-tab-active', t === tab))\r\n        panes.forEach(p => p.classList.toggle('fw-pane-active', p.dataset.pane === key))\r\n      })\r\n    })\r\n  }\r\n\r\n  /** 绑定实时预览 */\r\n  private bindPreview(): void {\r\n    const ids = [\r\n      '#fw-font-cjk', '#fw-style', '#fw-size', '#fw-color',\r\n      '#fw-strikeout', '#fw-underline'\r\n    ]\r\n    for (const id of ids) {\r\n      const el = this.root!.querySelector<HTMLElement>(id)!\r\n      el.addEventListener('input', () => this.updatePreview())\r\n      el.addEventListener('change', () => this.updatePreview())\r\n    }\r\n    const scale = this.root!.querySelector<HTMLElement>('#fw-scale')!\r\n    scale.addEventListener('change', () => this.updatePreviewSpacing())\r\n  }\r\n\r\n  /** 从编辑器读取当前字体状态并填充表单 */\r\n  private fillValues(): void {\r\n    if (!this.onCommand) return\r\n    let style: any = null\r\n    try { style = this.onCommand('getRangeStyle') } catch { /* noop */ }\r\n    if (!style) return\r\n\r\n    const fontValue = style.font || 'SimSun'\r\n    const fontLabel = FONT_FAMILY_LABEL[fontValue] || fontValue\r\n    const fontEntry = FONT_FAMILY_MAP.find(e => e.label === fontLabel)\r\n\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!\r\n    if (fontEntry) {\r\n      cjk.value = fontEntry.value\r\n    }\r\n\r\n    const styleSel = this.root!.querySelector<HTMLSelectElement>('#fw-style')!\r\n    const bold = !!style.bold\r\n    const italic = !!style.italic\r\n    styleSel.value = bold && italic ? 'bold-italic' : bold ? 'bold' : italic ? 'italic' : 'regular'\r\n\r\n    const sizeSel = this.root!.querySelector<HTMLSelectElement>('#fw-size')!\r\n    const pt = Number(style.size) || 10.5\r\n    const cnName = Object.keys(FONT_SIZE).find(k => FONT_SIZE[k] === pt)\r\n    sizeSel.value = cnName ? cnName : String(pt)\r\n    if (!sizeSel.value) sizeSel.value = '五号'\r\n\r\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!\r\n    color.value = style.color || '#000000'\r\n\r\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!\r\n    strikeout.checked = !!style.strikeout\r\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!\r\n    underline.checked = !!style.underline\r\n\r\n    const doubleStrikeout = this.root!.querySelector<HTMLInputElement>('#fw-double-strikeout')!\r\n    doubleStrikeout.checked = !!style.doubleStrikeout\r\n    const hidden = this.root!.querySelector<HTMLInputElement>('#fw-hidden')!\r\n    hidden.checked = !!style.hidden\r\n    const superscript = this.root!.querySelector<HTMLInputElement>('#fw-superscript')!\r\n    superscript.checked = !!style.superscript\r\n    const subscript = this.root!.querySelector<HTMLInputElement>('#fw-subscript')!\r\n    subscript.checked = !!style.subscript\r\n\r\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!\r\n    scale.value = String(style.characterScale || 100)\r\n\r\n    this.updatePreview()\r\n    this.updatePreviewSpacing()\r\n  }\r\n\r\n  /** 实时更新字体预览 */\r\n  private updatePreview(): void {\r\n    const preview = this.root!.querySelector<HTMLElement>('#fw-preview')!\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!.value\r\n    const styleVal = this.root!.querySelector<HTMLSelectElement>('#fw-style')!.value\r\n    const sizeVal = this.root!.querySelector<HTMLSelectElement>('#fw-size')!.value\r\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!.value\r\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!.checked\r\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!.checked\r\n\r\n    const entry = FONT_FAMILY_MAP.find(e => e.value === cjk)\r\n    preview.style.fontFamily = entry ? entry.css : cjk\r\n    const pt = FONT_SIZE[sizeVal] ?? Number(sizeVal) ?? 14\r\n    preview.style.fontSize = `${pt * 1.5}px`\r\n    preview.style.color = color\r\n    preview.style.fontWeight = (styleVal === 'bold' || styleVal === 'bold-italic') ? 'bold' : 'normal'\r\n    preview.style.fontStyle = (styleVal === 'italic' || styleVal === 'bold-italic') ? 'italic' : 'normal'\r\n    preview.style.textDecoration = [\r\n      underline ? 'underline' : '',\r\n      strikeout ? 'line-through' : ''\r\n    ].filter(Boolean).join(' ') || 'none'\r\n  }\r\n\r\n  /** 实时更新字符间距预览 */\r\n  private updatePreviewSpacing(): void {\r\n    const preview = this.root!.querySelector<HTMLElement>('#fw-preview-spacing')!\r\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!.value\r\n    preview.style.transform = `scaleX(${Number(scale) / 100})`\r\n    preview.style.transformOrigin = 'center'\r\n  }\r\n\r\n  /** 确定按钮：应用所有设置到编辑器 */\r\n  private apply(): void {\r\n    if (!this.onCommand) return\r\n    const cmd = this.onCommand\r\n\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!.value\r\n    cmd('executeSetFont', cjk)\r\n\r\n    const styleVal = this.root!.querySelector<HTMLSelectElement>('#fw-style')!.value\r\n    const bold = styleVal === 'bold' || styleVal === 'bold-italic'\r\n    const italic = styleVal === 'italic' || styleVal === 'bold-italic'\r\n    cmd('executeSetBold', bold)\r\n    cmd('executeSetItalic', italic)\r\n\r\n    const sizeVal = this.root!.querySelector<HTMLSelectElement>('#fw-size')!.value\r\n    const pt = FONT_SIZE[sizeVal] ?? Number(sizeVal)\r\n    if (pt) cmd('executeSetSize', pt)\r\n\r\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!.value\r\n    if (color) cmd('executeSetColor', color)\r\n\r\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!.checked\r\n    cmd('executeSetStrikeout', strikeout)\r\n\r\n    const doubleStrikeout = this.root!.querySelector<HTMLInputElement>('#fw-double-strikeout')!.checked\r\n    cmd('executeSetDoubleStrikeout', doubleStrikeout)\r\n\r\n    const hidden = this.root!.querySelector<HTMLInputElement>('#fw-hidden')!.checked\r\n    cmd('executeSetHidden', hidden)\r\n\r\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!.checked\r\n    cmd('executeSetUnderline', underline)\r\n\r\n    const superscript = this.root!.querySelector<HTMLInputElement>('#fw-superscript')!.checked\r\n    if (superscript) cmd('executeSetSuperscript')\r\n\r\n    const subscript = this.root!.querySelector<HTMLInputElement>('#fw-subscript')!.checked\r\n    if (subscript) cmd('executeSetSubscript')\r\n\r\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!.value\r\n    cmd('executeSetCharacterScale', Number(scale))\r\n  }\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask hw-mask\\\">\\r\\n  <div class=\\\"pw-panel hw-panel\\\" role=\\\"dialog\\\" aria-modal=\\\"true\\\" aria-labelledby=\\\"hw-title\\\">\\r\\n    <div class=\\\"pw-panel-title\\\" id=\\\"hw-title\\\" data-i18n-key=\\\"view.paragraph.link\\\">超链接</div>\\r\\n    <div class=\\\"hw-body\\\">\\r\\n      <label for=\\\"hw-text\\\" data-i18n-key=\\\"view.hyperlink.text\\\">显示文字</label>\\r\\n      <input id=\\\"hw-text\\\" type=\\\"text\\\" />\\r\\n      <label for=\\\"hw-url\\\" data-i18n-key=\\\"view.hyperlink.address\\\">链接地址</label>\\r\\n      <input id=\\\"hw-url\\\" type=\\\"url\\\" placeholder=\\\"https://\\\" data-i18n-placeholder=\\\"view.hyperlink.addressPlaceholder\\\" />\\r\\n      <div class=\\\"hw-error\\\" id=\\\"hw-error\\\" role=\\\"alert\\\" aria-live=\\\"polite\\\"></div>\\r\\n    </div>\\r\\n    <div class=\\\"pw-panel-actions\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"hw-cancel\\\" data-i18n-key=\\\"view.common.cancel\\\">取消</button>\\r\\n      <button type=\\\"button\\\" id=\\\"hw-ok\\\" data-i18n-key=\\\"view.common.confirm\\\">确定</button>\\r\\n    </div>\\r\\n  </div>\\r\\n</div>\\r\\n\"","import '../../assets/css/hyperlink-widget.css'\r\nimport panelHtml from '../../assets/components/hyperlink-widget.html?raw'\r\nimport { translatePanel, viewTranslate } from '../../view-i18n'\r\nimport type { ViewTranslate } from '../../view-i18n'\r\nimport type { HyperlinkInsertionError } from '@vervedoc/docx-editor-transform'\r\n\r\nexport class HyperlinkWidget {\r\n  private root: HTMLElement | null = null\r\n  private translate?: ViewTranslate\r\n  setTranslate(translate?: ViewTranslate): void {\r\n    this.translate = translate\r\n  }\r\n\r\n  private t(key: string): string {\r\n    return viewTranslate(this.translate, key)\r\n  }\r\n\r\n  show(text: string, onConfirm: (text: string, url: string) => boolean | HyperlinkInsertionError, onSuccess?: () => void): void {\r\n    this.hide()\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.translate, 'view.')\r\n    document.body.appendChild(this.root)\r\n\r\n    const root = this.root\r\n    const textInput = root.querySelector<HTMLInputElement>('#hw-text')!\r\n    const urlInput = root.querySelector<HTMLInputElement>('#hw-url')!\r\n    const error = root.querySelector<HTMLElement>('#hw-error')!\r\n    const controls: HTMLElement[] = [textInput, urlInput, root.querySelector<HTMLButtonElement>('#hw-cancel')!, root.querySelector<HTMLButtonElement>('#hw-ok')!]\r\n    const setError = (key: string, control: HTMLElement): void => {\r\n      error.dataset.i18nKey = key\r\n      error.textContent = this.t(key)\r\n      control.focus()\r\n    }\r\n    textInput.value = text\r\n    textInput.focus()\r\n    root.querySelector('#hw-cancel')!.addEventListener('click', () => this.hide())\r\n    root.querySelector('#hw-ok')!.addEventListener('click', () => {\r\n      const value = textInput.value\r\n      const url = urlInput.value.trim()\r\n      if (!value.trim()) return setError('view.hyperlink.textRequired', textInput)\r\n      if (!url) return setError('view.hyperlink.addressRequired', urlInput)\r\n      try {\r\n        if (/[\\u0000-\\u0020\\u007F]/.test(url)) return setError('view.hyperlink.addressInvalid', urlInput)\r\n        const protocol = new URL(url).protocol\r\n        if (!['http:', 'https:', 'mailto:', 'tel:', 'ftp:'].includes(protocol)) return setError('view.hyperlink.addressInvalid', urlInput)\r\n      } catch {\r\n        return setError('view.hyperlink.addressInvalid', urlInput)\r\n      }\r\n      const result = onConfirm(value, url)\r\n      if (result === true) {\r\n        this.hide()\r\n        onSuccess?.()\r\n      } else setError(`view.hyperlink.${typeof result === 'string' ? result : 'unsupported'}`, urlInput)\r\n    })\r\n    root.addEventListener('keyup', event => event.stopPropagation())\r\n    root.addEventListener('keypress', event => event.stopPropagation())\r\n    root.addEventListener('keydown', event => {\r\n      event.stopPropagation()\r\n      if (event.key === 'Escape') {\r\n        event.preventDefault()\r\n        this.hide()\r\n      } else if (event.key === 'Enter' && !event.isComposing) {\r\n        event.preventDefault()\r\n        root.querySelector<HTMLButtonElement>('#hw-ok')?.click()\r\n      } else if (event.key === 'Tab') {\r\n        event.preventDefault()\r\n        const index = controls.indexOf(document.activeElement as HTMLElement)\r\n        controls[(index + (event.shiftKey ? controls.length - 1 : 1)) % controls.length].focus()\r\n      }\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (this.root) translatePanel(this.root, this.translate, 'view.')\r\n  }\r\n\r\n  hide(): void {\r\n    this.root?.remove()\r\n    this.root = null\r\n  }\r\n}\r\n","/**\r\n * ParagraphWidget —— 段落格式悬浮 widget\r\n *\r\n * 光标在段落中或鼠标悬浮在段落上时，在首行左侧显示小图标，\r\n * 点击弹出菜单可修改标题类型、对齐方式。\r\n */\r\n\r\nimport type { DocumentLayout, ParagraphBlock, BlockNode } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Command } from '@vervedoc/docx-editor-transform'\r\nimport type { IPosition, IRangeStyle } from '@vervedoc/docx-editor-schema'\r\nimport { TITLE_LEVEL, ROW_FLEX, comparePosition } from '@vervedoc/docx-editor-schema'\r\nimport { ContextMenu, type MenuItem } from '../context-menu'\r\nimport { ParagraphLayoutWidget } from './layout/paragraph-layout-widget'\r\nimport { FontLayoutWidget } from './layout/font-layout-widget'\r\nimport { HyperlinkWidget } from './layout/hyperlink-widget'\r\nimport { positionHandle } from './handle-position'\r\nimport { viewTranslate, type ViewTranslate } from '../view-i18n'\r\nimport '../assets/css/paragraph-handle-menu.css'\r\n\r\n\r\n/**\r\n * ParagraphWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface ParagraphWidgetDeps {\r\n  translate?: ViewTranslate\r\n  /** Whether editing interactions are currently allowed. */\r\n  canEdit: () => boolean\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => any\r\n  /** 根据客户端坐标命中测试，返回位置信息或 null */\r\n  hit: (clientX: number, clientY: number) => IPosition | null\r\n  /** 临时抑制工具栏显示 */\r\n  suppressToolbar: () => void\r\n  /** 让隐藏输入区获焦，以接收后续键盘事件 */\r\n  focusInput: () => void\r\n}\r\n\r\n/**\r\n * 段落格式悬浮 widget\r\n *\r\n * 在段落首行左侧显示拖拽手柄，点击后弹出两行格式菜单，可修改标题级别和对齐方式。\r\n */\r\nexport class ParagraphWidget {\r\n  /** 段落左侧的拖拽手柄 DOM 元素 */\r\n  private handle: HTMLDivElement | null = null\r\n  /** 当前关联的段落块 */\r\n  private currentBlock: ParagraphBlock | null = null\r\n  /** 段落右键菜单控制器 */\r\n  private contextMenu = new ContextMenu()\r\n  /** 段落设置弹出面板 */\r\n  private panel = new ParagraphLayoutWidget()\r\n  /** 字体设置弹出面板 */\r\n  private fontPanel = new FontLayoutWidget()\r\n  private hyperlinkPanel = new HyperlinkWidget()\r\n\r\n  /**\r\n   * 构造 ParagraphWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ParagraphWidgetDeps) {\r\n    const onCommand = (cmd: string, ...args: any[]) => {\r\n      if (this.deps.canEdit()) return this.deps.onCommand(cmd, ...args)\r\n    }\r\n    this.panel.setDeps({ onCommand, translate: deps.translate })\r\n    this.fontPanel.setDeps({ onCommand, translate: deps.translate })\r\n    this.hyperlinkPanel.setTranslate(deps.translate)\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    this.hideMenu()\r\n    if (this.handle) {\r\n      this.handle.title = this.t('view.paragraph.format')\r\n      this.handle.setAttribute('aria-label', this.handle.title)\r\n    }\r\n    this.panel.refreshTranslations()\r\n    this.fontPanel.refreshTranslations()\r\n    this.hyperlinkPanel.refreshTranslations()\r\n  }\r\n\r\n  /**\r\n   * 创建手柄 DOM 并挂载到 document.body\r\n   *\r\n   * 手柄包含一个 drag_indicator 图标，并绑定鼠标悬停、点击等事件。\r\n   */\r\n  create(): void {\r\n    this.handle = document.createElement('div')\r\n    this.handle.className = 'vervedocs-paragraph-handle'\r\n    this.handle.setAttribute('role', 'button')\r\n    this.handle.setAttribute('aria-label', this.t('view.paragraph.format'))\r\n    this.handle.title = this.t('view.paragraph.format')\r\n    Object.assign(this.handle.style, {\r\n      position: 'fixed',\r\n      width: '22px',\r\n      height: '22px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '4px',\r\n      display: 'none',\r\n      zIndex: '99',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      boxShadow: '0 1px 3px rgba(0,0,0,.12)',\r\n      transition: 'background .15s'\r\n    } as CSSStyleDeclaration)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'drag_indicator'\r\n    icon.style.cssText = 'font-size:14px;color:#606266;'\r\n    this.handle.appendChild(icon)\r\n    this.handle.addEventListener('mouseenter', () => { this.handle!.style.background = '#f0f0f0' })\r\n    this.handle.addEventListener('mouseleave', () => { this.handle!.style.background = '#fff' })\r\n    this.handle.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n    this.handle.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); this.selectParagraph(); this.showMenu() })\r\n    this.handle.addEventListener('dblclick', (e) => { e.preventDefault(); e.stopPropagation() })\r\n    document.body.appendChild(this.handle)\r\n  }\r\n\r\n  /**\r\n   * 根据当前选区更新手柄位置\r\n   *\r\n   * 当光标位于段落中时，将手柄定位到段落首行左侧；否则隐藏手柄。\r\n   */\r\n  update(): void {\r\n    if (!this.deps.canEdit()) {\r\n      this.hide()\r\n      this.panel.hide()\r\n      this.fontPanel.hide()\r\n      this.currentBlock = null\r\n      return\r\n    }\r\n    if (!this.handle) return\r\n    this.handle.title = this.t('view.paragraph.format')\r\n    this.handle.setAttribute('aria-label', this.handle.title)\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) { this.hide(); return }\r\n\r\n    const pos = range.getFocus()\r\n    if (!pos) { this.hide(); return }\r\n\r\n    const block = this.findParagraphBlock(layout, pos)\r\n    if (!block) { this.hide(); return }\r\n\r\n    this.currentBlock = block\r\n    const rect = this.deps.getContainerRect()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n\r\n    const page = layout.pages.find(p => p.blocks.includes(block as BlockNode))\r\n    if (!page) { this.hide(); return }\r\n\r\n    const firstLine = block.lines[0]\r\n    if (!firstLine) { this.hide(); return }\r\n\r\n    const bx = rect.left + pageOffsetX + page.contentRect.x + block.rect.x\r\n    const by = rect.top - scrollY + page.contentRect.y + block.rect.y + firstLine.y\r\n    if (!positionHandle(this.handle, bx - 34, by + (firstLine.height - 22) / 2, 22, rect)) {\r\n      this.hide()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 隐藏手柄和菜单\r\n   */\r\n  private hide(): void {\r\n    if (this.handle) this.handle.style.display = 'none'\r\n    this.hideMenu()\r\n  }\r\n\r\n  /**\r\n   * 选中当前段落的所有内容\r\n   *\r\n   * 根据段落首行第一个 inline 和末行最后一个 inline 设置选区范围。\r\n   */\r\n  private selectParagraph(): void {\r\n    if (!this.deps.canEdit()) return\r\n    const range = this.deps.getRange()\r\n    if (!range || !this.currentBlock) return\r\n    const lines = this.currentBlock.lines\r\n    if (!lines.length) return\r\n    const firstLine = lines[0]\r\n    const lastLine = lines[lines.length - 1]\r\n    const firstInline = firstLine.inlines[0]\r\n    const lastInline = lastLine.inlines[lastLine.inlines.length - 1]\r\n    if (!firstInline || !lastInline) return\r\n    this.deps.suppressToolbar()\r\n    range.setRange({\r\n      anchor: { path: firstInline.path, offset: firstInline.startOffset },\r\n      focus: { path: lastInline.path, offset: lastInline.endOffset }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在文档布局中查找包含指定位置的段落块\r\n   *\r\n   * @param layout 文档布局\r\n   * @param pos 位置信息\r\n   * @returns 命中的段落块，未找到返回 null\r\n   */\r\n  private findParagraphBlock(layout: DocumentLayout, pos: IPosition): ParagraphBlock | null {\r\n    for (const page of layout.pages) {\r\n      const r = this.findParagraphInBlocks(page.blocks, pos)\r\n      if (r) return r\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 在块列表中递归查找包含指定位置的段落块\r\n   *\r\n   * 支持在表格单元格内继续递归查找。\r\n   *\r\n   * @param blocks 块列表\r\n   * @param pos 位置信息\r\n   * @returns 命中的段落块，未找到返回 null\r\n   */\r\n  private findParagraphInBlocks(blocks: BlockNode[], pos: IPosition): ParagraphBlock | null {\r\n    for (const b of blocks) {\r\n      if (b.kind === 'paragraph') {\r\n        for (const line of b.lines) {\r\n          for (const inl of line.inlines) {\r\n            if (this.pathContains(inl.path, pos.path)) return b\r\n          }\r\n        }\r\n      } else if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          for (const cell of row.cells) {\r\n            const r = this.findParagraphInBlocks(cell.content, pos)\r\n            if (r) return r\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 判断 parent 路径是否为 child 路径的前缀\r\n   *\r\n   * @param parent 父路径\r\n   * @param child 子路径\r\n   * @returns 是前缀返回 true，否则返回 false\r\n   */\r\n  private pathContains(parent: IPosition['path'], child: IPosition['path']): boolean {\r\n    if (parent.length > child.length) return false\r\n    for (let i = 0; i < parent.length; i++) {\r\n      if (parent[i] !== child[i]) return false\r\n    }\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 在手柄下方弹出格式菜单\r\n   *\r\n   * 第一行为正文和 H1-H6，第二行为五种对齐方式。\r\n   * 同时绑定滚动隐藏和点击外部关闭逻辑。\r\n   */\r\n  private t(key: string): string { return viewTranslate(this.deps.translate, key) }\r\n\r\n  private showMenu(): void {\r\n    this.hideMenu()\r\n    if (!this.deps.canEdit()) return\r\n    if (!this.handle || !this.currentBlock) return\r\n\r\n    const style: Partial<IRangeStyle> = this.deps.onCommand('getRangeStyle') ?? {}\r\n    const alignment = style.rowFlex === ROW_FLEX.ALIGNMENT ? ROW_FLEX.JUSTIFY : (style.rowFlex || ROW_FLEX.LEFT)\r\n    const menu = document.createElement('div')\r\n    menu.className = 'ce-paragraph-handle-menu'\r\n    menu.setAttribute('role', 'toolbar')\r\n    menu.setAttribute('aria-label', this.t('view.paragraph.format'))\r\n    menu.addEventListener('mousedown', e => e.preventDefault())\r\n    menu.addEventListener('keydown', e => {\r\n      e.stopPropagation()\r\n      if (e.key === 'Escape') {\r\n        this.hideMenu()\r\n        this.deps.focusInput()\r\n      }\r\n    })\r\n\r\n    const addButton = (label: string, active: boolean, command: keyof Command, value: unknown) => {\r\n      const button = document.createElement('button')\r\n      button.type = 'button'\r\n      button.title = label\r\n      button.setAttribute('aria-label', label)\r\n      button.setAttribute('aria-pressed', String(active))\r\n      button.addEventListener('click', () => {\r\n        this.hideMenu()\r\n        if (!this.deps.canEdit()) return\r\n        this.deps.onCommand(command, value)\r\n        this.deps.focusInput()\r\n      })\r\n      menu.appendChild(button)\r\n      return button\r\n    }\r\n\r\n    const levels = [null, TITLE_LEVEL.FIRST, TITLE_LEVEL.SECOND, TITLE_LEVEL.THIRD, TITLE_LEVEL.FOURTH, TITLE_LEVEL.FIFTH, TITLE_LEVEL.SIXTH]\r\n    const labels = ['body', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6'].map(key => this.t(`view.paragraph.${key}`))\r\n    levels.forEach((level, index) => {\r\n      const button = addButton(labels[index], (style.level ?? null) === level, 'executeSetTitle', level)\r\n      button.className = 'ce-paragraph-handle-menu__heading'\r\n      button.append(index === 0 ? 'T' : 'H')\r\n      if (index > 0) {\r\n        const sub = document.createElement('sub')\r\n        sub.textContent = String(index)\r\n        button.appendChild(sub)\r\n      }\r\n    })\r\n\r\n    const alignments = [\r\n      { label: this.t('view.common.leftAlign'), value: ROW_FLEX.LEFT, path: 'M4 5H19M4 12H12M4 19H19' },\r\n      { label: this.t('view.common.center'), value: ROW_FLEX.CENTER, path: 'M4 5H19M8 12H15M4 19H19' },\r\n      { label: this.t('view.common.rightAlign'), value: ROW_FLEX.RIGHT, path: 'M4 5H19M11 12H19M4 19H19' },\r\n      { label: this.t('view.common.justify'), value: ROW_FLEX.JUSTIFY, path: 'M4 5H19M4 12H19M4 19H19' },\r\n      { label: this.t('view.common.distribute'), value: ROW_FLEX.DISTRIBUTE, path: 'M3 4V20M21 4V20M7 13H17M7 19H17' }\r\n    ]\r\n    for (const item of alignments) {\r\n      const button = addButton(item.label, alignment === item.value, 'executeSetRowFlex', item.value)\r\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\r\n      svg.setAttribute('viewBox', '0 0 24 24')\r\n      svg.setAttribute('aria-hidden', 'true')\r\n      const path = document.createElementNS(svg.namespaceURI, 'path')\r\n      path.setAttribute('d', item.path)\r\n      svg.appendChild(path)\r\n      if (item.value === ROW_FLEX.DISTRIBUTE) {\r\n        const arrows = document.createElementNS(svg.namespaceURI, 'path')\r\n        arrows.setAttribute('d', 'M9 4L7 6L9 8M15 4L17 6L15 8')\r\n        arrows.setAttribute('stroke', '#527bb5')\r\n        svg.appendChild(arrows)\r\n      }\r\n      button.appendChild(svg)\r\n    }\r\n\r\n    const hx = parseFloat(this.handle.style.left)\r\n    const hy = parseFloat(this.handle.style.top)\r\n    this.contextMenu.showContent(hx, hy + 22, menu)\r\n  }\r\n\r\n  /**\r\n   * 隐藏格式菜单及其所有子菜单\r\n   */\r\n  private hideMenu(): void {\r\n    this.contextMenu.hide()\r\n  }\r\n\r\n  /**\r\n   * 显示段落右键菜单。\r\n   *\r\n   * 参照 Word 段落右键菜单，覆盖剪切/复制/粘贴、样式、对齐、缩进、行距、\r\n   * 项目符号/编号、超链接、清除格式、段落对话框等常用功能。\r\n   * 复用 ContextMenu 类，样式与表格右键菜单一致（紧凑）。\r\n   *\r\n   * @param clientX 右键横坐标（视口）\r\n   * @param clientY 右键纵坐标（视口）\r\n   * @returns 命中段落并显示菜单返回 true，否则 false\r\n   */\r\n  showContextMenu(clientX: number, clientY: number): boolean {\r\n    if (!this.deps.canEdit()) return false\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return false\r\n\r\n    const pos = this.deps.hit(clientX, clientY)\r\n    if (!pos) return false\r\n\r\n    // 表格内选区由 tableWidget 处理，此处跳过\r\n    if (pos.path.length >= 5 && pos.path[1] === 'trList') return false\r\n\r\n    const block = this.findParagraphBlock(layout, pos)\r\n    if (!block) return false\r\n\r\n    const ordered = range.getOrdered()\r\n    if (!ordered || range.isCollapsed() ||\r\n        comparePosition(pos, ordered.start) < 0 || comparePosition(pos, ordered.end) > 0) {\r\n      range.setCaret(pos)\r\n    }\r\n    this.deps.focusInput()\r\n\r\n    const icons = ContextMenu.getIcons()\r\n    const fire = (cmd: keyof Command | 'requestInsertComment', ...args: any[]) => {\r\n      if (this.deps.canEdit()) this.deps.onCommand(cmd, ...args)\r\n    }\r\n\r\n    const items: MenuItem[] = [\r\n      { label: this.t('view.paragraph.cut'), icon: 'content_cut', shortcut: 'Ctrl+X', onClick: () => fire('executeCut') },\r\n      { label: this.t('view.paragraph.copy'), icon: 'content_copy', shortcut: 'Ctrl+C', onClick: () => fire('executeCopy') },\r\n      { label: this.t('view.paragraph.paste'), icon: 'content_paste', shortcut: 'Ctrl+V', onClick: () => fire('executePaste') },\r\n      { label: '---' },\r\n      { label: this.t('view.paragraph.fontSettings'), icon: 'format_size', onClick: () => { if (this.deps.canEdit()) this.fontPanel.show() } },\r\n      { label: this.t('view.paragraph.advancedSettings'), icon: 'subject', onClick: () => { if (this.deps.canEdit()) this.panel.show() } },\r\n      { label: '---' },\r\n      { label: this.t('view.paragraph.link'), icon: icons.link, shortcut: 'Ctrl+K', onClick: () => {\r\n        if (!this.deps.canEdit()) return\r\n        const range = this.deps.getRange()\r\n        const savedRange = range?.getRange()\r\n        if (!range || !savedRange) {\r\n          this.hyperlinkPanel.show('', () => 'noSelection')\r\n          return\r\n        }\r\n        const snapshot = {\r\n          anchor: { path: savedRange.anchor.path.slice(), offset: savedRange.anchor.offset },\r\n          focus: { path: savedRange.focus.path.slice(), offset: savedRange.focus.offset }\r\n        }\r\n        const text = this.deps.onCommand('executeExtractSelectionText') as string || ''\r\n        this.hyperlinkPanel.show(text, (value, url) => {\r\n          range.setRange({\r\n            anchor: { ...snapshot.anchor, path: snapshot.anchor.path.slice() },\r\n            focus: { ...snapshot.focus, path: snapshot.focus.path.slice() }\r\n          })\r\n          const inserted = this.deps.onCommand('executeHyperlink', { url, valueList: [{ type: 'text', value }] })\r\n          return inserted === true ? true : this.deps.onCommand('getHyperlinkInsertionError') ?? false\r\n        }, () => this.deps.focusInput())\r\n      } },\r\n      { label: this.t('view.paragraph.comment'), icon: 'comment', onClick: () => fire('requestInsertComment') },\r\n\r\n    ]\r\n\r\n    this.contextMenu.show(clientX, clientY, items)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 隐藏段落右键菜单。\r\n   */\r\n  hideContextMenu(): void {\r\n    this.contextMenu.hide()\r\n  }\r\n\r\n  /**\r\n   * 销毁 widget，移除菜单和手柄 DOM 及相关事件监听\r\n   */\r\n  destroy(): void {\r\n    this.hideMenu()\r\n    this.hideContextMenu()\r\n    this.panel.hide()\r\n    this.fontPanel.hide()\r\n    this.hyperlinkPanel.hide()\r\n    if (this.handle) { this.handle.remove(); this.handle = null }\r\n  }\r\n}\r\n","/**\r\n * HeaderFooterWidget —— 页眉页脚交互 widget\r\n *\r\n * 从 Draw 分离的页眉页脚 UI 交互逻辑：\r\n *  - 双击页眉/页脚区域进入编辑\r\n *  - 双击正文区域退出编辑\r\n *  - 编辑时绘制虚线边框 + 标签栏（左侧 \"页眉 - 第 1 节\" + 居中 \"插入页码\"）\r\n *  - \"插入页码\" 弹出面板：样式 + 位置（左侧 / 居中 / 右侧）+ 确定\r\n *\r\n * 生命周期：create() → renderBorder() → destroy()\r\n */\r\n\r\nimport type { DocumentLayout } from '../layout-types'\r\nimport { viewTranslate, type ViewTranslate } from '../view-i18n'\r\n\r\n/** 文档区域类型：正文 / 页眉 / 页脚 */\r\nexport type Zone = 'main' | 'header' | 'footer'\r\n\r\n/** 页码位置：左侧 / 居中 / 右侧 */\r\nexport type PageNumberPosition = 'left' | 'center' | 'right'\r\n/** 页码样式（对齐 Word 标准） */\r\nexport type PageNumberStyle =\r\n  | '第1页'\r\n  | '第1页共x页'\r\n  | '1/x'\r\n  | '第一页'\r\n  | '第一页共X页'\r\n  | '1, 2, 3 ...'\r\n  | 'I, II, III ...'\r\n  | 'i, ii, iii ...'\r\n  | 'A, B, C ...'\r\n  | 'a, b, c ...'\r\n  | '一, 二, 三 ...'\r\n  | '壹, 贰, 叁 ...'\r\n\r\n/** 插入页码的配置选项 */\r\nexport interface PageNumberOptions {\r\n  /** 页码样式 */\r\n  style: PageNumberStyle\r\n  /** 页码位置 */\r\n  position: PageNumberPosition\r\n}\r\n\r\n/** HeaderFooterWidget 的依赖注入接口 */\r\nexport interface HeaderFooterWidgetDeps {\r\n  translate?: ViewTranslate\r\n  /** 获取当前文档布局 */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取容器元素的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移 */\r\n  getScrollY: () => number\r\n  /** 获取编辑区可视宽度 */\r\n  getWrapperWidth: () => number\r\n  /** 获取水平滚动偏移 */\r\n  getScrollLeft: () => number\r\n  /** 获取页面在容器中的水平偏移 */\r\n  getPageOffsetX: () => number\r\n  /** 获取当前所处区域 */\r\n  getZone: () => Zone\r\n  /** 设置当前所处区域 */\r\n  setZone: (zone: Zone) => void\r\n  /** 切换区域并设置初始光标到对应区域起始位置 */\r\n  setZoneWithCaret: (zone: Zone) => void\r\n  /** 让编辑区获取焦点 */\r\n  focusInput: () => void\r\n  /** 绘制页眉/页脚区域虚线边框 */\r\n  drawZoneBorder: (layout: DocumentLayout, scrollY: number, zone: 'header' | 'footer', pageOffsetX: number) => void\r\n  /** 插入页码回调（可选） */\r\n  onInsertPageNumber?: (options: PageNumberOptions) => void\r\n}\r\n\r\n/** 页眉页脚交互 widget，负责双击进入/退出编辑、虚线边框、标签栏及插入页码面板 */\r\nexport class HeaderFooterWidget {\r\n  /** 页眉标签栏容器 */\r\n  private headerLabelEl: HTMLDivElement | null = null\r\n  /** 页脚标签栏容器 */\r\n  private footerLabelEl: HTMLDivElement | null = null\r\n\r\n  /** 居中的\"插入页码\"按钮 */\r\n  private insertBtnEl: HTMLButtonElement | null = null\r\n\r\n  /** 插入页码弹出面板 */\r\n  private popupEl: HTMLDivElement | null = null\r\n  /** 弹出面板是否可见 */\r\n  private popupVisible = false\r\n\r\n  /** 面板内当前选中的页码位置 */\r\n  private selectedPosition: PageNumberPosition = 'center'\r\n  /** 面板内当前选中的页码样式 */\r\n  private selectedStyle: PageNumberStyle = '第1页'\r\n  private t(key: string): string { return viewTranslate(this.deps.translate, key) }\r\n\r\n  /** 点击面板外部时隐藏 popup 的全局 mousedown 监听 */\r\n  private onDocumentMouseDown = (e: MouseEvent) => {\r\n    if (!this.popupVisible) return\r\n    const target = e.target as Node\r\n    if (this.popupEl && this.popupEl.contains(target)) return\r\n    if (this.insertBtnEl && this.insertBtnEl.contains(target)) return\r\n    this.hidePopup()\r\n  }\r\n\r\n  /**\r\n   * 创建 HeaderFooterWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: HeaderFooterWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 创建所有 DOM 元素并绑定全局监听 */\r\n  create(): void {\r\n    this.createLabel()\r\n    this.createInsertButton()\r\n    this.createPopup()\r\n    document.addEventListener('mousedown', this.onDocumentMouseDown, true)\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    for (const [el, zone] of [[this.headerLabelEl, 'header'], [this.footerLabelEl, 'footer']] as const) {\r\n      const label = el?.querySelector('span')\r\n      if (label) label.textContent = this.t(`view.pageNumber.${zone}`)\r\n    }\r\n    if (this.insertBtnEl) {\r\n      const label = this.t('view.pageNumber.insert')\r\n      this.insertBtnEl.children[1].textContent = label\r\n      this.insertBtnEl.title = label\r\n      this.insertBtnEl.setAttribute('aria-label', label)\r\n    }\r\n    this.popupEl?.querySelectorAll<HTMLElement>('[data-i18n-key]').forEach(el => {\r\n      el.textContent = this.t(el.dataset.i18nKey!)\r\n    })\r\n    this.popupEl?.querySelector('select')?.setAttribute('aria-label', this.t('view.pageNumber.style'))\r\n    if (this.popupVisible) this.positionPopup()\r\n  }\r\n\r\n  /** 销毁 widget：移除全局监听与所有 DOM 元素并清理引用 */\r\n  destroy(): void {\r\n    document.removeEventListener('mousedown', this.onDocumentMouseDown, true)\r\n    this.headerLabelEl?.remove()\r\n    this.footerLabelEl?.remove()\r\n    this.insertBtnEl?.remove()\r\n    this.popupEl?.remove()\r\n    this.headerLabelEl = null\r\n    this.footerLabelEl = null\r\n    this.insertBtnEl = null\r\n    this.popupEl = null\r\n  }\r\n\r\n  /* -------------------- DOM 构建 -------------------- */\r\n\r\n  /** 创建左侧标签栏 DOM（页眉/页脚 - 第 N 节） */\r\n  private createLabel(): void {\r\n    const make = (text: string): { el: HTMLDivElement; textEl: HTMLSpanElement } => {\r\n      const el = document.createElement('div')\r\n      el.className = 'vervedocs-zone-label'\r\n      Object.assign(el.style, {\r\n        position: 'fixed',\r\n        display: 'none',\r\n        zIndex: '100',\r\n        alignItems: 'center',\r\n        gap: '6px',\r\n        padding: '2px 10px',\r\n        background: '#e8e8e8',\r\n        border: '1px solid #bfbfbf',\r\n        borderRadius: '0',\r\n        fontSize: '12px',\r\n        color: '#595959',\r\n        userSelect: 'none',\r\n        pointerEvents: 'auto',\r\n        fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", sans-serif',\r\n        boxShadow: 'none',\r\n      } as CSSStyleDeclaration)\r\n      const textEl = document.createElement('span')\r\n      textEl.textContent = text\r\n      el.appendChild(textEl)\r\n      document.body.appendChild(el)\r\n      return { el, textEl }\r\n    }\r\n\r\n    const h = make(this.t('view.pageNumber.header'))\r\n    this.headerLabelEl = h.el\r\n    const f = make(this.t('view.pageNumber.footer'))\r\n    this.footerLabelEl = f.el\r\n  }\r\n\r\n  /** 创建居中\"插入页码\"按钮 DOM（含图标、文字、下拉箭头及悬停态） */\r\n  private createInsertButton(): void {\r\n    const btn = document.createElement('button')\r\n    btn.className = 'vervedocs-zone-insert-pagenumber'\r\n    btn.title = this.t('view.pageNumber.insert')\r\n    btn.setAttribute('aria-label', btn.title)\r\n    Object.assign(btn.style, {\r\n      position: 'fixed',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      alignItems: 'center',\r\n      gap: '4px',\r\n      height: '22px',\r\n      padding: '0 10px',\r\n      background: '#e8e8e8',\r\n      border: '1px solid #bfbfbf',\r\n      borderRadius: '0',\r\n      fontSize: '12px',\r\n      color: '#333333',\r\n      cursor: 'pointer',\r\n      userSelect: 'none',\r\n      pointerEvents: 'auto',\r\n      fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", sans-serif',\r\n      boxShadow: 'none',\r\n    } as CSSStyleDeclaration)\r\n\r\n    // 左侧图标（灰色页码 icon，统一色调）\r\n    const icon = document.createElement('span')\r\n    icon.innerHTML =\r\n      '<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">' +\r\n      '<rect x=\"2\" y=\"1.5\" width=\"10\" height=\"11\" rx=\"1\" stroke=\"#333333\" stroke-width=\"1\"/>' +\r\n      '<text x=\"7\" y=\"9.5\" text-anchor=\"middle\" font-size=\"6.5\" fill=\"#333333\" font-family=\"Arial\" font-weight=\"600\">1</text>' +\r\n      '</svg>'\r\n    icon.style.display = 'inline-flex'\r\n    icon.style.alignItems = 'center'\r\n    btn.appendChild(icon)\r\n\r\n    const label = document.createElement('span')\r\n    label.textContent = this.t('view.pageNumber.insert')\r\n    label.style.color = '#333333'\r\n    btn.appendChild(label)\r\n\r\n    const caret = document.createElement('span')\r\n    caret.textContent = '▾'\r\n    caret.style.fontSize = '10px'\r\n    caret.style.color = '#595959'\r\n    caret.style.marginLeft = '2px'\r\n    btn.appendChild(caret)\r\n\r\n    btn.addEventListener('mouseenter', () => { btn.style.background = '#dcdcdc'; btn.style.borderColor = '#a6a6a6' })\r\n    btn.addEventListener('mouseleave', () => { btn.style.background = '#e8e8e8'; btn.style.borderColor = '#bfbfbf' })\r\n    btn.addEventListener('click', (e) => {\r\n      e.stopPropagation()\r\n      this.togglePopup()\r\n    })\r\n\r\n    this.insertBtnEl = btn\r\n    document.body.appendChild(btn)\r\n  }\r\n\r\n  /** 创建插入页码弹出面板 DOM（样式选择 + 位置预览 + 确定按钮） */\r\n  private createPopup(): void {\r\n    const popup = document.createElement('div')\r\n    popup.className = 'ce-zone-pagenumber-menu'\r\n    Object.assign(popup.style, {\r\n      position: 'fixed',\r\n      display: 'none',\r\n      zIndex: '1000',\r\n      width: '244px',\r\n      padding: '10px 14px 12px',\r\n      background: '#ffffff',\r\n      border: '1px solid #d9d9d9',\r\n      borderRadius: '5px',\r\n      boxShadow: '0 4px 14px rgba(0, 0, 0, 0.12)',\r\n      fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", sans-serif',\r\n      userSelect: 'none',\r\n    } as CSSStyleDeclaration)\r\n\r\n    // -------- 样式 --------\r\n    const styleRow = document.createElement('div')\r\n    Object.assign(styleRow.style, {\r\n      display: 'flex',\r\n      alignItems: 'center',\r\n      marginBottom: '10px',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const styleLabel = document.createElement('span')\r\n    styleLabel.dataset.i18nKey = 'view.pageNumber.style'\r\n    styleLabel.textContent = this.t('view.pageNumber.style')\r\n    Object.assign(styleLabel.style, {\r\n      width: '40px',\r\n      fontSize: '12px',\r\n      color: '#1f1f1f',\r\n      flexShrink: '0',\r\n    } as CSSStyleDeclaration)\r\n    styleRow.appendChild(styleLabel)\r\n\r\n    const styleSelect = document.createElement('select')\r\n    styleSelect.setAttribute('aria-label', this.t('view.pageNumber.style'))\r\n    Object.assign(styleSelect.style, {\r\n      flex: '1',\r\n      height: '26px',\r\n      padding: '0 8px',\r\n      fontSize: '12px',\r\n      color: '#1f1f1f',\r\n      background: '#ffffff',\r\n      border: '1px solid #cfcfcf',\r\n      borderRadius: '3px',\r\n      outline: 'none',\r\n      cursor: 'pointer',\r\n    } as CSSStyleDeclaration)\r\n    const styleOptions: PageNumberStyle[] = [\r\n      '第1页',\r\n      '第1页共x页',\r\n      '1/x',\r\n      '第一页',\r\n      '第一页共X页',\r\n      '1, 2, 3 ...',\r\n      'I, II, III ...',\r\n      'i, ii, iii ...',\r\n      'A, B, C ...',\r\n      'a, b, c ...',\r\n      '一, 二, 三 ...',\r\n      '壹, 贰, 叁 ...',\r\n    ]\r\n    styleOptions.forEach((s) => {\r\n      const opt = document.createElement('option')\r\n      opt.value = s\r\n      const styleKeys: Partial<Record<PageNumberStyle, string>> = {\r\n        '第1页': 'stylePage', '第1页共x页': 'styleTotal',\r\n        '第一页': 'styleFirst', '第一页共X页': 'styleFirstTotal'\r\n      }\r\n      if (styleKeys[s]) opt.dataset.i18nKey = `view.pageNumber.${styleKeys[s]}`\r\n      opt.textContent = styleKeys[s] ? this.t(`view.pageNumber.${styleKeys[s]}`) : s\r\n      styleSelect.appendChild(opt)\r\n    })\r\n    styleSelect.value = this.selectedStyle\r\n    styleSelect.addEventListener('change', () => {\r\n      this.selectedStyle = styleSelect.value as PageNumberStyle\r\n    })\r\n    styleRow.appendChild(styleSelect)\r\n    popup.appendChild(styleRow)\r\n\r\n    // -------- 位置 --------\r\n    const posTitle = document.createElement('div')\r\n    posTitle.dataset.i18nKey = 'view.pageNumber.position'\r\n    posTitle.textContent = this.t('view.pageNumber.position')\r\n    Object.assign(posTitle.style, {\r\n      fontSize: '12px',\r\n      color: '#1f1f1f',\r\n      marginBottom: '6px',\r\n    } as CSSStyleDeclaration)\r\n    popup.appendChild(posTitle)\r\n\r\n    const posRow = document.createElement('div')\r\n    Object.assign(posRow.style, {\r\n      display: 'flex',\r\n      gap: '12px',\r\n      justifyContent: 'flex-start',\r\n      marginBottom: '12px',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const positions: Array<{ value: PageNumberPosition; text: string }> = [\r\n      { value: 'left', text: this.t('view.pageNumber.left') },\r\n      { value: 'center', text: this.t('view.pageNumber.center') },\r\n      { value: 'right', text: this.t('view.pageNumber.right') },\r\n    ]\r\n\r\n    const posItems: Array<{ value: PageNumberPosition; el: HTMLDivElement; preview: HTMLDivElement }> = []\r\n\r\n    positions.forEach(({ value, text }) => {\r\n      const item = document.createElement('div')\r\n      Object.assign(item.style, {\r\n        display: 'inline-flex',\r\n        flexDirection: 'column',\r\n        alignItems: 'center',\r\n        gap: '4px',\r\n        cursor: 'pointer',\r\n      } as CSSStyleDeclaration)\r\n\r\n      const preview = document.createElement('div')\r\n      Object.assign(preview.style, {\r\n        position: 'relative',\r\n        display: 'flex',\r\n        flexDirection: 'column',\r\n        width: '40px',\r\n        height: '54px',\r\n        padding: '7px 5px',\r\n        background: '#ffffff',\r\n        border: '1px solid #dddddd',\r\n        borderRadius: '3px',\r\n        boxSizing: 'border-box',\r\n      } as CSSStyleDeclaration)\r\n\r\n      // 顶部数字\r\n      const num = document.createElement('span')\r\n      num.textContent = '1'\r\n      Object.assign(num.style, {\r\n        position: 'absolute',\r\n        top: '3px',\r\n        fontSize: '8px',\r\n        lineHeight: '1',\r\n        color: '#666666',\r\n      } as CSSStyleDeclaration)\r\n      if (value === 'left') { num.style.left = '5px' }\r\n      else if (value === 'right') { num.style.right = '5px' }\r\n      else { num.style.left = '50%'; num.style.transform = 'translateX(-50%)' }\r\n      preview.appendChild(num)\r\n\r\n      // 页内假的文本行\r\n      for (let i = 0; i < 5; i++) {\r\n        const line = document.createElement('div')\r\n        Object.assign(line.style, {\r\n          height: '2px',\r\n          marginTop: i === 0 ? '14px' : '3px',\r\n          background: '#dadada',\r\n          borderRadius: '999px',\r\n          width: i === 4 ? '70%' : '100%',\r\n        } as CSSStyleDeclaration)\r\n        preview.appendChild(line)\r\n      }\r\n\r\n      const textEl = document.createElement('span')\r\n      textEl.dataset.i18nKey = `view.pageNumber.${value}`\r\n      textEl.textContent = text\r\n      Object.assign(textEl.style, {\r\n        fontSize: '11px',\r\n        color: '#1f1f1f',\r\n      } as CSSStyleDeclaration)\r\n\r\n      item.appendChild(preview)\r\n      item.appendChild(textEl)\r\n      item.addEventListener('click', () => {\r\n        this.selectedPosition = value\r\n\r\n        // 更新所有项高亮\r\n        posItems.forEach((it) => {\r\n          const isActive = it.value === value\r\n          it.preview.style.background = isActive ? '#ececec' : '#ffffff'\r\n          it.preview.style.borderColor = isActive ? '#d6d6d6' : '#dddddd'\r\n          const t = it.el.querySelector('span:last-child') as HTMLSpanElement | null\r\n          if (t) t.style.color = isActive ? '#1677ff' : '#1f1f1f'\r\n        })\r\n      })\r\n\r\n      posRow.appendChild(item)\r\n      posItems.push({ value, el: item, preview })\r\n    })\r\n    popup.appendChild(posRow)\r\n\r\n    // 初始化默认选中\r\n    posItems.forEach((it) => {\r\n      const isActive = it.value === this.selectedPosition\r\n      it.preview.style.background = isActive ? '#ececec' : '#ffffff'\r\n      it.preview.style.borderColor = isActive ? '#d6d6d6' : '#dddddd'\r\n      const t = it.el.querySelector('span:last-child') as HTMLSpanElement | null\r\n      if (t) t.style.color = isActive ? '#1677ff' : '#1f1f1f'\r\n    })\r\n\r\n    // -------- 确定 --------\r\n    const footer = document.createElement('div')\r\n    Object.assign(footer.style, {\r\n      display: 'flex',\r\n      justifyContent: 'flex-end',\r\n      marginTop: '4px',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const confirmBtn = document.createElement('button')\r\n    confirmBtn.dataset.i18nKey = 'view.common.confirm'\r\n    confirmBtn.textContent = this.t('view.common.confirm')\r\n    Object.assign(confirmBtn.style, {\r\n      minWidth: '58px',\r\n      height: '26px',\r\n      padding: '0 14px',\r\n      fontSize: '12px',\r\n      color: '#ffffff',\r\n      background: '#1677ff',\r\n      border: '1px solid #1677ff',\r\n      borderRadius: '3px',\r\n      cursor: 'pointer',\r\n    } as CSSStyleDeclaration)\r\n    confirmBtn.addEventListener('mouseenter', () => {\r\n      confirmBtn.style.background = '#4096ff'\r\n      confirmBtn.style.borderColor = '#4096ff'\r\n    })\r\n    confirmBtn.addEventListener('mouseleave', () => {\r\n      confirmBtn.style.background = '#1677ff'\r\n      confirmBtn.style.borderColor = '#1677ff'\r\n    })\r\n    confirmBtn.addEventListener('click', (e) => {\r\n      e.stopPropagation()\r\n      this.deps.onInsertPageNumber?.({\r\n        style: this.selectedStyle,\r\n        position: this.selectedPosition,\r\n      })\r\n      this.hidePopup()\r\n    })\r\n    footer.appendChild(confirmBtn)\r\n    popup.appendChild(footer)\r\n\r\n    this.popupEl = popup\r\n    document.body.appendChild(popup)\r\n  }\r\n\r\n\r\n  /* -------------------- 交互 -------------------- */\r\n\r\n  /**\r\n   * 处理 mousedown 事件中的页眉/页脚交互逻辑（参照 Word 标准）。\r\n   * - 双击页眉/页脚区域：进入对应区域编辑并设置初始光标\r\n   * - 双击正文区域：若当前处于页眉/页脚编辑，切回正文\r\n   * - 单击页眉/页脚区域：若当前处于页眉/页脚编辑，切换到对应区域并命中\r\n   * - 单击正文区域：若当前处于页眉/页脚编辑，拦截事件（正文不可编辑不可选中）\r\n   * 返回 true 表示已处理（Draw 应跳过后续 hit/选词逻辑）。\r\n   * @param e 鼠标事件\r\n   * @returns 是否已处理该事件\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return false\r\n    const rect = this.deps.getContainerRect()\r\n    const docY = e.clientY - rect.top + this.deps.getScrollY()\r\n    const hitZone = this.hitZone(docY)\r\n    const currentZone = this.deps.getZone()\r\n    // 双击页眉/页脚：进入对应区域编辑\r\n    if (e.detail === 2 && (hitZone === 'header' || hitZone === 'footer')) {\r\n      this.deps.setZoneWithCaret(hitZone)\r\n      return true\r\n    }\r\n    // 双击正文 + 当前在页眉/页脚：切回正文\r\n    if (e.detail === 2 && hitZone === 'main' && currentZone !== 'main') {\r\n      this.hidePopup()\r\n      this.deps.setZone('main')\r\n      this.deps.focusInput()\r\n      return true\r\n    }\r\n    // 当前处于页眉/页脚编辑模式\r\n    if (currentZone !== 'main') {\r\n      // 单击页眉/页脚区域：切换到对应区域，让后续 hit 在对应 zone 中命中\r\n      if (hitZone === 'header' || hitZone === 'footer') {\r\n        if (hitZone !== currentZone) {\r\n          this.deps.setZoneWithCaret(hitZone)\r\n          return true\r\n        }\r\n        return false\r\n      }\r\n      // 单击正文区域：拦截事件，正文不可编辑不可选中\r\n      return true\r\n    }\r\n    return false\r\n  }\r\n\r\n\r\n  /**\r\n   * 判断文档坐标 docY 落在哪个区域\r\n   * @param docY 文档纵向坐标\r\n   * @returns 命中的区域类型\r\n   */\r\n  hitZone(docY: number): Zone {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return 'main'\r\n    for (const page of layout.pages) {\r\n      if (docY < page.rect.y || docY > page.rect.y + page.rect.height) continue\r\n      if (page.headerRect && docY >= page.headerRect.y && docY <= page.headerRect.y + page.headerRect.height) return 'header'\r\n      if (page.footerRect && docY >= page.footerRect.y && docY <= page.footerRect.y + page.footerRect.height) return 'footer'\r\n      return 'main'\r\n    }\r\n    return 'main'\r\n  }\r\n\r\n  /**\r\n   * 渲染 zone 边框 + 更新标签栏（在 overlay clearOverlay 之后调用）\r\n   * 页眉/页脚编辑模式下同时绘制两个区域的虚线边框（Word 标准行为）\r\n   */\r\n  renderBorder(): void {\r\n    const layout = this.deps.getLayout()\r\n    const zone = this.deps.getZone()\r\n    if (!layout) return\r\n\r\n    if (zone === 'main') {\r\n      this.hideLabel()\r\n      this.hideInsertButton()\r\n      this.hidePopup()\r\n      return\r\n    }\r\n\r\n    // 同时绘制页眉和页脚的虚线边框\r\n    this.deps.drawZoneBorder(layout, this.deps.getScrollY(), 'header', this.deps.getPageOffsetX())\r\n    this.deps.drawZoneBorder(layout, this.deps.getScrollY(), 'footer', this.deps.getPageOffsetX())\r\n\r\n    // 同时更新页眉和页脚标签\r\n    this.updateLabelForZone(layout, 'header')\r\n    this.updateLabelForZone(layout, 'footer')\r\n    // 居中\"插入页码\"按钮跟随当前激活区域\r\n    this.updateInsertButton(layout, zone)\r\n    // 若 popup 显示中，同步跟随按钮位置\r\n    if (this.popupVisible) this.positionPopup()\r\n  }\r\n\r\n  /**\r\n   * 更新指定区域标签栏的位置与文本\r\n   * @param layout 文档布局\r\n   * @param zone 区域（header / footer）\r\n   */\r\n  private updateLabelForZone(layout: DocumentLayout, zone: 'header' | 'footer'): void {\r\n    const el = zone === 'header' ? this.headerLabelEl : this.footerLabelEl\r\n    if (!el) return\r\n    el.querySelector('span')!.textContent = this.t(`view.pageNumber.${zone}`)\r\n    const page = layout.pages[0]\r\n    if (!page) return\r\n    const rect = zone === 'header' ? page.headerRect : page.footerRect\r\n    if (!rect) { el.style.display = 'none'; return }\r\n\r\n    const containerRect = this.deps.getContainerRect()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n\r\n    // 分隔虚线的 y（页眉：headerRect 下沿；页脚：footerRect 上沿）\r\n    const dividerDocY = zone === 'header' ? rect.y + rect.height : rect.y\r\n    const dividerScreenY = dividerDocY - scrollY + containerRect.top\r\n\r\n    // 标签贴在页面左边缘（页边距之外）并向右微移，与虚线对齐\r\n    const screenX = page.rect.x + pageOffsetX + containerRect.left + 24\r\n    const labelY = zone === 'header'\r\n      ? dividerScreenY + 1\r\n      : dividerScreenY - el.offsetHeight - 1\r\n\r\n    el.style.left = `${screenX}px`\r\n    el.style.top = `${labelY}px`\r\n    el.style.display = 'flex'\r\n  }\r\n\r\n  /**\r\n   * 更新居中\"插入页码\"按钮的位置（横向居中于页面，纵向贴齐虚线）\r\n   * @param layout 文档布局\r\n   * @param zone 当前区域（header / footer）\r\n   */\r\n  private updateInsertButton(layout: DocumentLayout, zone: 'header' | 'footer'): void {\r\n    if (!this.insertBtnEl) return\r\n    const label = this.t('view.pageNumber.insert')\r\n    this.insertBtnEl.children[1].textContent = label\r\n    this.insertBtnEl.title = label\r\n    this.insertBtnEl.setAttribute('aria-label', label)\r\n    const page = layout.pages[0]\r\n    if (!page) return\r\n    const rect = zone === 'header' ? page.headerRect : page.footerRect\r\n    if (!rect) return\r\n\r\n    const containerRect = this.deps.getContainerRect()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n\r\n    // 先显示以便可以拿到宽度\r\n    this.insertBtnEl.style.display = 'inline-flex'\r\n\r\n    // 居中于页面（沿页面横向中点）\r\n    const pageCenterX = rect.x + pageOffsetX + containerRect.left + rect.width / 2\r\n    const btnWidth = this.insertBtnEl.offsetWidth\r\n    const left = pageCenterX - btnWidth / 2\r\n\r\n    // 与虚线对齐：按钮紧贴虚线（页眉时在下方，页脚时在上方）\r\n    const dividerDocY = zone === 'header' ? rect.y + rect.height : rect.y\r\n    const dividerScreenY = dividerDocY - scrollY + containerRect.top\r\n    const btnHeight = this.insertBtnEl.offsetHeight\r\n    const top = zone === 'header'\r\n      ? dividerScreenY + 1\r\n      : dividerScreenY - btnHeight - 1\r\n\r\n    this.insertBtnEl.style.left = `${left}px`\r\n    this.insertBtnEl.style.top = `${top}px`\r\n  }\r\n\r\n  /** 隐藏所有标签栏 */\r\n  private hideLabel(): void {\r\n    if (this.headerLabelEl) this.headerLabelEl.style.display = 'none'\r\n    if (this.footerLabelEl) this.footerLabelEl.style.display = 'none'\r\n  }\r\n\r\n  /** 隐藏\"插入页码\"按钮 */\r\n  private hideInsertButton(): void {\r\n    if (this.insertBtnEl) this.insertBtnEl.style.display = 'none'\r\n  }\r\n\r\n  /* -------------------- 弹出面板 -------------------- */\r\n\r\n  /** 切换弹出面板的显示/隐藏状态 */\r\n  private togglePopup(): void {\r\n    if (this.popupVisible) this.hidePopup()\r\n    else this.showPopup()\r\n  }\r\n\r\n  /** 显示弹出面板并定位 */\r\n  private showPopup(): void {\r\n    if (!this.popupEl) return\r\n    for (const node of Array.from(this.popupEl.querySelectorAll<HTMLElement>('[data-i18n-key]'))) {\r\n      node.textContent = this.t(node.dataset.i18nKey!)\r\n    }\r\n    this.popupEl.querySelector('select')!.setAttribute('aria-label', this.t('view.pageNumber.style'))\r\n    this.popupEl.style.display = 'block'\r\n    this.popupVisible = true\r\n    this.positionPopup()\r\n  }\r\n\r\n  /** 隐藏弹出面板 */\r\n  private hidePopup(): void {\r\n    if (!this.popupEl) return\r\n    this.popupEl.style.display = 'none'\r\n    this.popupVisible = false\r\n  }\r\n\r\n  /** 根据按钮位置计算弹出面板坐标，含越界翻转处理 */\r\n  private positionPopup(): void {\r\n    if (!this.popupEl || !this.insertBtnEl) return\r\n    const btnRect = this.insertBtnEl.getBoundingClientRect()\r\n    const popupWidth = this.popupEl.offsetWidth\r\n    const popupHeight = this.popupEl.offsetHeight\r\n\r\n    let left = btnRect.left + btnRect.width / 2 - popupWidth / 2\r\n    let top = btnRect.bottom + 6\r\n\r\n    // 越界处理\r\n    const vw = window.innerWidth\r\n    const vh = window.innerHeight\r\n    if (left < 4) left = 4\r\n    if (left + popupWidth > vw - 4) left = vw - popupWidth - 4\r\n    if (top + popupHeight > vh - 4) {\r\n      // 若下方空间不足，则显示在按钮上方\r\n      top = btnRect.top - popupHeight - 6\r\n    }\r\n\r\n    this.popupEl.style.left = `${left}px`\r\n    this.popupEl.style.top = `${top}px`\r\n  }\r\n}\r\n","import type { DocumentLayout } from '../layout-types'\r\n\r\nconst PX_PER_CM = 96 / 2.54\r\nconst RULER_SIZE = 27\r\nconst BAND_START = 3\r\nconst BAND_SIZE = 17\r\nconst BACKGROUND = '#e2e2e2'\r\nconst MARGIN_BACKGROUND = '#d6d6d6'\r\nconst BORDER = '#bcbcbc'\r\n\r\n/** Positions relative to the paragraph's available content area, in document pixels. */\r\nexport interface RulerIndent {\r\n  first: number\r\n  left: number\r\n  right: number\r\n}\r\n\r\nexport interface RulerWidgetDeps {\r\n  container: HTMLDivElement\r\n  getLayout: () => DocumentLayout | null\r\n  getScrollY: () => number\r\n  getWrapperWidth: () => number\r\n  getWrapperHeight: () => number\r\n  getPageOffsetX: () => number\r\n  getScale: () => number\r\n  getPageMargins: () => [number, number, number, number]\r\n  getParagraphIndent: () => RulerIndent | null\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n}\r\n\r\ntype MarginSide = 'left' | 'right' | 'top' | 'bottom'\r\ntype IndentSide = 'first' | 'hanging' | 'indent' | 'end'\r\ntype Handle = MarginSide | IndentSide\r\nconst MARGINS: MarginSide[] = ['left', 'right', 'top', 'bottom']\r\nconst INDENTS: IndentSide[] = ['first', 'hanging', 'indent', 'end']\r\n\r\n/** Compact Word-style rulers. All screen positions use the rendered page geometry. */\r\nexport class RulerWidget {\r\n  private hRuler: HTMLDivElement | null = null\r\n  private vRuler: HTMLDivElement | null = null\r\n  private hCanvas: HTMLCanvasElement | null = null\r\n  private vCanvas: HTMLCanvasElement | null = null\r\n  private corner: HTMLDivElement | null = null\r\n  private markers = new Map<Handle, HTMLDivElement>()\r\n  private drag: { side: Handle; start: number; indent: RulerIndent | null; pageIndex: number } | null = null\r\n  private visible = false\r\n\r\n  constructor(private deps: RulerWidgetDeps) {}\r\n\r\n  create(): void {\r\n    const createRuler = (horizontal: boolean): [HTMLDivElement, HTMLCanvasElement] => {\r\n      const ruler = document.createElement('div')\r\n      ruler.className = `vervedocs-ruler-${horizontal ? 'horizontal' : 'vertical'}`\r\n      Object.assign(ruler.style, {\r\n        position: 'absolute', top: '0', left: '0', zIndex: horizontal ? '6' : '5',\r\n        background: BACKGROUND, pointerEvents: 'none', overflow: 'hidden',\r\n        ...(horizontal ? { right: '0', height: `${RULER_SIZE}px` } : { bottom: '0', width: `${RULER_SIZE}px` })\r\n      })\r\n      const canvas = document.createElement('canvas')\r\n      canvas.style.cssText = 'width:100%;height:100%;display:block;'\r\n      ruler.appendChild(canvas)\r\n      this.deps.container.appendChild(ruler)\r\n      return [ruler, canvas]\r\n    }\r\n    ;[this.hRuler, this.hCanvas] = createRuler(true)\r\n    ;[this.vRuler, this.vCanvas] = createRuler(false)\r\n    this.corner = document.createElement('div')\r\n    this.corner.style.cssText = `position:absolute;top:0;left:0;width:${RULER_SIZE}px;height:${RULER_SIZE}px;background:${BACKGROUND};z-index:8;pointer-events:none;`\r\n    this.deps.container.appendChild(this.corner)\r\n\r\n    for (const side of [...MARGINS, ...INDENTS]) {\r\n      const marker = this.createMarker(side)\r\n      this.markers.set(side, marker)\r\n      this.deps.container.appendChild(marker)\r\n    }\r\n    this.applyVisible()\r\n  }\r\n\r\n  private createMarker(side: Handle): HTMLDivElement {\r\n    const marker = document.createElement('div')\r\n    const vertical = side === 'top' || side === 'bottom'\r\n    const isMargin = MARGINS.includes(side as MarginSide)\r\n    marker.dataset.rulerHandle = side\r\n    const titles: Record<Handle, string> = {\r\n      left: '左页边距', right: '右页边距', top: '上页边距', bottom: '下页边距',\r\n      first: '首行缩进', hanging: '悬挂缩进', indent: '左缩进', end: '右缩进'\r\n    }\r\n    marker.title = titles[side]\r\n    Object.assign(marker.style, {\r\n      position: 'absolute', zIndex: isMargin ? '6' : '7', pointerEvents: 'auto',\r\n      cursor: vertical ? 'ns-resize' : 'ew-resize', touchAction: 'none',\r\n      // Keep a grab area outside the indent handles when they share the margin.\r\n      width: vertical ? `${BAND_SIZE}px` : isMargin ? '20px' : '12px',\r\n      height: vertical ? '6px' : isMargin ? `${BAND_SIZE}px` : side === 'indent' ? '6px' : '12px',\r\n      ...(vertical ? { left: `${BAND_START}px` } : {\r\n        top: `${isMargin ? BAND_START : side === 'first' ? 0 : side === 'indent' ? 20 : 9}px`\r\n      })\r\n    })\r\n    if (!isMargin) {\r\n      const canvas = document.createElement('canvas')\r\n      const height = side === 'indent' ? 6 : 12\r\n      const dpr = window.devicePixelRatio || 1\r\n      canvas.width = Math.round(12 * dpr)\r\n      canvas.height = Math.round(height * dpr)\r\n      canvas.style.cssText = `display:block;width:12px;height:${height}px;pointer-events:none;`\r\n      const ctx = canvas.getContext('2d')!\r\n      ctx.scale(dpr, dpr)\r\n      ctx.fillStyle = '#fff'\r\n      ctx.strokeStyle = '#666'\r\n      ctx.lineWidth = 1\r\n      ctx.beginPath()\r\n      if (side === 'indent') {\r\n        ctx.rect(0.5, 0.5, 11, 5)\r\n      } else if (side === 'first') {\r\n        ctx.moveTo(0.5, 0.5)\r\n        ctx.lineTo(11.5, 0.5)\r\n        ctx.lineTo(11.5, 4.5)\r\n        ctx.lineTo(6, 11.5)\r\n        ctx.lineTo(0.5, 4.5)\r\n        ctx.closePath()\r\n      } else {\r\n        ctx.moveTo(6, 0.5)\r\n        ctx.lineTo(11.5, 6.5)\r\n        ctx.lineTo(11.5, 10.5)\r\n        ctx.lineTo(0.5, 10.5)\r\n        ctx.lineTo(0.5, 6.5)\r\n        ctx.closePath()\r\n      }\r\n      ctx.fill()\r\n      ctx.stroke()\r\n      marker.appendChild(canvas)\r\n    }\r\n    marker.addEventListener('mousedown', (event) => {\r\n      if (event.button !== 0) return\r\n      event.preventDefault()\r\n      event.stopPropagation()\r\n      this.drag = {\r\n        side, start: event.clientX, indent: this.deps.getParagraphIndent(),\r\n        pageIndex: this.getVerticalPage()?.index ?? 0\r\n      }\r\n      window.addEventListener('mousemove', this.onDragMove)\r\n      window.addEventListener('mouseup', this.onDragEnd)\r\n      window.addEventListener('blur', this.onDragEnd)\r\n    })\r\n    return marker\r\n  }\r\n\r\n  private getVerticalPage() {\r\n    const page = this.deps.getLayout()?.pages[0]\r\n    const scrollY = this.deps.getScrollY()\r\n    return page && page.rect.y + page.rect.height > scrollY + RULER_SIZE &&\r\n      page.rect.y - scrollY < this.deps.getWrapperHeight() ? page : undefined\r\n  }\r\n\r\n  private onDragMove = (event: MouseEvent): void => {\r\n    const drag = this.drag\r\n    const layout = this.deps.getLayout()\r\n    if (!drag || !layout) return\r\n    event.preventDefault()\r\n    const scale = this.deps.getScale()\r\n    const rect = this.deps.container.getBoundingClientRect()\r\n    const pageX = this.deps.getPageOffsetX()\r\n    const [mt, mr, mb, ml] = this.deps.getPageMargins()\r\n    const width = layout.pageWidth / scale\r\n    const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(Math.max(min, max), value))\r\n    if (INDENTS.includes(drag.side as IndentSide)) {\r\n      if (!drag.indent) return\r\n      const next = { ...drag.indent }\r\n      const contentWidth = width - ml - mr\r\n      const movement = (event.clientX - drag.start) / scale\r\n      const limit = contentWidth - next.right - 20\r\n      if (drag.side === 'first') next.first = clamp(next.first + movement, 0, limit)\r\n      if (drag.side === 'hanging') next.left = clamp(next.left + movement, 0, limit)\r\n      if (drag.side === 'end') next.right = clamp(next.right - movement, 0, contentWidth - Math.max(next.first, next.left) - 20)\r\n      if (drag.side === 'indent') {\r\n        const delta = clamp(movement,\r\n          -Math.min(next.first, next.left), limit - Math.max(next.first, next.left))\r\n        next.first += delta\r\n        next.left += delta\r\n      }\r\n      this.deps.onCommand('executeSetRulerIndent', next.first, next.left, next.right)\r\n      return\r\n    }\r\n    const page = layout.pages[drag.pageIndex]\r\n    if (!page) return\r\n    const height = page.rect.height / scale\r\n    const y = (event.clientY - rect.top + this.deps.getScrollY() - page.rect.y) / scale\r\n    const x = (event.clientX - rect.left - pageX) / scale\r\n    const margins: [number, number, number, number] = [mt, mr, mb, ml]\r\n    if (drag.side === 'left') margins[3] = clamp(x, 0, width - mr - 50)\r\n    if (drag.side === 'right') margins[1] = clamp(width - x, 0, width - ml - 50)\r\n    if (drag.side === 'top') margins[0] = clamp(y, 0, height - mb - 50)\r\n    if (drag.side === 'bottom') margins[2] = clamp(height - y, 0, height - mt - 50)\r\n    this.deps.onCommand('executeSetPaperMargin', margins)\r\n  }\r\n\r\n  private onDragEnd = (): void => {\r\n    this.drag = null\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n    window.removeEventListener('blur', this.onDragEnd)\r\n  }\r\n\r\n  setVisible(visible: boolean): void {\r\n    this.visible = visible\r\n    if (!visible) this.onDragEnd()\r\n    this.applyVisible()\r\n    if (visible) this.update()\r\n  }\r\n\r\n  private applyVisible(): void {\r\n    for (const element of [this.hRuler, this.vRuler, this.corner, ...this.markers.values()]) {\r\n      if (element) element.style.display = this.visible ? 'block' : 'none'\r\n    }\r\n  }\r\n\r\n  update(): void {\r\n    if (!this.visible || !this.hCanvas || !this.vCanvas) return\r\n    this.drawHorizontal()\r\n    this.drawVertical()\r\n    this.updateMarkers()\r\n  }\r\n\r\n  private updateMarkers(): void {\r\n    const layout = this.deps.getLayout()\r\n    const page = this.getVerticalPage()\r\n    const scale = this.deps.getScale()\r\n    const [mt, mr, mb, ml] = this.deps.getPageMargins()\r\n    const start = this.deps.getPageOffsetX() + ml * scale\r\n    const end = this.deps.getPageOffsetX() + (layout?.pageWidth ?? 0) - mr * scale\r\n    const indent = this.deps.getParagraphIndent()\r\n    const positions: Record<Handle, number> = {\r\n      left: start, right: end,\r\n      top: (page?.rect.y ?? 0) - this.deps.getScrollY() + mt * scale,\r\n      bottom: (page?.rect.y ?? 0) + (page?.rect.height ?? 0) - this.deps.getScrollY() - mb * scale,\r\n      first: start + (indent?.first ?? 0) * scale,\r\n      hanging: start + (indent?.left ?? 0) * scale,\r\n      indent: start + (indent?.left ?? 0) * scale,\r\n      end: end - (indent?.right ?? 0) * scale\r\n    }\r\n    for (const [side, marker] of this.markers) {\r\n      const vertical = side === 'top' || side === 'bottom'\r\n      const isMargin = MARGINS.includes(side as MarginSide)\r\n      const position = Math.round(positions[side])\r\n      const max = vertical ? this.deps.getWrapperHeight() : this.deps.getWrapperWidth()\r\n      marker.style.display = layout && (!vertical || page) && (isMargin || indent) &&\r\n        position >= RULER_SIZE + 6 && position <= max - 6 ? 'block' : 'none'\r\n      marker.style[vertical ? 'top' : 'left'] = `${position - (isMargin ? vertical ? 3 : 10 : 6)}px`\r\n    }\r\n  }\r\n\r\n  private prepareCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {\r\n    const dpr = window.devicePixelRatio || 1\r\n    canvas.width = Math.max(1, Math.round(width * dpr))\r\n    canvas.height = Math.max(1, Math.round(height * dpr))\r\n    const ctx = canvas.getContext('2d')!\r\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n    ctx.clearRect(0, 0, width, height)\r\n    return ctx\r\n  }\r\n\r\n  /** The same 17px band is used horizontally and vertically (via a canvas transform). */\r\n  private drawBand(ctx: CanvasRenderingContext2D, start: number, end: number, origin: number, contentEnd: number, viewport: number): void {\r\n    const step = PX_PER_CM * this.deps.getScale()\r\n    const center = BAND_START + BAND_SIZE / 2\r\n    ctx.fillStyle = MARGIN_BACKGROUND\r\n    ctx.fillRect(start, BAND_START, end - start, BAND_SIZE)\r\n    ctx.fillStyle = '#fff'\r\n    ctx.fillRect(origin, BAND_START, Math.max(0, contentEnd - origin), BAND_SIZE)\r\n    ctx.strokeStyle = BORDER\r\n    ctx.lineWidth = 1\r\n    ctx.strokeRect(Math.round(start) + 0.5, BAND_START + 0.5, Math.round(end) - Math.round(start) - 1, BAND_SIZE - 1)\r\n    ctx.save()\r\n    ctx.beginPath()\r\n    ctx.rect(start + 1, BAND_START + 1, Math.max(0, end - start - 2), BAND_SIZE - 2)\r\n    ctx.clip()\r\n    ctx.strokeStyle = '#363636'\r\n    ctx.fillStyle = '#161616'\r\n    ctx.font = '11px Arial, sans-serif'\r\n    ctx.textAlign = 'center'\r\n    ctx.textBaseline = 'middle'\r\n    const firstTick = Math.ceil((Math.max(start, 0) - origin) / step * 4)\r\n    const lastTick = Math.floor((Math.min(end, viewport) - origin) / step * 4)\r\n    for (let tick = firstTick; tick <= lastTick; tick++) {\r\n      const x = Math.round(origin + tick * step / 4) + 0.5\r\n      if (tick % 4 === 0) {\r\n        if (tick !== 0) ctx.fillText(String(Math.abs(tick / 4)), x, center)\r\n      } else {\r\n        const height = tick % 2 === 0 ? 5 : 3\r\n        ctx.beginPath()\r\n        ctx.moveTo(x, Math.round(center - height / 2))\r\n        ctx.lineTo(x, Math.round(center + height / 2))\r\n        ctx.stroke()\r\n      }\r\n    }\r\n    ctx.restore()\r\n  }\r\n\r\n  private drawHorizontal(): void {\r\n    const width = this.deps.getWrapperWidth()\r\n    const ctx = this.prepareCanvas(this.hCanvas!, width, RULER_SIZE)\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return\r\n    const scale = this.deps.getScale()\r\n    const start = this.deps.getPageOffsetX()\r\n    const end = start + layout.pageWidth\r\n    const [, mr, , ml] = this.deps.getPageMargins()\r\n    const origin = start + ml * scale\r\n    const contentEnd = end - mr * scale\r\n    this.drawBand(ctx, start, end, origin, contentEnd, width)\r\n    // Default tab stops sit below the band, starting at the text origin.\r\n    const tabStep = PX_PER_CM * 1.25 * scale\r\n    ctx.strokeStyle = '#777'\r\n    ctx.beginPath()\r\n    for (let x = origin + tabStep; x < Math.min(contentEnd, width); x += tabStep) {\r\n      if (x < 0) continue\r\n      const aligned = Math.round(x) + 0.5\r\n      ctx.moveTo(aligned, 22)\r\n      ctx.lineTo(aligned, 25)\r\n    }\r\n    ctx.stroke()\r\n  }\r\n\r\n  private drawVertical(): void {\r\n    const page = this.getVerticalPage()\r\n    if (!page) {\r\n      this.vRuler!.style.display = 'none'\r\n      return\r\n    }\r\n    const start = page.rect.y - this.deps.getScrollY()\r\n    const end = start + page.rect.height\r\n    // Limit both the canvas and its background to the first page.\r\n    const height = Math.min(this.deps.getWrapperHeight(), Math.ceil(end))\r\n    this.vRuler!.style.display = 'block'\r\n    this.vRuler!.style.bottom = 'auto'\r\n    this.vRuler!.style.height = `${height}px`\r\n    const ctx = this.prepareCanvas(this.vCanvas!, RULER_SIZE, height)\r\n    const scale = this.deps.getScale()\r\n    const [mt, , mb] = this.deps.getPageMargins()\r\n    // Rotate, rather than reflect, so vertical labels remain readable.\r\n    ctx.transform(0, 1, -1, 0, BAND_START * 2 + BAND_SIZE, 0)\r\n    this.drawBand(ctx, start, end, start + mt * scale, end - mb * scale, height)\r\n  }\r\n\r\n  destroy(): void {\r\n    this.onDragEnd()\r\n    for (const element of [this.hRuler, this.vRuler, this.corner, ...this.markers.values()]) element?.remove()\r\n    this.markers.clear()\r\n    this.hRuler = this.vRuler = this.corner = null\r\n    this.hCanvas = this.vCanvas = null\r\n  }\r\n}\r\n","/**\r\n * WatermarkWidget —— 水印渲染 widget\r\n *\r\n * 负责在每页内容区绘制水印文本：\r\n *  - repeat=true：平铺水印（按 gapX/gapY 间隔，斜向 45° 排列）\r\n *  - repeat=false：单条居中水印（斜向 45° 居中于页面内容区）\r\n *  - 支持 color / opacity / size / font 自定义\r\n *\r\n * 生命周期：create() → drawWatermark() 每页调用 → destroy()\r\n */\r\n\r\nimport type { PageLayout } from '../layout-types'\r\n\r\n/** 水印配置 */\r\nexport interface WatermarkConfig {\r\n  /** 水印文本内容 */\r\n  data: string\r\n  /** 字体（如 'Microsoft YaHei'） */\r\n  font?: string\r\n  /** 字号（如 120） */\r\n  size?: number\r\n  /** 颜色（如 '#AEB5C0'） */\r\n  color?: string\r\n  /** 透明度（0-1） */\r\n  opacity?: number\r\n  /** 是否平铺重复 */\r\n  repeat?: boolean\r\n  /** 水平间隔（px，平铺模式生效） */\r\n  gapX?: number\r\n  /** 垂直间隔（px，平铺模式生效） */\r\n  gapY?: number\r\n}\r\n\r\n/** WatermarkWidget 的依赖注入接口 */\r\nexport interface WatermarkWidgetDeps {\r\n  /** 获取页面在容器中的水平偏移 */\r\n  getPageOffsetX: () => number\r\n}\r\n\r\n/** 水印渲染 widget，负责在每页 canvas 上绘制水印文本 */\r\nexport class WatermarkWidget {\r\n  /** 当前水印配置 */\r\n  private config: WatermarkConfig | null = null\r\n\r\n  /**\r\n   * 创建 WatermarkWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: WatermarkWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 初始化（当前无需额外操作，保留接口一致性） */\r\n  create(): void {}\r\n\r\n  /** 销毁 widget：清理配置引用 */\r\n  destroy(): void {\r\n    this.config = null\r\n  }\r\n\r\n  /* -------------------- 配置 -------------------- */\r\n\r\n  /** 设置水印配置 */\r\n  setConfig(cfg: WatermarkConfig | null): void {\r\n    this.config = cfg\r\n  }\r\n\r\n  /** 获取当前水印配置 */\r\n  getConfig(): WatermarkConfig | null {\r\n    return this.config\r\n  }\r\n\r\n  /* -------------------- 渲染 -------------------- */\r\n\r\n  /**\r\n   * 在指定页面上绘制水印。\r\n   * @param ctx 内容 canvas 2d 上下文\r\n   * @param page 页面布局信息\r\n   * @param scrollY 当前垂直滚动偏移\r\n   */\r\n  drawWatermark(\r\n    ctx: CanvasRenderingContext2D,\r\n    page: PageLayout,\r\n    scrollY: number\r\n  ): void {\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const px = page.rect.x + pageOffsetX\r\n    const py = page.rect.y - scrollY\r\n    this.renderAt(ctx, px, py, page.rect.width, page.rect.height)\r\n  }\r\n\r\n  /**\r\n   * 为缩略图绘制水印（原点在页面左上角 0,0）。\r\n   * @param ctx 离屏 canvas 2d 上下文\r\n   * @param page 页面布局信息\r\n   */\r\n  drawWatermarkForThumbnail(\r\n    ctx: CanvasRenderingContext2D,\r\n    page: PageLayout\r\n  ): void {\r\n    this.renderAt(ctx, 0, 0, page.rect.width, page.rect.height)\r\n  }\r\n\r\n  /** 水印渲染核心：在指定位置和尺寸内绘制水印 */\r\n  private renderAt(\r\n    ctx: CanvasRenderingContext2D,\r\n    px: number, py: number,\r\n    pw: number, ph: number\r\n  ): void {\r\n    const cfg = this.config\r\n    if (!cfg || !cfg.data) return\r\n\r\n    const font = cfg.font || 'Microsoft YaHei'\r\n    const fontSize = cfg.size || 120\r\n    const color = cfg.color || '#AEB5C0'\r\n    const opacity = cfg.opacity ?? 0.3\r\n    const repeat = cfg.repeat ?? false\r\n\r\n    ctx.save()\r\n    ctx.rect(px, py, pw, ph)\r\n    ctx.clip()\r\n    ctx.globalAlpha = opacity\r\n    ctx.fillStyle = color\r\n    ctx.font = `${fontSize}px \"${font}\", \"PingFang SC\", sans-serif`\r\n\r\n    if (repeat) {\r\n      this.drawTiled(ctx, cfg.data, px, py, pw, ph, fontSize, cfg.gapX ?? 10, cfg.gapY ?? 10)\r\n    } else {\r\n      this.drawCentered(ctx, cfg.data, px, py, pw, ph)\r\n    }\r\n\r\n    ctx.restore()\r\n  }\r\n\r\n  /**\r\n   * 绘制单条居中水印（斜向 45° 居中于页面）。\r\n   */\r\n  private drawCentered(\r\n    ctx: CanvasRenderingContext2D,\r\n    text: string,\r\n    px: number, py: number,\r\n    pw: number, ph: number\r\n  ): void {\r\n    const cx = px + pw / 2\r\n    const cy = py + ph / 2\r\n    ctx.translate(cx, cy)\r\n    ctx.rotate(-Math.PI / 4)\r\n    ctx.textAlign = 'center'\r\n    ctx.textBaseline = 'middle'\r\n    ctx.fillText(text, 0, 0)\r\n  }\r\n\r\n  /**\r\n   * 绘制平铺水印（按间隔斜向 45° 排列，覆盖整页）。\r\n   */\r\n  private drawTiled(\r\n    ctx: CanvasRenderingContext2D,\r\n    text: string,\r\n    px: number, py: number,\r\n    pw: number, ph: number,\r\n    fontSize: number,\r\n    gapX: number, gapY: number\r\n  ): void {\r\n    const metrics = ctx.measureText(text)\r\n    const textW = metrics.width\r\n    const stepX = textW + gapX\r\n    const stepY = fontSize + gapY\r\n\r\n    ctx.textAlign = 'center'\r\n    ctx.textBaseline = 'middle'\r\n\r\n    const diag = Math.sqrt(pw * pw + ph * ph)\r\n    const cols = Math.ceil(diag / stepX) + 1\r\n    const rows = Math.ceil(diag / stepY) + 1\r\n\r\n    const cx = px + pw / 2\r\n    const cy = py + ph / 2\r\n\r\n    ctx.translate(cx, cy)\r\n    ctx.rotate(-Math.PI / 4)\r\n\r\n    const startX = -(cols * stepX) / 2\r\n    const startY = -(rows * stepY) / 2\r\n\r\n    for (let r = 0; r < rows; r++) {\r\n      const y = startY + r * stepY\r\n      const offsetX = (r % 2 === 0) ? 0 : stepX / 2\r\n      for (let c = 0; c < cols; c++) {\r\n        const x = startX + c * stepX + offsetX\r\n        ctx.fillText(text, x, y)\r\n      }\r\n    }\r\n  }\r\n}","/**\r\n * SystemWatermarkWidget —— 系统级水印 widget\r\n *\r\n * 与普通水印（canvas 内绘制）不同，系统级水印是覆盖整个编辑器视口的 DOM 层：\r\n *  - 创建一个 position:absolute; inset:0 的 div，叠加在 canvas 之上\r\n *  - pointer-events:none，不拦截鼠标交互\r\n *  - repeat=true：用 SVG 背景平铺水印文本\r\n *  - repeat=false：单条居中水印（CSS transform 旋转 -45°）\r\n *\r\n * 生命周期：create() → setConfig() → destroy()\r\n */\r\n\r\n/** 系统级水印配置 */\r\nexport interface SystemWatermarkConfig {\r\n  /** 水印文本内容 */\r\n  data: string\r\n  /** 字体（如 'Microsoft YaHei'） */\r\n  font?: string\r\n  /** 字号（如 120） */\r\n  size?: number\r\n  /** 颜色（如 '#AEB5C0'） */\r\n  color?: string\r\n  /** 透明度（0-1） */\r\n  opacity?: number\r\n  /** 是否平铺重复 */\r\n  repeat?: boolean\r\n  /** 水平间隔（px，平铺模式生效） */\r\n  gapX?: number\r\n  /** 垂直间隔（px，平铺模式生效） */\r\n  gapY?: number\r\n}\r\n\r\n/** SystemWatermarkWidget 的依赖注入接口 */\r\nexport interface SystemWatermarkWidgetDeps {\r\n  /** 获取编辑器容器 DOM（水印覆盖层挂载于此） */\r\n  getContainer: () => HTMLDivElement\r\n}\r\n\r\n/** 系统级水印 widget，在编辑器容器上叠加 DOM 水印层 */\r\nexport class SystemWatermarkWidget {\r\n  /** 水印覆盖层 div */\r\n  private overlayEl: HTMLDivElement | null = null\r\n  /** 当前水印配置 */\r\n  private config: SystemWatermarkConfig | null = null\r\n\r\n  /**\r\n   * 创建 SystemWatermarkWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: SystemWatermarkWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 创建覆盖层 DOM 并挂载到容器 */\r\n  create(): void {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-system-watermark'\r\n    Object.assign(el.style, {\r\n      position: 'absolute',\r\n      inset: '0',\r\n      pointerEvents: 'none',\r\n      zIndex: '50',\r\n      display: 'none',\r\n      overflow: 'hidden',\r\n    } as CSSStyleDeclaration)\r\n    this.deps.getContainer().appendChild(el)\r\n    this.overlayEl = el\r\n  }\r\n\r\n  /** 销毁 widget：移除 DOM 并清理引用 */\r\n  destroy(): void {\r\n    this.overlayEl?.remove()\r\n    this.overlayEl = null\r\n    this.config = null\r\n  }\r\n\r\n  /* -------------------- 配置 -------------------- */\r\n\r\n  /** 设置系统水印配置，null 表示移除水印 */\r\n  setConfig(config: SystemWatermarkConfig | null): void {\r\n    this.config = config\r\n    this.render()\r\n  }\r\n\r\n  /** 获取当前配置 */\r\n  getConfig(): SystemWatermarkConfig | null {\r\n    return this.config\r\n  }\r\n\r\n  /* -------------------- 渲染 -------------------- */\r\n\r\n  /** 根据配置渲染水印 */\r\n  private render(): void {\r\n    const el = this.overlayEl\r\n    if (!el) return\r\n    const cfg = this.config\r\n    if (!cfg || !cfg.data) {\r\n      el.style.display = 'none'\r\n      el.innerHTML = ''\r\n      el.style.backgroundImage = ''\r\n      return\r\n    }\r\n\r\n    const font = cfg.font || 'Microsoft YaHei'\r\n    const fontSize = cfg.size || 120\r\n    const color = cfg.color || '#AEB5C0'\r\n    const opacity = cfg.opacity ?? 0.3\r\n    const repeat = cfg.repeat ?? false\r\n\r\n    el.style.display = 'block'\r\n    el.innerHTML = ''\r\n    el.style.backgroundImage = ''\r\n\r\n    if (repeat) {\r\n      this.renderTiled(el, cfg.data, font, fontSize, color, opacity, cfg.gapX ?? 10, cfg.gapY ?? 10)\r\n    } else {\r\n      this.renderCentered(el, cfg.data, font, fontSize, color, opacity)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 平铺水印：用 SVG data URL 作为 background-image，background-repeat: repeat\r\n   */\r\n  private renderTiled(\r\n    el: HTMLDivElement,\r\n    text: string, font: string, fontSize: number,\r\n    color: string, opacity: number,\r\n    gapX: number, gapY: number\r\n  ): void {\r\n    const tileW = fontSize * 2 + gapX\r\n    const tileH = fontSize + gapY\r\n    const cx = tileW / 2\r\n    const cy = tileH / 2\r\n    const escText = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\r\n    const svg =\r\n      `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileW}\" height=\"${tileH}\">` +\r\n      `<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"middle\" ` +\r\n      `transform=\"rotate(-45 ${cx} ${cy})\" ` +\r\n      `font-family=\"${font}\" font-size=\"${fontSize}\" fill=\"${color}\" opacity=\"${opacity}\">${escText}</text>` +\r\n      `</svg>`\r\n    const encoded = encodeURIComponent(svg).replace(/'/g, '%27').replace(/\"/g, '%22')\r\n    el.style.backgroundImage = `url(\"data:image/svg+xml,${encoded}\")`\r\n    el.style.backgroundRepeat = 'repeat'\r\n  }\r\n\r\n  /**\r\n   * 居中水印：单个文本元素，CSS transform 旋转 -45° 居中\r\n   */\r\n  private renderCentered(\r\n    el: HTMLDivElement,\r\n    text: string, font: string, fontSize: number,\r\n    color: string, opacity: number\r\n  ): void {\r\n    const span = document.createElement('span')\r\n    span.textContent = text\r\n    Object.assign(span.style, {\r\n      position: 'absolute',\r\n      top: '50%',\r\n      left: '50%',\r\n      transform: 'translate(-50%, -50%) rotate(-45deg)',\r\n      fontSize: `${fontSize}px`,\r\n      fontFamily: `\"${font}\", \"PingFang SC\", sans-serif`,\r\n      color: color,\r\n      opacity: String(opacity),\r\n      whiteSpace: 'nowrap',\r\n      userSelect: 'none',\r\n      pointerEvents: 'none',\r\n    } as CSSStyleDeclaration)\r\n    el.appendChild(span)\r\n  }\r\n}","/**\r\n * SelectionToolbarWidget —— 悬浮选区工具栏 widget\r\n *\r\n * 选区非折叠时在选区起点上方显示悬浮工具栏，提供字体/字号/B/I/U/S/颜色/高亮/对齐/清除格式等操作。\r\n */\r\n\r\nimport type { DocumentLayout } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Command } from '@vervedoc/docx-editor-transform'\r\nimport type { IDocxDocumentMeta } from '@vervedoc/docx-editor-schema'\r\nimport { getByPath, FONT_FAMILY_LIST, FONT_FAMILY_VALUE, FONT_FAMILY_LABEL, FONT_SIZE, FONT_SIZE_LIST } from '@vervedoc/docx-editor-schema'\r\nimport { locateCaret } from '../caret-rect'\r\nimport type { Zone } from './header-footer-widget'\r\n\r\n/**\r\n * SelectionToolbarWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface SelectionToolbarWidgetDeps {\r\n  /** Whether editing interactions are currently allowed. */\r\n  canEdit: () => boolean\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取当前文档元数据 */\r\n  getDocument: () => IDocxDocumentMeta\r\n  /** 获取当前编辑区域 */\r\n  getZone: () => Zone\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 获取视口宽度（像素） */\r\n  getViewportWidth: () => number\r\n  /** 获取外层容器 DOM */\r\n  getContainer: () => HTMLDivElement\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: keyof Command, ...args: any[]) => void\r\n  /** 查询是否抑制下一次工具栏显示 */\r\n  isSuppressToolbar: () => boolean\r\n  /** 消费（重置）抑制标志 */\r\n  consumeSuppressToolbar: () => void\r\n}\r\n\r\n/**\r\n * 悬浮选区工具栏 widget\r\n *\r\n * 在选区起点上方显示工具栏，回显光标所在 run 的格式状态，\r\n * 点击按钮触发对应命令。\r\n */\r\nexport class SelectionToolbarWidget {\r\n  /** 工具栏 DOM 元素 */\r\n  private toolbar: HTMLDivElement | null = null\r\n\r\n  /**\r\n   * 构造 SelectionToolbarWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: SelectionToolbarWidgetDeps) {}\r\n\r\n  /** 创建工具栏 DOM 并挂载到容器 */\r\n  create(): void {\r\n    const tb = document.createElement('div')\r\n    tb.className = 'vervedocs-selection-toolbar'\r\n    Object.assign(tb.style, {\r\n      position: 'absolute',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      background: '#fff',\r\n      borderRadius: '0',\r\n      boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\r\n      padding: '8px 10px',\r\n      gap: '6px',\r\n      alignItems: 'center',\r\n      fontSize: '14px',\r\n      userSelect: 'none',\r\n      whiteSpace: 'nowrap',\r\n      fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const fire = (cmd: keyof Command, ...args: any[]) => {\r\n      if (this.deps.canEdit()) this.deps.onCommand?.(cmd, ...args)\r\n    }\r\n\r\n\r\n    const mkBtn = (icon: string, cmd: keyof Command, args: any[] = [], title = ''): HTMLButtonElement => {\r\n      const el = document.createElement('button')\r\n      el.title = title\r\n      el.dataset.cmd = cmd\r\n      el.dataset.args = JSON.stringify(args)\r\n      Object.assign(el.style, {\r\n        border: 'none', background: 'transparent', borderRadius: '4px',\r\n        padding: '4px', cursor: 'pointer', display: 'flex',\r\n        alignItems: 'center', justifyContent: 'center', lineHeight: '0',\r\n      } as CSSStyleDeclaration)\r\n      const sp = document.createElement('span')\r\n      sp.className = 'material-symbols-outlined'\r\n      sp.textContent = icon\r\n      sp.style.cssText = 'font-size:18px;color:#3D4757;'\r\n      el.appendChild(sp)\r\n      el.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n      el.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); fire(cmd, ...args) })\r\n      return el\r\n    }\r\n\r\n    const mkSep = (): HTMLSpanElement => {\r\n      const sep = document.createElement('span')\r\n      Object.assign(sep.style, {\r\n        display: 'inline-block', width: '1px', height: '24px',\r\n        background: '#e0e0e0', margin: '0 3px',\r\n      } as CSSStyleDeclaration)\r\n      return sep\r\n    }\r\n\r\n    // 字体下拉\r\n    const fontSel = document.createElement('select')\r\n    Object.assign(fontSel.style, {\r\n      border: '1px solid #ddd', borderRadius: '4px', padding: '4px 6px',\r\n      fontSize: '13px', background: '#fff', cursor: 'pointer', maxWidth: '110px',\r\n    } as CSSStyleDeclaration)\r\n    for (const f of FONT_FAMILY_LIST) {\r\n      const opt = document.createElement('option')\r\n      opt.value = FONT_FAMILY_VALUE[f] ?? f; opt.textContent = f\r\n      fontSel.appendChild(opt)\r\n    }\r\n    fontSel.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    fontSel.addEventListener('change', () => fire('executeSetFont', fontSel.value))\r\n    tb.appendChild(fontSel)\r\n\r\n    // 字号下拉\r\n    const sizeSel = document.createElement('select')\r\n    Object.assign(sizeSel.style, {\r\n      border: '1px solid #ddd', borderRadius: '4px', padding: '4px 6px',\r\n      fontSize: '13px', background: '#fff', cursor: 'pointer', width: '68px',\r\n    } as CSSStyleDeclaration)\r\n    for (const s of FONT_SIZE_LIST) {\r\n      const opt = document.createElement('option')\r\n      const pt = FONT_SIZE[s] ?? Number(s)\r\n      opt.value = String(pt); opt.textContent = s\r\n      sizeSel.appendChild(opt)\r\n    }\r\n    sizeSel.value = '14'\r\n    sizeSel.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    // The selector uses points; the core stores font sizes in pixels.\r\n    sizeSel.addEventListener('change', () => fire('executeSetSize', Number(sizeSel.value) * 96 / 72))\r\n    tb.appendChild(sizeSel)\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // B I U S\r\n    tb.appendChild(mkBtn('format_bold', 'executeSetBold', [], '加粗'))\r\n    tb.appendChild(mkBtn('format_italic', 'executeSetItalic', [], '斜体'))\r\n    tb.appendChild(mkBtn('format_underlined', 'executeSetUnderline', [], '下划线'))\r\n    tb.appendChild(mkBtn('format_strikethrough', 'executeSetStrikeout', [], '删除线'))\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 颜色\r\n    const colorBtn = document.createElement('input')\r\n    colorBtn.type = 'color'\r\n    colorBtn.value = '#000000'\r\n    colorBtn.dataset.cmd = 'executeSetColor'\r\n    Object.assign(colorBtn.style, {\r\n      width: '32px', height: '28px', border: '1px solid #ddd',\r\n      borderRadius: '4px', cursor: 'pointer', padding: '0', background: 'transparent',\r\n    } as CSSStyleDeclaration)\r\n    colorBtn.title = '字体颜色'\r\n    colorBtn.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    colorBtn.addEventListener('input', () => fire('executeSetColor', colorBtn.value))\r\n    tb.appendChild(colorBtn)\r\n\r\n    // 高亮\r\n    const hlBtn = document.createElement('input')\r\n    hlBtn.type = 'color'\r\n    hlBtn.value = '#ffff00'\r\n    hlBtn.dataset.cmd = 'executeSetHighlight'\r\n    Object.assign(hlBtn.style, {\r\n      width: '32px', height: '28px', border: '1px solid #ddd',\r\n      borderRadius: '4px', cursor: 'pointer', padding: '0', background: 'transparent',\r\n    } as CSSStyleDeclaration)\r\n    hlBtn.title = '高亮颜色'\r\n    hlBtn.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    hlBtn.addEventListener('input', () => fire('executeSetHighlight', hlBtn.value))\r\n    tb.appendChild(hlBtn)\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 对齐\r\n    tb.appendChild(mkBtn('format_align_left', 'executeSetRowFlex', ['left'], '左对齐'))\r\n    tb.appendChild(mkBtn('format_align_center', 'executeSetRowFlex', ['center'], '居中'))\r\n    tb.appendChild(mkBtn('format_align_right', 'executeSetRowFlex', ['right'], '右对齐'))\r\n    tb.appendChild(mkBtn('format_align_justify', 'executeSetRowFlex', ['justify'], '两端对齐'))\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 清除格式\r\n    tb.appendChild(mkBtn('format_clear', 'executeClearFormat', [], '清除格式'))\r\n\r\n    this.deps.getContainer().appendChild(tb)\r\n    this.toolbar = tb\r\n  }\r\n\r\n  /** 更新工具栏：折叠选区/表格内选区时隐藏，否则定位到选区起点上方并回显格式状态。 */\r\n  update(): void {\r\n    if (!this.toolbar) return\r\n    const tb = this.toolbar\r\n    if (!this.deps.canEdit()) { tb.style.display = 'none'; return }\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) { tb.style.display = 'none'; return }\r\n    if (this.deps.isSuppressToolbar()) { tb.style.display = 'none'; this.deps.consumeSuppressToolbar(); return }\r\n    if (range.isCollapsed()) {\r\n      tb.style.display = 'none'\r\n      return\r\n    }\r\n    const ordered = range.getOrdered()\r\n    if (!ordered) { tb.style.display = 'none'; return }\r\n    // 表格内选区不显示段落悬浮工具栏\r\n    if (ordered.start.path.length >= 2 && ordered.start.path[1] === 'trList') {\r\n      tb.style.display = 'none'\r\n      return\r\n    }\r\n    const rect = locateCaret(layout, ordered.start, this.deps.getZone())\r\n    if (!rect) { tb.style.display = 'none'; return }\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const x = Math.round(rect.x + pageOffsetX)\r\n    const gap = Math.max(16, Math.round(rect.height * 0.5))\r\n    tb.style.display = 'flex'\r\n    const y = Math.round(rect.y - this.deps.getScrollY()) - tb.offsetHeight - gap\r\n    tb.style.left = `${Math.max(4, Math.min(x, this.deps.getViewportWidth() - tb.offsetWidth - 4))}px`\r\n    tb.style.top = `${Math.max(4, y)}px`\r\n\r\n    this.syncToolbarState(tb)\r\n  }\r\n\r\n  /** 读取光标所在 run 的格式状态，回显到工具栏控件 */\r\n  private syncToolbarState(tb: HTMLDivElement): void {\r\n    const range = this.deps.getRange()\r\n    if (!range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const node = getByPath(this.deps.getDocument().elements, pos.path)\r\n    if (!node || node.type !== 'text') return\r\n    const run = node as unknown as Record<string, unknown>\r\n\r\n    const fontSel = tb.querySelector('select:nth-of-type(1)') as HTMLSelectElement | null\r\n    const sizeSel = tb.querySelector('select:nth-of-type(2)') as HTMLSelectElement | null\r\n\r\n    // 回显字体\r\n    if (fontSel) {\r\n      const font = String(run.font ?? '')\r\n      const label = FONT_FAMILY_LABEL[font] ?? font\r\n      for (let i = 0; i < fontSel.options.length; i++) {\r\n        const opt = fontSel.options[i]\r\n        opt.selected = opt.value === font || opt.textContent === label\r\n      }\r\n    }\r\n\r\n    // 回显字号（run.size 是 px，选项值是 pt，需要转换）\r\n    if (sizeSel) {\r\n      const sizePt = Math.round(Number(run.size ?? 0) * (72 / 96) * 2) / 2\r\n      const size = String(sizePt)\r\n      for (let i = 0; i < sizeSel.options.length; i++) {\r\n        if (sizeSel.options[i].value === size) { sizeSel.options[i].selected = true; break }\r\n      }\r\n    }\r\n\r\n    // 回显 B/I/U/S 高亮\r\n    const btns = tb.querySelectorAll<HTMLButtonElement>('button[data-cmd]')\r\n    for (let i = 0; i < btns.length; i++) {\r\n      const btn = btns[i]\r\n      const cmd = btn.dataset.cmd\r\n      let active = false\r\n      if (cmd === 'executeSetBold') active = !!run.bold\r\n      else if (cmd === 'executeSetItalic') active = !!run.italic\r\n      else if (cmd === 'executeSetUnderline') active = !!run.underline\r\n      else if (cmd === 'executeSetStrikeout') active = !!run.strikeout\r\n      else if (cmd === 'executeSetRowFlex') {\r\n        const args = JSON.parse(btn.dataset.args || '[]')\r\n        active = String(run.rowFlex ?? 'left') === args[0]\r\n      }\r\n      btn.style.background = active ? '#e8eaf6' : 'transparent'\r\n    }\r\n\r\n    // 回显字体颜色和高亮颜色\r\n    const colorInputs = tb.querySelectorAll<HTMLInputElement>('input[type=color][data-cmd]')\r\n    for (let i = 0; i < colorInputs.length; i++) {\r\n      const input = colorInputs[i]\r\n      if (input.dataset.cmd === 'executeSetColor') {\r\n        input.value = String(run.color ?? '#000000')\r\n      } else if (input.dataset.cmd === 'executeSetHighlight') {\r\n        input.value = String(run.highlight ?? '#ffff00')\r\n      }\r\n    }\r\n  }\r\n\r\n  /** 销毁工具栏：从容器移除 DOM */\r\n  destroy(): void {\r\n    if (this.toolbar && this.toolbar.parentElement) {\r\n      this.toolbar.parentElement.removeChild(this.toolbar)\r\n    }\r\n    this.toolbar = null\r\n  }\r\n}\r\n","/**\r\n * CaretWidget —— DOM 光标 widget\r\n *\r\n * 用一个 position:absolute 的 div 绘制文本光标（1px 竖线），替代 canvas overlay 绘制。\r\n *  - 挂载于 canvasHost（覆盖 container 视口，pointer-events:none）\r\n *  - 增量更新 style.left/top/height + display，不每帧重建 DOM\r\n *  - 显隐由外部 visible 开关驱动（沿用原 setInterval 闪烁机制）\r\n *\r\n * 生命周期：create() → update() / hide() → destroy()\r\n */\r\n\r\nimport type { CaretRect } from '../caret-rect'\r\n\r\n/** CaretWidget 的依赖注入接口 */\r\nexport interface CaretWidgetDeps {\r\n  /** 获取 canvasHost DOM（光标 div 挂载于此） */\r\n  getCanvasHost: () => HTMLDivElement\r\n}\r\n\r\n/** DOM 光标 widget，在 canvasHost 上叠加 1px 竖线 div */\r\nexport class CaretWidget {\r\n  /** 光标 div 元素 */\r\n  private el: HTMLDivElement | null = null\r\n\r\n  /**\r\n   * 创建 CaretWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: CaretWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 创建光标 div 并挂载到 canvasHost */\r\n  create(): void {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-caret'\r\n    Object.assign(el.style, {\r\n      position: 'absolute',\r\n      left: '0px',\r\n      top: '0px',\r\n      width: '1px',\r\n      height: '0px',\r\n      background: '#111',\r\n      display: 'none',\r\n      pointerEvents: 'none',\r\n      zIndex: '3'\r\n    } as CSSStyleDeclaration)\r\n    this.deps.getCanvasHost().appendChild(el)\r\n    this.el = el\r\n\r\n  }\r\n\r\n  /** 销毁 widget：移除 DOM 并清理引用 */\r\n  destroy(): void {\r\n    this.el?.remove()\r\n    this.el = null\r\n  }\r\n\r\n  /* -------------------- 渲染 -------------------- */\r\n\r\n  /**\r\n   * 更新光标位置与可见性。\r\n   * rect 为文档坐标系（未减 scrollY），内部应用 scrollY 与 pageOffsetX 转为视口坐标。\r\n   * @param rect 光标矩形（文档坐标）\r\n   * @param scrollY 当前垂直滚动偏移\r\n   * @param pageOffsetX 页面水平居中偏移\r\n   * @param visible 是否可见（闪烁开关）\r\n   */\r\n  update(rect: CaretRect, scrollY: number, pageOffsetX: number, visible: boolean): void {\r\n    const el = this.el\r\n    if (!el) return\r\n    if (!visible) {\r\n      el.style.display = 'none'\r\n      return\r\n    }\r\n    const x = Math.round(rect.x + pageOffsetX)\r\n    const y = Math.round(rect.y - scrollY)\r\n    el.style.left = `${x}px`\r\n    el.style.top = `${y}px`\r\n    el.style.height = `${rect.height}px`\r\n    el.style.display = 'block'\r\n  }\r\n\r\n  /** 隐藏光标（无 focus 或定位失败时调用） */\r\n  hide(): void {\r\n    if (this.el) this.el.style.display = 'none'\r\n  }\r\n}","import type { BlockNode, DocumentLayout, Rect } from './layout-types'\r\nimport { signBlock } from './block-signature'\r\n\r\ninterface BlockState {\r\n  id: number\r\n  signature: string\r\n  rect: Rect\r\n}\r\n\r\nexport interface RenderState {\r\n  blocks: Map<string, BlockState>\r\n  pageBlocks: Map<number, BlockState>\r\n  pageSignatures: Map<number, string>\r\n  geometry: string\r\n}\r\n\r\nlet nextRenderId = 0\r\n\r\n/** Separate a block's stable identity from its mutable paint signature. */\r\nexport function prepareRenderState(layout: DocumentLayout, previous?: RenderState): {\r\n  state: RenderState\r\n  dirty: number[]\r\n} {\r\n  const state: RenderState = {\r\n    blocks: new Map(),\r\n    pageBlocks: new Map(),\r\n    pageSignatures: new Map(),\r\n    geometry: JSON.stringify(layout.pages.map(p => [p.rect, p.contentRect, p.headerRect, p.footerRect]))\r\n  }\r\n  const dirty: number[] = []\r\n  const visit = (source: BlockNode, key: string, x: number, y: number, topLevel: boolean): BlockNode => {\r\n    // Header/footer and repeated table fragments can share source layout objects.\r\n    // Never assign occurrence IDs into those shared objects or cached geometry.\r\n    const b = { ...source, rect: { ...source.rect } }\r\n    if (b.kind === 'table') {\r\n      b.rows = b.rows.map((row, ri) => ({\r\n        ...row,\r\n        cells: row.cells.map((cell, ci) => ({\r\n          ...cell,\r\n          content: cell.content.map((child, bi) =>\r\n            visit(child, `${key}/${ri}/${ci}/${bi}`, 0, 0, false))\r\n        }))\r\n      }))\r\n    }\r\n    const old = previous?.blocks.get(key)\r\n    b.id = old?.id ?? ++nextRenderId\r\n    const signature = signBlock(b, layout)\r\n    const entry = {\r\n      id: b.id, signature,\r\n      rect: { ...b.rect, x: x + b.rect.x, y: y + b.rect.y }\r\n    }\r\n    state.blocks.set(key, entry)\r\n    if (topLevel) state.pageBlocks.set(b.id, entry)\r\n    if (!old || old.signature !== signature) dirty.push(b.id)\r\n    return b\r\n  }\r\n  for (const page of layout.pages) {\r\n    const parts: unknown[] = [page.rect, page.contentRect, page.headerRect, page.footerRect]\r\n    const zone = (blocks: BlockNode[], name: string, origin: Rect) => blocks.map((block, index) => {\r\n      const b = visit(block, `${page.index}/${name}/${index}`, origin.x, origin.y, true)\r\n      parts.push([b.rect, state.pageBlocks.get(b.id)!.signature])\r\n      return b\r\n    })\r\n    page.blocks = zone(page.blocks, 'main', page.contentRect)\r\n    if (page.headerBlocks && page.headerRect) page.headerBlocks = zone(page.headerBlocks, 'header', page.headerRect)\r\n    if (page.footerBlocks && page.footerRect) page.footerBlocks = zone(page.footerBlocks, 'footer', page.footerRect)\r\n    state.pageSignatures.set(page.index, JSON.stringify(parts))\r\n  }\r\n  return { state, dirty }\r\n}\r\n\r\n/** Diff against the last painted frame, not the last edit queued in that frame. */\r\nexport function computeDirtyRect(\r\n  painted: RenderState | undefined,\r\n  next: RenderState,\r\n  viewport: Rect\r\n): Rect | null {\r\n  if (!painted || painted.geometry !== next.geometry) return null\r\n  let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\r\n  const include = (rect: Rect) => {\r\n    left = Math.min(left, rect.x - 2)\r\n    top = Math.min(top, rect.y - 2)\r\n    right = Math.max(right, rect.x + rect.width + 2)\r\n    bottom = Math.max(bottom, rect.y + rect.height + 2)\r\n  }\r\n  const ids = new Set([...painted.pageBlocks.keys(), ...next.pageBlocks.keys()])\r\n  for (const id of ids) {\r\n    const old = painted.pageBlocks.get(id)\r\n    const current = next.pageBlocks.get(id)\r\n    if (old && current && old.signature === current.signature &&\r\n        JSON.stringify(old.rect) === JSON.stringify(current.rect)) continue\r\n    if (old) include(old.rect)\r\n    if (current) include(current.rect)\r\n  }\r\n  left = Math.max(left, viewport.x)\r\n  top = Math.max(top, viewport.y)\r\n  right = Math.min(right, viewport.x + viewport.width)\r\n  bottom = Math.min(bottom, viewport.y + viewport.height)\r\n  if (right <= left || bottom <= top) return { x: 0, y: 0, width: 0, height: 0 }\r\n  return { x: left, y: top, width: right - left, height: bottom - top }\r\n}\r\n","/**\r\n * LayoutQuery —— 布局查询纯函数\r\n *\r\n * 提供按 position 定位 inline / paragraph / line / hyperlink 等布局节点的工具函数。\r\n * 所有函数均不持有状态，调用方传入 DocumentLayout / blocks 即可。\r\n */\r\n\r\nimport type { DocumentLayout, BlockNode, InlineBox, LineBox, ParagraphBlock } from './layout-types'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { isSamePath } from '@vervedoc/docx-editor-schema'\r\n\r\n/**\r\n * 按 position 在 layout 中查找所属 inline。\r\n * @param layout 文档布局\r\n * @param pos 待定位位置\r\n * @returns 命中的 InlineBox；未命中返回 null\r\n */\r\nexport function findInlineByPos(layout: DocumentLayout | null, pos: IPosition): InlineBox | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findInlineInBlocks(page.blocks, pos)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找所属 inline（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param pos 待定位位置\r\n * @returns 命中的 InlineBox；未命中返回 null\r\n */\r\nexport function findInlineInBlocks(blocks: BlockNode[], pos: IPosition): InlineBox | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          if (isSamePath(inl.path, pos.path) && pos.offset >= inl.startOffset && pos.offset <= inl.endOffset) {\r\n            return inl\r\n          }\r\n        }\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findInlineInBlocks(cell.content, pos)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 按 position 在 layout 中查找所属段落块。\r\n * @param layout 文档布局\r\n * @param pos 待定位位置\r\n * @returns 命中的 ParagraphBlock；未命中返回 null\r\n */\r\nexport function findParagraphByPos(layout: DocumentLayout | null, pos: IPosition): ParagraphBlock | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findParagraphInBlocks(page.blocks, pos)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找所属段落块（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param pos 待定位位置\r\n * @returns 命中的 ParagraphBlock；未命中返回 null\r\n */\r\nexport function findParagraphInBlocks(blocks: BlockNode[], pos: IPosition): ParagraphBlock | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          if (isSamePath(inl.path, pos.path)) return b\r\n        }\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findParagraphInBlocks(cell.content, pos)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 按 position 在 layout 中查找所属行盒。\r\n * @param layout 文档布局\r\n * @param pos 待定位位置\r\n * @returns 命中的 LineBox；未命中返回 null\r\n */\r\nexport function findLineByPos(layout: DocumentLayout | null, pos: IPosition): LineBox | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findLineInBlocks(page.blocks, pos)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找所属行盒（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param pos 待定位位置\r\n * @returns 命中的 LineBox；未命中返回 null\r\n */\r\nexport function findLineInBlocks(blocks: BlockNode[], pos: IPosition): LineBox | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          if (isSamePath(inl.path, pos.path) && pos.offset >= inl.startOffset && pos.offset <= inl.endOffset) {\r\n            return line\r\n          }\r\n        }\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findLineInBlocks(cell.content, pos)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 查找文档首个 inline（用于光标兜底定位到文档首）。\r\n * @param layout 文档布局\r\n * @returns 首个 InlineBox；空文档返回 null\r\n */\r\nexport function findFirstInline(layout: DocumentLayout | null): InlineBox | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findFirstInlineInBlocks(page.blocks)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找首个 inline（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @returns 首个 InlineBox；未命中返回 null\r\n */\r\nexport function findFirstInlineInBlocks(blocks: BlockNode[]): InlineBox | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        if (line.inlines[0]) return line.inlines[0]\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findFirstInlineInBlocks(cell.content)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 查找文档末个 inline（用于光标定位到文档尾/全选终点）。\r\n * @param layout 文档布局\r\n * @returns 末个 InlineBox；空文档返回 null\r\n */\r\nexport function findLastInline(layout: DocumentLayout | null): InlineBox | null {\r\n  if (!layout) return null\r\n  let last: InlineBox | null = null\r\n  for (const page of layout.pages) {\r\n    findLastInlineInBlocks(page.blocks, (inl) => { last = inl })\r\n  }\r\n  return last\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归遍历所有 inline，对每个 inline 调用回调（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param onInline 每个 inline 的回调\r\n */\r\nexport function findLastInlineInBlocks(blocks: BlockNode[], onInline: (inl: InlineBox) => void): void {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) onInline(inl)\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          findLastInlineInBlocks(cell.content, onInline)\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/** 按 position 定位 inline，若属于超链接则返回其 URL（供 Ctrl+点击跳转） */\r\nexport function findHyperlinkByPos(layout: DocumentLayout | null, pos: IPosition): string | null {\r\n  return findInlineByPos(layout, pos)?.hyperlink ?? null\r\n}","/**\r\n * AnchorCollector —— 锚点收集纯函数\r\n *\r\n * 遍历 layout 收集批注组/修订锚点坐标，供批注/修订 overlay 绘制竖线。\r\n */\r\n\r\nimport type { BlockNode } from './layout-types'\r\n\r\n/** 锚点坐标信息 */\r\nexport interface AnchorInfo {\r\n  startX: number\r\n  startY: number\r\n  endX: number\r\n  endY: number\r\n  lineHeight: number\r\n  endLineHeight?: number\r\n  glyphHeight: number\r\n  startGlyphTop: number\r\n  endGlyphTop: number\r\n}\r\n\r\n/**\r\n * 遍历 block 列表，收集每个 groupId 所对应的锚点坐标（文档绝对坐标）。\r\n * @param blocks 块列表\r\n * @param originX 块列表原点 x\r\n * @param originY 块列表原点 y\r\n * @param result 收集结果的 Map\r\n */\r\nexport function collectGroupAnchors(\r\n  blocks: BlockNode[],\r\n  originX: number,\r\n  originY: number,\r\n  result: Map<string, AnchorInfo>\r\n): void {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const cx = originX + b.rect.x + cell.rect.x + cell.contentPaddingLeft\r\n          const cy = originY + b.rect.y + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n          collectGroupAnchors(cell.content, cx, cy, result)\r\n        }\r\n      }\r\n      continue\r\n    }\r\n    if (b.kind !== 'paragraph') continue\r\n    const bx = originX + b.rect.x\r\n    const by = originY + b.rect.y\r\n    for (const line of b.lines) {\r\n      for (const inl of line.inlines) {\r\n        if (!inl.groupIds?.length) continue\r\n        const absX = bx + inl.x\r\n        const absY = by + line.y\r\n        const absEndX = absX + inl.width\r\n        const absEndY = absY + line.height\r\n        const glyphHeight = inl.size * 1.15\r\n        const absGlyphTop = absY + line.baseline - inl.size * 0.875\r\n        for (const gid of inl.groupIds) {\r\n          const existing = result.get(gid)\r\n          if (!existing) {\r\n            result.set(gid, { startX: absX, startY: absY, endX: absEndX, endY: absEndY, lineHeight: line.height, endLineHeight: line.height, glyphHeight, startGlyphTop: absGlyphTop, endGlyphTop: absGlyphTop })\r\n          } else {\r\n            if (absY < existing.startY || (absY === existing.startY && absX < existing.startX)) {\r\n              existing.startX = absX\r\n              existing.startY = absY\r\n              existing.lineHeight = line.height\r\n              existing.startGlyphTop = absGlyphTop\r\n            }\r\n            if (absEndY > existing.endY || (absEndY === existing.endY && absEndX > existing.endX)) {\r\n              existing.endX = absEndX\r\n              existing.endY = absEndY\r\n              existing.endLineHeight = line.height\r\n              existing.endGlyphTop = absGlyphTop\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 遍历 block 列表，收集每个 revisionId 所对应的锚点坐标（文档绝对坐标）。\r\n * @param blocks 块列表\r\n * @param originX 块列表原点 x\r\n * @param originY 块列表原点 y\r\n * @param result 收集结果的 Map\r\n */\r\nexport function collectRevisionAnchors(\r\n  blocks: BlockNode[],\r\n  originX: number,\r\n  originY: number,\r\n  result: Map<string, AnchorInfo>\r\n): void {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const cx = originX + b.rect.x + cell.rect.x + cell.contentPaddingLeft\r\n          const cy = originY + b.rect.y + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n          collectRevisionAnchors(cell.content, cx, cy, result)\r\n        }\r\n      }\r\n      continue\r\n    }\r\n    if (b.kind !== 'paragraph') continue\r\n    const bx = originX + b.rect.x\r\n    const by = originY + b.rect.y\r\n    for (const line of b.lines) {\r\n      for (const inl of line.inlines) {\r\n        const revisionId = (inl.run as any)?.revisionId\r\n        if (!revisionId) continue\r\n        const absX = bx + inl.x\r\n        const absY = by + line.y\r\n        const absEndX = absX + inl.width\r\n        const absEndY = absY + line.height\r\n        const glyphHeight = inl.size * 1.15\r\n        const absGlyphTop = absY + line.baseline - inl.size * 0.875\r\n        const existing = result.get(revisionId)\r\n        if (!existing) {\r\n          result.set(revisionId, {\r\n            startX: absX,\r\n            startY: absY,\r\n            endX: absEndX,\r\n            endY: absEndY,\r\n            lineHeight: line.height,\r\n            endLineHeight: line.height,\r\n            glyphHeight,\r\n            startGlyphTop: absGlyphTop,\r\n            endGlyphTop: absGlyphTop\r\n          })\r\n        } else {\r\n          if (absY < existing.startY || (absY === existing.startY && absX < existing.startX)) {\r\n            existing.startX = absX\r\n            existing.startY = absY\r\n            existing.lineHeight = line.height\r\n            existing.startGlyphTop = absGlyphTop\r\n          }\r\n          if (absEndY > existing.endY || (absEndY === existing.endY && absEndX > existing.endX)) {\r\n            existing.endX = absEndX\r\n            existing.endY = absEndY\r\n            existing.endLineHeight = line.height\r\n            existing.endGlyphTop = absGlyphTop\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n","/**\r\n * CaretNavigation —— 光标导航 Controller\r\n *\r\n * 提供双击选词、三击选段、方向键移动、Home/End、词移动、文档首尾、全选等光标导航功能。\r\n */\r\n\r\nimport type { DocumentLayout, InlineBox, LineBox, ParagraphBlock } from './layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { locateCaret } from './caret-rect'\r\nimport { hitTest } from './hit-test'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\n\r\n/**\r\n * CaretNavigation 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取布局、选区、区域信息以及布局查询方法等。\r\n */\r\nexport interface CaretNavigationDeps {\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取当前编辑区域 */\r\n  getZone: () => Zone\r\n  /** 按 position 查找所属 inline */\r\n  findInlineByPos: (pos: IPosition) => InlineBox | null\r\n  /** 按 position 查找所属段落块 */\r\n  findParagraphByPos: (pos: IPosition) => ParagraphBlock | null\r\n  /** 按 position 查找所属行盒 */\r\n  findLineByPos: (pos: IPosition) => LineBox | null\r\n  /** 查找文档首个 inline */\r\n  findFirstInline: () => InlineBox | null\r\n  /** 查找文档末个 inline */\r\n  findLastInline: () => InlineBox | null\r\n  /** 设置光标可见性 */\r\n  setCaretVisible: (visible: boolean) => void\r\n  /** 重绘光标 overlay */\r\n  renderCaretIfAny: () => void\r\n}\r\n\r\n/**\r\n * 光标导航 Controller\r\n *\r\n * 封装光标移动、选词、选段、全选等导航操作。\r\n */\r\nexport class CaretNavigation {\r\n  /**\r\n   * 构造 CaretNavigation 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: CaretNavigationDeps) {}\r\n\r\n  /**\r\n   * 双击选词：在命中 inline 内按 word char 边界扩展选区；非 word char 选当前单字。\r\n   * @param pos 命中位置\r\n   */\r\n  selectWordAt(pos: IPosition): void {\r\n    const range = this.deps.getRange()\r\n    const layout = this.deps.getLayout()\r\n    if (!range || !layout) return\r\n    const inl = this.deps.findInlineByPos(pos)\r\n    if (!inl) { range.setCaret(pos); return }\r\n    const text = inl.text\r\n    const localOff = pos.offset - inl.startOffset\r\n    const isWord = (ch: string) => /[A-Za-z0-9_]/.test(ch)\r\n    let left = localOff\r\n    let right = localOff\r\n    while (left > 0 && isWord(text[left - 1])) left--\r\n    while (right < text.length && isWord(text[right])) right++\r\n    // 非 word char（CJK / 标点 / 空格）：选当前单字\r\n    if (left === right) {\r\n      if (localOff < text.length) right = localOff + 1\r\n      else left = Math.max(0, localOff - 1)\r\n    }\r\n    range.setRange({\r\n      anchor: { path: inl.path, offset: inl.startOffset + left },\r\n      focus: { path: inl.path, offset: inl.startOffset + right }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 三击选段：把选区扩展到命中段落的首 inline 起点到末 inline 终点。\r\n   * @param pos 命中位置\r\n   */\r\n  selectParagraphAt(pos: IPosition): void {\r\n    const range = this.deps.getRange()\r\n    const layout = this.deps.getLayout()\r\n    if (!range || !layout) return\r\n    const para = this.deps.findParagraphByPos(pos)\r\n    if (!para) { range.setCaret(pos); return }\r\n    let first: InlineBox | undefined\r\n    let last: InlineBox | undefined\r\n    for (const line of para.lines) {\r\n      for (const inl of line.inlines) {\r\n        if (!first) first = inl\r\n        last = inl\r\n      }\r\n    }\r\n    if (!first || !last) { range.setCaret(pos); return }\r\n    range.setRange({\r\n      anchor: { path: first.path, offset: first.startOffset },\r\n      focus: { path: last.path, offset: last.endOffset }\r\n    })\r\n  }\r\n\r\n  /** 光标上移：基于当前光标矩形，用 hitTest 命中上一行同 x 最近字符 */\r\n  moveCaretUp(): void {\r\n    this.moveCaretVertical(-1)\r\n  }\r\n\r\n  /** 光标下移 */\r\n  moveCaretDown(): void {\r\n    this.moveCaretVertical(1)\r\n  }\r\n\r\n  /**\r\n   * 光标垂直移动：基于当前光标矩形，用 hitTest 命中上一/下一行同 x 最近字符。\r\n   * @param dir 移动方向，1=下移，-1=上移\r\n   */\r\n  private moveCaretVertical(dir: 1 | -1): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const rect = locateCaret(layout, pos, this.deps.getZone())\r\n    if (!rect) return\r\n    // 目标 y = 当前光标 y ± 行高（估算上一/下一行中部）\r\n    const targetY = rect.y + dir * rect.height\r\n    const newPos = hitTest(layout, rect.x, targetY, this.deps.getZone())\r\n    if (newPos) {\r\n      range.setCaret(newPos)\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 当前行首 */\r\n  moveCaretToLineStart(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const line = this.deps.findLineByPos(pos)\r\n    if (!line) return\r\n    const first = line.inlines[0]\r\n    if (first) {\r\n      range.setCaret({ path: first.path, offset: first.startOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 当前行尾 */\r\n  moveCaretToLineEnd(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const line = this.deps.findLineByPos(pos)\r\n    if (!line) return\r\n    const last = line.inlines[line.inlines.length - 1]\r\n    if (last) {\r\n      range.setCaret({ path: last.path, offset: last.endOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 按词左移 */\r\n  moveCaretWordLeft(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const inl = this.deps.findInlineByPos(pos)\r\n    if (!inl) return\r\n    const text = inl.text\r\n    const localOff = pos.offset - inl.startOffset\r\n    const isWord = (ch: string) => /[A-Za-z0-9_]/.test(ch)\r\n    let off = localOff\r\n    // 先跳过非 word char（空格/标点），再跳过 word char\r\n    while (off > 0 && !isWord(text[off - 1])) off--\r\n    while (off > 0 && isWord(text[off - 1])) off--\r\n    if (off === localOff && off > 0) off = localOff - 1\r\n    range.setCaret({ path: inl.path, offset: inl.startOffset + off })\r\n    this.deps.setCaretVisible(true)\r\n    this.deps.renderCaretIfAny()\r\n  }\r\n\r\n  /** 按词右移 */\r\n  moveCaretWordRight(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const inl = this.deps.findInlineByPos(pos)\r\n    if (!inl) return\r\n    const text = inl.text\r\n    const localOff = pos.offset - inl.startOffset\r\n    const isWord = (ch: string) => /[A-Za-z0-9_]/.test(ch)\r\n    let off = localOff\r\n    while (off < text.length && !isWord(text[off])) off++\r\n    while (off < text.length && isWord(text[off])) off++\r\n    if (off === localOff && off < text.length) off = localOff + 1\r\n    range.setCaret({ path: inl.path, offset: inl.startOffset + off })\r\n    this.deps.setCaretVisible(true)\r\n    this.deps.renderCaretIfAny()\r\n  }\r\n\r\n  /** 文档首 */\r\n  moveCaretToDocStart(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const first = this.deps.findFirstInline()\r\n    if (first) {\r\n      range.setCaret({ path: first.path, offset: first.startOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 文档尾 */\r\n  moveCaretToDocEnd(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const last = this.deps.findLastInline()\r\n    if (last) {\r\n      range.setCaret({ path: last.path, offset: last.endOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 全选：从文档首到文档尾 */\r\n  selectAll(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const first = this.deps.findFirstInline()\r\n    const last = this.deps.findLastInline()\r\n    if (!first || !last) return\r\n    range.setRange({\r\n      anchor: { path: first.path, offset: first.startOffset },\r\n      focus: { path: last.path, offset: last.endOffset }\r\n    })\r\n    this.deps.setCaretVisible(false)\r\n    this.deps.renderCaretIfAny()\r\n  }\r\n}","/**\r\n * ZoneManager —— 编辑区域 Manager\r\n *\r\n * 管理正文/页眉/页脚编辑区域切换、活动文档获取与写回。\r\n */\r\n\r\nimport type { IDocxDocumentMeta, IElement, IPosition } from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\n\r\n/**\r\n * ZoneManager 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取/设置区域、文档、选区以及触发渲染等。\r\n */\r\nexport interface ZoneManagerDeps {\r\n  /** 获取当前编辑区域 */\r\n  getZone: () => Zone\r\n  /** 直接设置区域状态（不触发副作用） */\r\n  setZoneState: (zone: Zone) => void\r\n  /** 获取当前文档元数据 */\r\n  getDocument: () => IDocxDocumentMeta\r\n  getPage: () => import('@vervedoc/docx-editor-schema').PageLayout | undefined\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 聚焦隐藏输入框 */\r\n  focusInput: () => void\r\n  /** zone 变化回调 */\r\n  onZoneChange: (zone: Zone) => void\r\n  /** 调度一帧渲染 */\r\n  scheduleRender: () => void\r\n  /** 重排版+重渲染 */\r\n  reformatAndRender: () => void\r\n}\r\n\r\n/**\r\n * 编辑区域 Manager\r\n *\r\n * 封装区域切换、活动文档获取/写回、区域首文本位置查找等逻辑。\r\n */\r\nexport class ZoneManager {\r\n  /**\r\n   * 构造 ZoneManager 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ZoneManagerDeps) {}\r\n\r\n  /** 切换编辑区域（main/header/footer） */\r\n  setZone(zone: Zone): void {\r\n    if (this.deps.getZone() === zone) return\r\n    this.deps.setZoneState(zone)\r\n    this.deps.onZoneChange(zone)\r\n    this.deps.scheduleRender()\r\n  }\r\n\r\n  /**\r\n   * 切换编辑区域并设置初始光标。\r\n   * 切换到页眉/页脚时，将光标定位到对应区域的起始文本位置；\r\n   * 切回正文时清空选区。\r\n   * @param zone 目标区域\r\n   */\r\n  setZoneWithCaret(zone: Zone): void {\r\n    const changed = this.deps.getZone() !== zone\r\n    this.setZone(zone)\r\n    if (!changed) return\r\n    const range = this.deps.getRange()\r\n    if (!range) return\r\n    if (zone === 'header' || zone === 'footer') {\r\n      const pos = this.findZoneFirstPosition()\r\n      range.setCaret(pos)\r\n      this.deps.focusInput()\r\n    } else {\r\n      range.clear()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 查找当前活动区域（页眉/页脚）的第一个文本位置，用于切换区域时设置初始光标。\r\n   * 若区域为空则返回指向元素数组末尾的虚拟位置，便于后续插入。\r\n   * @returns 起始文本位置\r\n   */\r\n  private findZoneFirstPosition(): IPosition {\r\n    const doc = this.getActiveDocument()\r\n    const pos = this.findFirstTextPositionInElements(doc.elements)\r\n    if (pos) return pos\r\n    return { path: [doc.elements.length], offset: 0 }\r\n  }\r\n\r\n  /**\r\n   * 递归查找元素列表中的第一个文本元素位置。\r\n   * @param elements 元素列表\r\n   * @returns 第一个文本位置；未找到返回 null\r\n   */\r\n  private findFirstTextPositionInElements(elements: IElement[]): IPosition | null {\r\n    for (let i = 0; i < elements.length; i++) {\r\n      const el = elements[i] as any\r\n      if (el.type === 'text') {\r\n        return { path: [i], offset: 0 }\r\n      }\r\n      if (el.type === 'title' || el.type === 'list') {\r\n        const sub = el.valueList ?? el.elements ?? []\r\n        const pos = this.findFirstTextPositionInElements(sub)\r\n        if (pos) return { path: [i, 'valueList', ...pos.path], offset: pos.offset }\r\n      }\r\n      if (el.type === 'table') {\r\n        const trList = el.trList ?? []\r\n        for (let r = 0; r < trList.length; r++) {\r\n          const tdList = trList[r].tdList ?? []\r\n          for (let c = 0; c < tdList.length; c++) {\r\n            const pos = this.findFirstTextPositionInElements(tdList[c].value ?? [])\r\n            if (pos) return { path: [i, 'trList', r, 'tdList', c, 'value', ...pos.path], offset: pos.offset }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /** 获取当前活动区域的文档（zone=header/footer 时 elements 指向对应区域） */\r\n  getActiveDocument(): IDocxDocumentMeta {\r\n    const doc = this.deps.getDocument()\r\n    const zone = this.deps.getZone()\r\n    if (zone === 'header' || zone === 'footer') {\r\n      if (doc.sections) {\r\n        const page = this.deps.getPage()\r\n        const partId = zone === 'header' ? page?.headerPartId : page?.footerPartId\r\n        if (!partId || !doc.headerFooterParts?.[partId]) throw new TypeError('当前页没有 Java 页眉页脚 part 引用，不能隐式创建')\r\n        return { ...doc, elements: doc.headerFooterParts[partId] }\r\n      }\r\n      return { ...doc, elements: doc[zone] ?? doc.contentZones?.[zone] ?? (doc[zone] = []) }\r\n    }\r\n    return doc\r\n  }\r\n\r\n  /** 将修改后的活动文档写回对应区域并触发重渲染 */\r\n  applyActiveDocument(doc: IDocxDocumentMeta): void {\r\n    const current = this.deps.getDocument()\r\n    const zone = this.deps.getZone()\r\n    if (zone === 'header' || zone === 'footer') {\r\n      if (current.sections) {\r\n        const page = this.deps.getPage()\r\n        const partId = zone === 'header' ? page?.headerPartId : page?.footerPartId\r\n        if (!partId || !current.headerFooterParts?.[partId]) throw new TypeError('当前页没有 Java 页眉页脚 part 引用，不能隐式创建')\r\n        current.headerFooterParts[partId] = doc.elements\r\n      } else if (current[zone] !== undefined || !current.contentZones?.[zone]) {\r\n        current[zone] = doc.elements\r\n      } else {\r\n        current.contentZones[zone] = doc.elements\r\n      }\r\n    } else {\r\n      current.elements = doc.elements\r\n    }\r\n    this.deps.reformatAndRender()\r\n  }\r\n}","/**\r\n * VerveDocs View —— Draw\r\n *\r\n * 编辑器视图门面。\r\n *\r\n * 增量策略：\r\n *  - Reuse unchanged paragraph layout and block bitmaps.\r\n *  - Diff paint snapshots against the last rendered frame.\r\n *  - Regenerate thumbnails only for changed pages.\r\n */\r\n\r\nimport { createEditorI18n, type EditorI18n, type Translate } from '@vervedoc/i18n'\r\nimport type { IDocxDocumentMeta, IEditorOption, IPosition, Path } from '@vervedoc/docx-editor-schema'\r\nimport { formatElementTree, pairBookmarkMarkers, getByPath } from '@vervedoc/docx-editor-schema'\r\n\r\nimport type { Listener, RangeManager, EventBus } from '@vervedoc/docx-editor-state'\r\nimport { LayoutEngine, type LayoutOptions } from './layout-engine'\r\nimport type { DocumentLayout, ParagraphBlock, InlineBox, LineBox } from './layout-types'\r\nimport { CanvasRenderer } from './canvas-renderer'\r\nimport { hitTest } from './hit-test'\r\nimport { locateCaret, computeSelectionRects } from './caret-rect'\r\nimport { TableWidget } from './widgets/table-widget'\r\nimport { ImageWidget } from './widgets/image-widget'\r\nimport { ChartWidget } from './widgets/chart-widget'\r\nimport { ParagraphWidget } from './widgets/paragraph-widget'\r\nimport { HeaderFooterWidget, type Zone } from './widgets/header-footer-widget'\r\nimport { RulerWidget } from './widgets/ruler-widget'\r\nimport { WatermarkWidget, type WatermarkConfig } from './widgets/watermark-widget'\r\nimport { SystemWatermarkWidget, type SystemWatermarkConfig } from './widgets/watermark-system-widget'\r\nimport { SelectionToolbarWidget } from './widgets/selection-toolbar-widget'\r\nimport { CaretWidget } from './widgets/caret-widget'\r\nimport { computeDirtyRect, prepareRenderState, type RenderState } from './render-state'\r\nimport {\r\n  findInlineByPos,\r\n  findParagraphByPos,\r\n  findLineByPos,\r\n  findFirstInline,\r\n  findLastInline,\r\n  findHyperlinkByPos\r\n} from './layout-query'\r\nimport { collectGroupAnchors, collectRevisionAnchors, type AnchorInfo } from './anchor-collector'\r\nimport { CaretNavigation } from './caret-navigation'\r\nimport { ZoneManager } from './zone-manager'\r\n\r\n// 固定黑色 I-beam，避免系统文本指针在白色页面上不可见。\r\nconst TEXT_CURSOR = `url(\"data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\"><path d=\"M8 3h8M12 3v18M8 21h8\" fill=\"none\" stroke=\"black\" stroke-width=\"2\"/></svg>')}\") 9 9, text`\r\n\r\n/** Draw 门面依赖：装配文档、状态管理器与各类回调 */\r\nexport interface DrawDeps {\r\n  /** 文档元数据 */\r\n  document: IDocxDocumentMeta\r\n  /** 事件监听器（用于发射 page-count-change 等事件） */\r\n  listener?: Listener\r\n  /** 事件总线（用于发射用户交互事件，如 editor-mousedown/chart-click 等） */\r\n  eventBus?: EventBus\r\n\r\n  /** 选区管理器 */\r\n  rangeManager?: RangeManager\r\n  /** 键盘/输入时触发的回调（由 core 装配） */\r\n  onInput?: (text: string) => void\r\n  /** 键盘事件回调（由 core 装配） */\r\n  onKeyDown?: (e: KeyboardEvent) => void\r\n  /** 每次 RAF 渲染完成后调用（用于驱动批注/修订 overlay 更新） */\r\n  afterRender?: () => void\r\n  /** 悬浮工具栏命令回调（由 core 装配，转发到 Command） */\r\n  onCommand?: (command: string, ...args: any[]) => any\r\n  /** zone 变化回调（由 core 装配，用于驱动 UI 标签显示） */\r\n  onZoneChange?: (zone: Zone) => void\r\n  i18n?: EditorI18n\r\n}\r\n\r\n/**\r\n * 编辑器视图门面类：装配 LayoutEngine + CanvasRenderer + 各交互 widget，\r\n * 对外提供文档/光标/选区/工具栏 API，对内调度排版、渲染、事件绑定。\r\n */\r\nexport class Draw {\r\n  /** 外层容器 DOM */\r\n  private container: HTMLDivElement\r\n  /** 滚动包装层（绝对定位、自身溢出滚动） */\r\n  private wrapper: HTMLDivElement\r\n  /** 撑起文档总高度的占位元素（驱动 wrapper 滚动） */\r\n  private scroller: HTMLDivElement\r\n  /** canvas 三层宿主（pointer-events:none，覆盖 container 视口） */\r\n  private canvasHost: HTMLDivElement\r\n  /** canvas 渲染器 */\r\n  private renderer: CanvasRenderer\r\n\r\n  setChartRenderer(renderer: import('@vervedoc/docx-editor-schema').IChartRenderer | null): void {\r\n    this.renderer.setChartRenderer(renderer)\r\n    this.thumbnailCache.clear()\r\n    this.forceFullRender = true\r\n    this.scheduleRender()\r\n  }\r\n  /** 排版引擎 */\r\n  private engine: LayoutEngine\r\n  /** 最近一次排版结果 */\r\n  private layout: DocumentLayout | null = null\r\n  private diagnosticNotice?: HTMLDivElement\r\n  private diagnosticSignature = ''\r\n\r\n  /** 文档元数据 */\r\n  private document: IDocxDocumentMeta\r\n  /** 编辑器选项 */\r\n  private options: IEditorOption\r\n  /** 选区管理器 */\r\n  private range?: RangeManager\r\n  /** 事件监听器 */\r\n  private listener?: Listener\r\n  /** 事件总线（用户交互事件） */\r\n  private eventBus?: EventBus\r\n  private translate: Translate\r\n  private unsubscribeI18n: () => void\r\n\r\n  /** 当前滚动 y（wrapper.scrollTop） */\r\n  private scrollY = 0\r\n  /** 视口高度 */\r\n  private viewportHeight = 0\r\n  /** 视口宽度 */\r\n  private viewportWidth = 0\r\n  /** RAF 帧句柄 */\r\n  private rafId: number | null = null\r\n  /** 当前 RAF 是否跳过 afterRender（滚动渲染时为 true，避免每帧生成缩略图） */\r\n  private _pendingSkipAfterRender = false\r\n\r\n  /** 容器尺寸观察器 */\r\n  private ro?: ResizeObserver\r\n\r\n  private renderState?: RenderState\r\n  private paintedState?: RenderState\r\n  private forceFullRender = true\r\n  private thumbnailCache = new Map<number, { signature: string; image: string; foreground?: string }>()\r\n\r\n  /** 隐藏 textarea：作为输入焦点与 IME 组合的宿主 */\r\n  private inputEl!: HTMLTextAreaElement\r\n  /** IME 组合输入中标志 */\r\n  private isComposing = false\r\n\r\n  /** 光标闪烁可见性 */\r\n  private caretVisible = true\r\n  /** 光标闪烁定时器句柄 */\r\n  private caretTimer: number | null = null\r\n\r\n  /** 鼠标拖拽选区状态 */\r\n  private isDragging = false\r\n  /** 拖拽锚点（按下位置） */\r\n  private dragAnchor: IPosition | null = null\r\n  /** 拖拽过程中最近一次命中位置（RAF 节流） */\r\n  private dragPendingPos: IPosition | null = null\r\n  /** 拖拽 RAF 句柄 */\r\n  private dragRafId: number | null = null\r\n\r\n  /** 文本输入回调 */\r\n  private onInput?: (text: string) => void\r\n  /** 键盘事件回调 */\r\n  private onKeyDown?: (e: KeyboardEvent) => void\r\n  /** 渲染完成后回调 */\r\n  private afterRender?: () => void\r\n  /** 命令回调（转发到 Command） */\r\n  private onCommand?: (command: string, ...args: any[]) => any\r\n\r\n  /** 悬浮选区工具栏 widget */\r\n  private selectionToolbarWidget: SelectionToolbarWidget | null = null\r\n  /** 抑制下一次悬浮工具栏显示（段落手柄选中时用） */\r\n  private _suppressToolbar = false\r\n\r\n\r\n  /** 当前编辑区域：正文 / 页眉 / 页脚 */\r\n  private zone: Zone = 'main'\r\n  /** zone 变化回调（由 core 装配，用于驱动 UI 标签显示） */\r\n  private onZoneChange?: (zone: Zone) => void\r\n\r\n  /** 表格交互 widget（手柄 + 右键菜单） */\r\n  private tableWidget: TableWidget | null = null\r\n  /** 图片交互 widget（选中 + 缩放手柄 + 右键菜单） */\r\n  private imageWidget: ImageWidget | null = null\r\n  /** 图表交互 widget（选中 + 缩放手柄 + 编辑/删除工具栏） */\r\n  private chartWidget: ChartWidget | null = null\r\n  /** 段落格式悬浮 widget */\r\n  private paragraphWidget: ParagraphWidget | null = null\r\n  /** 页眉页脚交互 widget */\r\n  private headerFooterWidget: HeaderFooterWidget | null = null\r\n  /** 标尺 widget */\r\n  private rulerWidget: RulerWidget | null = null\r\n  /** 水印渲染 widget */\r\n  private watermarkWidget: WatermarkWidget | null = null\r\n  /** 系统级水印 widget（DOM 覆盖层） */\r\n  private systemWatermarkWidget: SystemWatermarkWidget | null = null\r\n  /** DOM 光标 widget（替代 canvas overlay 绘制光标） */\r\n  private caretWidget: CaretWidget | null = null\r\n  /** 光标导航 Controller */\r\n  private caretNavigation: CaretNavigation | null = null\r\n  /** 编辑区域 Manager */\r\n  private zoneManager: ZoneManager | null = null\r\n\r\n  /**\r\n   * 创建 Draw 视图门面：构建 DOM 骨架、装配渲染器/排版引擎/各 widget、绑定事件并首次渲染。\r\n   * @param container 外层容器 DOM\r\n   * @param options 编辑器选项\r\n   * @param deps 依赖装配（文档、状态、回调）\r\n   */\r\n  constructor(container: HTMLDivElement, options: IEditorOption, deps: DrawDeps) {\r\n    this.container = container\r\n    this.options = options\r\n    this.document = deps.document\r\n    this.range = deps.rangeManager\r\n    this.onInput = deps.onInput\r\n    this.onKeyDown = deps.onKeyDown\r\n    this.afterRender = deps.afterRender\r\n    this.onCommand = deps.onCommand\r\n    this.onZoneChange = deps.onZoneChange\r\n    this.listener = deps.listener\r\n    this.eventBus = deps.eventBus\r\n    const i18n = deps.i18n ?? createEditorI18n(options.locale)\r\n    this.translate = i18n.t\r\n    this.unsubscribeI18n = i18n.subscribe(() => {\r\n      this.options.locale = i18n.locale\r\n      this.refreshTranslations()\r\n    })\r\n\r\n    container.classList.add('vervedocs-container')\r\n    // container 需要作为绝对定位的参照\r\n    if (getComputedStyle(container).position === 'static') {\r\n      container.style.position = 'relative'\r\n    }\r\n    container.style.overflow = 'hidden'\r\n    container.style.background = '#E2E2E2'\r\n\r\n    // scroller 是可滚动容器（自身溢出出现滚动条）\r\n    this.wrapper = document.createElement('div')\r\n    this.wrapper.className = 'vervedocs-wrapper'\r\n    this.wrapper.style.position = 'absolute'\r\n    this.wrapper.style.inset = '0'\r\n    this.wrapper.style.overflow = 'auto'\r\n    this.wrapper.style.background = 'transparent'\r\n    this.wrapper.style.cursor = TEXT_CURSOR\r\n    this.wrapper.style.zIndex = '5'\r\n\r\n    // 撑起文档总高度的占位元素\r\n    this.scroller = document.createElement('div')\r\n    this.scroller.className = 'vervedocs-scroller'\r\n    this.scroller.style.position = 'relative'\r\n\r\n    this.wrapper.appendChild(this.scroller)\r\n    container.appendChild(this.wrapper)\r\n\r\n    // canvas 层放在 container 内、wrapper 之上；绝对定位覆盖 container 视口，不参与滚动\r\n    this.canvasHost = document.createElement('div')\r\n    this.canvasHost.className = 'vervedocs-canvas-host'\r\n    this.canvasHost.style.position = 'absolute'\r\n    this.canvasHost.style.inset = '0'\r\n    this.canvasHost.style.pointerEvents = 'none'\r\n    container.appendChild(this.canvasHost)\r\n\r\n    this.renderer = new CanvasRenderer(this.canvasHost, {\r\n      dpr: Number(options.devicePixelRatio ?? window.devicePixelRatio ?? 1),\r\n      scale: Number(options.scale ?? 1),\r\n      pageMargins: (options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      showMarginRuler: (options as unknown as { showMarginRuler?: boolean }).showMarginRuler ?? true,\r\n      groupColors: (options as unknown as { group?: { groupColors?: Record<string, import('@vervedoc/docx-editor-schema').IGroupColor> } }).group?.groupColors\r\n    })\r\n\r\n    this.renderer.setEyeCare(!!options.eyeCare)\r\n    this.engine = new LayoutEngine(this.toLayoutOptions())\r\n\r\n    this.wrapper.addEventListener('scroll', this.onScroll, { passive: true })\r\n    if (typeof ResizeObserver !== 'undefined') {\r\n      this.ro = new ResizeObserver(() => this.resize())\r\n      this.ro.observe(container)\r\n    }\r\n    const assetLoaded = () => {\r\n      this.thumbnailCache.clear()\r\n      this.forceFullRender = true\r\n      this.scheduleRender()\r\n    }\r\n    this.canvasHost.addEventListener('vervedocs:image-loaded', assetLoaded)\r\n    this.canvasHost.addEventListener('vervedocs:chart-loaded', assetLoaded)\r\n\r\n    // Range 变化时触发光标重绘 + 悬浮工具栏 + 工具栏样式同步\r\n    if (deps.listener && this.range) {\r\n      deps.listener.on('rangeChange', () => {\r\n        this.caretVisible = true\r\n        this.renderCaretIfAny()\r\n        // 拖拽过程中不更新悬浮工具栏，等 mouseup 再触发，避免工具栏跟随拖拽闪烁\r\n        if (!this.isDragging) {\r\n          // 同步选区样式到工具栏（formatChange）\r\n          const style = this.onCommand?.('getRangeStyle')\r\n          if (style) this.listener?.emit('formatChange', style)\r\n          this.selectionToolbarWidget?.update()\r\n          this.tableWidget?.update()\r\n          this.imageWidget?.update()\r\n          this.chartWidget?.update()\r\n          this.paragraphWidget?.update()\r\n          this.rulerWidget?.update()\r\n        }\r\n      })\r\n    }\r\n\r\n    // 隐藏输入框（textarea）：捕获所有键盘 & IME 输入\r\n    this.inputEl = document.createElement('textarea')\r\n    this.inputEl.className = 'vervedocs-hidden-input'\r\n    this.inputEl.readOnly = !!options.readonly\r\n    this.inputEl.disabled = !!options.disabled\r\n    Object.assign(this.inputEl.style, {\r\n      position: 'absolute',\r\n      left: '0px',\r\n      top: '0px',\r\n      width: '1px',\r\n      height: '1px',\r\n      opacity: '0',\r\n      border: 'none',\r\n      outline: 'none',\r\n      resize: 'none',\r\n      padding: '0',\r\n      margin: '0',\r\n      overflow: 'hidden',\r\n      zIndex: '10',\r\n      background: 'transparent',\r\n      color: 'transparent',\r\n      cursor: TEXT_CURSOR,\r\n      caretColor: 'transparent'\r\n    } as CSSStyleDeclaration)\r\n    this.inputEl.setAttribute('autocorrect', 'off')\r\n    this.inputEl.setAttribute('autocapitalize', 'off')\r\n    this.inputEl.setAttribute('spellcheck', 'false')\r\n    container.appendChild(this.inputEl)\r\n\r\n    this.bindEditingEvents()\r\n\r\n    this.resize()\r\n    this.reformatAndRender()\r\n    this.startCaretBlink()\r\n    this.selectionToolbarWidget = new SelectionToolbarWidget({\r\n      canEdit: () => !this.options.readonly && !this.options.disabled,\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getDocument: () => this.document,\r\n      getZone: () => this.zone,\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      getViewportWidth: () => this.viewportWidth,\r\n      getContainer: () => this.container,\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      isSuppressToolbar: () => this._suppressToolbar,\r\n      consumeSuppressToolbar: () => { this._suppressToolbar = false }\r\n    })\r\n    this.selectionToolbarWidget.create()\r\n    this.tableWidget = new TableWidget({\r\n      translate: this.translate,\r\n      canEdit: () => !this.options.readonly && !this.options.disabled,\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      hit: (clientX: number, clientY: number) => this.hit(clientX, clientY),\r\n      focusInput: () => this.focusInput(),\r\n      setCursor: (cursor: string) => {\r\n        this.wrapper.style.cursor = cursor === 'text' || cursor === 'default' ? TEXT_CURSOR : cursor\r\n      }\r\n    })\r\n    this.tableWidget.create()\r\n    this.headerFooterWidget = new HeaderFooterWidget({\r\n      translate: this.translate,\r\n      getLayout: () => this.layout,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getWrapperWidth: () => this.wrapper.clientWidth,\r\n      getScrollLeft: () => this.wrapper.scrollLeft,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      getZone: () => this.zone,\r\n      setZone: (zone: Zone) => this.setZone(zone),\r\n      setZoneWithCaret: (zone: Zone) => this.setZoneWithCaret(zone),\r\n      focusInput: () => this.focusInput(),\r\n      drawZoneBorder: (layout, scrollY, zone, pageOffsetX) => this.renderer.drawZoneBorder(layout, scrollY, zone, pageOffsetX),\r\n      onInsertPageNumber: (options) => {\r\n        const zone: 'header' | 'footer' = this.zone === 'header' ? 'header' : 'footer'\r\n        this.onCommand?.('executeSetPageNumber', { ...options, zone })\r\n      }\r\n    })\r\n    this.headerFooterWidget.create()\r\n    this.imageWidget = new ImageWidget({\r\n      getContainer: () => this.canvasHost,\r\n      getLayout: () => this.layout,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      onUpdateImageSizeLive: (path: Path, width: number, height: number) => this.updateImageSizeLive(path, width, height)\r\n    })\r\n    this.imageWidget.create()\r\n    this.chartWidget = new ChartWidget({\r\n      getContainer: () => this.canvasHost,\r\n      getLayout: () => this.layout,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      onUpdateChartSizeLive: (path: Path, width: number, height: number) => this.updateChartSizeLive(path, width, height),\r\n      getEventBus: () => this.eventBus\r\n    })\r\n    this.chartWidget.create()\r\n    this.paragraphWidget = new ParagraphWidget({\r\n      translate: this.translate,\r\n      canEdit: () => !this.options.readonly && !this.options.disabled,\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      hit: (clientX: number, clientY: number) => this.hit(clientX, clientY),\r\n      suppressToolbar: () => { this._suppressToolbar = true },\r\n      focusInput: () => this.focusInput()\r\n    })\r\n    this.paragraphWidget.create()\r\n    this.rulerWidget = new RulerWidget({\r\n      container: container,\r\n      getLayout: () => this.layout,\r\n      getScrollY: () => this.scrollY,\r\n      getWrapperWidth: () => this.wrapper.clientWidth,\r\n      getWrapperHeight: () => this.wrapper.clientHeight,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      // Layout coordinates are already the renderer's page coordinates.\r\n      getScale: () => (this.layout?.pageWidth ?? Number(this.options.pageWidth ?? 794)) / Number(this.options.pageWidth ?? 794),\r\n      getPageMargins: () => (this.options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      getParagraphIndent: () => {\r\n        const pos = this.range?.getFocus()\r\n        const paragraph = pos ? findParagraphByPos(this.layout, pos) : null\r\n        if (!paragraph) return null\r\n        const run = paragraph.lines[0]?.inlines[0]?.run\r\n        const attr = (key: string) => Number(\r\n          (paragraph.block as unknown as Record<string, unknown> | null)?.[key] ??\r\n          (run as unknown as Record<string, unknown> | undefined)?.[key] ?? 0\r\n        )\r\n        const left = Math.max(0, attr('paragraphIndentLeft'))\r\n        const hanging = Math.max(0, attr('indentHanging'))\r\n        return {\r\n          first: left + (hanging ? 0 : Math.max(0, attr('paragraphFirstLineIndent'))),\r\n          left: left + hanging,\r\n          right: Math.max(0, attr('paragraphIndentRight'))\r\n        }\r\n      },\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args)\r\n    })\r\n    this.rulerWidget.create()\r\n    if ((options as unknown as { showRuler?: boolean }).showRuler) {\r\n      this.rulerWidget.setVisible(true)\r\n    }\r\n\r\n    this.watermarkWidget = new WatermarkWidget({\r\n      getPageOffsetX: () => this.getPageOffsetX()\r\n    })\r\n    this.watermarkWidget.create()\r\n    this.renderer.setWatermarkWidget(this.watermarkWidget)\r\n\r\n    this.systemWatermarkWidget = new SystemWatermarkWidget({\r\n      getContainer: () => this.container\r\n    })\r\n    this.systemWatermarkWidget.create()\r\n\r\n    this.caretWidget = new CaretWidget({\r\n      getCanvasHost: () => this.canvasHost\r\n    })\r\n    this.caretWidget.create()\r\n\r\n    this.caretNavigation = new CaretNavigation({\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getZone: () => this.zone,\r\n      findInlineByPos: (pos) => this.findInlineByPos(pos),\r\n      findParagraphByPos: (pos) => this.findParagraphByPos(pos),\r\n      findLineByPos: (pos) => this.findLineByPos(pos),\r\n      findFirstInline: () => this.findFirstInline(),\r\n      findLastInline: () => this.findLastInline(),\r\n      setCaretVisible: (visible: boolean) => { this.caretVisible = visible },\r\n      renderCaretIfAny: () => this.renderCaretIfAny()\r\n    })\r\n\r\n    this.zoneManager = new ZoneManager({\r\n      getPage: () => this.layout?.pages.find(page => this.scrollY < page.rect.y + page.rect.height),\r\n      getZone: () => this.zone,\r\n      setZoneState: (zone: Zone) => { this.zone = zone },\r\n      getDocument: () => this.document,\r\n      getRange: () => this.range ?? null,\r\n      focusInput: () => this.focusInput(),\r\n      onZoneChange: (zone: Zone) => { this.onZoneChange?.(zone) },\r\n      scheduleRender: () => this.scheduleRender(),\r\n      reformatAndRender: () => this.reformatAndRender()\r\n    })\r\n  }\r\n\r\n  /* -------------------- 输入 / 键盘事件 -------------------- */\r\n\r\n  /** 绑定编辑相关事件：鼠标点选/拖拽、右键菜单、键盘、IME 组合输入。 */\r\n  private bindEditingEvents(): void {\r\n    // 让 wrapper 可接收指针事件（canvasHost 为 pointer-events:none）\r\n    this.wrapper.addEventListener('mousedown', this.onMouseDown)\r\n    this.wrapper.addEventListener('contextmenu', this.onContextMenu)\r\n    // 拖拽选区：mousemove/mouseup 绑定在 window，以捕获拖出 wrapper 的情况\r\n    window.addEventListener('mousemove', this.onMouseMove)\r\n    window.addEventListener('mouseup', this.onMouseUp)\r\n\r\n    // 键盘事件在 inputEl 上\r\n    this.inputEl.addEventListener('keydown', (e) => {\r\n      // 光标可见性重置（阻止闪烁在打字时消失）\r\n      this.caretVisible = true\r\n      this.renderCaretIfAny()\r\n      if (this.onKeyDown) this.onKeyDown(e)\r\n    })\r\n\r\n    // 组合输入（中文/emoji）\r\n    this.inputEl.addEventListener('compositionstart', () => { this.isComposing = true })\r\n    this.inputEl.addEventListener('compositionend', (e) => {\r\n      this.isComposing = false\r\n      const text = (e as CompositionEvent).data ?? ''\r\n      if (text && !this.options.readonly && !this.options.disabled) this.onInput?.(text)\r\n      this.inputEl.value = ''\r\n    })\r\n\r\n    // 普通输入（非 IME）\r\n    this.inputEl.addEventListener('input', (e) => {\r\n      if (this.isComposing) return\r\n      const ie = e as InputEvent\r\n      const data = ie.data ?? this.inputEl.value\r\n      if (data && !this.options.readonly && !this.options.disabled) this.onInput?.(data)\r\n      this.inputEl.value = ''\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 鼠标按下处理：表格/图片/页眉页脚手柄优先；否则命中文档位置后处理\r\n   * Ctrl+点击跳转、双击选词、三击选段、Shift+扩展选区、普通点击+开始拖拽。\r\n   * @param e 鼠标事件\r\n   */\r\n  /** 获取事件总线（供 commands 插件等发射交互事件） */\r\n  getEventBus(): EventBus | undefined {\r\n    return this.eventBus\r\n  }\r\n\r\n  private isAnnotationEvent(e: MouseEvent): boolean {\r\n    return e.target instanceof Element\r\n      && !!e.target.closest('.ce-comment-overlay, .ce-revision-overlay')\r\n  }\r\n\r\n  private onMouseDown = (e: MouseEvent): void => {\r\n    // Annotation controls own their native focus and text selection.\r\n    if (this.isAnnotationEvent(e)) return\r\n    if (this.options.disabled) return\r\n    this.eventBus?.emit('editorMousedown', e)\r\n    if (!this.range || e.button !== 0) return\r\n    // 阻止 mousedown 默认行为抢走隐藏输入框的焦点\r\n    e.preventDefault()\r\n\r\n    // 表格边框拖拽\r\n    if (!this.options.readonly && this.tableWidget?.handleMouseDown(e)) return\r\n\r\n    // 图片选中/缩放\r\n    if (!this.options.readonly && this.imageWidget?.handleMouseDown(e)) {\r\n      this.eventBus?.emit('imageMousedown', e)\r\n      return\r\n    }\r\n\r\n    // 图表选中/缩放\r\n    if (!this.options.readonly && this.chartWidget?.handleMouseDown(e)) {\r\n      return\r\n    }\r\n\r\n    // 双击页眉/页脚区域：切换编辑区域\r\n    if (!this.options.readonly && this.headerFooterWidget?.handleMouseDown(e)) return\r\n\r\n    const pos = this.hit(e.clientX, e.clientY)\r\n    if (!pos) { this.inputEl.focus(); return }\r\n    // Ctrl/Cmd + 单击：命中超链接则打开浏览器跳转（WPS 行为）\r\n    if ((e.ctrlKey || e.metaKey) && !e.shiftKey && e.detail === 1) {\r\n      const url = this.findHyperlinkByPos(pos)\r\n      if (url) { window.open(url, '_blank', 'noopener'); return }\r\n    }\r\n    // 三击：选段\r\n    if (e.detail >= 3) { this.selectParagraphAt(pos); this.finishMouseSelect(); return }\r\n    // 双击：选词\r\n    if (e.detail === 2) { this.selectWordAt(pos); this.finishMouseSelect(); return }\r\n    // Shift+Click：扩展选区（anchor 不动，focus 移到点击点）\r\n    if (e.shiftKey) {\r\n      const anchor = this.range.getAnchor()\r\n      if (anchor) { this.range.setRange({ anchor, focus: pos }); this.finishMouseSelect(); return }\r\n    }\r\n    // 普通点击：折叠光标并开始拖拽\r\n    this.range.setCaret(pos)\r\n    this.dragAnchor = pos\r\n    this.isDragging = true\r\n    this.wrapper.style.cursor = TEXT_CURSOR\r\n    this.finishMouseSelect()\r\n  }\r\n\r\n  /**\r\n   * 鼠标移动处理：非拖拽时按 hover 超链接切换光标；拖拽时 RAF 节流更新选区 focus。\r\n   * @param e 鼠标事件\r\n   */\r\n  private onMouseMove = (e: MouseEvent): void => {\r\n    if (!this.isDragging && this.isAnnotationEvent(e)) return\r\n    // 文本选区拖拽保持文本指针；表格边框悬浮和拖拽优先于链接指针。\r\n    if (!this.isDragging && this.tableWidget?.handleMouseMove(e)) return\r\n    // 非拖拽时：hover 超链接显示手型，提示可 Ctrl+点击跳转\r\n    if (!this.isDragging) {\r\n      const pos = this.hit(e.clientX, e.clientY)\r\n      const url = pos ? this.findHyperlinkByPos(pos) : null\r\n      this.wrapper.style.cursor = url ? 'pointer' : TEXT_CURSOR\r\n      // 正文模式下，悬浮页眉/页脚区域显示提示\r\n      this.updateZoneHoverTooltip(e)\r\n      return\r\n    }\r\n    if (!this.range || !this.dragAnchor || !this.layout) return\r\n    const pos = this.hit(e.clientX, e.clientY)\r\n    if (!pos) return\r\n    this.dragPendingPos = pos\r\n    if (this.dragRafId == null) {\r\n      this.dragRafId = requestAnimationFrame(() => {\r\n        this.dragRafId = null\r\n        if (!this.dragPendingPos || !this.range || !this.dragAnchor) return\r\n        this.range.setRange({ anchor: this.dragAnchor, focus: this.dragPendingPos })\r\n        this.caretVisible = true\r\n        this.renderCaretIfAny()\r\n      })\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 正文模式下，鼠标悬浮在页眉/页脚区域时设置 title 提示。\r\n   * @param e 鼠标事件\r\n   */\r\n  private updateZoneHoverTooltip(e: MouseEvent): void {\r\n    if (!this.layout || this.zone !== 'main') {\r\n      this.wrapper.title = ''\r\n      return\r\n    }\r\n    const rect = this.canvasHost.getBoundingClientRect()\r\n    const docY = e.clientY - rect.top + this.scrollY\r\n    for (const page of this.layout.pages) {\r\n      if (docY < page.rect.y || docY > page.rect.y + page.rect.height) continue\r\n      if (page.headerRect && docY >= page.headerRect.y && docY <= page.headerRect.y + page.headerRect.height) {\r\n        this.wrapper.title = '双击编辑页眉'\r\n        return\r\n      }\r\n      if (page.footerRect && docY >= page.footerRect.y && docY <= page.footerRect.y + page.footerRect.height) {\r\n        this.wrapper.title = '双击编辑页脚'\r\n        return\r\n      }\r\n      break\r\n    }\r\n    this.wrapper.title = ''\r\n  }\r\n\r\n  /**\r\n   * 鼠标松开处理：结束拖拽、清理 RAF、更新悬浮工具栏与各 widget。\r\n   * @param e 鼠标事件\r\n   */\r\n  private onMouseUp = (e: MouseEvent): void => {\r\n    this.eventBus?.emit('editorMouseup', e)\r\n    this.tableWidget?.handleMouseUp(e)\r\n    const wasDragging = this.isDragging\r\n    if (wasDragging && this.dragRafId != null && this.dragPendingPos && this.dragAnchor && this.range) {\r\n      this.range.setRange({ anchor: this.dragAnchor, focus: this.dragPendingPos })\r\n    }\r\n    this.isDragging = false\r\n    this.dragAnchor = null\r\n    this.dragPendingPos = null\r\n    if (this.dragRafId != null) { cancelAnimationFrame(this.dragRafId); this.dragRafId = null }\r\n    if (wasDragging) {\r\n      const style = this.onCommand?.('getRangeStyle')\r\n      if (style) this.listener?.emit('formatChange', style)\r\n    }\r\n    // 松开鼠标后才显示悬浮工具栏\r\n    this.selectionToolbarWidget?.update()\r\n\r\n  }\r\n\r\n  /** 鼠标选区结束收尾：聚焦隐藏输入框、重置光标可见性并重绘。 */\r\n  private finishMouseSelect(): void {\r\n    this.focusInput()\r\n    this.caretVisible = true\r\n    this.renderCaretIfAny()\r\n  }\r\n\r\n  /* -------------------- 右键菜单 -------------------- */\r\n\r\n  /**\r\n   * 右键菜单处理：优先交给图片/表格 widget 显示上下文菜单。\r\n   * @param e 鼠标事件\r\n   */\r\n  private onContextMenu = (e: MouseEvent): void => {\r\n    if (this.isAnnotationEvent(e)) return\r\n    e.preventDefault()\r\n    if (this.options.readonly || this.options.disabled) return\r\n\r\n    // 命中超链接时通知 UI 显示超链接右键菜单\r\n    const pos = this.hit(e.clientX, e.clientY)\r\n    if (pos && this.findHyperlinkByPos(pos)) {\r\n      this.eventBus?.emit('hyperlinkMenuClick')\r\n      return\r\n    }\r\n\r\n    // 优先表格，未命中再尝试段落\r\n    if (this.tableWidget?.showContextMenu(e.clientX, e.clientY)) return\r\n    this.paragraphWidget?.showContextMenu(e.clientX, e.clientY)\r\n  }\r\n\r\n\r\n  /* -------------------- 双击选词 / 三击选段 -------------------- */\r\n\r\n  /**\r\n   * 双击选词：在命中 inline 内按 word char 边界扩展选区；非 word char 选当前单字。\r\n   * @param pos 命中位置\r\n   */\r\n  private selectWordAt(pos: IPosition): void {\r\n    this.caretNavigation?.selectWordAt(pos)\r\n  }\r\n\r\n  /**\r\n   * 三击选段：把选区扩展到命中段落的首 inline 起点到末 inline 终点。\r\n   * @param pos 命中位置\r\n   */\r\n  private selectParagraphAt(pos: IPosition): void {\r\n    this.caretNavigation?.selectParagraphAt(pos)\r\n  }\r\n\r\n  /**\r\n   * 按 position 在当前 layout 中查找所属 inline。\r\n   * @param pos 待定位位置\r\n   * @returns 命中的 InlineBox；未命中返回 null\r\n   */\r\n  private findInlineByPos(pos: IPosition): InlineBox | null {\r\n    return findInlineByPos(this.layout, pos)\r\n  }\r\n\r\n  /**\r\n   * 按 position 在当前 layout 中查找所属段落块。\r\n   * @param pos 待定位位置\r\n   * @returns 命中的 ParagraphBlock；未命中返回 null\r\n   */\r\n  private findParagraphByPos(pos: IPosition): ParagraphBlock | null {\r\n    return findParagraphByPos(this.layout, pos)\r\n  }\r\n\r\n  /* -------------------- 光标移动（方向键 / Home / End / 词移动） -------------------- */\r\n\r\n  /** 光标上移：基于当前光标矩形，用 hitTest 命中上一行同 x 最近字符 */\r\n  moveCaretUp(): void {\r\n    this.caretNavigation?.moveCaretUp()\r\n  }\r\n\r\n  /** 光标下移 */\r\n  moveCaretDown(): void {\r\n    this.caretNavigation?.moveCaretDown()\r\n  }\r\n\r\n  /** 当前行首 */\r\n  moveCaretToLineStart(): void {\r\n    this.caretNavigation?.moveCaretToLineStart()\r\n  }\r\n\r\n  /** 当前行尾 */\r\n  moveCaretToLineEnd(): void {\r\n    this.caretNavigation?.moveCaretToLineEnd()\r\n  }\r\n\r\n  /** 按词左移 */\r\n  moveCaretWordLeft(): void {\r\n    this.caretNavigation?.moveCaretWordLeft()\r\n  }\r\n\r\n  /** 按词右移 */\r\n  moveCaretWordRight(): void {\r\n    this.caretNavigation?.moveCaretWordRight()\r\n  }\r\n\r\n  /** 文档首 */\r\n  moveCaretToDocStart(): void {\r\n    this.caretNavigation?.moveCaretToDocStart()\r\n  }\r\n\r\n  /** 文档尾 */\r\n  moveCaretToDocEnd(): void {\r\n    this.caretNavigation?.moveCaretToDocEnd()\r\n  }\r\n\r\n  /** 全选：从文档首到文档尾 */\r\n  selectAll(): void {\r\n    this.caretNavigation?.selectAll()\r\n  }\r\n\r\n  /**\r\n   * 按 position 在当前 layout 中查找所属行盒。\r\n   * @param pos 待定位位置\r\n   * @returns 命中的 LineBox；未命中返回 null\r\n   */\r\n  private findLineByPos(pos: IPosition): LineBox | null {\r\n    return findLineByPos(this.layout, pos)\r\n  }\r\n\r\n  /**\r\n   * 查找文档首个 inline（用于光标兜底定位到文档首）。\r\n   * @returns 首个 InlineBox；空文档返回 null\r\n   */\r\n  private findFirstInline(): InlineBox | null {\r\n    return findFirstInline(this.layout)\r\n  }\r\n\r\n  /** 按 position 定位 inline，若属于超链接则返回其 URL（供 Ctrl+点击跳转） */\r\n  private findHyperlinkByPos(pos: IPosition): string | null {\r\n    return findHyperlinkByPos(this.layout, pos)\r\n  }\r\n\r\n  /**\r\n   * 查找文档末个 inline（用于光标定位到文档尾/全选终点）。\r\n   * @returns 末个 InlineBox；空文档返回 null\r\n   */\r\n  private findLastInline(): InlineBox | null {\r\n    return findLastInline(this.layout)\r\n  }\r\n\r\n  /** 把隐藏输入框放到当前光标位置，以便 IME 弹窗位置正确 */\r\n  focusInput(): void {\r\n    if (!this.range) return\r\n    const pos = this.range.getFocus()\r\n    if (!pos || !this.layout) { this.inputEl.focus(); return }\r\n    const rect = locateCaret(this.layout, pos, this.zone)\r\n    if (rect) {\r\n      const pageOffsetX = this.getPageOffsetX()\r\n      this.inputEl.style.left = `${Math.round(rect.x + pageOffsetX)}px`\r\n      this.inputEl.style.top = `${Math.round(rect.y - this.scrollY)}px`\r\n    }\r\n    this.inputEl.focus()\r\n  }\r\n\r\n  /* -------------------- 光标闪烁 -------------------- */\r\n\r\n  /** 启动光标闪烁定时器（530ms 切换可见性）。 */\r\n  private startCaretBlink(): void {\r\n    if (this.caretTimer != null) return\r\n    this.caretTimer = window.setInterval(() => {\r\n      this.caretVisible = !this.caretVisible\r\n      this.renderCaretIfAny()\r\n    }, 530) as unknown as number\r\n  }\r\n\r\n  /** 重绘 overlay：zone 边框 + 选区高亮 + 光标（按 caretVisible 闪烁）。 */\r\n  private renderCaretIfAny(): void {\r\n    if (!this.layout || !this.range) return\r\n    this.renderer.clearOverlay()\r\n    // zone 边框（页眉/页脚编辑时）\r\n    this.headerFooterWidget?.renderBorder()\r\n    // 选区高亮（非折叠时）\r\n    const ordered = this.range.getOrdered()\r\n    if (ordered && !this.range.isCollapsed()) {\r\n      const tableRects = this.computeTableSelectionRects(ordered)\r\n      if (tableRects) {\r\n        this.renderer.drawSelection(tableRects, this.scrollY)\r\n      } else {\r\n        const selRects = computeSelectionRects(this.layout, ordered.start, ordered.end, this.zone)\r\n        this.renderer.drawSelection(selRects, this.scrollY)\r\n      }\r\n    }\r\n    // 光标（DOM 绘制）\r\n    const pos = this.range.getFocus()\r\n    if (!pos || this.options.readonly || this.options.disabled) {\r\n      this.caretWidget?.hide()\r\n      return\r\n    }\r\n    const rect = locateCaret(this.layout, pos, this.zone)\r\n    if (rect) {\r\n      this.caretWidget?.update(rect, this.scrollY, this.getPageOffsetX(), this.caretVisible)\r\n    } else {\r\n      this.caretWidget?.hide()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 计算表格整表选区高亮矩形：当选区恰好覆盖整张表（首格到末格）时返回所有 cell 矩形，\r\n   * 否则返回 null（交由普通文本选区处理）。\r\n   * @param ordered 有序选区\r\n   * @returns 单元格矩形数组；非整表选区返回 null\r\n   */\r\n  private computeTableSelectionRects(ordered: { start: IPosition; end: IPosition }): { x: number; y: number; width: number; height: number }[] | null {\r\n    if (!this.layout) return null\r\n    const { start, end } = ordered\r\n    if (start.path.length < 5 || end.path.length < 5) return null\r\n    if (start.path[1] !== 'trList' || end.path[1] !== 'trList') return null\r\n    if (start.path[0] !== end.path[0]) return null\r\n    const tableIndex = start.path[0] as number\r\n    for (const page of this.layout.pages) {\r\n      const block = page.blocks.find(b => b.kind === 'table' && b.indexInParent === tableIndex)\r\n      if (!block || block.kind !== 'table') continue\r\n      const rowCount = block.rows.length\r\n      const lastRow = block.rows[rowCount - 1]\r\n      if (!lastRow) return null\r\n      const lastColIdx = lastRow.cells.length - 1\r\n      const startRow = start.path[2] as number\r\n      const startCol = start.path[4] as number\r\n      const endRow = end.path[2] as number\r\n      const endCol = end.path[4] as number\r\n      if (startRow !== 0 || startCol !== 0 || endRow !== rowCount - 1 || endCol !== lastColIdx) return null\r\n      const rects: { x: number; y: number; width: number; height: number }[] = []\r\n      for (const row of block.rows) {\r\n        for (const cell of row.cells) {\r\n          rects.push({\r\n            x: page.contentRect.x + block.rect.x + cell.rect.x,\r\n            y: page.contentRect.y + block.rect.y + cell.rect.y,\r\n            width: cell.rect.width,\r\n            height: cell.rect.height\r\n          })\r\n        }\r\n      }\r\n      return rects\r\n    }\r\n    return null\r\n  }\r\n\r\n\r\n\r\n  /* -------------------- 对外 API -------------------- */\r\n\r\n  /**\r\n   * 设置新文档并触发重排版+重渲染。\r\n   * @param doc 新文档元数据\r\n   */\r\n  setDocument(doc: IDocxDocumentMeta): void {\r\n    if (!doc || !Array.isArray(doc.elements)) {\r\n      doc = { ...(doc ?? {}), elements: (doc as { elements?: unknown[] })?.elements ?? [] } as IDocxDocumentMeta\r\n    }\r\n    this.document = doc\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /**\r\n   * 获取当前文档元数据。\r\n   * @returns 文档元数据\r\n   */\r\n  getDocument(): IDocxDocumentMeta { return this.document }\r\n\r\n  /**\r\n   * 设置渲染缩放倍数并重排+重渲染。\r\n   * @param scale 缩放倍数\r\n   */\r\n  setScale(scale: number): void {\r\n    this.options.scale = scale\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /**\r\n   * 设置标尺可见性。\r\n   * @param visible 是否可见\r\n   */\r\n  setRulerVisible(visible: boolean): void {\r\n    this.rulerWidget?.setVisible(visible)\r\n  }\r\n\r\n  /**\r\n   * 实时更新图片尺寸（拖拽缩放时调用）并重排+重渲染。\r\n   * @param path 图片元素路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateImageSizeLive(path: Path, width: number, height: number): void {\r\n    const el = getByPath(this.document.elements, path)\r\n    if (!el || el.type !== 'image') return\r\n    ;(el as unknown as { width: number; height: number }).width = Math.max(1, Math.round(width))\r\n    ;(el as unknown as { width: number; height: number }).height = Math.max(1, Math.round(height))\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放图表过程中实时更新尺寸（不写文档历史，仅刷新显示）。\r\n   * @param path 图表路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateChartSizeLive(path: Path, width: number, height: number): void {\r\n    const el = getByPath(this.document.elements, path)\r\n    if (!el || el.type !== 'block') return\r\n    const metrics = (el as unknown as { metrics?: { width: number; height: number } }).metrics\r\n    if (!metrics) return\r\n    metrics.width = Math.max(1, Math.round(width))\r\n    metrics.height = Math.max(1, Math.round(height))\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /**\r\n   * 设置页边距并重排+重渲染。\r\n   * @param margins 页边距 [top, right, bottom, left]\r\n   */\r\n  setPaperMargins(margins: [number, number, number, number]): void {\r\n    this.options.pageMargins = margins\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /**\r\n   * 设置页面尺寸（宽/高）并重排+重渲染。\r\n   * @param width 页面宽度\r\n   * @param height 页面高度\r\n   */\r\n  setPageSize(width: number, height: number): void {\r\n    this.options.pageWidth = width\r\n    this.options.pageHeight = height\r\n    // Imported document geometry takes precedence over layout option defaults.\r\n    const paperDirection = width > height ? 'horizontal' : 'vertical'\r\n    this.document.pageWidth = width\r\n    this.document.pageHeight = height\r\n    this.document.paperDirection = paperDirection\r\n    for (const section of this.document.sections ?? []) {\r\n      section.pageWidth = width\r\n      section.pageHeight = height\r\n      section.paperDirection = paperDirection\r\n    }\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /**\r\n   * 获取当前编辑器选项。\r\n   * @returns 编辑器选项\r\n   */\r\n  getOptions(): IEditorOption { return this.options }\r\n\r\n  /** Refresh display translations without rebuilding open panels or changing editor state. */\r\n  refreshTranslations(): void {\r\n    this.paragraphWidget?.refreshTranslations()\r\n    this.tableWidget?.refreshTranslations()\r\n    this.headerFooterWidget?.refreshTranslations()\r\n  }\r\n\r\n  /**\r\n   * 批量更新编辑器选项并重排+重渲染。\r\n   * @param patch 选项补丁\r\n   */\r\n  updateOptions(patch: Partial<IEditorOption>): void {\r\n    Object.assign(this.options, patch)\r\n    if ('readonly' in patch || 'disabled' in patch) {\r\n      this.inputEl.readOnly = !!this.options.readonly\r\n      this.inputEl.disabled = !!this.options.disabled\r\n      this.inputEl.value = ''\r\n      this.isComposing = false\r\n      this._suppressToolbar = false\r\n      this.selectionToolbarWidget?.update()\r\n      this.paragraphWidget?.update()\r\n      this.tableWidget?.update()\r\n      this.renderCaretIfAny()\r\n    }\r\n    if (Object.prototype.hasOwnProperty.call(patch, 'eyeCare')) {\r\n      this.renderer.setEyeCare(!!this.options.eyeCare)\r\n      this.listener?.emit('thumbnailAppearanceChange')\r\n    }\r\n    // View-only toggles must not enter the document layout/render lifecycle.\r\n    if (Object.keys(patch).every(key => ['eyeCare', 'readonly', 'disabled'].includes(key))) return\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /** 打印完整分页，不依赖仅包含当前视口的 Canvas 图层。 */\r\n  print(): void {\r\n    if (!this.layout?.pages.length) return\r\n    const frame = document.createElement('iframe')\r\n    frame.title = '文档打印'\r\n    frame.setAttribute('aria-hidden', 'true')\r\n    frame.tabIndex = -1\r\n    frame.style.cssText = 'position:fixed;width:0;height:0;border:0;left:-10000px;top:0;'\r\n    try {\r\n      const images = this.getPageThumbnails()\r\n      const pageStyles = this.layout.pages.map((page, index) =>\r\n        `@page docx-page-${index}{size:${page.rect.width}px ${page.rect.height}px;margin:0}`\r\n      ).join('')\r\n      const pages = this.layout.pages.map((page, index) =>\r\n        `<div class=\"page\" style=\"page:docx-page-${index};width:${page.rect.width}px;height:${page.rect.height}px\"><img src=\"${images[index]}\" alt=\"\"/></div>`\r\n      ).join('')\r\n      // Wait for every page image before opening the native print dialog.\r\n      frame.onload = () => {\r\n        const w = frame.contentWindow\r\n        if (!w) {\r\n          frame.remove()\r\n          return\r\n        }\r\n        frame.onload = null\r\n        w.addEventListener('afterprint', () => {\r\n          setTimeout(() => frame.remove(), 0)\r\n        }, { once: true })\r\n        w.focus()\r\n        w.print()\r\n      }\r\n      frame.srcdoc = `<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"UTF-8\"><title>打印文档</title><style>\r\n        @page{margin:0}${pageStyles};\r\n        body{margin:0}\r\n        .page{break-after:page;page-break-after:always}\r\n        .page:last-child{break-after:auto;page-break-after:auto}\r\n        .page img{display:block;width:100%;height:100%}\r\n      </style></head><body>${pages}</body></html>`\r\n      document.body.appendChild(frame)\r\n    } catch (error) {\r\n      frame.remove()\r\n      throw error\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取所有页面的缩略图图片（data URL）。\r\n   * Reuse cached PNGs; only changed page content or visual options require painting.\r\n   * @returns 缩略图 data URL 数组，每个元素对应一页\r\n   */\r\n  getPageThumbnails(): string[] {\r\n    if (!this.layout) return []\r\n    this.syncPageNumberToRenderer()\r\n    this.syncWatermarkToRenderer()\r\n    const visualSignature = JSON.stringify([\r\n      { ...this.options, eyeCare: undefined }, this.layout.pages.length\r\n    ])\r\n    const images: string[] = []\r\n    for (const page of this.layout.pages) {\r\n      const signature = `${visualSignature}|${this.renderState?.pageSignatures.get(page.index)}`\r\n      let cached = this.thumbnailCache.get(page.index)\r\n      if (cached?.signature !== signature) {\r\n        let foreground: string | undefined\r\n        const image = this.renderer.renderPageThumbnail(page, 0.7, this.layout.pages.length, value => { foreground = value })\r\n        cached = { signature, image, foreground }\r\n        this.thumbnailCache.set(page.index, cached)\r\n      }\r\n      if (cached.image) images.push(cached.image)\r\n    }\r\n    for (const index of this.thumbnailCache.keys()) {\r\n      if (index >= this.layout.pages.length) this.thumbnailCache.delete(index)\r\n    }\r\n    return images\r\n  }\r\n\r\n  /** Cached transparent content only: this never renders pages on an appearance toggle. */\r\n  getThumbnailForegrounds(): string[] {\r\n    return Array.from(this.thumbnailCache.values(), cached => cached.foreground ?? '')\r\n  }\r\n\r\n  /**\r\n   * 获取最近一次排版结果。\r\n   * @returns 排版结果；未排版返回 null\r\n   */\r\n  getLayout(): DocumentLayout | null { return this.layout }\r\n\r\n  /**\r\n   * 获取滚动占位元素（驱动 wrapper 滚动，批注/修订组件据此判断新架构）。\r\n   * @returns scroller DOM\r\n   */\r\n  getScroller(): HTMLDivElement {\r\n    // 打标记，让批注/修订组件的 _applyContainerWidth 跳过宽度覆盖\r\n    ;(this.scroller as any).__vervedocsNewLayout = true\r\n    return this.scroller\r\n  }\r\n\r\n  /** 供 commands 组件（BlockParticle 等）挂载 DOM 的容器（随文档滚动） */\r\n  getContainer(): HTMLDivElement {\r\n    return this.scroller\r\n  }\r\n\r\n  /**\r\n   * 滚动到指定文档位置使其可见。\r\n   * @param pos 文档位置\r\n   */\r\n  scrollPositionIntoView(pos: IPosition): void {\r\n    if (!this.layout) return\r\n    const rect = locateCaret(this.layout, pos, this.zone)\r\n    if (!rect) return\r\n    const anchor = document.createElement('div')\r\n    anchor.style.position = 'absolute'\r\n    anchor.style.left = `${rect.x}px`\r\n    anchor.style.top = `${rect.y}px`\r\n    anchor.style.width = '1px'\r\n    anchor.style.height = `${rect.height}px`\r\n    this.scroller.append(anchor)\r\n    anchor.scrollIntoView({ block: 'center' })\r\n    anchor.remove()\r\n\r\n  }\r\n\r\n  /** 供 commands 组件获取当前活动区域元素列表 */\r\n  getElementList(): import('@vervedoc/docx-editor-schema').IElement[] {\r\n    return this.getActiveDocument().elements\r\n  }\r\n\r\n\r\n  /** 供 commands 组件访问 RangeManager（路径接口） */\r\n  getRange(): RangeManager | null {\r\n    return this.range ?? null\r\n  }\r\n\r\n\r\n  /** 获取当前编辑区域 */\r\n  getZone(): Zone { return this.zone }\r\n\r\n  /** 切换编辑区域（main/header/footer） */\r\n  setZone(zone: Zone): void {\r\n    this.zoneManager?.setZone(zone)\r\n  }\r\n\r\n  /**\r\n   * 切换编辑区域并设置初始光标。\r\n   * 切换到页眉/页脚时，将光标定位到对应区域的起始文本位置；\r\n   * 切回正文时清空选区。\r\n   * @param zone 目标区域\r\n   */\r\n  setZoneWithCaret(zone: Zone): void {\r\n    this.zoneManager?.setZoneWithCaret(zone)\r\n  }\r\n\r\n  /** 获取当前活动区域的文档（zone=header/footer 时 elements 指向对应区域） */\r\n  getActiveDocument(): IDocxDocumentMeta {\r\n    return this.zoneManager?.getActiveDocument() ?? this.document\r\n  }\r\n\r\n  /** 将修改后的活动文档写回对应区域并触发重渲染 */\r\n  applyActiveDocument(doc: IDocxDocumentMeta): void {\r\n    this.zoneManager?.applyActiveDocument(doc)\r\n  }\r\n\r\n  /** 设置当前高亮的批注/修订组 ID（鼠标悬浮气泡时调用） */\r\n  setActiveGroup(groupId: string | null): void {\r\n    if (!this.renderer.setActiveGroup(groupId) || !this.layout) return\r\n    // Hover is transient: paint now, without rebuilding cards, widgets or thumbnails.\r\n    // Keep any pending document RAF intact; it still owns its normal lifecycle hooks.\r\n    this.renderer.render(this.layout, this.scrollY, this.viewportHeight)\r\n  }\r\n\r\n  setActiveRevision(revisionId: string | null, color?: string): void {\r\n    if (!this.renderer.setActiveRevision(revisionId, color) || !this.layout) return\r\n    this.renderer.render(this.layout, this.scrollY, this.viewportHeight)\r\n  }\r\n\r\n  /**\r\n   * 遍历当前 layout，收集每个 groupId 所对应的锚点坐标（文档绝对坐标）。\r\n   * 返回 Map<groupId, { startX, startY, endX, endY, lineHeight, glyphHeight, startGlyphTop, endGlyphTop }>\r\n   * glyphHeight / startGlyphTop / endGlyphTop 用于按字形实际高度绘制竖线（而非行高）\r\n   */\r\n  getGroupAnchorMap(): Map<string, AnchorInfo> {\r\n    const result = new Map<string, AnchorInfo>()\r\n    if (!this.layout) return result\r\n    for (const page of this.layout.pages) {\r\n      collectGroupAnchors(page.blocks, page.contentRect.x, page.contentRect.y, result)\r\n    }\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 遍历当前 layout，收集每个 revisionId 所对应的锚点坐标（文档绝对坐标）。\r\n   * 返回 Map<revisionId, { startX, startY, endX, endY, lineHeight, glyphHeight, startGlyphTop, endGlyphTop }>\r\n   */\r\n  getRevisionAnchorMap(): Map<string, AnchorInfo> {\r\n    const result = new Map<string, AnchorInfo>()\r\n    if (!this.layout) return result\r\n    for (const page of this.layout.pages) {\r\n      collectRevisionAnchors(page.blocks, page.contentRect.x, page.contentRect.y, result)\r\n    }\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 命中测试：把客户端坐标转为文档坐标并调用 hitTest。\r\n   * @param clientX 客户端 x\r\n   * @param clientY 客户端 y\r\n   * @returns 命中位置；未命中返回 null\r\n   */\r\n  hit(clientX: number, clientY: number): IPosition | null {\r\n    if (!this.layout) return null\r\n    const rect = this.canvasHost.getBoundingClientRect()\r\n    // canvasHost 覆盖 container 视口；页面在 canvas 上的 x = page.rect.x + pageOffsetX\r\n    // 反推：文档坐标 x = (clientX - rect.left) - pageOffsetX\r\n    const pageOffsetX = this.getPageOffsetX()\r\n    const x = clientX - rect.left - pageOffsetX\r\n    const y = clientY - rect.top + this.scrollY\r\n    return hitTest(this.layout, x, y, this.zone)\r\n  }\r\n\r\n  /** 销毁视图：解绑事件、断开 ResizeObserver、取消 RAF/定时器、销毁各 widget、移除 DOM。 */\r\n  destroy(): void {\r\n    this.unsubscribeI18n()\r\n    this.diagnosticNotice?.remove()\r\n    this.wrapper.removeEventListener('scroll', this.onScroll)\r\n    this.wrapper.removeEventListener('mousedown', this.onMouseDown)\r\n    this.wrapper.removeEventListener('contextmenu', this.onContextMenu)\r\n    window.removeEventListener('mousemove', this.onMouseMove)\r\n    window.removeEventListener('mouseup', this.onMouseUp)\r\n    this.ro?.disconnect()\r\n    if (this.rafId != null) cancelAnimationFrame(this.rafId)\r\n    if (this.caretTimer != null) { clearInterval(this.caretTimer); this.caretTimer = null }\r\n    this.tableWidget?.destroy()\r\n    this.imageWidget?.destroy()\r\n    this.chartWidget?.destroy()\r\n    this.paragraphWidget?.destroy()\r\n    this.headerFooterWidget?.destroy()\r\n    this.rulerWidget?.destroy()\r\n    this.watermarkWidget?.destroy()\r\n    this.systemWatermarkWidget?.destroy()\r\n    this.selectionToolbarWidget?.destroy()\r\n    this.caretWidget?.destroy()\r\n    this.renderer.destroy()\r\n    this.thumbnailCache.clear()\r\n\r\n    if (this.inputEl && this.inputEl.parentElement === this.container) {\r\n      this.container.removeChild(this.inputEl)\r\n    }\r\n    this.container.removeChild(this.wrapper)\r\n  }\r\n\r\n  /* -------------------- 内部 -------------------- */\r\n\r\n  /**\r\n   * 把编辑器选项映射为排版引擎选项。\r\n   * @returns 排版选项\r\n   */\r\n  private toLayoutOptions(): LayoutOptions {\r\n    return {\r\n      pageWidth: Number(this.options.pageWidth ?? 794),\r\n      pageHeight: Number(this.options.pageHeight ?? 1123),\r\n      pageMargins: (this.options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      defaultFont: String(this.options.defaultFont ?? 'Microsoft YaHei'),\r\n      defaultSize: Number(this.options.defaultSize ?? 16),\r\n      defaultLineHeight: Number(this.options.defaultLineHeight ?? 1.5),\r\n      scale: Number(this.options.scale ?? 1),\r\n      pageGap: Number((this.options as unknown as { pageGap?: number }).pageGap ?? 24)\r\n    }\r\n  }\r\n\r\n  /** 重排版+重渲染：格式化元素树 → 排版 → 复用 block id → 标脏 → 同步视觉 → 调度渲染。 */\r\n  private reformatAndRender(): void {\r\n    if (!this.document || !Array.isArray(this.document.elements)) {\r\n      this.document = { ...this.document, elements: this.document?.elements ?? [] }\r\n    }\r\n    const bookmarkMarkers: { name: string; position: string; path: Path }[] = []\r\n    formatElementTree(this.document.elements, { editorOptions: this.options, bookmarkMarkers })\r\n    // Imported markers initialize the runtime index; repainting must not undo edits.\r\n    if (this.document.bookmarks === undefined && bookmarkMarkers.length > 0) {\r\n      this.document.bookmarks = pairBookmarkMarkers(bookmarkMarkers, this.document.elements)\r\n    }\r\n    const headerElements = this.document.header ?? this.document.contentZones?.header\r\n    const footerElements = this.document.footer ?? this.document.contentZones?.footer\r\n    for (const elements of [headerElements, footerElements, ...Object.values(this.document.headerFooterParts ?? {})]) {\r\n      if (elements?.length) formatElementTree(elements, { editorOptions: this.options })\r\n    }\r\n    const layout = this.engine.layout(this.document.elements, headerElements, footerElements, this.document)\r\n\r\n    const { state, dirty } = prepareRenderState(layout, this.renderState)\r\n    this.renderState = state\r\n    this.layout = layout\r\n    const diagnostics = layout.diagnostics ?? []\r\n    const signature = JSON.stringify(diagnostics)\r\n    if (signature !== this.diagnosticSignature) {\r\n      this.diagnosticSignature = signature\r\n      this.diagnosticNotice?.remove()\r\n      this.diagnosticNotice = undefined\r\n      if (diagnostics.length) {\r\n        const notice = document.createElement('div')\r\n        notice.className = 'vervedocs-layout-diagnostics'\r\n        notice.setAttribute('role', 'status')\r\n        notice.style.cssText = 'position:absolute;top:0;left:0;right:0;z-index:100;max-height:120px;overflow:auto;white-space:pre-wrap;padding:8px 12px;background:#fff4ce;color:#663c00;font-size:13px;'\r\n        notice.textContent = diagnostics.map(item => `[${item.zone} / ${item.path.join('.')} / ${item.feature}] ${item.message}`).join('\\n')\r\n        this.container.appendChild(notice)\r\n        this.diagnosticNotice = notice\r\n      }\r\n      this.listener?.emit('layoutDiagnosticsChange', diagnostics)\r\n    }\r\n    this.listener?.emit('pageCountChange', layout.pages.length)\r\n\r\n    // scroller 撑起文档总高（页面居中通过 CSS margin:0 auto）\r\n    this.scroller.style.height = `${layout.totalHeight}px`\r\n    this.scroller.style.width = `${layout.pageWidth}px`\r\n    this.scroller.style.margin = '0 auto'\r\n\r\n    if (dirty.length > 0) this.renderer.markDirty(dirty)\r\n    this.renderer.setLayout(layout, new Set([...state.blocks.values()].map(block => block.id)))\r\n    this.updateVisualLayout()\r\n    // 光标兜底：若 range 尚未定位（首次渲染 / 之前是空文档），把光标置到文档首位，\r\n    // 避免\"看不到光标 / 无法输入\"。findFirstInline 在空文档兜底 run 上也能命中零宽 inline。\r\n    if (this.range && !this.range.getFocus()) {\r\n      const first = this.findFirstInline()\r\n      if (first) {\r\n        this.range.setCaret({ path: first.path, offset: first.startOffset })\r\n        this.caretVisible = true\r\n      }\r\n    }\r\n    this.scheduleRender()\r\n  }\r\n\r\n  /** 计算页面水平居中偏移：(wrapperWidth - pageWidth)/2 - scrollLeft */\r\n  private getPageOffsetX(): number {\r\n    const wrapperWidth = this.wrapper.clientWidth\r\n    const scrollLeft = this.wrapper.scrollLeft\r\n    return Math.max(0, (wrapperWidth - (this.layout?.pageWidth ?? 0)) / 2) - scrollLeft\r\n  }\r\n\r\n\r\n  /** 选项变更后重排版并重渲染：更新引擎选项、失效位图缓存、重排版 */\r\n  private reformatWithInvalidation(): void {\r\n    this.engine.updateOptions(this.toLayoutOptions())\r\n    this.renderer.invalidateAll()\r\n    this.thumbnailCache.clear()\r\n    this.forceFullRender = true\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /** 计算居中偏移并同步给 renderer */\r\n  private updateVisualLayout(): void {\r\n    if (!this.layout) return\r\n    const pageOffsetX = this.getPageOffsetX()\r\n    const bg = (this.options as unknown as { background?: { color?: string } }).background\r\n    this.renderer.updateVisualOptions({\r\n      pageOffsetX,\r\n      pageMargins: (this.options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      pageBg: bg?.color || '#ffffff',\r\n      groupColors: (this.options as unknown as { group?: { groupColors?: Record<string, import('@vervedoc/docx-editor-schema').IGroupColor> } }).group?.groupColors\r\n    })\r\n    this.rulerWidget?.update()\r\n  }\r\n\r\n  /** 容器 resize 处理：更新视口尺寸、同步 renderer、刷新视觉布局并调度重渲染。 */\r\n  private resize = (): void => {\r\n    const rect = this.container.getBoundingClientRect()\r\n    if (rect.width === this.viewportWidth && rect.height === this.viewportHeight) return\r\n    this.forceFullRender = true\r\n    this.viewportWidth = rect.width\r\n    this.viewportHeight = rect.height\r\n    this.renderer.setSize(this.viewportWidth, this.viewportHeight)\r\n    this.updateVisualLayout()\r\n    this.scheduleRender()\r\n\r\n  }\r\n\r\n  /** 滚动处理：更新 scrollY、刷新视觉布局与各 widget、发射当前页码变化事件。 */\r\n  private onScroll = (): void => {\r\n    this.forceFullRender = true\r\n    this.scrollY = this.wrapper.scrollTop\r\n    this.updateVisualLayout()\r\n    // 滚动渲染跳过 afterRender（避免每帧生成缩略图等重操作），widget 更新在 RAF 内完成\r\n    this.scheduleRender(true)\r\n\r\n    // 发射当前页码变化\r\n    if (this.layout && this.listener) {\r\n      const midY = this.scrollY + this.wrapper.clientHeight / 2\r\n      for (const page of this.layout.pages) {\r\n        if (midY >= page.rect.y && midY < page.rect.y + page.rect.height) {\r\n          this.listener.emit('currentPageNoChange', page.index)\r\n          break\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 调度一帧渲染：RAF 内执行 renderer.render + 光标/工具栏重绘 + afterRender 回调。\r\n   * @param skipAfterRender 是否跳过 afterRender 回调（滚动时传 true，避免每帧生成缩略图等重操作）\r\n   */\r\n  private scheduleRender(skipAfterRender = false): void {\r\n    if (this.rafId != null) {\r\n      this._pendingSkipAfterRender = this._pendingSkipAfterRender && skipAfterRender\r\n      return\r\n    }\r\n    this._pendingSkipAfterRender = skipAfterRender\r\n    this.rafId = requestAnimationFrame(() => {\r\n      this.rafId = null\r\n      if (!this.layout) return\r\n      this.syncPageNumberToRenderer()\r\n      this.syncWatermarkToRenderer()\r\n      const dirtyRect = this.forceFullRender || !this.renderState ? null :\r\n        computeDirtyRect(this.paintedState, this.renderState, {\r\n          x: -this.getPageOffsetX(), y: this.scrollY,\r\n          width: this.viewportWidth, height: this.viewportHeight\r\n        })\r\n      this.forceFullRender = false\r\n\r\n      this.renderer.render(this.layout, this.scrollY, this.viewportHeight, dirtyRect)\r\n      this.paintedState = this.renderState\r\n      this.renderCaretIfAny()\r\n      this.selectionToolbarWidget?.update()\r\n      this.tableWidget?.update()\r\n      this.paragraphWidget?.update()\r\n      this.imageWidget?.update()\r\n      this.chartWidget?.update()\r\n      if (!this._pendingSkipAfterRender) {\r\n        this.afterRender?.()\r\n      }\r\n      this._pendingSkipAfterRender = false\r\n    })\r\n  }\r\n\r\n  /** 将 options.pageNumber 配置同步到渲染器 */\r\n  private syncPageNumberToRenderer(): void {\r\n    const pn = (this.options as any).pageNumber ?? null\r\n    this.renderer.updatePageNumber(pn)\r\n  }\r\n\r\n  /** 将 options.watermark 配置同步到水印 widget */\r\n  private syncWatermarkToRenderer(): void {\r\n    const wm = (this.options as any).watermark ?? null\r\n    this.watermarkWidget?.setConfig(wm as WatermarkConfig | null)\r\n  }\r\n\r\n  /** 设置系统级水印（DOM 覆盖层） */\r\n  setSystemWatermark(config: SystemWatermarkConfig | null): void {\r\n    this.systemWatermarkWidget?.setConfig(config)\r\n  }\r\n}\r\n","/**\r\n * 命令分发责任链（Chain of Responsibility）\r\n *\r\n * 将命令分发从 if-else 硬编码改为可插拔的 handler 链。\r\n * 每个 handler 决定是否处理命令，或调 next() 传递给下一个 handler。\r\n * 支持运行时插入中间件（日志/权限/撤销重做等）而不侵入核心逻辑。\r\n */\r\n\r\n/** 传递给下一个 handler 的函数，调 next() 表示\"我不处理，交给下一个\" */\r\nexport type CommandNext = () => any\r\n\r\n/** 命令处理器：(command, args, next) → result | next() */\r\nexport type CommandHandler = (command: string, args: any[], next: CommandNext) => any\r\n\r\n/**\r\n * 命令责任链。\r\n *\r\n * 用法：\r\n * ```ts\r\n * const chain = new CommandChain()\r\n *   .use((cmd, args, next) => {\r\n *     if (cmd === 'foo') return handleFoo(...args)\r\n *     return next() // 不归我管，交给下一个\r\n *   })\r\n *   .use((cmd, args, next) => {\r\n *     // 兜底 handler\r\n *     return defaultHandler(cmd, ...args)\r\n *   })\r\n * chain.dispatch('foo', 1, 2) // → handleFoo(1, 2)\r\n * ```\r\n */\r\nexport class CommandChain {\r\n  /** 有序 handler 列表 */\r\n  private readonly handlers: CommandHandler[] = []\r\n\r\n  /** 注册 handler，返回 this 支持链式调用 */\r\n  use(handler: CommandHandler): this {\r\n    this.handlers.push(handler)\r\n    return this\r\n  }\r\n\r\n  /**\r\n   * 沿链分发命令。\r\n   * 从第一个 handler 开始，依次调用；handler 返回 next() 时传递给下一个。\r\n   * 所有 handler 都不处理时返回 undefined。\r\n   */\r\n  dispatch(command: string, ...args: any[]): any {\r\n    let index = 0\r\n    const next: CommandNext = () => {\r\n      if (index >= this.handlers.length) return undefined\r\n      const handler = this.handlers[index++]\r\n      return handler(command, args, next)\r\n    }\r\n    return next()\r\n  }\r\n}","/**\r\n * VerveDocs Transform —— CommandAdapt\r\n *\r\n * 基于路径的树编辑命令。所有命令直接操作 IDocxDocumentMeta.elements 树。\r\n * 通过 draw.setDocument 通知视图重排（避免直接依赖 view）。\r\n */\r\n\r\nimport type {\r\n  IDocxDocumentMeta, IElement, IImageElement, Path, ITextElement,\r\n  ITitleElement, ITableElement, IListElement, ListTypeName, IPosition, IRange, ITd, VerticalAlign,\r\n  IAutoTocItem, IAutoTocResult, DocumentLayout, IBookmark, IEditorOption, BlockNode,\r\n  HistorySnapshot, IHistoryManager, TableBorderPreset, RevisionMeta\r\n} from '@vervedoc/docx-editor-schema'\r\nimport {\r\n  getByPath, getParentContainer, cloneTree, walkTree, isSamePath, splitParagraphs, comparePath, formatElementTree,\r\n  DEFAULT_EDITOR_OPTION, applyImageLayout, updateImageLayout, TableBorder, BULLET_STYLES, NUMBER_STYLES, toDocxExportDocument,\r\n  clearRevision, snapshotRevisionFormat, recordFormatRevision\r\n} from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager, IRangeStyle, IEditorAbility, Listener } from '@vervedoc/docx-editor-state'\r\n\r\n/** Heading sizes in layout pixels, matching the units used by text runs. */\r\nconst HEADING_SIZES: Record<ITitleElement['level'], number> = {\r\n  first: 26,\r\n  second: 24,\r\n  third: 22,\r\n  fourth: 20,\r\n  fifth: 18,\r\n  sixth: 16\r\n}\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 transform 包 API 兼容\r\nexport type { HistorySnapshot, IHistoryManager } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 文档编辑区域类型：主体、页眉、页脚 */\r\nexport type Zone = 'main' | 'header' | 'footer'\r\n\r\nexport type HyperlinkInsertionError =\r\n  | 'readOnly' | 'disabled' | 'tracking' | 'revisions' | 'bookmarkSelection'\r\n  | 'fieldSelection' | 'existingLink' | 'crossContainer' | 'crossParagraph'\r\n  | 'noSelection' | 'invalidSelection' | 'nonText' | 'invalidText' | 'addressInvalid'\r\n\r\n/**\r\n * DrawLike 接口：描述 CommandAdapt 所依赖的视图/绘制层抽象。\r\n * 通过该接口隔离命令适配器与具体视图实现，便于测试与解耦。\r\n */\r\nexport interface DrawLike {\r\n  /** 获取当前文档元数据 */\r\n  getDocument(): IDocxDocumentMeta\r\n  /** 设置文档元数据并触发重排 */\r\n  setDocument(doc: IDocxDocumentMeta): void\r\n  /** 获取当前活动文档（根据 zone 切换的文档） */\r\n  getActiveDocument(): IDocxDocumentMeta\r\n  /** 应用活动文档变更 */\r\n  applyActiveDocument(doc: IDocxDocumentMeta): void\r\n  /** 获取文档布局信息，未布局时返回 null */\r\n  getLayout(): DocumentLayout | null\r\n  /** 获取滚动容器元素 */\r\n  getScroller(): HTMLDivElement\r\n  /** 设置页面缩放比例 */\r\n  setScale(scale: number): void\r\n  /** 设置页面尺寸（宽高） */\r\n  setPageSize(width: number, height: number): void\r\n  /** 设置标尺可见性 */\r\n  setRulerVisible(visible: boolean): void\r\n  /** 设置页边距（上、右、下、左） */\r\n  setPaperMargins(margins: [number, number, number, number]): void\r\n  /** 获取编辑器选项 */\r\n  getOptions(): { pageWidth?: number; pageHeight?: number; scale?: number; [key: string]: unknown }\r\n  /** 以补丁方式更新编辑器选项 */\r\n  updateOptions(patch: Partial<IEditorOption>): void\r\n  /** 获取当前编辑区域 */\r\n  getZone(): Zone\r\n  /** 设置当前编辑区域 */\r\n  setZone(zone: Zone): void\r\n  /** 切换编辑区域并设置初始光标到对应区域起始位置 */\r\n  setZoneWithCaret(zone: Zone): void\r\n  /** 打印文档 */\r\n  print(): void\r\n  /** 获取所有页面缩略图（data URL 数组） */\r\n  getPageThumbnails(): string[]\r\n  /** 滚动到指定文档位置使其可见 */\r\n  scrollPositionIntoView?(pos: IPosition): void\r\n  /** 设置系统级水印（DOM 覆盖层），null 表示移除 */\r\n  setSystemWatermark?(config: { data: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | null): void\r\n}\r\n\r\n/**\r\n * CommandAdapt 类：基于路径的树编辑命令适配器。\r\n * 所有命令直接操作 IDocxDocumentMeta.elements 树，通过 draw.setDocument 通知视图重排，\r\n * 避免直接依赖 view。是 Command 门面背后真正执行编辑逻辑的核心实现。\r\n */\r\nexport class CommandAdapt {\r\n  /** 格式刷暂存的文本格式片段，null 表示未启用格式刷 */\r\n  private _paintFmt: Partial<Pick<ITextElement, 'bold' | 'italic' | 'underline' | 'strikeout' | 'color' | 'highlight' | 'font' | 'size'>> | null = null\r\n  /** 当前搜索命中结果列表，每项记录命中的路径与起止偏移 */\r\n  private _searchHits: { path: Path; start: number; end: number }[] = []\r\n  /** 当前搜索命中索引（高亮位置） */\r\n  private _searchIdx = 0\r\n  private _searchDocument: IDocxDocumentMeta | null = null\r\n  private _searchZone: Zone = 'main'\r\n  private _searchContent = ''\r\n  private _revisionSequence = 0\r\n  private _hyperlinkInsertionError: HyperlinkInsertionError | null = null\r\n\r\n  /** 生成指定类型的修订元数据，包含递增数字 ID、当前作者和时间。 */\r\n  private newRevision(type: 'insert' | 'delete' | 'format'): RevisionMeta {\r\n    // Numeric IDs are also accepted by Word's w:id attribute.\r\n    this._revisionSequence = Math.max(Date.now(), this._revisionSequence + 1)\r\n    return {\r\n      revisionId: String(this._revisionSequence),\r\n      revisionType: type,\r\n      revisionAuthor: String(this.draw.getOptions().revisionAuthor || '当前用户'),\r\n      revisionDate: new Date().toISOString()\r\n    }\r\n  }\r\n\r\n  /** 跳过删除修订元素并应用格式变更，开启修订时记录变更前的格式。 */\r\n  private formatElements(elements: IElement[], mutate: (element: IElement) => void): void {\r\n    const tracking = !!this.draw.getOptions().trackChanges\r\n    const meta = tracking ? this.newRevision('format') : null\r\n    for (const element of elements) {\r\n      if ((element as ITextElement).revisionType === 'delete') continue\r\n      const before = meta ? snapshotRevisionFormat(element) : null\r\n      mutate(element)\r\n      if (meta && before) recordFormatRevision(element, before, meta)\r\n    }\r\n  }\r\n\r\n  /** 统一目标文本附近同作者连续删除修订的 ID 和时间，保留各 run 的恢复数据。 */\r\n  private mergeAdjacentDeletions(doc: IDocxDocumentMeta, runs: ITextElement[], meta: RevisionMeta): void {\r\n    const targets = new Set<IElement>(runs)\r\n    const parents = new Set<IElement[]>()\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (targets.has(node) && Array.isArray(ctx.parent)) parents.add(ctx.parent)\r\n    })\r\n    for (const parent of parents) {\r\n      let index = 0\r\n      while (index < parent.length) {\r\n        const group: ITextElement[] = []\r\n        while (index < parent.length) {\r\n          const node = parent[index]\r\n          if (node.type !== 'text' || node.revisionType !== 'delete' ||\r\n            node.revisionAuthor !== meta.revisionAuthor || node.extension?.bookmarkMarker ||\r\n            /^[\\u200B\\uFEFF]+$/.test(node.value)) break\r\n          group.push(node as ITextElement)\r\n          index++\r\n        }\r\n        if (group.length > 1 && group.some(node => targets.has(node))) {\r\n          // Reuse the existing ID in either direction; keep each run's restore data intact.\r\n          const existing = group.find(node => node.revisionId !== meta.revisionId) ?? group[0]\r\n          for (const node of group) {\r\n            node.revisionId = existing.revisionId\r\n            node.revisionDate = existing.revisionDate\r\n          }\r\n        }\r\n        index++\r\n      }\r\n    }\r\n  }\r\n\r\n  /** 将范围内文本标记为删除修订（本人新增文本直接清空），收拢光标并按 commit 决定是否提交；无目标 run 时返回 false。 */\r\n  private deleteTrackedRange(doc: IDocxDocumentMeta, start: IPosition, end: IPosition, commit: boolean): boolean {\r\n    const adjusted = this.splitBoundaryRuns(doc, start, end)\r\n    const runs = this.collectRunsInRange(doc.elements, adjusted.start, adjusted.end)\r\n    if (!runs.length) return false\r\n    const meta = this.newRevision('delete')\r\n    for (const run of runs) {\r\n      if (run.revisionType === 'delete') continue\r\n      if (run.revisionType === 'insert' && run.revisionAuthor === meta.revisionAuthor) {\r\n        run.value = ''\r\n        clearRevision(run)\r\n      } else {\r\n        const previous = run.revisionId ? {\r\n          revisionId: run.revisionId, revisionType: run.revisionType,\r\n          revisionAuthor: run.revisionAuthor, revisionDate: run.revisionDate,\r\n          revisionOldRPr: run.revisionOldRPr,\r\n          oldProps: run.extension?.revisionOldProps\r\n        } : null\r\n        clearRevision(run)\r\n        Object.assign(run, meta)\r\n        if (previous) run.extension = { ...run.extension, revisionPrevious: previous }\r\n      }\r\n    }\r\n    this.mergeAdjacentDeletions(doc, runs, meta)\r\n    this.range.setCaret(adjusted.start)\r\n    if (commit) this._commit(doc, 'text')\r\n    return true\r\n  }\r\n\r\n  /** 按修订方式删除光标相邻的一个 Unicode 字符；backward 为 true 时向前查找，跳过已删除文本和书签标记。 */\r\n  private deleteTrackedCharacter(backward: boolean): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return\r\n    const current = Number(pos.path[pos.path.length - 1])\r\n    for (let index = current; index >= 0 && index < parent.length; index += backward ? -1 : 1) {\r\n      const run = parent[index]\r\n      if (run.type !== 'text') return\r\n      if (run.revisionType === 'delete' || !run.value.length || run.extension?.bookmarkMarker) continue\r\n      const offset = index === current ? pos.offset : backward ? run.value.length : 0\r\n      if ((backward && offset <= 0) || (!backward && offset >= run.value.length)) continue\r\n      const text = backward ? Array.from(run.value.slice(0, offset)).at(-1)! : Array.from(run.value.slice(offset))[0]\r\n      const path: Path = [...pos.path.slice(0, -1), index]\r\n      this.deleteTrackedRange(doc,\r\n        { path, offset: backward ? offset - text.length : offset },\r\n        { path, offset: backward ? offset : offset + text.length }, true)\r\n      return\r\n    }\r\n  }\r\n\r\n  /** 文档、编辑区域或内容与搜索快照不一致时，清空失效的搜索结果。 */\r\n  private validateSearch(): void {\r\n    if (this._searchDocument !== this.draw.getDocument() ||\r\n      this._searchZone !== this.draw.getZone() ||\r\n      this._searchContent !== JSON.stringify(this.draw.getActiveDocument().elements)) {\r\n      this._searchHits = []\r\n      this._searchIdx = 0\r\n    }\r\n  }\r\n\r\n  /** 保存当前文档引用、编辑区域和内容快照，供搜索结果有效性校验使用。 */\r\n  private captureSearch(): void {\r\n    this._searchDocument = this.draw.getDocument()\r\n    this._searchZone = this.draw.getZone()\r\n    this._searchContent = JSON.stringify(this.draw.getActiveDocument().elements)\r\n  }\r\n  /** 历史管理器实例，未设置时为 null */\r\n  private _historyManager: IHistoryManager | null = null\r\n\r\n\r\n  /**\r\n   * 创建 CommandAdapt 实例。\r\n   * @param draw 绘制层抽象，用于读写文档与触发视图更新\r\n   * @param range 选区管理器，用于维护光标与选区\r\n   * @param listener 事件监听器，可选，用于对外发射状态变更事件\r\n   */\r\n  constructor(\r\n    private draw: DrawLike,\r\n    private range: RangeManager,\r\n    private listener?: Listener\r\n  ) {}\r\n\r\n  /**\r\n   * 设置历史管理器。\r\n   * @param hm 历史管理器实例\r\n   */\r\n  setHistoryManager(hm: IHistoryManager): void {\r\n    this._historyManager = hm\r\n  }\r\n\r\n\r\n  /** 计算当前页面内容区宽度（pageWidth - 左右边距） */\r\n  private getContentWidth(): number {\r\n    const opts = this.draw.getOptions()\r\n    const pageWidth = Number(opts.pageWidth ?? 794)\r\n    const margins = (opts.pageMargins as [number, number, number, number] | undefined) ?? [96, 120, 96, 120]\r\n    return Math.max(100, pageWidth - margins[0] - margins[2])\r\n  }\r\n\r\n  /** 初始化历史首快照（编辑器就绪后调用一次） */\r\n  pushInitialHistory(): void {\r\n    if (!this._historyManager) return\r\n    this._historyManager.pushInitial({\r\n      doc: cloneTree(this.draw.getDocument()),\r\n      range: this.range.getRange(),\r\n      zone: this.draw.getZone()\r\n    })\r\n  }\r\n\r\n  /** 克隆并规范化文档各内容区，切回正文并清空选区，按 resetHistory 初始化或追加历史后通知状态变更。 */\r\n  replaceDocument(document: IDocxDocumentMeta, resetHistory = false): void {\r\n    const doc = cloneTree(document)\r\n    const options = { editorOptions: this.draw.getOptions() as IEditorOption, styles: doc.styles, numbering: doc.numbering }\r\n    formatElementTree(doc.elements, options)\r\n    for (const elements of [doc.header, doc.footer, ...Object.values(doc.contentZones ?? {}), ...Object.values(doc.headerFooterParts ?? {})]) {\r\n      if (Array.isArray(elements)) formatElementTree(elements, options)\r\n    }\r\n    this.draw.setZone('main')\r\n    this.range.clear()\r\n    this.draw.setDocument(doc)\r\n    if (resetHistory) this.pushInitialHistory()\r\n    else this._historyManager?.push({ doc: cloneTree(doc), range: null, zone: this.draw.getZone() })\r\n    this.listener?.emit('documentSet', doc)\r\n    this.listener?.emit('contentChange')\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /** 在可编辑时对文档副本执行插件事务，清空选区并提交历史与状态通知；回调返回 false 时取消提交。 */\r\n  commitPluginTransaction(action: (doc: IDocxDocumentMeta) => boolean | void): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = cloneTree(this.draw.getDocument())\r\n    if (action(doc) === false) return\r\n    this.range.clear()\r\n    this.draw.setDocument(doc)\r\n    this._historyManager?.push({ doc: cloneTree(doc), range: null, zone: this.draw.getZone() })\r\n    this.listener?.emit('contentChange')\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /** 提交变更并推送历史快照，同时通知调用方状态变更 */\r\n  private _commit(doc: IDocxDocumentMeta, coalesceKey?: string): void {\r\n    this.draw.applyActiveDocument(doc)\r\n    if (this._historyManager) {\r\n      this._historyManager.push(\r\n        { doc: cloneTree(this.draw.getDocument()), range: this.range.getRange(), zone: this.draw.getZone() },\r\n        coalesceKey\r\n      )\r\n    }\r\n    // 通知调用方：内容变更 + 选区样式变更 + 能力变更（含撤销/重做状态）\r\n    this.listener?.emit('contentChange')\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /**\r\n   * 模板方法：获取活动文档 → 执行修改动作 → 提交（重渲染 + 历史 + 事件）。\r\n   *\r\n   * 命令方法只需提供修改逻辑（action），无需手动调 `_commit`。\r\n   * action 返回 `false` 时跳过提交（用于校验失败提前退出）。\r\n   *\r\n   * @param action 修改动作，接收 doc 引用直接 mutate，返回 false 跳过提交\r\n   * @param coalesceKey 历史合并键（如 'text' 用于连续输入合并为一条撤销记录）\r\n   *\r\n   * @example\r\n   * ```ts\r\n   * setBold(): void {\r\n   *   this.execute(doc => {\r\n   *     const pos = this.range.getFocus()\r\n   *     if (!pos) return false\r\n   *     // ... mutate doc\r\n   *   })\r\n   * }\r\n   * ```\r\n   */\r\n  protected execute(\r\n    action: (doc: IDocxDocumentMeta) => boolean | void,\r\n    coalesceKey?: string\r\n  ): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getActiveDocument()\r\n    if (action(doc) !== false) {\r\n      this._commit(doc, coalesceKey)\r\n    }\r\n  }\r\n\r\n  /* -------------------- 文本编辑 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标位置插入文本。若存在选区则先删除选区再插入。\r\n   * @param text 待插入的文本内容\r\n   */\r\n  insertText(text: string): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!text) return\r\n    if (this.deleteSelection(false)) {\r\n      // 选区已删除，光标在原选区 start，继续插入 text\r\n    }\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node) return\r\n    if (node.type === 'text') {\r\n      const t = node as ITextElement\r\n      const before = t.value.slice(0, pos.offset)\r\n      const after = t.value.slice(pos.offset)\r\n      const tracking = !!this.draw.getOptions().trackChanges\r\n      const author = String(this.draw.getOptions().revisionAuthor || '当前用户')\r\n      if ((tracking && !(t.revisionType === 'insert' && t.revisionAuthor === author)) ||\r\n        (!tracking && t.revisionId)) {\r\n        const parent = getParentContainer(doc.elements, pos.path)\r\n        if (!parent) return\r\n        const index = Number(pos.path[pos.path.length - 1])\r\n        const inserted = cloneTree(t)\r\n        clearRevision(inserted)\r\n        inserted.value = text\r\n        if (tracking) Object.assign(inserted, this.newRevision('insert'))\r\n        const parts: ITextElement[] = []\r\n        if (before) parts.push({ ...cloneTree(t), value: before })\r\n        const insertIndex = index + parts.length\r\n        parts.push(inserted)\r\n        if (after) parts.push({ ...cloneTree(t), value: after })\r\n        parent.splice(index, 1, ...parts)\r\n        this.range.setCaret({ path: [...pos.path.slice(0, -1), insertIndex], offset: text.length })\r\n        this._commit(doc, 'text')\r\n        return\r\n      }\r\n      t.value = before + text + after\r\n      this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset + text.length })\r\n      // 不可迁移：前置 deleteSelection() 可能已 commit\r\n      this._commit(doc, 'text')\r\n    }\r\n  }\r\n\r\n  /** 删除当前选区内容（若已 collapsed 则不操作）。光标收缩到选区 start。返回是否实际删除。 */\r\n  deleteSelection(commit = true): boolean {\r\n    if (!this.getIsCanInput()) return false\r\n    if (this.range.isCollapsed()) return false\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) return false\r\n    const { start, end } = ordered\r\n    const doc = this.draw.getActiveDocument()\r\n    if (this.draw.getOptions().trackChanges) {\r\n      return this.deleteTrackedRange(doc, start, end, commit)\r\n    }\r\n\r\n    const runs: { path: Path; parent: IElement[]; idx: number }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text' && Array.isArray(ctx.parent)) {\r\n        runs.push({ path: ctx.path.slice() as Path, parent: ctx.parent as IElement[], idx: ctx.index })\r\n      }\r\n    })\r\n\r\n    let startRunIdx = -1, endRunIdx = -1\r\n    for (let i = 0; i < runs.length; i++) {\r\n      if (isSamePath(runs[i].path, start.path)) startRunIdx = i\r\n      if (isSamePath(runs[i].path, end.path)) endRunIdx = i\r\n    }\r\n    if (startRunIdx === -1 || endRunIdx === -1 || startRunIdx > endRunIdx) return false\r\n\r\n    if (startRunIdx === endRunIdx) {\r\n      const node = getByPath(doc.elements, start.path)\r\n      if (node && node.type === 'text') {\r\n        const t = node as ITextElement\r\n        t.value = t.value.slice(0, start.offset) + t.value.slice(end.offset)\r\n        this.range.setCaret({ path: start.path.slice() as Path, offset: start.offset })\r\n        if (commit) this._commit(doc, 'text')\r\n        return true\r\n      }\r\n      return false\r\n    }\r\n\r\n    const startRun = runs[startRunIdx]\r\n    const endRun = runs[endRunIdx]\r\n    const startNode = startRun.parent[startRun.idx] as ITextElement\r\n    const endNode = endRun.parent[endRun.idx] as ITextElement\r\n    if (startNode.type !== 'text' || endNode.type !== 'text') return false\r\n\r\n    const before = startNode.value.slice(0, start.offset)\r\n    const after = endNode.value.slice(end.offset)\r\n    startNode.value = before + after\r\n\r\n    if (start.path.length === 1 && end.path.length === 1) {\r\n      const first = Number(start.path[0]), last = Number(end.path[0])\r\n      this.removeSectionBoundaries(doc, first + 1, last)\r\n      doc.elements.splice(first + 1, last - first)\r\n      this.range.setCaret({ path: [first], offset: start.offset })\r\n      if (commit) this._commit(doc, 'text')\r\n      return true\r\n    }\r\n\r\n    const toDelete = runs.slice(startRunIdx + 1, endRunIdx + 1)\r\n    const groups = new Map<IElement[], number[]>()\r\n    for (const r of toDelete) {\r\n      let arr = groups.get(r.parent)\r\n      if (!arr) { arr = []; groups.set(r.parent, arr) }\r\n      arr.push(r.idx)\r\n    }\r\n    for (const [parent, idxs] of groups) {\r\n      idxs.sort((a, b) => b - a)\r\n      for (const idx of idxs) parent.splice(idx, 1)\r\n    }\r\n\r\n    this.range.setCaret({ path: start.path.slice() as Path, offset: start.offset })\r\n    if (commit) this._commit(doc, 'text')\r\n    return true\r\n  }\r\n\r\n  /** 获取文档全文纯文本（所有 text run 的 value 拼接）。 */\r\n  getFullText(): string {\r\n    const doc = this.draw.getDocument()\r\n    return (doc.elements || []).map(el => (el as any).value || '').join('')\r\n  }\r\n\r\n  /** 跳转到指定页码（通过设置滚动位置）。 */\r\n  jumpToPage(pageNo: number): void {\r\n    const opts = this.draw.getOptions()\r\n    const pageHeight = Number(opts.pageHeight ?? 1123)\r\n    const pageGap = Number(opts.pageGap ?? 24) * Number(opts.scale ?? 1)\r\n    const scroller = this.draw.getScroller()\r\n    const wrapper = scroller?.parentElement as HTMLElement | null\r\n    if (wrapper) {\r\n      wrapper.scrollTop = pageNo * (pageHeight + pageGap)\r\n    }\r\n  }\r\n\r\n  /** 定位到指定修订 ID 的首个元素位置，返回是否找到。 */\r\n  locateRevision(id: string): boolean {\r\n    if (!id) return false\r\n    const doc = this.draw.getDocument()\r\n    let position: IPosition | null = null\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (!position && (node as ITextElement).revisionId === id) position = { path: ctx.path, offset: 0 }\r\n    })\r\n    if (!position) return false\r\n    this.range.setCaret(position)\r\n    this.draw.scrollPositionIntoView?.(position)\r\n    return true\r\n  }\r\n\r\n  /** 提取当前选区纯文本（用于复制/剪切）。 */\r\n  extractSelectionText(): string {\r\n    if (this.range.isCollapsed()) return ''\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) return ''\r\n    const { start, end } = ordered\r\n    const doc = this.draw.getActiveDocument()\r\n\r\n    const runs: { path: Path; text: string }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        runs.push({\r\n          path: ctx.path.slice() as Path,\r\n          text: node.extension?.bookmarkMarker ? '' : (node as ITextElement).value\r\n        })\r\n      }\r\n    })\r\n\r\n    let startRunIdx = -1, endRunIdx = -1\r\n    for (let i = 0; i < runs.length; i++) {\r\n      if (isSamePath(runs[i].path, start.path)) startRunIdx = i\r\n      if (isSamePath(runs[i].path, end.path)) endRunIdx = i\r\n    }\r\n    if (startRunIdx === -1 || endRunIdx === -1 || startRunIdx > endRunIdx) return ''\r\n\r\n    if (startRunIdx === endRunIdx) {\r\n      return runs[startRunIdx].text.slice(start.offset, end.offset)\r\n    }\r\n\r\n    let result = runs[startRunIdx].text.slice(start.offset)\r\n    for (let i = startRunIdx + 1; i < endRunIdx; i++) {\r\n      const t = runs[i].text\r\n      result += t === '\\u200B' ? '\\n' : t\r\n    }\r\n    result += runs[endRunIdx].text.slice(0, end.offset)\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 向后删除一个字符（Backspace 行为）。若有选区则删除选区；否则删除光标前一个字符，\r\n   * 列表起点先取消编号，其他 run 起点尝试与前一个 text run 合并。\r\n   */\r\n  deleteBackward(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this.deleteSelection()) return\r\n    if (this.draw.getOptions().trackChanges) {\r\n      this.deleteTrackedCharacter(true)\r\n      return\r\n    }\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node) return\r\n    if (pos.offset === 0) {\r\n      const listPath = this.getListPath(doc.elements, pos.path)\r\n      if (listPath) {\r\n        const list = getByPath(doc.elements, listPath) as IListElement\r\n        const childIndex = Number(pos.path[listPath.length + 1])\r\n        const atStart = isSamePath(pos.path, listPath) || (\r\n          pos.path.length === listPath.length + 2 &&\r\n          pos.path[listPath.length] === 'valueList' &&\r\n          list.valueList.slice(0, childIndex).every(child =>\r\n            child.extension?.bookmarkMarker || (child.type === 'text' && child.value === '')\r\n          )\r\n        )\r\n        if (atStart) {\r\n          this.setList(null, null)\r\n          return\r\n        }\r\n      }\r\n    }\r\n    if (node.type === 'text') {\r\n      const t = node as ITextElement\r\n      if (pos.offset > 0) {\r\n        t.value = t.value.slice(0, pos.offset - 1) + t.value.slice(pos.offset)\r\n        this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset - 1 })\r\n        // 不可迁移：多个 _commit 在不同分支\r\n        this._commit(doc, 'text')\r\n      } else {\r\n        // 与前一个 text run 合并\r\n        const parent = getParentContainer(doc.elements, pos.path)\r\n        const idx = pos.path[pos.path.length - 1] as number\r\n        if (parent && idx > 0) {\r\n          const prev = parent[idx - 1]\r\n          if (parent === doc.elements && prev && this.isSectionBoundary(prev)) {\r\n            this.removeSectionBoundaries(doc, idx - 1, idx - 1)\r\n            parent.splice(idx - 1, 1)\r\n            this.range.setCaret({ path: [idx - 1], offset: 0 })\r\n            this._commit(doc)\r\n            return\r\n          }\r\n          if (prev && prev.type === 'text') {\r\n            const p = prev as ITextElement\r\n            const newOffset = p.value.length > 0 ? p.value.length - 1 : 0\r\n            if (p.value.length > 0) p.value = p.value.slice(0, -1)\r\n            // 合并 current 到 prev\r\n            p.value += t.value\r\n            parent.splice(idx, 1)\r\n            const newPath = pos.path.slice() as Path\r\n            newPath[newPath.length - 1] = idx - 1\r\n            this.range.setCaret({ path: newPath, offset: newOffset })\r\n            // 不可迁移：多个 _commit 在不同分支\r\n            this._commit(doc, 'text')\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 向前删除一个字符（Delete 行为）。若有选区则删除选区；否则删除光标后一个字符。\r\n   */\r\n  deleteForward(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this.deleteSelection()) return\r\n    if (this.draw.getOptions().trackChanges) {\r\n      this.deleteTrackedCharacter(false)\r\n      return\r\n    }\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const node = getByPath(doc.elements, pos.path)\r\n      if (!node || node.type !== 'text') return false\r\n      const t = node as ITextElement\r\n      if (pos.offset >= t.value.length) {\r\n        const next = Number(pos.path[0]) + 1\r\n        if (pos.path.length !== 1 || !doc.elements[next] || !this.isSectionBoundary(doc.elements[next])) return false\r\n        this.removeSectionBoundaries(doc, next, next)\r\n        doc.elements.splice(next, 1)\r\n        return\r\n      }\r\n      t.value = t.value.slice(0, pos.offset) + t.value.slice(pos.offset + 1)\r\n      return\r\n    }, 'text')\r\n  }\r\n\r\n  /** Enter 换段：在当前 text run 内切成两半，第二半为新 run；对普通段落即插入零宽段分隔 */\r\n  splitParagraph(): void {\r\n    if (this.deleteSelection()) return\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const node = getByPath(doc.elements, pos.path)\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!node || !parent) return false\r\n      if (node.type !== 'text') return false\r\n      const t = node as ITextElement\r\n      const idx = pos.path[pos.path.length - 1] as number\r\n\r\n      const before = t.value.slice(0, pos.offset)\r\n      const after = t.value.slice(pos.offset)\r\n      t.value = before\r\n      // 插入段落分隔标记 + 后半 text\r\n      const sep: ITextElement = { type: 'text', value: '\\u200B' } as ITextElement\r\n      // Splitting must preserve pending revisions and their independent format snapshots.\r\n      const rest: ITextElement = { ...cloneTree(t), value: after }\r\n      parent.splice(idx + 1, 0, sep, rest)\r\n      const newPath = pos.path.slice() as Path\r\n      newPath[newPath.length - 1] = idx + 2\r\n      this.range.setCaret({ path: newPath, offset: 0 })\r\n      return\r\n    }, 'text')\r\n  }\r\n\r\n  /* -------------------- 光标移动 -------------------- */\r\n\r\n  /**\r\n   * 将光标向左移动一位。若已处于 run 起点，则跨 run 向前移动到上一个 text run 末尾。\r\n   */\r\n  moveCaretLeft(): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    if (pos.offset > 0) {\r\n      this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset - 1 })\r\n      return\r\n    }\r\n    // 跨 run 向前\r\n    const doc = this.draw.getActiveDocument()\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    const idx = pos.path[pos.path.length - 1] as number\r\n    if (parent && idx > 0) {\r\n      for (let i = idx - 1; i >= 0; i--) {\r\n        const p = parent[i]\r\n        if (p && p.type === 'text') {\r\n          const newPath = pos.path.slice() as Path\r\n          newPath[newPath.length - 1] = i\r\n          const t = p as ITextElement\r\n          this.range.setCaret({ path: newPath, offset: t.value.length })\r\n          return\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将光标向右移动一位。若已处于 run 末尾，则跨 run 向后移动到下一个 text run 起点。\r\n   */\r\n  moveCaretRight(): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (node && node.type === 'text') {\r\n      const t = node as ITextElement\r\n      if (pos.offset < t.value.length) {\r\n        this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset + 1 })\r\n        return\r\n      }\r\n    }\r\n    // 跨 run 向后\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    const idx = pos.path[pos.path.length - 1] as number\r\n    if (parent && idx < parent.length - 1) {\r\n      for (let i = idx + 1; i < parent.length; i++) {\r\n        const p = parent[i]\r\n        if (p && p.type === 'text') {\r\n          const newPath = pos.path.slice() as Path\r\n          newPath[newPath.length - 1] = i\r\n          this.range.setCaret({ path: newPath, offset: 0 })\r\n          return\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /* -------------------- 段落属性 -------------------- */\r\n\r\n  /**\r\n   * 设置当前段落的行弹性对齐方式。\r\n   * @param flex 对齐方式：'left' | 'center' | 'right' | 'justify' | 'alignment' | 'distribute'\r\n   */\r\n  setRowFlex(flex: 'left' | 'center' | 'right' | 'justify' | 'alignment' | 'distribute'): void {\r\n    this.execute(doc => {\r\n      const ordered = this.range.getOrdered()\r\n      const pos = ordered?.start ?? this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        this.formatElements(g.block ? [g.block, ...g.runs] : g.runs, r => { r.rowFlex = flex })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 设置当前段落的行高及行高规则。\r\n   * @param lh 行高数值\r\n   * @param rule 行高规则，默认 'auto'\r\n   */\r\n  setLineHeight(lh: number, rule: 'auto' | 'exact' | 'atLeast' = 'auto'): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          const any = r as unknown as Record<string, unknown>\r\n          any.lineHeight = lh\r\n          any.lineHeightRule = rule\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 段间距（前后各 margin）。\r\n   * @param margin 段前段后间距数值\r\n   */\r\n  setRowMargin(margin: number): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          const any = r as unknown as Record<string, unknown>\r\n          any.paragraphSpacingBefore = margin\r\n          any.paragraphSpacingAfter = margin\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /* -------------------- run 样式 -------------------- */\r\n\r\n  /**\r\n   * 设置选区内 run 的加粗样式。\r\n   * @param bold 是否加粗，省略时为切换语义\r\n   */\r\n  setBold(bold?: boolean): void {\r\n    this.mutateRuns(run => { run.bold = bold }, 'bold')\r\n  }\r\n  /**\r\n   * 设置选区内 run 的斜体样式。\r\n   * @param italic 是否斜体，省略时为切换语义\r\n   */\r\n  setItalic(italic?: boolean): void {\r\n    this.mutateRuns(run => { run.italic = italic }, 'italic')\r\n  }\r\n  /**\r\n   * 设置选区内 run 的文字颜色。\r\n   * @param color 颜色值字符串\r\n   */\r\n  setColor(color: string): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).color = color })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的字体。\r\n   * @param font 字体名称\r\n   */\r\n  setFont(font: string): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).font = font })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的字号。\r\n   * @param size 字号数值\r\n   */\r\n  setSize(size: number): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).size = size })\r\n  }\r\n  /** 增大选区内 run 的字号（步进 2，上限 72）。 */\r\n  setSizeAdd(): void {\r\n    this.mutateRuns(run => { run.size = Math.min(72, (run.size ?? 14) + 2) })\r\n  }\r\n  /** 减小选区内 run 的字号（步进 2，下限 8）。 */\r\n  setSizeMinus(): void {\r\n    this.mutateRuns(run => { run.size = Math.max(8, (run.size ?? 14) - 2) })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的高亮颜色。\r\n   * @param color 高亮颜色值\r\n   */\r\n  setHighlight(color: string): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).highlight = color })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的删除线。\r\n   * @param v 是否显示删除线，省略时为切换语义\r\n   */\r\n  setStrikeout(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).strikeout = v }, 'strikeout')\r\n  }\r\n  /** 设置选区内 run 的双删除线 */\r\n  setDoubleStrikeout(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).doubleStrikeout = v })\r\n  }\r\n  /** 设置选区内 run 的隐藏属性 */\r\n  setHidden(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).hidden = v })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的下划线。\r\n   * @param v 是否显示下划线，省略时为切换语义\r\n   */\r\n  setUnderline(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).underline = v }, 'underline')\r\n  }\r\n\r\n  /** 清除当前选区所有 run 的字符格式 */\r\n  clearFormat(): void {\r\n    this.mutateRuns(run => {\r\n      run.bold = undefined\r\n      run.italic = undefined\r\n      run.underline = undefined\r\n      run.strikeout = undefined\r\n      run.color = undefined\r\n      run.highlight = undefined\r\n      run.font = undefined\r\n      run.size = undefined\r\n    })\r\n  }\r\n\r\n  /** 格式刷：首次调用复制当前 run 格式，二次调用应用到当前 run */\r\n  paintFormat(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this._paintFmt) {\r\n      this.mutateRun(run => {\r\n        Object.assign(run, this._paintFmt)\r\n      })\r\n      this._paintFmt = null\r\n    } else {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return\r\n      const doc = this.draw.getActiveDocument()\r\n      const node = getByPath(doc.elements, pos.path)\r\n      if (!node || node.type !== 'text') return\r\n      const t = node as ITextElement\r\n      this._paintFmt = {\r\n        bold: t.bold, italic: t.italic, underline: t.underline,\r\n        strikeout: t.strikeout, color: t.color, highlight: t.highlight,\r\n        font: t.font, size: t.size\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 对当前光标所在的 text run 执行变更并提交。\r\n   * @param fn 对目标 run 的变更函数\r\n   */\r\n  private mutateRun(fn: (run: ITextElement) => void): void {\r\n    this.mutateRuns(fn)\r\n  }\r\n\r\n  /**\r\n   * 选区感知的 run 变更：折叠时改当前 run，展开时改选区内所有 run。\r\n   * toggleKey 传入时：若 value 为 undefined 则按\"选区内任一 run 未设置 → 全设 true，全已设 → 全取消\"toggle。\r\n   */\r\n  private mutateRuns(fn: (run: ITextElement) => void, toggleKey?: keyof ITextElement): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) return\r\n    const { start, end } = ordered\r\n    const collapsed = this.range.isCollapsed()\r\n    const adjusted = collapsed ? { start, end } : this.splitBoundaryRuns(doc, start, end)\r\n    this.range.setRange({ anchor: adjusted.start, focus: adjusted.end })\r\n    const node = collapsed ? getByPath(doc.elements, start.path) : null\r\n    const selectedRuns = (collapsed\r\n      ? node?.type === 'text' ? [node] : []\r\n      : this.collectRunsInRange(doc.elements, adjusted.start, adjusted.end)\r\n    ).filter(run => run.revisionType !== 'delete')\r\n    if (!selectedRuns.length) return\r\n    const allSet = toggleKey ? selectedRuns.every(r => Boolean(r[toggleKey])) : false\r\n    this.formatElements(selectedRuns, element => {\r\n      const run = element as ITextElement\r\n      fn(run)\r\n      if (toggleKey && run[toggleKey] === undefined) {\r\n        ;(run as unknown as Record<string, unknown>)[toggleKey] = !allSet\r\n      }\r\n    })\r\n    // 不可迁移：多个分支各自 commit\r\n    this._commit(doc)\r\n  }\r\n\r\n  /** Map body bookmark endpoints before notifying layout or recording history. */\r\n  private mapBookmarkPositions(doc: IDocxDocumentMeta, map: (point: IPosition, forward: boolean) => IPosition): void {\r\n    // Header/footer paths belong to a different tree than body bookmarks.\r\n    if (doc.elements !== this.draw.getDocument().elements) return\r\n    for (const bookmark of doc.bookmarks ?? []) {\r\n      const { anchor, focus } = bookmark.range\r\n      const order = comparePath(anchor.path, focus.path) || anchor.offset - focus.offset\r\n      bookmark.range = {\r\n        anchor: map(anchor, order <= 0),\r\n        focus: map(focus, order >= 0)\r\n      }\r\n      bookmark.collapsed = isSamePath(bookmark.range.anchor.path, bookmark.range.focus.path) &&\r\n        bookmark.range.anchor.offset === bookmark.range.focus.offset\r\n    }\r\n  }\r\n\r\n  /** Keep offsets and descendant paths aligned when a text run is split. */\r\n  private mapBookmarksAfterSplit(doc: IDocxDocumentMeta, path: Path, offset: number): void {\r\n    const parentPath = path.slice(0, -1)\r\n    const depth = parentPath.length\r\n    const index = path[depth] as number\r\n    this.mapBookmarkPositions(doc, (point, forward) => {\r\n      if (isSamePath(point.path, path)) {\r\n        if (point.offset > offset || (point.offset === offset && forward)) {\r\n          return { path: [...parentPath, index + 1], offset: point.offset - offset }\r\n        }\r\n      } else if (point.path.length > depth &&\r\n        isSamePath(point.path.slice(0, depth), parentPath) &&\r\n        typeof point.path[depth] === 'number' && point.path[depth] > index) {\r\n        const shifted = point.path.slice() as Path\r\n        shifted[depth] = Number(shifted[depth]) + 1\r\n        return { path: shifted, offset: point.offset }\r\n      }\r\n      return point\r\n    })\r\n  }\r\n\r\n  /** Splice body blocks and move bookmarks with them; removed content collapses to the edit boundary. */\r\n  private spliceBodyWithBookmarks(doc: IDocxDocumentMeta, start: number, count: number, elements: IElement[] = []): void {\r\n    doc.elements.splice(start, count, ...elements)\r\n    if (!doc.elements.length) doc.elements.push({ type: 'text', value: '' })\r\n    let boundary: IPosition | undefined\r\n    const removedPosition = (): IPosition => {\r\n      if (!boundary) {\r\n        const index = Math.min(start, doc.elements.length - 1)\r\n        const leaves: { node: IElement; path: Path }[] = []\r\n        walkTree([doc.elements[index]], (node, { path }) => {\r\n          if (node.type !== 'table' && node.type !== 'title' && node.type !== 'list') {\r\n            leaves.push({ node, path: [index, ...path.slice(1)] })\r\n          }\r\n        })\r\n        const leaf = start < doc.elements.length ? leaves[0] : leaves[leaves.length - 1]\r\n        boundary = {\r\n          path: leaf?.path ?? [index],\r\n          offset: start >= doc.elements.length && leaf?.node.type === 'text' && !leaf.node.extension?.bookmarkMarker\r\n            ? leaf.node.value.length : 0\r\n        }\r\n      }\r\n      return { path: [...boundary.path], offset: boundary.offset }\r\n    }\r\n    this.mapBookmarkPositions(doc, point => {\r\n      const index = point.path[0]\r\n      if (typeof index !== 'number' || index < start) return point\r\n      if (index < start + count) return removedPosition()\r\n      return { path: [index + elements.length - count, ...point.path.slice(1)], offset: point.offset }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在选区边界拆分 text run，使选区恰好对齐 whole runs。\r\n   * 例：run=\"中国神华本部\"，选 offset 2~6 → 拆成 \"中国\"|\"神华本部\"|\"月度...\"，\r\n   * 返回调整后的 start/end（start 指向 \"神华本部\" offset 0，end 指向它 offset 4）。\r\n   */\r\n  private splitBoundaryRuns(doc: IDocxDocumentMeta, start: IPosition, end: IPosition): { start: IPosition; end: IPosition } {\r\n    let startPath = start.path.slice() as Path\r\n    let startOffset = start.offset\r\n    let endPath = end.path.slice() as Path\r\n    let endOffset = end.offset\r\n    const sameRun = isSamePath(start.path, end.path)\r\n\r\n    // 拆分 start run（start.offset > 0 且 < run.length）\r\n    if (startOffset > 0) {\r\n      const node = getByPath(doc.elements, startPath)\r\n      if (node && node.type === 'text') {\r\n        const t = node as ITextElement\r\n        if (startOffset < t.value.length) {\r\n          const parent = getParentContainer(doc.elements, startPath)\r\n          if (parent) {\r\n            const idx = startPath[startPath.length - 1] as number\r\n            const after = t.value.slice(startOffset)\r\n            t.value = t.value.slice(0, startOffset)\r\n            const second = { ...cloneTree(t), value: after } as ITextElement\r\n            parent.splice(idx + 1, 0, second as IElement)\r\n            this.mapBookmarksAfterSplit(doc, startPath, startOffset)\r\n            startPath = startPath.slice() as Path\r\n            startPath[startPath.length - 1] = idx + 1\r\n            startOffset = 0\r\n            if (sameRun) {\r\n              endPath = startPath.slice() as Path\r\n              endOffset = end.offset - start.offset\r\n            } else {\r\n              const startParent = start.path.slice(0, -1)\r\n              const depth = startParent.length\r\n              if (isSamePath(startParent, endPath.slice(0, depth)) && Number(endPath[depth]) > idx) {\r\n                endPath[depth] = Number(endPath[depth]) + 1\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    // 拆分 end run（end.offset > 0 且 < run.length）\r\n    if (endOffset > 0) {\r\n      const node = getByPath(doc.elements, endPath)\r\n      if (node && node.type === 'text') {\r\n        const t = node as ITextElement\r\n        if (endOffset < t.value.length) {\r\n          const parent = getParentContainer(doc.elements, endPath)\r\n          if (parent) {\r\n            const idx = endPath[endPath.length - 1] as number\r\n            const after = t.value.slice(endOffset)\r\n            t.value = t.value.slice(0, endOffset)\r\n            const second = { ...cloneTree(t), value: after } as ITextElement\r\n            parent.splice(idx + 1, 0, second as IElement)\r\n            this.mapBookmarksAfterSplit(doc, endPath, endOffset)\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    return { start: { path: startPath, offset: startOffset }, end: { path: endPath, offset: endOffset } }\r\n  }\r\n\r\n  /**\r\n   * 收集选区范围内的所有 text run。\r\n   * @param elements 文档元素树\r\n   * @param start 选区起点\r\n   * @param end 选区终点\r\n   * @returns 范围内的 text run 数组\r\n   */\r\n  private collectRunsInRange(elements: IElement[], start: IPosition, end: IPosition): ITextElement[] {\r\n    const runs: { path: Path; node: ITextElement }[] = []\r\n    walkTree(elements, (node, ctx) => {\r\n      if (node.type === 'text') runs.push({ path: ctx.path.slice() as Path, node: node as ITextElement })\r\n    })\r\n    let startIdx = -1, endIdx = -1\r\n    for (let i = 0; i < runs.length; i++) {\r\n      if (startIdx === -1 && isSamePath(runs[i].path, start.path)) startIdx = i\r\n      if (isSamePath(runs[i].path, end.path)) endIdx = i\r\n    }\r\n    if (startIdx === -1 || endIdx === -1) return []\r\n    if (startIdx > endIdx) { const t = startIdx; startIdx = endIdx; endIdx = t }\r\n    return runs.slice(startIdx, endIdx + 1)\r\n      .filter(r => (!isSamePath(r.path, start.path) || start.offset < r.node.value.length) &&\r\n        (!isSamePath(r.path, end.path) || end.offset > 0) && !r.node.extension?.bookmarkMarker)\r\n      .map(r => r.node)\r\n  }\r\n\r\n  /* -------------------- 标题 / 列表 -------------------- */\r\n\r\n  /**\r\n   * 设置选区涉及段落的标题级别，null 表示正文。保留 runs、段落边界和选区。\r\n   * @param level 标题级别，null 表示取消标题\r\n   */\r\n  setTitle(level: ITitleElement['level'] | null): void {\r\n    if (!this.getIsCanInput()) return\r\n    const selection = this.range.getRange()\r\n    const ordered = this.range.getOrdered()\r\n    if (!selection || !ordered) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const targets = new Map<IElement, { parent: IElement[]; start: number; end: number; path: Path }>()\r\n    const collect = (path: Path) => {\r\n      const titlePath = this.getTitlePath(doc.elements, path)\r\n      const targetPath = titlePath ?? path\r\n      const parent = getParentContainer(doc.elements, targetPath)\r\n      if (!parent) return\r\n      const index = targetPath[targetPath.length - 1] as number\r\n      const group = splitParagraphs(parent).find(g => index >= g.start && index < g.end)\r\n      if (!group || (group.kind !== 'normal' && group.kind !== 'title')) return\r\n      targets.set(parent[group.start], {\r\n        parent, start: group.start, end: group.end,\r\n        path: [...targetPath.slice(0, -1), group.start]\r\n      })\r\n    }\r\n    if (this.range.isCollapsed()) {\r\n      collect(selection.focus.path)\r\n    } else {\r\n      walkTree(doc.elements, (node, ctx) => {\r\n        if (node.type !== 'text' && node.type !== 'title') return\r\n        if (node.type === 'title' && (node as ITitleElement).valueList.length\r\n          && !isSamePath(ctx.path, ordered.start.path) && !isSamePath(ctx.path, ordered.end.path)) return\r\n        const fromStart = comparePath(ctx.path, ordered.start.path)\r\n        const fromEnd = comparePath(ctx.path, ordered.end.path)\r\n        if (fromStart >= 0 && (fromEnd < 0 || (fromEnd === 0 && ordered.end.offset > 0))) {\r\n          collect(ctx.path)\r\n        }\r\n      })\r\n    }\r\n    const anchorNode = getByPath(doc.elements, selection.anchor.path)\r\n    const focusNode = getByPath(doc.elements, selection.focus.path)\r\n    const replacements = new Map<IElement, IElement>()\r\n    const isTerminator = (node?: IElement) =>\r\n      node?.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(node.value)\r\n    const options = this.draw.getOptions()\r\n    const textFormat = {\r\n      font: String(options.defaultFont ?? DEFAULT_EDITOR_OPTION.defaultFont),\r\n      size: level === null ? Number(options.defaultSize ?? DEFAULT_EDITOR_OPTION.defaultSize) : HEADING_SIZES[level],\r\n      bold: level !== null\r\n    }\r\n    const formatRuns = (elements: IElement[]) => {\r\n      const runs: IElement[] = []\r\n      walkTree(elements, element => {\r\n        if (element.type === 'text') runs.push(element)\r\n      })\r\n      this.formatElements(runs, element => {\r\n        Object.assign(element, textFormat)\r\n        delete element.paragraphStyleId\r\n      })\r\n    }\r\n    let changed = false\r\n    // Reverse document order keeps pending sibling indices valid after splicing.\r\n    for (const [node, target] of [...targets].sort((a, b) => comparePath(b[1].path, a[1].path))) {\r\n      const { parent, start, end } = target\r\n      if (node.type === 'title') {\r\n        const title = node as ITitleElement\r\n        if (level !== null) {\r\n          title.level = level\r\n          delete title.paragraphStyleId\r\n          formatRuns(title.valueList)\r\n        } else {\r\n          const runs = title.valueList.length ? [...title.valueList] : [{ type: 'text', value: '' } as IElement]\r\n          formatRuns(runs)\r\n          replacements.set(title, runs[0])\r\n          const paragraphKeys = [\r\n            'rowFlex', 'paragraphFirstLineIndent', 'paragraphIndentLeft', 'paragraphIndentRight',\r\n            'paragraphSpacingBefore', 'paragraphSpacingAfter', 'lineHeight', 'lineHeightRule'\r\n          ] as const\r\n          for (const run of runs) {\r\n            for (const key of paragraphKeys) {\r\n              if (title[key] !== undefined) Object.assign(run, { [key]: title[key] })\r\n            }\r\n            delete run.paragraphStyleId\r\n          }\r\n          // A title is a block boundary; unwrapping must not merge adjacent paragraphs.\r\n          if (!isTerminator(runs[runs.length - 1])) runs.push({ type: 'text', value: '\\u200B' })\r\n          const previous = splitParagraphs(parent).find(g => g.end === start)\r\n          if (previous?.kind === 'normal' && !isTerminator(parent[start - 1])) {\r\n            runs.unshift({ type: 'text', value: '\\u200B' })\r\n          }\r\n          parent.splice(start, 1, ...runs)\r\n        }\r\n      } else {\r\n        if (level === null) continue\r\n        const runs = parent.slice(start, end)\r\n        formatRuns(runs)\r\n        parent.splice(start, end - start, {\r\n          type: 'title', value: '', level, valueList: runs\r\n        })\r\n      }\r\n      changed = true\r\n    }\r\n    if (!changed) return\r\n    const restored = { anchor: selection.anchor, focus: selection.focus }\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node === (anchorNode && (replacements.get(anchorNode) ?? anchorNode))) {\r\n        restored.anchor = { path: ctx.path, offset: selection.anchor.offset }\r\n      }\r\n      if (node === (focusNode && (replacements.get(focusNode) ?? focusNode))) {\r\n        restored.focus = { path: ctx.path, offset: selection.focus.offset }\r\n      }\r\n    })\r\n    this.range.setRange(restored)\r\n    this._commit(doc)\r\n  }\r\n\r\n  /** Resolve the heading container even when the caret is on one of its text runs. */\r\n  private getTitlePath(elements: IElement[], path: Path): Path | null {\r\n    for (let length = path.length; length > 0; length--) {\r\n      if (typeof path[length - 1] !== 'number') continue\r\n      const candidate = path.slice(0, length) as Path\r\n      if (getByPath(elements, candidate)?.type === 'title') return candidate\r\n    }\r\n    return null\r\n  }\r\n\r\n  /** 从指定路径逐级向上查找最近的列表容器路径，未找到时返回 null。 */\r\n  private getListPath(elements: IElement[], path: Path): Path | null {\r\n    for (let length = path.length; length > 0; length--) {\r\n      if (typeof path[length - 1] !== 'number') continue\r\n      const candidate = path.slice(0, length) as Path\r\n      if (getByPath(elements, candidate)?.type === 'list') return candidate\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 设置或取消列表。\r\n   * @param type 列表类型名\r\n   * @param style 列表样式\r\n   */\r\n  setList(type: ListTypeName | null, style: string | null): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const path = this.getListPath(doc.elements, pos.path) ?? pos.path\r\n      const parent = getParentContainer(doc.elements, path)\r\n      if (!parent) return false\r\n      const idx = path[path.length - 1] as number\r\n      const cur = parent[idx]\r\n      if (!cur) return false\r\n      if (cur.type === 'list' && (!type || !style || (cur.listType === type && cur.listStyle === style))) {\r\n        const valueList = (cur as IListElement).valueList\r\n        const children = valueList.length ? [...valueList] : [{ type: 'text', value: '' } as IElement]\r\n        const groups = splitParagraphs(parent)\r\n        const isTerminator = (element?: IElement) =>\r\n          element?.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(element.value) && !element.extension?.bookmarkMarker\r\n        let leadingSeparator = 0\r\n        // Removing the list container must retain its paragraph boundaries.\r\n        if (groups.some(group => group.kind === 'normal' && group.end === idx) && !isTerminator(parent[idx - 1])) {\r\n          children.unshift({ type: 'text', value: '\\u200B' })\r\n          leadingSeparator = 1\r\n        }\r\n        if (groups.some(group => group.kind === 'normal' && group.start === idx + 1) && !isTerminator(children[children.length - 1])) {\r\n          children.push({ type: 'text', value: '\\u200B' })\r\n        }\r\n        parent.splice(idx, 1, ...children)\r\n        const childIndex = pos.path[path.length] === 'valueList' ? Number(pos.path[path.length + 1]) : 0\r\n        this.range.setCaret({ path: [...path.slice(0, -1), idx + leadingSeparator + childIndex, ...pos.path.slice(path.length + 2)] as Path, offset: pos.offset })\r\n        return\r\n      }\r\n      if (!type || !style) return false\r\n      let list: IListElement\r\n      if (cur.type === 'list') {\r\n        list = cur as IListElement\r\n        list.listType = type\r\n        list.listStyle = style\r\n      } else if (cur.type === 'text') {\r\n        list = { type: 'list', value: '', listType: type, listStyle: style, listLevel: 0, valueList: [cloneTree(cur)] }\r\n        parent[idx] = list\r\n        this.range.setCaret({ path: [...path, 'valueList', 0], offset: pos.offset })\r\n      } else return false\r\n      const bullet = type === 'ul' ? BULLET_STYLES.find(item => item.style === style) : undefined\r\n      const number = type === 'ol' ? NUMBER_STYLES.find(item => item.style === style) : undefined\r\n      const previous = list.listNumbering\r\n      delete list.listNumbering\r\n      if (bullet || number) {\r\n        list.listNumbering = {\r\n          numId: previous?.numId ?? list.listId ?? style,\r\n          abstractNumId: previous?.abstractNumId ?? style,\r\n          level: list.listLevel,\r\n          numFmt: number?.numFmt ?? 'bullet',\r\n          lvlText: number ? number.lvlText.replace('%1', `%${list.listLevel + 1}`) : bullet!.icon,\r\n          start: previous?.start ?? 1,\r\n          indentLeft: previous?.indentLeft ?? list.listIndent ?? 0,\r\n          indentHanging: previous?.indentHanging ?? list.listHanging ?? 0,\r\n          lvlJc: previous?.lvlJc ?? 'left'\r\n        }\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /* -------------------- 表格 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入表格。\r\n   * @param rows 行数\r\n   * @param cols 列数\r\n   * @param availableWidth 可用宽度，省略时取内容区宽度\r\n   */\r\n  insertTable(rows: number, cols: number, availableWidth?: number): void {\r\n    if (!Number.isInteger(rows) || !Number.isInteger(cols) || rows < 1 || cols < 1) return\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const contentWidth = availableWidth ?? this.getContentWidth()\r\n      const colWidth = contentWidth / cols\r\n      const table: ITableElement = {\r\n        type: 'table',\r\n        value: '',\r\n        colgroup: Array.from({ length: cols }, () => ({ width: colWidth })),\r\n        trList: Array.from({ length: rows }, () => ({\r\n          height: 32,\r\n          tdList: Array.from({ length: cols }, () => ({\r\n            width: colWidth,\r\n            colspan: 1,\r\n            rowspan: 1,\r\n            value: [{ type: 'text', value: '' } as IElement],\r\n            verticalAlign: 'top' as const,\r\n            borderStyle: {\r\n              top: { width: 1, color: '#000', style: 'solid' as const },\r\n              right: { width: 1, color: '#000', style: 'solid' as const },\r\n              bottom: { width: 1, color: '#000', style: 'solid' as const },\r\n              left: { width: 1, color: '#000', style: 'solid' as const }\r\n            },\r\n            padding: [5, 5, 5, 5] as [number, number, number, number]\r\n          }))\r\n        }))\r\n      }\r\n      const path = this.insertBlockAtCaret(doc, table)\r\n      if (!path) return false\r\n      this.range.setCaret({ path: [...path, 'trList', 0, 'tdList', 0, 'value', 0], offset: 0 })\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前光标所在的表格上下文信息。\r\n   * @returns 包含 doc/table/tableIndex/trIndex/tdIndex 的对象；光标不在表格内时返回 null\r\n   */\r\n  private getTableContext(): { doc: IDocxDocumentMeta; table: ITableElement; tableIndex: number; trIndex: number; tdIndex: number } | null {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return null\r\n    const p = pos.path\r\n    if (p.length < 5 || p[1] !== 'trList' || p[3] !== 'tdList') return null\r\n    const doc = this.draw.getActiveDocument()\r\n    const tableIndex = p[0] as number\r\n    const trIndex = p[2] as number\r\n    const tdIndex = p[4] as number\r\n    const table = doc.elements[tableIndex]\r\n    if (!table || table.type !== 'table') return null\r\n    return { doc, table: table as ITableElement, tableIndex, trIndex, tdIndex }\r\n  }\r\n\r\n  /**\r\n   * 创建一个空的表格单元格。\r\n   * @param width 单元格宽度\r\n   * @returns 空单元格对象\r\n   */\r\n  private makeEmptyTd(width: number): ITd {\r\n    return {\r\n      width,\r\n      colspan: 1,\r\n      rowspan: 1,\r\n      value: [{ type: 'text', value: '' } as IElement],\r\n      verticalAlign: 'top' as const,\r\n      borderStyle: {\r\n        top: { width: 1, color: '#000', style: 'solid' as const },\r\n        right: { width: 1, color: '#000', style: 'solid' as const },\r\n        bottom: { width: 1, color: '#000', style: 'solid' as const },\r\n        left: { width: 1, color: '#000', style: 'solid' as const }\r\n      },\r\n      padding: [5, 5, 5, 5] as [number, number, number, number]\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 在当前行上方或下方插入指定数量的表格行。\r\n   * @param position 插入位置：'above' | 'below'\r\n   * @param count 插入行数，默认 1\r\n   */\r\n  insertTableRow(position: 'above' | 'below', count = 1): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex } = ctx\r\n      const insertAt = position === 'above' ? trIndex : trIndex + 1\r\n      for (let i = 0; i < count; i++) {\r\n        const newRow = cloneTree(table.trList[trIndex])\r\n        for (const td of newRow.tdList) {\r\n          td.value = [{ type: 'text', value: '' } as IElement]\r\n        }\r\n        table.trList.splice(insertAt + i, 0, newRow)\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在当前列左侧或右侧插入指定数量的表格列，并重新均分列宽。\r\n   * @param position 插入位置：'left' | 'right'\r\n   * @param count 插入列数，默认 1\r\n   */\r\n  insertTableCol(position: 'left' | 'right', count = 1): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, tdIndex } = ctx\r\n      const totalWidth = table.colgroup.reduce((s, c) => s + c.width, 0)\r\n      const newColCount = table.colgroup.length + count\r\n      const colWidth = totalWidth / newColCount\r\n      const insertAt = position === 'left' ? tdIndex : tdIndex + 1\r\n      for (let i = 0; i < count; i++) {\r\n        for (const tr of table.trList) {\r\n          const newTd = this.makeEmptyTd(colWidth)\r\n          tr.tdList.splice(insertAt + i, 0, newTd)\r\n        }\r\n        table.colgroup.splice(insertAt + i, 0, { width: colWidth })\r\n      }\r\n      for (const tr of table.trList) {\r\n        for (const td of tr.tdList) td.width = colWidth\r\n      }\r\n      for (const c of table.colgroup) c.width = colWidth\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除当前表格行（至少保留一行）。 */\r\n  deleteTableRow(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex } = ctx\r\n      if (table.trList.length <= 1) return false\r\n      table.trList.splice(trIndex, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除当前表格列（至少保留一列）。 */\r\n  deleteTableCol(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, tdIndex } = ctx\r\n      if (table.trList[0].tdList.length <= 1) return false\r\n      for (const tr of table.trList) {\r\n        tr.tdList.splice(tdIndex, 1)\r\n      }\r\n      table.colgroup.splice(tdIndex, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 将当前单元格拆分为两个单元格，并均分原列宽。 */\r\n  splitTableCell(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex, tdIndex } = ctx\r\n      const td = table.trList[trIndex].tdList[tdIndex]\r\n      const newTd = this.makeEmptyTd(td.width)\r\n      table.trList[trIndex].tdList.splice(tdIndex + 1, 0, newTd)\r\n      const colWidth = td.width / 2\r\n      td.width = colWidth\r\n      newTd.width = colWidth\r\n      if (table.colgroup[tdIndex]) {\r\n        const totalWidth = table.colgroup[tdIndex].width\r\n        table.colgroup.splice(tdIndex, 1, { width: colWidth }, { width: totalWidth - colWidth })\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 选中当前表格的全部内容。 */\r\n  selectTable(): void {\r\n    const ctx = this.getTableContext()\r\n    if (!ctx) return\r\n    const { table, tableIndex } = ctx\r\n    const firstTr = table.trList[0]\r\n    const lastTr = table.trList[table.trList.length - 1]\r\n    if (!firstTr || !lastTr) return\r\n    const anchor: IPosition = { path: [tableIndex, 'trList', 0, 'tdList', 0, 'value', 0], offset: 0 }\r\n    const lastTdIdx = lastTr.tdList.length - 1\r\n    const lastValue = lastTr.tdList[lastTdIdx].value\r\n    const lastIdx = lastValue.length - 1\r\n    const lastEl = lastValue[lastIdx]\r\n    const focus: IPosition = {\r\n      path: [tableIndex, 'trList', table.trList.length - 1, 'tdList', lastTdIdx, 'value', lastIdx],\r\n      offset: lastEl && typeof (lastEl as { value?: unknown }).value === 'string' ? String((lastEl as { value: string }).value).length : 1\r\n    }\r\n    this.range.setRange({ anchor, focus })\r\n  }\r\n\r\n  /** 合并选区内单元格 */\r\n  mergeTableCells(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table } = ctx\r\n\r\n      const ordered = this.range.getOrdered()\r\n      if (!ordered) return false\r\n      const { start, end } = ordered\r\n      if (start.path.length < 5 || end.path.length < 5) return false\r\n      if (start.path[0] !== end.path[0]) return false\r\n\r\n      const minRow = Math.min(start.path[2] as number, end.path[2] as number)\r\n      const maxRow = Math.max(start.path[2] as number, end.path[2] as number)\r\n      const minCol = Math.min(start.path[4] as number, end.path[4] as number)\r\n      const maxCol = Math.max(start.path[4] as number, end.path[4] as number)\r\n\r\n      if (minRow === maxRow && minCol === maxCol) return false\r\n\r\n      const firstTd = table.trList[minRow]?.tdList[minCol]\r\n      if (!firstTd) return false\r\n\r\n      const allContent: IElement[] = []\r\n      for (let r = minRow; r <= maxRow; r++) {\r\n        for (let c = minCol; c <= maxCol; c++) {\r\n          const td = table.trList[r]?.tdList[c]\r\n          if (td && !td.merged) {\r\n            for (const el of td.value) allContent.push(el)\r\n          }\r\n        }\r\n      }\r\n\r\n      firstTd.colspan = maxCol - minCol + 1\r\n      firstTd.rowspan = maxRow - minRow + 1\r\n      firstTd.value = allContent.length > 0 ? allContent : [{ type: 'text', value: '' } as IElement]\r\n      firstTd.width = table.colgroup.slice(minCol, maxCol + 1).reduce((s, c) => s + c.width, 0)\r\n\r\n      for (let r = minRow; r <= maxRow; r++) {\r\n        for (let c = minCol; c <= maxCol; c++) {\r\n          if (r === minRow && c === minCol) continue\r\n          const td = table.trList[r]?.tdList[c]\r\n          if (td) {\r\n            td.merged = true\r\n            td.value = []\r\n          }\r\n        }\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除整个表格 */\r\n  deleteTable(): void {\r\n    this.execute(doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { tableIndex } = ctx\r\n      doc.elements.splice(tableIndex, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 获取当前单元格的垂直对齐与底纹颜色（默认顶部对齐、空颜色），无单元格时返回 null。 */\r\n  getCellProperties() {\r\n    const ctx = this.getTableContext()\r\n    const cell = ctx?.table.trList[ctx.trIndex]?.tdList[ctx.tdIndex]\r\n    return cell ? { verticalAlign: cell.verticalAlign ?? 'top', backgroundColor: cell.backgroundColor ?? '' } : null\r\n  }\r\n\r\n  /** 设置当前单元格垂直对齐 */\r\n  setCellVerticalAlign(align: VerticalAlign): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex, tdIndex } = ctx\r\n      const td = table.trList[trIndex]?.tdList[tdIndex]\r\n      if (!td) return false\r\n      td.verticalAlign = align\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 设置当前单元格底纹颜色 */\r\n  setCellBackground(color: string): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex, tdIndex } = ctx\r\n      const td = table.trList[trIndex]?.tdList[tdIndex]\r\n      if (!td) return false\r\n      td.backgroundColor = color\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 切换当前行重复表头 */\r\n  toggleRepeatHeader(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex } = ctx\r\n      const tr = table.trList[trIndex]\r\n      if (!tr) return false\r\n      tr.pagingRepeat = !tr.pagingRepeat\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 设置指定表格列的宽度。\r\n   * @param tableIndex 表格索引\r\n   * @param colIndex 列索引\r\n   * @param width 列宽\r\n   */\r\n  setTableColWidth(tableIndex: number, colIndex: number, width: number): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getDocument()\r\n    const table = doc.elements[tableIndex]\r\n    if (!table || table.type !== 'table') return\r\n    const t = table as ITableElement\r\n    if (colIndex < 0 || colIndex >= t.colgroup.length) return\r\n    const w = Math.max(20, Math.round(width))\r\n    t.colgroup[colIndex].width = w\r\n    for (const tr of t.trList) {\r\n      const td = tr.tdList[colIndex]\r\n      if (td && !td.merged) td.width = w\r\n    }\r\n    // 不可迁移：doc 来自 this.draw.getDocument() 而非 getActiveDocument()\r\n    this._commit(doc)\r\n  }\r\n\r\n  /**\r\n   * 设置指定表格行的高度。\r\n   * @param tableIndex 表格索引\r\n   * @param rowIndex 行索引\r\n   * @param height 行高\r\n   */\r\n  setTableRowHeight(tableIndex: number, rowIndex: number, height: number): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getDocument()\r\n    const table = doc.elements[tableIndex]\r\n    if (!table || table.type !== 'table') return\r\n    const t = table as ITableElement\r\n    if (rowIndex < 0 || rowIndex >= t.trList.length) return\r\n    t.trList[rowIndex].height = Math.max(20, Math.round(height))\r\n    // 不可迁移：doc 来自 this.draw.getDocument() 而非 getActiveDocument()\r\n    this._commit(doc)\r\n  }\r\n\r\n  /* -------------------- 图片 / 分页 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入图片。\r\n   * @param src 图片源，可以是 URL 字符串或包含 value/width/height 的对象\r\n   * @param width 宽度，当 src 为字符串时生效，默认 200\r\n   * @param height 高度，当 src 为字符串时生效，默认 150\r\n   */\r\n  insertImage(src: string | { value: string; width?: number; height?: number }, width?: number, height?: number): void {\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const imgSrc = typeof src === 'string' ? src : src.value\r\n      const w = (typeof src === 'string' ? width : src.width) ?? 200\r\n      const h = (typeof src === 'string' ? height : src.height) ?? 150\r\n      const imgW = Number.isFinite(w) && w > 0 ? w : 200\r\n      const imgH = Number.isFinite(h) && h > 0 ? h : 150\r\n      const bounds = this.getImageInsertionBounds(doc)\r\n      const ratio = Math.min(1, bounds.width / imgW, bounds.height / imgH)\r\n      const img: IElement = { type: 'image', value: imgSrc, width: imgW * ratio, height: imgH * ratio } as unknown as IElement\r\n      const path = this.insertBlockAtCaret(doc, img)\r\n      if (!path) return false\r\n      const parent = getParentContainer(doc.elements, path)!\r\n      const idx = (path[path.length - 1] as number) + 1\r\n      if (parent[idx]?.type !== 'text') parent.splice(idx, 0, { type: 'text', value: '' } as IElement)\r\n      this.range.setCaret({ path: [...path.slice(0, -1), idx], offset: 0 })\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 使用文档坐标限制新图片；单元格高度可增长，但不应超过一页内容区。 */\r\n  private getImageInsertionBounds(doc: IDocxDocumentMeta): { width: number; height: number } {\r\n    const opts = this.draw.getOptions()\r\n    const [mt, mr, mb, ml] = (opts.pageMargins as [number, number, number, number] | undefined)\r\n      ?? DEFAULT_EDITOR_OPTION.pageMargins\r\n    const zone = this.draw.getZone()\r\n    let width = Number(opts.pageWidth ?? DEFAULT_EDITOR_OPTION.pageWidth) - ml - mr\r\n    let height = zone === 'header' ? mt : zone === 'footer' ? mb\r\n      : Number(opts.pageHeight ?? DEFAULT_EDITOR_OPTION.pageHeight) - mt - mb\r\n    const path = this.range.getFocus()?.path ?? []\r\n    const cells = new Map<string, number>()\r\n    const collect = (blocks: BlockNode[]) => {\r\n      for (const block of blocks) {\r\n        if (block.kind !== 'table') continue\r\n        for (const row of block.rows) {\r\n          for (const cell of row.cells) {\r\n            cells.set(JSON.stringify(cell.cellPath), cell.rect.width)\r\n            collect(cell.content)\r\n          }\r\n        }\r\n      }\r\n    }\r\n    for (const page of this.draw.getLayout()?.pages ?? []) {\r\n      collect(zone === 'header' ? page.headerBlocks ?? [] : zone === 'footer' ? page.footerBlocks ?? [] : page.blocks)\r\n    }\r\n    for (let i = 0; i < path.length; i++) {\r\n      if (path[i] !== 'trList' || path[i + 2] !== 'tdList' || path[i + 4] !== 'value') continue\r\n      const table = getByPath(doc.elements, path.slice(0, i) as Path) as ITableElement\r\n      const ri = path[i + 1] as number\r\n      const ci = path[i + 3] as number\r\n      const td = table.trList[ri].tdList[ci]\r\n      let cellWidth = cells.get(JSON.stringify(path.slice(0, i + 4)))\r\n      if (cellWidth === undefined) {\r\n        // 尚未排版时使用与 layoutTable 一致的列宽、合并格占位规则。\r\n        let cols = table.colgroup.map(c => c.width || 0)\r\n        if (!cols.length || cols.every(v => v <= 0)) {\r\n          cols = (table.trList[0]?.tdList ?? []).flatMap(cell =>\r\n            Array.from({ length: cell.colspan || 1 }, () => (cell.width || 0) / (cell.colspan || 1)))\r\n        }\r\n        const total = cols.reduce((sum, v) => sum + v, 0)\r\n        if (total > width * 1.02) cols = cols.map(v => v * width / total)\r\n        else if (total <= 0) {\r\n          const count = Math.max(1, cols.length || (table.trList[0]?.tdList.length ?? 1))\r\n          cols = Array.from({ length: count }, () => width / count)\r\n        }\r\n        const occupied: boolean[][] = table.trList.map(() => [])\r\n        for (let r = 0; r <= ri; r++) {\r\n          let col = 0\r\n          for (let c = 0; c < table.trList[r].tdList.length; c++) {\r\n            while (col < cols.length && occupied[r][col]) col++\r\n            const cell = table.trList[r].tdList[c]\r\n            const span = Math.max(1, cell.colspan || 1)\r\n            if (r === ri && c === ci) cellWidth = cols.slice(col, col + span).reduce((sum, v) => sum + v, 0)\r\n            for (let rr = r + 1; rr < Math.min(r + Math.max(1, cell.rowspan || 1), table.trList.length); rr++) {\r\n              for (let cc = col; cc < Math.min(col + span, cols.length); cc++) occupied[rr][cc] = true\r\n            }\r\n            col += span\r\n          }\r\n        }\r\n      }\r\n      const [pt, pr, pb, pl] = td.padding\r\n      width = Math.min(width, Math.max(10, (cellWidth ?? width) - pl - pr))\r\n      height -= pt + pb\r\n    }\r\n    return { width: Math.max(1, width), height: Math.max(1, height) }\r\n  }\r\n\r\n  /** 在文本偏移处分段，并将块节点放入正文或单元格的块容器。 */\r\n  private insertBlockAtCaret(doc: IDocxDocumentMeta, block: IElement): Path | null {\r\n    const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n    let path = pos.path.slice() as Path\r\n    let parent = getParentContainer(doc.elements, path)\r\n    if (!parent) return null\r\n    let idx = Math.min(path[path.length - 1] as number, parent.length)\r\n    const node = parent[idx]\r\n    if (node?.type === 'text') {\r\n      const offset = Math.max(0, Math.min(pos.offset, node.value.length))\r\n      if (offset > 0) {\r\n        if (offset < node.value.length) {\r\n          parent.splice(idx + 1, 0, { ...node, value: node.value.slice(offset) } as IElement)\r\n          node.value = node.value.slice(0, offset)\r\n        }\r\n        idx++\r\n      }\r\n    } else if (node) {\r\n      idx++\r\n    }\r\n    // valueList 是标题、列表和超链接的行内容器，不可直接容纳独立块。\r\n    while (path[path.length - 2] === 'valueList') {\r\n      const containerPath = path.slice(0, -2) as Path\r\n      const container = getByPath(doc.elements, containerPath)!\r\n      const outer = getParentContainer(doc.elements, containerPath)!\r\n      const containerIndex = containerPath[containerPath.length - 1] as number\r\n      const tail = parent.splice(idx)\r\n      const replacements: IElement[] = []\r\n      if (parent.length) replacements.push(container)\r\n      const insertionIndex = containerIndex + replacements.length\r\n      if (tail.length) replacements.push({ ...container, valueList: tail } as IElement)\r\n      outer.splice(containerIndex, 1, ...replacements)\r\n      parent = outer\r\n      path = containerPath\r\n      idx = insertionIndex\r\n    }\r\n    parent.splice(idx, 0, block)\r\n    return [...path.slice(0, -1), idx] as Path\r\n  }\r\n\r\n  /** 插入电子签名图片，固定 100×100 */\r\n  signature(dataUrl: string): void {\r\n    this.insertImage({ value: dataUrl, width: 100, height: 100 })\r\n  }\r\n\r\n  /**\r\n   * 在当前光标处插入 LaTeX 公式元素。\r\n   * @param payload LaTeX 参数，包含 latex/svg/width/height\r\n   */\r\n  insertLatex(payload: { latex: string; svg: string; width: number; height: number }): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n      const el: IElement = { type: 'latex', value: payload.latex, laTexSVG: payload.svg, width: payload.width, height: payload.height } as unknown as IElement\r\n      const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n      parent.splice(idx, 0, el)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新指定图片的尺寸。\r\n   * @param path 图片路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateImageSize(path: Path, width: number, height: number): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path)\r\n      if (!el || el.type !== 'image') return false\r\n      ;(el as unknown as { width: number; height: number }).width = Math.max(1, Math.round(width))\r\n      ;(el as unknown as { width: number; height: number }).height = Math.max(1, Math.round(height))\r\n      updateImageLayout(el as IImageElement, { width: (el as IImageElement).width, height: (el as IImageElement).height })\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 删除指定路径的图片元素。\r\n   * @param path 图片路径\r\n   */\r\n  deleteImage(path: Path): void {\r\n    this.execute(doc => {\r\n      const parent = getParentContainer(doc.elements, path)\r\n      if (!parent) return false\r\n      const idx = path[path.length - 1]\r\n      if (typeof idx !== 'number' || idx < 0 || idx >= parent.length) return false\r\n      if (parent[idx].type !== 'image') return false\r\n      parent.splice(idx, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 重置指定图片为原始尺寸（通过加载图片获取 naturalWidth/Height）。\r\n   * @param path 图片路径\r\n   */\r\n  resetImageSize(path: Path): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const el = getByPath(doc.elements, path) as unknown as { type: string; value?: string; width: number; height: number } | null\r\n    if (!el || el.type !== 'image' || !el.value) return\r\n    const img = new Image()\r\n    img.onload = () => {\r\n      if (!this.getIsCanInput()) return\r\n      el.width = img.naturalWidth\r\n      el.height = img.naturalHeight\r\n      updateImageLayout(el as IImageElement, { width: el.width, height: el.height })\r\n      // 不可迁移：_commit 在异步 onload 回调内\r\n      this._commit(doc)\r\n    }\r\n    img.src = el.value\r\n  }\r\n\r\n  /**\r\n   * 设置图片对齐方式。\r\n   * @param path 图片路径\r\n   * @param align 对齐方式：'left' | 'center' | 'right'\r\n   */\r\n  imageAlign(path: Path, align: 'left' | 'center' | 'right'): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path)\r\n      if (!el || el.type !== 'image') return false\r\n      ;(el as unknown as { rowFlex: string }).rowFlex = align\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 替换指定图片：弹出文件选择框，读取本地图片并以 data URL 替换原图片，同时更新尺寸。\r\n   * @param path 图片路径\r\n   */\r\n  replaceImage(path: Path): void {\r\n    if (!this.getIsCanInput()) return\r\n    const input = document.createElement('input')\r\n    input.type = 'file'\r\n    input.accept = 'image/*'\r\n    input.onchange = () => {\r\n      const file = input.files?.[0]\r\n      if (!file) return\r\n      const reader = new FileReader()\r\n      reader.onload = () => {\r\n        const value = reader.result\r\n        if (typeof value !== 'string') return\r\n        const doc = this.draw.getActiveDocument()\r\n        const el = getByPath(doc.elements, path) as unknown as { type: string; value: string; width: number; height: number } | null\r\n        if (!el || el.type !== 'image') return\r\n        const img = new Image()\r\n        img.onload = () => {\r\n          if (!this.getIsCanInput()) return\r\n          el.value = value\r\n          el.width = img.naturalWidth\r\n          el.height = img.naturalHeight\r\n          updateImageLayout(el as IImageElement, { width: el.width, height: el.height })\r\n          // 不可迁移：_commit 在异步嵌套回调内\r\n          this._commit(doc)\r\n        }\r\n        img.src = value\r\n      }\r\n      reader.readAsDataURL(file)\r\n    }\r\n    input.click()\r\n  }\r\n\r\n  /**\r\n   * 将指定图片顺时针旋转 90 度。\r\n   * @param path 图片路径\r\n   */\r\n  rotateImage(path: Path): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path) as unknown as { type: string; rotate?: number; width: number; height: number } | null\r\n      if (!el || el.type !== 'image') return false\r\n      applyImageLayout(el as IImageElement)\r\n      const cur = el.rotate ?? 0\r\n      el.rotate = (cur + 90) % 360\r\n      updateImageLayout(el as IImageElement, { rotate: el.rotate })\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 保存指定图片到本地（触发浏览器下载）。\r\n   * @param path 图片路径\r\n   */\r\n  async saveImage(path: Path): Promise<void> {\r\n    const doc = this.draw.getActiveDocument()\r\n    const el = getByPath(doc.elements, path) as unknown as { type: string; value: string } | null\r\n    if (!el || el.type !== 'image') return\r\n    try {\r\n      const url = new URL(el.value, document.baseURI)\r\n      if (!['https:', 'http:', 'data:', 'blob:'].includes(url.protocol)) return\r\n      const imageType = /^image\\/(png|jpeg|gif|webp|avif|bmp|x-icon|vnd\\.microsoft\\.icon)$/i\r\n      if (url.protocol === 'data:' && !imageType.test(url.pathname.split(/[;,]/, 1)[0])) return\r\n      const response = await fetch(url.href)\r\n      if (!response.ok) return\r\n      const blob = await response.blob()\r\n      if (!imageType.test(blob.type)) return\r\n      const href = URL.createObjectURL(blob)\r\n      const a = document.createElement('a')\r\n      a.href = href\r\n      a.download = `image-${Date.now()}`\r\n      document.body.appendChild(a)\r\n      a.click()\r\n      a.remove()\r\n      setTimeout(() => URL.revokeObjectURL(href), 1000)\r\n    } catch {\r\n      // 网络、CORS 或已释放的 blob URL 无法下载。\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置图片环绕方式。\r\n   * @param path 图片路径\r\n   * @param mode 环绕模式：'block' | 'surround' | 'floatTop' | 'floatBottom'\r\n   */\r\n  imageWrap(path: Path, mode: 'block' | 'surround' | 'float-top' | 'float-bottom'): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path) as unknown as { type: string; imgDisplay?: string; rowFlex?: string } | null\r\n      if (!el || el.type !== 'image') return false\r\n      el.imgDisplay = mode\r\n      updateImageLayout(el as IImageElement, { wrap: mode })\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 在光标处切开正文，后文移至下一页。 */\r\n  insertPageBreak(): void {\r\n    if (!this.getIsCanInput() || this.draw.getZone() !== 'main') return\r\n    const pos = this.range.getOrdered()?.start ?? this.range.getFocus()\r\n    if (pos?.path.includes('trList')) throw new Error('暂不支持在表格单元格内插入分页符：表格分页及 DOCX 导出无法保真')\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const path = this.insertBlockAtCaret(doc, { type: 'pageBreak', value: 'manual' })\r\n      if (!path) return false\r\n      const index = Number(path[path.length - 1])\r\n      const parent = getParentContainer(doc.elements, path)!\r\n      const next = parent[index + 1]\r\n      if (next?.type === 'text') this.range.setCaret({ path: [...path.slice(0, -1), index + 1], offset: 0 })\r\n      else if (next?.type === 'title' || next?.type === 'list') this.range.setCaret({ path: [...path.slice(0, -1), index + 1, 'valueList', 0], offset: 0 })\r\n      else this.range.setCaret(path.length === 1 ? { path: [index], offset: 0 } : { path, offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 在光标处插入可编辑的空白页。 */\r\n  insertBlankPage(): void {\r\n    if (!this.getIsCanInput() || this.draw.getZone() !== 'main') return\r\n    const pos = this.range.getOrdered()?.start ?? this.range.getFocus()\r\n    if (pos?.path.includes('trList')) throw new Error('暂不支持在表格单元格内插入空白页：表格分页及 DOCX 导出无法保真')\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const path = this.insertBlockAtCaret(doc, { type: 'text', value: '' })\r\n      if (!path) return false\r\n      const parent = getParentContainer(doc.elements, path)!\r\n      let index = Number(path[path.length - 1])\r\n      const previous = parent[index - 1]\r\n      const next = parent[index + 1]\r\n      if (previous && !(previous.type === 'pageBreak' && previous.value !== 'continuous')) {\r\n        parent.splice(index++, 0, { type: 'pageBreak', value: 'manual' })\r\n      }\r\n      if (next && !(next.type === 'pageBreak' && next.value !== 'continuous')) {\r\n        parent.splice(index + 1, 0, { type: 'pageBreak', value: 'manual' })\r\n      }\r\n      this.range.setCaret({ path: [...path.slice(0, -1), index], offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 最近一次插入超链接失败的原因；成功后清空，供 UI 翻译显示。 */\r\n  getHyperlinkInsertionError(): HyperlinkInsertionError | null {\r\n    return this._hyperlinkInsertionError\r\n  }\r\n\r\n  /**\r\n   * 插入超链接。\r\n   * @param payload 超链接参数，包含 url 与 valueList\r\n   */\r\n  insertHyperlink(payload: { url: string; valueList: IElement[] }): boolean {\r\n    this._hyperlinkInsertionError = null\r\n    const fail = (reason: HyperlinkInsertionError): false => {\r\n      this._hyperlinkInsertionError = reason\r\n      return false\r\n    }\r\n    if (this.getIsReadonly()) return fail('readOnly')\r\n    if (this.getIsDisabled()) return fail('disabled')\r\n    if (!payload || typeof payload.url !== 'string') return fail('addressInvalid')\r\n    if (!Array.isArray(payload.valueList) || !payload.valueList.length) return fail('invalidText')\r\n    const url = payload.url.trim()\r\n    if (!url || /[\\u0000-\\u0020\\u007F]/.test(url)) return fail('addressInvalid')\r\n    try {\r\n      if (!['http:', 'https:', 'mailto:', 'tel:', 'ftp:'].includes(new URL(url).protocol)) return fail('addressInvalid')\r\n    } catch {\r\n      return fail('addressInvalid')\r\n    }\r\n    const hasRevision = (element: IElement): boolean => {\r\n      const run = element as ITextElement\r\n      return !!(run.revisionId || run.revisionType || run.revisionOldRPr ||\r\n        run.extension?.revisionOldProps || run.extension?.revisionPrevious)\r\n    }\r\n    if (payload.valueList.some(run => !run || run.type !== 'text' || typeof run.value !== 'string' ||\r\n      hasRevision(run) || run.extension?.bookmarkMarker || run.extension?.fieldMarker)) return fail('invalidText')\r\n    const text = payload.valueList.map(run => run.value).join('')\r\n    // 链接子 run 尚不参与修订遍历，不能把待审修订藏入 valueList 或绕过修订模式。\r\n    if (this.draw.getOptions().trackChanges) return fail('tracking')\r\n    let success = false\r\n    this.execute(doc => {\r\n      const ordered = this.range.getOrdered()\r\n      if (!ordered) return fail('noSelection')\r\n      const { start, end } = ordered\r\n      const parentPath = start.path.slice(0, -1)\r\n      if (!isSamePath(parentPath, end.path.slice(0, -1))) return fail('crossContainer')\r\n      const startNode = getByPath(doc.elements, start.path)\r\n      const endNode = getByPath(doc.elements, end.path)\r\n      if (!startNode || !endNode) return fail('invalidSelection')\r\n      if (startNode.type === 'hyperlink' || endNode.type === 'hyperlink') return fail('existingLink')\r\n      if (startNode.type !== 'text' || endNode.type !== 'text') return fail('nonText')\r\n      if (!Number.isInteger(start.offset) || !Number.isInteger(end.offset) ||\r\n        start.offset < 0 || start.offset > startNode.value.length ||\r\n        end.offset < 0 || end.offset > endNode.value.length) return fail('invalidSelection')\r\n      if (parentPath[parentPath.length - 1] === 'valueList') {\r\n        const container = getByPath(doc.elements, parentPath.slice(0, -1))\r\n        if (container?.type === 'hyperlink') return fail('existingLink')\r\n        if (container?.type !== 'title' && container?.type !== 'list') return fail('nonText')\r\n      }\r\n      const parent = getParentContainer(doc.elements, start.path)\r\n      if (!parent) return fail('invalidSelection')\r\n      const first = Number(start.path[start.path.length - 1])\r\n      const last = Number(end.path[end.path.length - 1])\r\n      const runs = parent.slice(first, last + 1)\r\n      if (runs.some(run => run.extension?.bookmarkMarker)) return fail('bookmarkSelection')\r\n      if (runs.some(run => run.extension?.fieldMarker)) return fail('fieldSelection')\r\n      if (runs.some(run => run.type === 'hyperlink')) return fail('existingLink')\r\n      if (runs.some(run => run.type !== 'text')) return fail('nonText')\r\n      if (runs.some(hasRevision)) return fail('revisions')\r\n      const selected = runs.map((run, i) => ({\r\n        ...cloneTree(run),\r\n        value: run.value.slice(i === 0 ? start.offset : 0, i === runs.length - 1 ? end.offset : run.value.length)\r\n      })).filter(run => run.value.length)\r\n      const selectedText = selected.map(run => run.value).join('')\r\n      // 不跨段落或吞掉段落终止符；不支持的选区必须在任何修改之前退出。\r\n      if (/[\\r\\n\\u200B\\uFEFF]/.test(selectedText)) return fail('crossParagraph')\r\n      // 先检查原选区，避免书签零宽标记被误报为显示文字错误。\r\n      if (!text.trim() || /[\\r\\n\\u200B\\uFEFF]/.test(text)) return fail('invalidText')\r\n      const base = selected[0] ?? startNode\r\n      // 对原选中文字加链接时沿用原 run 边界；更改显示文字时继承起点格式。\r\n      const valueList = selectedText === text ? selected : payload.valueList\r\n        .filter(run => run.value.length)\r\n        .map(run => ({ ...cloneTree(base), ...cloneTree(run) }))\r\n      const link = { ...cloneTree(base), type: 'hyperlink', value: url, valueList } as IElement\r\n      const parts: IElement[] = []\r\n      if (start.offset > 0) parts.push({ ...cloneTree(startNode), value: startNode.value.slice(0, start.offset) })\r\n      const linkIndex = first + parts.length\r\n      parts.push(link)\r\n      if (end.offset < endNode.value.length) parts.push({ ...cloneTree(endNode), value: endNode.value.slice(end.offset) })\r\n      parent.splice(first, last - first + 1, ...parts)\r\n      // layout-engine 将 valueList 展平到链接外层路径，offset 是所有子 run 的总长度。\r\n      this.range.setCaret({ path: [...parentPath, linkIndex], offset: text.length })\r\n      success = true\r\n      return true\r\n    })\r\n    return success\r\n  }\r\n\r\n  /**\r\n   * 插入分隔线。\r\n   * @param opts 分隔线选项，可以是对象或数组形式\r\n   */\r\n  insertSeparator(opts?: { lineType?: string; lineWidth?: number; dashArray?: number[]; color?: string } | any[]): void {\r\n    let normalized: { lineType?: string; lineWidth?: number; dashArray?: number[]; color?: string }\r\n    if (Array.isArray(opts)) {\r\n      const base: { lineType: string; lineWidth: number; dashArray: number[] } = { lineType: 'solid', lineWidth: 1, dashArray: [0, 0] }\r\n      if (opts.length === 3) {\r\n        base.lineType = opts[0]; base.lineWidth = opts[1]; base.dashArray = opts[2]\r\n      } else {\r\n        base.dashArray = opts\r\n      }\r\n      normalized = base\r\n    } else if (opts && typeof opts === 'object') {\r\n      normalized = {\r\n        lineType: (opts as any).type || (opts as any).lineType || 'solid',\r\n        lineWidth: (opts as any).width || (opts as any).lineWidth || 1,\r\n        dashArray: (opts as any).dashArray || [0, 0],\r\n        color: (opts as any).color\r\n      }\r\n    } else {\r\n      normalized = { lineType: 'solid', lineWidth: 1, dashArray: [0, 0] }\r\n    }\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n      const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n      const sep: IElement = { type: 'separator', value: '' } as unknown as IElement\r\n      const sepAny = sep as unknown as Record<string, unknown>\r\n      if (normalized.lineType != null) sepAny.lineType = normalized.lineType\r\n      if (normalized.lineWidth != null) sepAny.lineWidth = normalized.lineWidth\r\n      if (normalized.dashArray != null) sepAny.dashArray = normalized.dashArray\r\n      if (normalized.color != null) sepAny.color = normalized.color\r\n      parent.splice(idx, 0, sep)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 插入换行符 */\r\n  lineBreak(): void {\r\n    this.insertElementList([{ type: 'text', value: '\\n' } as IElement])\r\n  }\r\n\r\n  /** 插入分栏符 */\r\n  columnBreak(): void {\r\n    this.insertElementList([{ type: 'text', value: '\\n' } as IElement])\r\n  }\r\n\r\n  /** 通过分节命令在正文光标处插入连续分节符。 */\r\n  sectionBreakContinuous(): void { this.sectionBreak('continuous') }\r\n\r\n  /** 分节标记描述下一节的开始方式，sections 保存各节自己的设置。 */\r\n  sectionBreak(breakType: 'nextPage' | 'continuous' | 'evenPage' | 'oddPage'): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this.draw.getZone() !== 'main') throw new Error('分节符只能插入正文')\r\n    const ordered = this.range.getOrdered()\r\n    const positions = ordered ? [ordered.start, ordered.end] : [this.range.getFocus()]\r\n    if (positions.some(pos => pos?.path.includes('trList'))) throw new Error('暂不支持在表格单元格内插入分节符，请将光标移到表格前后的正文段落')\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const path = this.insertBlockAtCaret(doc, { type: 'pageBreak', value: breakType })\r\n      if (!path) return false\r\n      const index = Number(path[0])\r\n      if (!doc.sections) {\r\n        const options = this.draw.getOptions()\r\n        doc.sections = [{ pageWidth: doc.pageWidth ?? Number(options.pageWidth), pageHeight: doc.pageHeight ?? Number(options.pageHeight),\r\n          margins: [...(doc.margins ?? options.pageMargins as [number, number, number, number])],\r\n          paperDirection: doc.paperDirection, columnCount: doc.columnCount ?? 1, columnGap: doc.columnGap ?? 20, breakType: 'nextPage' }]\r\n        const parts = doc.headerFooterParts ??= {}\r\n        for (const zone of ['header', 'footer'] as const) {\r\n          const elements = doc[zone] ?? doc.contentZones?.[zone]\r\n          if (elements?.length) {\r\n            const id = `section-${zone}-${Date.now()}`\r\n            parts[id] = cloneTree(elements)\r\n            doc.sections[0][zone === 'header' ? 'headers' : 'footers'] = { default: id }\r\n          }\r\n        }\r\n      }\r\n      const sectionIndex = doc.elements.slice(0, index).filter(el => el.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(el.value)).length\r\n      const next = cloneTree(doc.sections[sectionIndex])\r\n      next.breakType = breakType\r\n      doc.sections.splice(sectionIndex + 1, 0, next)\r\n      if (!doc.elements[index + 1] || doc.elements[index + 1].type === 'pageBreak') doc.elements.splice(index + 1, 0, { type: 'text', value: '' })\r\n      const following = doc.elements[index + 1]\r\n      this.range.setCaret({ path: following.type === 'title' || following.type === 'list' ? [index + 1, 'valueList', 0] : [index + 1], offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /* -------------------- 内容读写 / 目录 -------------------- */\r\n\r\n  /**\r\n   * 获取当前活动文档的全部元素。\r\n   * @returns 文档元素数组\r\n   */\r\n  getValue(): IDocxDocumentMeta {\r\n    return cloneTree(this.draw.getDocument())\r\n  }\r\n\r\n  /**\r\n   * 完整替换文档内容，并重置编辑区域到 main。\r\n   * @param payload 文档内容，包含 main 及可选的 header/footer/comments\r\n   */\r\n  setValue(payload: Omit<Partial<IDocxDocumentMeta>, 'comments'> & { main?: IElement[]; comments?: unknown[] }): void {\r\n    const { main, ...document } = payload\r\n    const elements = main ?? document.elements\r\n    if (!Array.isArray(elements)) throw new TypeError('文档 elements/main 必须为数组')\r\n    if (document.sections !== undefined && !Array.isArray(document.sections)) {\r\n      throw new TypeError('旧 sections 内容区必须显式迁移到 contentZones')\r\n    }\r\n    this.replaceDocument({\r\n      ...document,\r\n      success: true,\r\n      elements,\r\n      comments: payload.comments as IDocxDocumentMeta['comments']\r\n    })\r\n\r\n  }\r\n\r\n  /**\r\n   * 统计文档字数（所有 text run 的字符数之和）。\r\n   * @returns 字数数值\r\n   */\r\n  getWordCount(): number {\r\n    const doc = this.draw.getActiveDocument()\r\n    let count = 0\r\n    walkTree(doc.elements, (node) => {\r\n      if (node.type === 'text') count += (node as ITextElement).value.length\r\n    })\r\n    return count\r\n  }\r\n\r\n  /**\r\n   * 获取文档目录（基于标题元素）。\r\n   * @returns 目录项数组，每项包含 id/level/name\r\n   */\r\n  getToc(): { id: string; level: number; name: string }[] {\r\n    const doc = this.draw.getActiveDocument()\r\n    const catalog: { id: string; level: number; name: string }[] = []\r\n    const levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'title') {\r\n        const t = node as ITitleElement\r\n        const name = (t.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\r\n        catalog.push({ id: JSON.stringify(ctx.path), level: levelMap[t.level] ?? 1, name })\r\n      }\r\n    })\r\n    return catalog\r\n  }\r\n\r\n  /**\r\n   * 定位到指定目录项：滚动到对应标题位置并设置光标。\r\n   * @param id 目录项 ID（序列化的路径字符串）\r\n   */\r\n  locationToc(id: string): void {\r\n    try {\r\n      const path = JSON.parse(id) as Path\r\n      const layout = this.draw.getLayout()\r\n      if (layout) {\r\n        for (const page of layout.pages) {\r\n          for (const b of page.blocks) {\r\n            if (b.kind !== 'paragraph') continue\r\n            const blockPath = b.parentPath.concat(b.startIndex)\r\n            if (blockPath.length === path.length && blockPath.every((v, i) => v === path[i])) {\r\n              const scroller = this.draw.getScroller()\r\n              const scrollContainer = scroller.parentElement as HTMLDivElement\r\n              const absY = page.contentRect.y + b.rect.y\r\n              scrollContainer.scrollTop = Math.max(0, absY - scrollContainer.clientHeight / 2)\r\n              this.range.setCaret({ path, offset: 0 })\r\n              return\r\n            }\r\n          }\r\n        }\r\n      }\r\n      this.range.setCaret({ path, offset: 0 })\r\n    } catch {\r\n      // ignore invalid catalog id\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置光标位置。\r\n   * @param path 光标路径\r\n   * @param offset 偏移量\r\n   */\r\n  setCaret(path: Path, offset: number): void {\r\n    this.range.setCaret({ path: path.slice() as Path, offset })\r\n  }\r\n\r\n  /**\r\n   * 基于布局分页生成自动目录结果（按层级过滤的三组目录）。\r\n   * @returns 包含 toc1/toc2/toc3 的自动目录结果\r\n   */\r\n  getAutoToc(): IAutoTocResult {\r\n    const layout = this.draw.getLayout()\r\n    const empty: IAutoTocResult = { toc1: [], toc2: [], toc3: [] }\r\n    if (!layout) return empty\r\n\r\n    const levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\r\n    const all: IAutoTocItem[] = []\r\n    const seen = new Set<string>()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageNo = page.index + 1\r\n      for (const b of page.blocks) {\r\n        if (b.kind !== 'paragraph' || b.paragraphKind !== 'title' || !b.block) continue\r\n        const titleEl = b.block as unknown as ITitleElement\r\n        const level = levelMap[titleEl.level] ?? 1\r\n        const name = (titleEl.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\r\n        const id = JSON.stringify(b.parentPath.concat(b.startIndex))\r\n        if (seen.has(id) || titleEl.extension?.toc) continue\r\n        seen.add(id)\r\n        // 从排版块中直接取编号文本（由排版引擎通过 listNumbering 计算得到）\r\n        const bulletText = (b as unknown as { bulletText?: string }).bulletText\r\n        const number = bulletText?.trim() || undefined\r\n\r\n        all.push({ id, level, name, pageNo, number })\r\n      }\r\n    }\r\n\r\n    return {\r\n      toc1: all.filter(i => i.level <= 1),\r\n      toc2: all.filter(i => i.level <= 2),\r\n      toc3: all.filter(i => i.level <= 3)\r\n    }\r\n  }\r\n\r\n  /** 在正文光标处插入 Office 自动目录模板（均收录三级标题）。 */\r\n  insertAutoToc(template: 1 | 2): void {\r\n    this.insertToc({ type: template })\r\n  }\r\n\r\n  /* -------------------- 页面 / 打印 -------------------- */\r\n\r\n  /**\r\n   * 设置纸张尺寸并发出页面尺寸变更事件。\r\n   * @param width 宽度\r\n   * @param height 高度\r\n   */\r\n  setPaperSize(width: number, height: number): void {\r\n    // Paper settings remain available in readonly mode.\r\n    if (this.getIsDisabled()) return\r\n    this.draw.setPageSize(width, height)\r\n    this.listener?.emit('pageSizeChange', { width, height })\r\n    this.listener?.emit('contentChange')\r\n  }\r\n\r\n  /**\r\n   * 设置纸张方向（纵向/横向），自动调整宽高。\r\n   * @param direction 方向：'vertical' | 'horizontal'\r\n   */\r\n  setPaperDirection(direction: 'vertical' | 'horizontal'): void {\r\n    const opts = this.draw.getOptions()\r\n    const doc = this.draw.getDocument()\r\n    const section = doc.sections?.[0]\r\n    const w = Number(section?.pageWidth ?? doc.pageWidth ?? opts.pageWidth ?? 794)\r\n    const h = Number(section?.pageHeight ?? doc.pageHeight ?? opts.pageHeight ?? 1123)\r\n    if (direction === 'horizontal') {\r\n      this.setPaperSize(Math.max(w, h), Math.min(w, h))\r\n    } else {\r\n      this.setPaperSize(Math.min(w, h), Math.max(w, h))\r\n    }\r\n  }\r\n\r\n  /** 放大页面缩放（步进 0.1，上限 3）。 */\r\n  pageScaleAdd(): void {\r\n    const opts = this.draw.getOptions()\r\n    const scale = Math.min(3, Number(opts.scale ?? 1) + 0.1)\r\n    this.draw.setScale(scale)\r\n    this.listener?.emit('pageScaleChange', scale)\r\n  }\r\n\r\n  /** 缩小页面缩放（步进 0.1，下限 0.5）。 */\r\n  pageScaleMinus(): void {\r\n    const opts = this.draw.getOptions()\r\n    const scale = Math.max(0.5, Number(opts.scale ?? 1) - 0.1)\r\n    this.draw.setScale(scale)\r\n    this.listener?.emit('pageScaleChange', scale)\r\n  }\r\n\r\n  /**\r\n   * 获取纸张高度（含缩放）。\r\n   * @returns 纸张高度数值\r\n   */\r\n  getPaperHeight(): number {\r\n    const opts = this.draw.getOptions()\r\n    return Number(opts.pageHeight ?? 1123) * Number(opts.scale ?? 1)\r\n  }\r\n\r\n  /**\r\n   * 获取编辑器选项。\r\n   * @returns 当前编辑器配置选项\r\n   */\r\n  getOptions(): IEditorOption {\r\n    return this.draw.getOptions() as IEditorOption\r\n  }\r\n\r\n  /**\r\n   * 设置页面模式。\r\n   * @param mode 页面模式字符串\r\n   */\r\n  setPageMode(mode: string): void {\r\n    this.draw.updateOptions({ pageMode: mode as 'paging' | 'continuity' })\r\n  }\r\n\r\n  /**\r\n   * 设置页面缩放比例。\r\n   * @param scale 缩放比例\r\n   */\r\n  setPageScale(scale: number): void {\r\n    this.draw.setScale(scale)\r\n    this.listener?.emit('pageScaleChange', scale)\r\n  }\r\n\r\n  /** 恢复默认缩放比例 */\r\n  setPageScaleRecovery(): void {\r\n    this.draw.setScale(1)\r\n    this.listener?.emit('pageScaleChange', 1)\r\n  }\r\n\r\n  /**\r\n   * 设置分栏数。\r\n   * @param value 分栏数量\r\n   */\r\n  setColumns(value: number): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (![1, 2, 3].includes(value)) throw new RangeError('仅支持一栏、二栏或三栏')\r\n    if (this.draw.getZone() !== 'main') throw new Error('分栏只能应用于正文')\r\n    const focus = this.range.getFocus()\r\n    if (focus?.path.includes('trList')) throw new Error('暂不支持在表格单元格内设置分栏，请将光标移到正文段落')\r\n    this.execute(doc => {\r\n      const index = Number(focus?.path[0] ?? 0)\r\n      const sectionIndex = doc.elements.slice(0, index).filter(el => el.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(el.value)).length\r\n      const section = doc.sections?.[sectionIndex]\r\n      if (section) {\r\n        section.columnCount = value\r\n        section.columnGap ??= doc.columnGap ?? 20\r\n      } else {\r\n        doc.columnCount = value\r\n        doc.columnGap ??= 20\r\n      }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 批量更新编辑器选项。\r\n   * @param patch 选项补丁对象\r\n   */\r\n  updateOptions(patch: Partial<IEditorOption>): void {\r\n    this.draw.updateOptions(patch)\r\n    if ('readonly' in patch || 'disabled' in patch) {\r\n      if (!this.getIsCanInput()) this._paintFmt = null\r\n      this.listener?.emit('formatChange', this.getRangeStyle())\r\n      this.listener?.emit('abilityChange', this.getAbility())\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置标尺可见性。\r\n   * @param visible 是否可见\r\n   */\r\n  setRulerVisible(visible: boolean): void {\r\n    this.draw.setRulerVisible(visible)\r\n  }\r\n\r\n  /**\r\n   * 设置页边距（四边数值取整并保证非负）。\r\n   * @param margins 边距数组，顺序为上、右、下、左\r\n   */\r\n  setPaperMargin(margins: number[]): void {\r\n    if (!this.getIsCanInput()) return\r\n    const m = [\r\n      Math.max(0, Math.round(margins[0] ?? 0)),\r\n      Math.max(0, Math.round(margins[1] ?? 0)),\r\n      Math.max(0, Math.round(margins[2] ?? 0)),\r\n      Math.max(0, Math.round(margins[3] ?? 0))\r\n    ] as [number, number, number, number]\r\n    this.draw.setPaperMargins(m)\r\n  }\r\n\r\n  /** 打印文档。 */\r\n  print(): void {\r\n    this.draw.print()\r\n  }\r\n\r\n  /**\r\n   * 获取所有页面缩略图。\r\n   * @returns 缩略图 data URL 数组\r\n   */\r\n  getPageThumbnails(): string[] {\r\n    return this.draw.getPageThumbnails()\r\n  }\r\n\r\n  /* -------------------- 水印 -------------------- */\r\n\r\n  /**\r\n   * 添加水印。\r\n   * @param payload 水印参数，可包含 data/content/color/opacity/size/font/repeat\r\n   */\r\n  addWatermark(payload: { data?: string; content?: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | any): void {\r\n    if (!this.getIsCanInput()) return\r\n    const p = payload || {}\r\n    this.draw.updateOptions({ watermark: {\r\n      data: p.data || p.content || '',\r\n      color: p.color,\r\n      opacity: p.opacity,\r\n      size: p.size,\r\n      font: p.font,\r\n      repeat: p.repeat,\r\n      gapX: p.gapX,\r\n      gapY: p.gapY\r\n    } } as Partial<IEditorOption>)\r\n  }\r\n\r\n  /** 删除水印 */\r\n  deleteWatermark(): void {\r\n    if (!this.getIsCanInput()) return\r\n    this.draw.updateOptions({ watermark: null } as Partial<IEditorOption>)\r\n  }\r\n\r\n  /**\r\n   * 设置系统级水印（全页面 DOM 覆盖层）。\r\n   * @param config 水印配置，null 表示移除\r\n   */\r\n  setSystemWatermark(config: { data: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | null): void {\r\n    this.draw.setSystemWatermark?.(config)\r\n  }\r\n\r\n  /** 删除系统级水印 */\r\n  deleteSystemWatermark(): void {\r\n    this.draw.setSystemWatermark?.(null)\r\n  }\r\n\r\n  /* -------------------- 查找替换 -------------------- */\r\n\r\n  /**\r\n   * 查找关键词，返回命中数，并选中第一个命中。\r\n   * @param keyword 搜索关键字\r\n   * @returns 包含命中数量 count 的结果对象\r\n   */\r\n  search(keyword: string): { count: number } {\r\n    this._searchHits = []\r\n    this._searchIdx = 0\r\n    if (!keyword) return { count: 0 }\r\n    const doc = this.draw.getActiveDocument()\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type !== 'text') return\r\n      const text = (node as ITextElement).value\r\n      let from = 0\r\n      while (true) {\r\n        const i = text.indexOf(keyword, from)\r\n        if (i === -1) break\r\n        this._searchHits.push({ path: ctx.path.slice() as Path, start: i, end: i + keyword.length })\r\n        from = i + keyword.length\r\n      }\r\n    })\r\n    this.captureSearch()\r\n    if (this._searchHits.length > 0) this._selectHit(0)\r\n    return { count: this._searchHits.length }\r\n  }\r\n\r\n  /**\r\n   * 替换当前命中为 text，跳到下一个命中。返回是否还有命中。opts.index 可指定替换第几个命中。\r\n   * @param text 替换文本\r\n   * @param opts 替换选项，可指定 index\r\n   * @returns 是否还存在后续命中\r\n   */\r\n  replace(text: string, opts?: { index?: number }): boolean {\r\n    if (!this.getIsCanInput()) return false\r\n    this.validateSearch()\r\n    if (opts?.index != null) {\r\n      if (!Number.isInteger(opts.index) || opts.index < 0 || opts.index >= this._searchHits.length) return false\r\n      this._searchIdx = opts.index\r\n    }\r\n    if (this._searchIdx >= this._searchHits.length) return false\r\n    const hit = this._searchHits[this._searchIdx]\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, hit.path)\r\n    if (node && node.type === 'text') {\r\n      const t = node as ITextElement\r\n      t.value = t.value.slice(0, hit.start) + text + t.value.slice(hit.end)\r\n      const delta = text.length - (hit.end - hit.start)\r\n      for (let i = this._searchIdx + 1; i < this._searchHits.length; i++) {\r\n        const h = this._searchHits[i]\r\n        if (isSamePath(h.path, hit.path)) { h.start += delta; h.end += delta }\r\n      }\r\n      this.captureSearch()\r\n      this._commit(doc)\r\n    }\r\n    this.captureSearch()\r\n    this._searchIdx++\r\n    if (this._searchIdx < this._searchHits.length) {\r\n      this._selectHit(this._searchIdx)\r\n      return true\r\n    }\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 定位到指定搜索结果索引。\r\n   * @param idx 搜索结果索引\r\n   */\r\n  locateSearchResult(idx: number): void {\r\n    this.validateSearch()\r\n    if (idx < 0 || idx >= this._searchHits.length) return\r\n    this._searchIdx = idx\r\n    this._selectHit(idx)\r\n  }\r\n\r\n  /**\r\n   * 获取当前搜索命中列表，每项包含匹配文本及前后上下文片段。\r\n   * @returns 匹配项数组，index 为命中序号，before/match/after 为上下文与匹配文本\r\n   */\r\n  getSearchMatches(): { index: number; before: string; match: string; after: string }[] {\r\n    this.validateSearch()\r\n    const doc = this.draw.getActiveDocument()\r\n    const PAD = 50\r\n    const result: { index: number; before: string; match: string; after: string }[] = []\r\n\r\n    // 预计算文本元素扁平列表，用于跨元素收集上下文\r\n    const textNodes: { path: Path; value: string }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        textNodes.push({ path: ctx.path.slice() as Path, value: (node as ITextElement).value })\r\n      }\r\n    })\r\n\r\n    for (let i = 0; i < this._searchHits.length; i++) {\r\n      const hit = this._searchHits[i]\r\n      const nodeIdx = textNodes.findIndex(t => isSamePath(t.path, hit.path))\r\n      if (nodeIdx === -1) continue\r\n      const value = textNodes[nodeIdx].value\r\n      const match = value.slice(hit.start, hit.end)\r\n\r\n      // 向前收集上下文（跨元素），不在开头加 …\r\n      let before = value.slice(Math.max(0, hit.start - PAD), hit.start)\r\n      let needBefore = PAD - before.length\r\n      let niBefore = nodeIdx - 1\r\n      while (needBefore > 0 && niBefore >= 0) {\r\n        const prevValue = textNodes[niBefore].value\r\n        const take = Math.min(needBefore, prevValue.length)\r\n        before = prevValue.slice(prevValue.length - take) + before\r\n        needBefore -= take\r\n        niBefore--\r\n      }\r\n\r\n      // 向后收集上下文（跨元素）\r\n      let after = value.slice(hit.end, Math.min(value.length, hit.end + PAD))\r\n      let needAfter = PAD - after.length\r\n      let niAfter = nodeIdx + 1\r\n      while (needAfter > 0 && niAfter < textNodes.length) {\r\n        const nextValue = textNodes[niAfter].value\r\n        const take = Math.min(needAfter, nextValue.length)\r\n        after += nextValue.slice(0, take)\r\n        needAfter -= take\r\n        niAfter++\r\n      }\r\n      if (niAfter < textNodes.length || hit.end + PAD < value.length) after += '…'\r\n\r\n      result.push({ index: i, before, match, after })\r\n    }\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 全部替换：先搜索 keyword，逐个替换为 replacement，返回替换计数。\r\n   * @param keyword 搜索关键字\r\n   * @param replacement 替换文本\r\n   * @returns 包含替换数量 count 的结果对象\r\n   */\r\n  replaceAll(keyword: string, replacement: string): { count: number } {\r\n    if (!this.getIsCanInput()) return { count: 0 }\r\n    this.search(keyword)\r\n    let count = 0\r\n    while (this._searchIdx < this._searchHits.length) {\r\n      this.replace(replacement)\r\n      count++\r\n    }\r\n    return { count }\r\n  }\r\n\r\n  /**\r\n   * 替换一处搜索结果并继续搜索，返回新的搜索结果。\r\n   * @param result 搜索结果定位信息\r\n   * @param replacement 替换文本\r\n   * @returns 包含新的命中数量 count 的结果对象\r\n   */\r\n  replaceOne(result: { resultIndex: number; keyword: string }, replacement: string): { count: number } {\r\n    if (!this.getIsCanInput()) return { count: 0 }\r\n    if (!result || !replacement) return { count: 0 }\r\n    this.replace(replacement, { index: result.resultIndex })\r\n    return this.search(result.keyword)\r\n  }\r\n\r\n  /**\r\n   * 选中指定索引的搜索命中区域。\r\n   * @param idx 搜索命中索引\r\n   */\r\n  private _selectHit(idx: number): void {\r\n    const hit = this._searchHits[idx]\r\n\r\n    if (!hit) return\r\n    this.range.setRange({\r\n      anchor: { path: hit.path, offset: hit.start },\r\n      focus: { path: hit.path, offset: hit.end }\r\n    })\r\n    this.draw.scrollPositionIntoView?.({ path: hit.path, offset: hit.start })\r\n  }\r\n\r\n  /* -------------------- 书签 -------------------- */\r\n\r\n  /**\r\n   * 获取所有书签。\r\n   * @returns 书签数组\r\n   */\r\n  getBookmarks(): IBookmark[] {\r\n    return this.draw.getDocument().bookmarks ?? []\r\n  }\r\n\r\n  /**\r\n   * 在当前选区添加书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  addBookmark(payload: { name: string }): void {\r\n    if (!this.getIsCanInput()) return\r\n    const range = this.range.getRange()\r\n    if (!range) return\r\n    const doc = this.draw.getDocument()\r\n    const bookmarks = doc.bookmarks ?? []\r\n    if (bookmarks.some(b => b.name === payload.name)) return\r\n    const collapsed = isSamePath(range.anchor.path, range.focus.path) && range.anchor.offset === range.focus.offset\r\n    bookmarks.push({ name: payload.name, range: cloneTree(range), collapsed })\r\n    doc.bookmarks = bookmarks\r\n    // 不可迁移：doc 来自 this.draw.getDocument() 而非 getActiveDocument()\r\n    this._commit(doc)\r\n  }\r\n\r\n  /**\r\n   * 删除指定书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  deleteBookmark(payload: { name: string }): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getDocument()\r\n    if (!doc.bookmarks) return\r\n    doc.bookmarks = doc.bookmarks.filter(b => b.name !== payload.name)\r\n    // 不可迁移：doc 来自 this.draw.getDocument() 而非 getActiveDocument()\r\n    this._commit(doc)\r\n  }\r\n\r\n  /**\r\n   * 跳转到指定书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  gotoBookmark(payload: { name: string }): void {\r\n    const doc = this.draw.getDocument()\r\n    const bookmark = doc.bookmarks?.find(b => b.name === payload.name)\r\n    if (!bookmark) return\r\n    const anchor = this.findVisiblePosNearby(doc.elements, bookmark.range.anchor) ?? bookmark.range.anchor\r\n    const focus = bookmark.collapsed\r\n      ? anchor\r\n      : this.findVisiblePosNearby(doc.elements, bookmark.range.focus) ?? bookmark.range.focus\r\n    this.range.setRange({ anchor, focus })\r\n    this.draw.scrollPositionIntoView?.(focus)\r\n  }\r\n\r\n  /**\r\n   * bookmarkMarker 是零宽 run，layout 中无 inline，locateCaret 找不到。\r\n   * 从 marker path 出发，在同一兄弟数组中找相邻的非零宽元素，返回其位置。\r\n   */\r\n  private findVisiblePosNearby(elements: IElement[], pos: IPosition): IPosition | null {\r\n    if (!getByPath(elements, pos.path)?.extension?.bookmarkMarker) return pos\r\n    const path = pos.path\r\n    if (path.length < 1) return null\r\n    const lastSeg = path[path.length - 1]\r\n    if (typeof lastSeg !== 'number') return null\r\n    const parentPath = path.slice(0, -1)\r\n    const parent = parentPath.length === 0 ? elements : getByPath(elements, parentPath as Path)\r\n    if (!Array.isArray(parent)) return null\r\n    const isVisible = (el: unknown): boolean => {\r\n      if ((el as IElement)?.extension?.bookmarkMarker) return false\r\n      const v = String((el as { value?: string })?.value ?? '')\r\n      return !!v && !/^[\\u200B\\uFEFF]+$/.test(v)\r\n    }\r\n    for (let i = lastSeg + 1; i < parent.length; i++) {\r\n      if (isVisible(parent[i])) return { path: [...parentPath, i] as Path, offset: 0 }\r\n    }\r\n    for (let i = lastSeg - 1; i >= 0; i--) {\r\n      if (isVisible(parent[i])) {\r\n        const node = parent[i] as IElement\r\n        return { path: [...parentPath, i] as Path, offset: node.type === 'text' ? node.value.length : 1 }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /* -------------------- 目录 -------------------- */\r\n\r\n  /** 读取元素扩展中的目录域元数据，未标记目录域时返回 undefined。 */\r\n  private tocMetadata(element?: IElement): { id: string; template: 1 | 2; maxLevel: number; role: 'heading' | 'entry' | 'placeholder'; level?: number } | undefined {\r\n    return element?.extension?.toc as ReturnType<CommandAdapt['tocMetadata']>\r\n  }\r\n\r\n  /** 查找光标所在目录组，否则取首个目录组，返回起止索引（结束不含）及元数据；无目录时返回 null。 */\r\n  private tocGroup(elements: IElement[]) {\r\n    const focus = this.range.getFocus()\r\n    const index = focus?.path.length === 1 ? Number(focus.path[0]) : -1\r\n    const selected = this.tocMetadata(elements[index])\r\n    const start = selected\r\n      ? elements.findIndex(el => this.tocMetadata(el)?.id === selected.id)\r\n      : elements.findIndex(el => !!this.tocMetadata(el))\r\n    if (start < 0) return null\r\n    const metadata = this.tocMetadata(elements[start])!\r\n    let end = start + 1\r\n    while (end < elements.length && this.tocMetadata(elements[end])?.id === metadata.id) end++\r\n    return { start, end, metadata }\r\n  }\r\n\r\n  /** 根据布局目录和最大标题级别生成带目录域标记的标题、条目及段落分隔，无条目时生成提示文本。 */\r\n  private buildToc(id: string, template: 1 | 2, maxLevel: number): IElement[] {\r\n    const elements: IElement[] = []\r\n    const append = (value: string, role: 'heading' | 'entry' | 'placeholder', level?: number) => {\r\n      const run: ITextElement = {\r\n        type: 'text', value, size: role === 'heading' ? 21 : 14,\r\n        bold: role === 'heading', rowFlex: role === 'heading' ? 'center' : 'left',\r\n        paragraphIndentLeft: role === 'entry' ? ((level ?? 1) - 1) * 21 : 0,\r\n        paragraphSpacingAfter: role === 'heading' ? 8 : 0,\r\n        extension: { toc: { id, template, maxLevel, role, ...(level ? { level } : {}) } }\r\n      }\r\n      elements.push(run, { ...cloneTree(run), value: '\\u200B' })\r\n    }\r\n    append('目录', 'heading')\r\n    const items = this.getAutoToc().toc3.filter(item => item.level <= maxLevel)\r\n    for (const item of items) {\r\n      const name = item.name.replace(/[\\u200B\\uFEFF\\t\\r\\n]/g, '').trim()\r\n      append(`${item.number ? item.number + ' ' : ''}${name}\\t${item.pageNo}`, 'entry', item.level)\r\n    }\r\n    if (!items.length) append('未找到目录项。请先为正文应用标题样式，再更新目录。', 'placeholder')\r\n    return elements\r\n  }\r\n\r\n  /** 在最终布局上刷新页码，所有重排结果合并为同一条历史记录。 */\r\n  private refreshToc(doc: IDocxDocumentMeta, start: number, count: number, id: string, template: 1 | 2, maxLevel: number): void {\r\n    for (let pass = 0; pass < 8; pass++) {\r\n      this.draw.applyActiveDocument(doc)\r\n      const next = this.buildToc(id, template, maxLevel)\r\n      const previous = doc.elements.slice(start, start + count)\r\n      if (next.length === previous.length && next.every((el, i) => el.value === previous[i].value)) break\r\n      this.spliceBodyWithBookmarks(doc, start, count, next)\r\n      count = next.length\r\n    }\r\n    this.range.setCaret({ path: [start], offset: 0 })\r\n  }\r\n\r\n  /** 插入普通文本目录，extension.toc 为前后端共享的目录域协议。 */\r\n  insertToc(payload: { type?: 1 | 2; mode?: string; [key: string]: unknown }): void {\r\n    if (payload.mode === 'update') { this.updateToc(); return }\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      // 在选区起点插入，保留选中的正文；标题/列表内部提升到整个正文块之前。\r\n      const pos = this.range.getOrdered()?.start ?? this.range.getFocus()\r\n      if (pos?.path.includes('trList')) throw new Error('暂不支持在表格单元格内插入目录，请将光标移到表格前后的正文段落')\r\n      let index = pos ? Number(pos.path[0]) : doc.elements.length\r\n      const node = doc.elements[index]\r\n      if (this.tocMetadata(node)) return false\r\n      if (pos && pos.path.length > 1 && node?.type !== 'title' && node?.type !== 'list') return false\r\n      if (node?.type === 'text' && pos) {\r\n        const offset = Math.max(0, Math.min(pos.offset, node.value.length))\r\n        if (offset > 0 && !/^[\\u200B\\uFEFF]*$/.test(node.value.slice(0, offset))) {\r\n          if (offset < node.value.length) {\r\n            doc.elements.splice(index + 1, 0, { ...cloneTree(node), value: node.value.slice(offset) })\r\n            node.value = node.value.slice(0, offset)\r\n            this.mapBookmarksAfterSplit(doc, [index], offset)\r\n          }\r\n          index++\r\n        }\r\n      } else if (node?.type === 'pageBreak') index++\r\n      const template = payload.type === 2 ? 2 : 1\r\n      const maxLevel = payload.maxLevel === 1 || payload.maxLevel === 2 || payload.maxLevel === 3 ? payload.maxLevel : 3\r\n      const id = `toc-${Date.now()}-${++this._revisionSequence}`\r\n      const elements = this.buildToc(id, template, maxLevel)\r\n      const isPageStart = (element?: IElement) => element?.type === 'pageBreak' && element.value !== 'continuous'\r\n      // 页首可能有编辑器的空文本/段落标记，不为这些占位内容再产生一张空白页。\r\n      let boundary = index\r\n      while (boundary > 0 && doc.elements[boundary - 1].type === 'text' && /^[\\u200B\\uFEFF]*$/.test(doc.elements[boundary - 1].value) && !this.tocMetadata(doc.elements[boundary - 1])) boundary--\r\n      if (boundary === 0 || isPageStart(doc.elements[boundary - 1])) index = boundary\r\n      // 单独的扩展标记不属于 extension.toc 域，Java 仍按普通 manual 分页符导出。\r\n      const pageBreak = (): IElement => ({ type: 'pageBreak', value: 'manual', extension: { tocPageBreak: id } })\r\n      if (index > 0 && !isPageStart(doc.elements[index - 1])) this.spliceBodyWithBookmarks(doc, index++, 0, [pageBreak()])\r\n      this.spliceBodyWithBookmarks(doc, index, 0, elements)\r\n      const end = index + elements.length\r\n      if (!isPageStart(doc.elements[end])) this.spliceBodyWithBookmarks(doc, end, 0, [pageBreak()])\r\n      if (end + 1 === doc.elements.length) doc.elements.push({ type: 'text', value: '' })\r\n      this.refreshToc(doc, index, elements.length, id, template, maxLevel)\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 更新选中目录；光标在正文时更新第一个目录。 */\r\n  updateToc(): void {\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      const group = this.tocGroup(doc.elements)\r\n      if (!group) return false\r\n      const { id, template, maxLevel } = group.metadata\r\n      const elements = this.buildToc(id, template, maxLevel)\r\n      this.spliceBodyWithBookmarks(doc, group.start, group.end - group.start, elements)\r\n      this.refreshToc(doc, group.start, elements.length, id, template, maxLevel)\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 删除选中目录组，保留正文及其他目录。 */\r\n  removeToc(): void {\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      const group = this.tocGroup(doc.elements)\r\n      if (!group) return false\r\n      const ownedBreak = (element?: IElement) => element?.type === 'pageBreak' && element.value === 'manual' && element.extension?.tocPageBreak === group.metadata.id\r\n      const start = ownedBreak(doc.elements[group.start - 1]) ? group.start - 1 : group.start\r\n      const end = ownedBreak(doc.elements[group.end]) ? group.end + 1 : group.end\r\n      this.spliceBodyWithBookmarks(doc, start, end - start)\r\n      this.range.setCaret({ path: [Math.min(start, doc.elements.length - 1)], offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /* -------------------- 撤销 / 重做 -------------------- */\r\n\r\n  /** 撤销上一步操作，恢复历史快照并通知选区样式与能力变更。 */\r\n  undo(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!this._historyManager) return\r\n    const current: HistorySnapshot = {\r\n      doc: cloneTree(this.draw.getDocument()),\r\n      range: this.range.getRange(),\r\n      zone: this.draw.getZone()\r\n    }\r\n    const prev = this._historyManager.undo(current)\r\n    if (prev) {\r\n      this.range.clear()\r\n      this.draw.setZone(prev.zone ?? 'main')\r\n      this.draw.setDocument(cloneTree(prev.doc))\r\n      if (prev.range) this.range.setRange(cloneTree(prev.range))\r\n      else this.range.clear()\r\n      this.listener?.emit('documentSet', this.draw.getDocument())\r\n      this.listener?.emit('contentChange')\r\n    }\r\n    // 撤销后通知：选区样式变更 + 能力变更（canUndo/canRedo 可能变化）\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /** 重做下一步操作，恢复历史快照并通知选区样式与能力变更。 */\r\n  redo(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!this._historyManager) return\r\n    const current: HistorySnapshot = {\r\n      doc: cloneTree(this.draw.getDocument()),\r\n      range: this.range.getRange(),\r\n      zone: this.draw.getZone()\r\n    }\r\n    const next = this._historyManager.redo(current)\r\n    if (next) {\r\n      this.range.clear()\r\n      this.draw.setZone(next.zone ?? 'main')\r\n      this.draw.setDocument(cloneTree(next.doc))\r\n      if (next.range) this.range.setRange(cloneTree(next.range))\r\n      else this.range.clear()\r\n      this.listener?.emit('documentSet', this.draw.getDocument())\r\n      this.listener?.emit('contentChange')\r\n    }\r\n    // 重做后通知：选区样式变更 + 能力变更\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /* -------------------- 区域切换 -------------------- */\r\n\r\n  /**\r\n   * 切换编辑区域。切换到页眉/页脚时，将光标定位到对应区域的起始文本位置；\r\n   * 切回正文时清空选区，由后续点击/键盘事件重新定位。\r\n   * @param zone 区域：'main' | 'header' | 'footer'\r\n   */\r\n  setZone(zone: Zone): void {\r\n    this.draw.setZoneWithCaret(zone)\r\n  }\r\n\r\n  /** 清除页眉内容并回到正文 */\r\n  clearHeader(): void {\r\n    if (!this.getIsCanInput()) return\r\n    this.setZone('header')\r\n    this.selectAll()\r\n    this.deleteBackward()\r\n    this.setZone('main')\r\n  }\r\n\r\n  /** 清除页脚内容并回到正文 */\r\n  clearFooter(): void {\r\n    if (!this.getIsCanInput()) return\r\n    this.setZone('footer')\r\n    this.selectAll()\r\n    this.deleteBackward()\r\n    this.setZone('main')\r\n  }\r\n\r\n  /**\r\n   * 设置页码配置（与现有配置合并）。\r\n   * @param payload 页码配置对象\r\n   */\r\n  setPageNumber(payload: Record<string, unknown>): void {\r\n    if (!this.getIsCanInput()) return\r\n    const currentOptions = this.draw.getOptions() || {}\r\n    this.draw.updateOptions({\r\n      ...currentOptions,\r\n      pageNumber: {\r\n        ...((currentOptions as any).pageNumber || {}),\r\n        ...payload\r\n      }\r\n    } as Partial<IEditorOption>)\r\n  }\r\n\r\n  /**\r\n\r\n   * 获取当前编辑区域。\r\n   * @returns 区域：'main' | 'header' | 'footer'\r\n   */\r\n  getZone(): Zone {\r\n    return this.draw.getZone()\r\n  }\r\n\r\n  /* -------------------- 选区 / 全选 -------------------- */\r\n\r\n  /** 选中当前活动文档的全部内容。 */\r\n  selectAll(): void {\r\n    const doc = this.draw.getActiveDocument()\r\n    const runs: { path: Path }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        runs.push({ path: ctx.path.slice() as Path })\r\n      }\r\n    })\r\n    if (runs.length === 0) return\r\n    const first = runs[0]\r\n    const last = runs[runs.length - 1]\r\n    const lastNode = getByPath(doc.elements, last.path) as ITextElement | null\r\n    const endOffset = lastNode ? lastNode.value.length : 0\r\n    this.range.setRange({\r\n      anchor: { path: first.path, offset: 0 },\r\n      focus: { path: last.path, offset: endOffset }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 按起止 run 索引设置选区范围。\r\n   * @param startIndex 起始 run 索引\r\n   * @param endIndex 结束 run 索引\r\n   */\r\n  setRange(startIndex: number, endIndex: number): void {\r\n    const doc = this.draw.getActiveDocument()\r\n    const runs: { path: Path }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        runs.push({ path: ctx.path.slice() as Path })\r\n      }\r\n    })\r\n    if (runs.length === 0) return\r\n    const startIdx = Math.max(0, Math.min(startIndex, runs.length - 1))\r\n    const endIdx = Math.max(0, Math.min(endIndex, runs.length - 1))\r\n    const startPath = runs[startIdx].path\r\n    const endPath = runs[endIdx].path\r\n    const endNode = getByPath(doc.elements, endPath) as ITextElement | null\r\n    const endOffset = endNode ? endNode.value.length : 0\r\n    this.range.setRange({\r\n      anchor: { path: startPath, offset: 0 },\r\n      focus: { path: endPath, offset: endOffset }\r\n    })\r\n  }\r\n\r\n  /* -------------------- 插入元素列表 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入元素列表，若存在选区则先删除选区。\r\n   * @param elements 待插入的元素数组\r\n   */\r\n  insertElementList(elements: IElement[]): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!elements || elements.length === 0) return\r\n    if (elements.some(element => this.isSectionBoundary(element))) {\r\n      throw new TypeError('粘贴分节符必须通过 pasteFragment 同时传入 sections')\r\n    }\r\n    this.deleteSelection()\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n    const inserted = cloneTree(elements)\r\n    this.remapParagraphIdentities(inserted, doc.elements)\r\n    for (const cloned of inserted) {\r\n      if (cloned.type === 'text') {\r\n        const textEl = cloned as ITextElement\r\n        const node = getByPath(doc.elements, pos.path)\r\n        if (node && node.type === 'text') {\r\n          const t = node as ITextElement\r\n          const before = t.value.slice(0, pos.offset)\r\n          const after = t.value.slice(pos.offset)\r\n          t.value = before + textEl.value + after\r\n          pos.offset += textEl.value.length\r\n        } else {\r\n          const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n          if (parent) {\r\n            const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n            parent.splice(idx, 0, cloned)\r\n            pos.path = [...pos.path.slice(0, -1), idx] as Path\r\n            pos.offset = 0\r\n          }\r\n        }\r\n      } else {\r\n        const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n        if (parent) {\r\n          const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n          parent.splice(idx, 0, cloned)\r\n          pos.path = [...pos.path.slice(0, -1), idx] as Path\r\n          pos.offset = 0\r\n        }\r\n      }\r\n    }\r\n    this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset })\r\n    // 不可迁移：前置 deleteSelection() 可能已 commit\r\n    this._commit(doc, 'text')\r\n  }\r\n\r\n  /** 为复制元素重新分配不冲突的段落 ID，并同步图片锚点；未复制的锚定段落改为脱离引用。 */\r\n  private remapParagraphIdentities(elements: IElement[], existing: IElement[]): void {\r\n    const used = new Set<string>()\r\n    const ids = new Map<string, string>()\r\n    walkTree(existing, node => { if (node.sourceParagraphId) used.add(node.sourceParagraphId) })\r\n    walkTree(elements, node => {\r\n      const id = node.sourceParagraphId\r\n      if (!id || ids.has(id)) return\r\n      let next = `${id}-copy`, suffix = 1\r\n      while (used.has(next)) next = `${id}-copy${suffix++}`\r\n      used.add(next)\r\n      ids.set(id, next)\r\n    })\r\n    walkTree(elements, node => {\r\n      if (node.sourceParagraphId) node.sourceParagraphId = ids.get(node.sourceParagraphId)!\r\n      const geometry = (node as IImageElement).imageLayout\r\n      if (geometry?.anchorParagraphId) {\r\n        // A drawing copied without its paragraph must not bind to the original.\r\n        geometry.anchorParagraphId = ids.get(geometry.anchorParagraphId) ?? `${geometry.anchorParagraphId}-detached`\r\n      }\r\n    })\r\n  }\r\n\r\n  /** 判断元素是否为连续、下一页、偶数页或奇数页分节符，不包含普通分页符。 */\r\n  private isSectionBoundary(element: IElement): boolean {\r\n    return element.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(element.value)\r\n  }\r\n\r\n  /** 按正文闭区间内的分节符移除对应节配置，保留后续节格式并补齐继承的页眉页脚引用。 */\r\n  private removeSectionBoundaries(doc: IDocxDocumentMeta, start: number, end: number): void {\r\n    if (!doc.sections || this.draw.getZone() !== 'main') return\r\n    const index = doc.elements.slice(0, start).filter(element => this.isSectionBoundary(element)).length\r\n    const count = doc.elements.slice(start, end + 1).filter(element => this.isSectionBoundary(element)).length\r\n    // Removing a section break joins into the following section's formatting.\r\n    if (count) {\r\n      const survivor = doc.sections[index + count]\r\n      for (const key of ['headers', 'footers'] as const) {\r\n        survivor[key] = Object.assign({}, ...doc.sections.slice(0, index + count + 1).map(section => section[key]))\r\n      }\r\n      doc.sections.splice(index, count)\r\n    }\r\n  }\r\n\r\n  /** 克隆顶层文本选区及其涉及的节配置、页眉页脚部件，裁剪边界文本；不支持的选区返回 null。 */\r\n  copyFragment(): Partial<IDocxDocumentMeta> | null {\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered || this.range.isCollapsed() || ordered.start.path.length !== 1 || ordered.end.path.length !== 1) return null\r\n    const doc = this.draw.getActiveDocument()\r\n    const first = Number(ordered.start.path[0]), last = Number(ordered.end.path[0])\r\n    const elements = cloneTree(doc.elements.slice(first, last + 1))\r\n    if (elements[0]?.type !== 'text' || elements[elements.length - 1]?.type !== 'text') return null\r\n    if (first === last) elements[0].value = elements[0].value.slice(ordered.start.offset, ordered.end.offset)\r\n    else {\r\n      elements[0].value = elements[0].value.slice(ordered.start.offset)\r\n      elements[elements.length - 1].value = elements[elements.length - 1].value.slice(0, ordered.end.offset)\r\n    }\r\n    const index = doc.elements.slice(0, first).filter(element => this.isSectionBoundary(element)).length\r\n    const count = elements.filter(element => this.isSectionBoundary(element)).length\r\n    const sections = count ? cloneTree(doc.sections?.slice(index, index + count + 1)) : undefined\r\n    if (sections?.length) for (const key of ['headers', 'footers'] as const) {\r\n      sections[0][key] = Object.assign({}, ...doc.sections!.slice(0, index + 1).map(section => section[key]))\r\n    }\r\n    return { elements, sections, headerFooterParts: count ? cloneTree(doc.headerFooterParts) : undefined }\r\n  }\r\n\r\n  /** 在正文顶层粘贴文档片段并替换选区，重映射段落标识、合并节配置及页眉页脚部件后提交。 */\r\n  pasteFragment(fragment: Partial<IDocxDocumentMeta>): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!fragment.elements?.length || this.draw.getZone() !== 'main') return\r\n    const boundaries = fragment.elements.filter(element => this.isSectionBoundary(element)).length\r\n    if (boundaries && fragment.sections?.length !== boundaries + 1) throw new TypeError('剪贴板 sections 与分节符数量不一致')\r\n    const focus = this.range.getFocus()\r\n    if (focus && focus.path.length !== 1) return\r\n    this.deleteSelection(false)\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n    const index = Number(pos.path[0])\r\n    const node = doc.elements[index]\r\n    const elements = cloneTree(fragment.elements)\r\n    this.remapParagraphIdentities(elements, doc.elements)\r\n    const sectionIndex = doc.elements.slice(0, index).filter(element => this.isSectionBoundary(element)).length\r\n    if (boundaries) {\r\n      if (!doc.sections?.[sectionIndex]) throw new TypeError('目标文档缺少 sections')\r\n      const sections = cloneTree(fragment.sections!)\r\n      const parts = cloneTree(fragment.headerFooterParts ?? {})\r\n      doc.headerFooterParts ??= {}\r\n      for (const [id, content] of Object.entries(parts)) {\r\n        let target = id\r\n        let suffix = 1\r\n        while (doc.headerFooterParts[target] && JSON.stringify(doc.headerFooterParts[target]) !== JSON.stringify(content)) {\r\n          target = id.replace(/\\.xml$/, '') + `-paste${suffix++}.xml`\r\n        }\r\n        doc.headerFooterParts[target] = content\r\n        for (const section of sections) for (const refs of [section.headers, section.footers]) {\r\n          if (refs) for (const key of Object.keys(refs) as (keyof typeof refs)[]) if (refs[key] === id) refs[key] = target\r\n        }\r\n      }\r\n      doc.sections.splice(sectionIndex, 0, ...sections.slice(0, boundaries))\r\n    }\r\n    const prefix = node?.type === 'text' ? [{ ...node, value: node.value.slice(0, pos.offset) }] : []\r\n    const suffix = node?.type === 'text' ? [{ ...node, value: node.value.slice(pos.offset) }] : []\r\n    doc.elements.splice(index, node?.type === 'text' ? 1 : 0, ...prefix, ...elements, ...suffix)\r\n    const caretIndex = index + prefix.length + elements.length - (suffix.length ? 0 : 1)\r\n    const caretNode = doc.elements[caretIndex]\r\n    this.range.setCaret({ path: [caretIndex], offset: suffix.length ? 0 : caretNode.type === 'text' ? caretNode.value.length : 0 })\r\n    this._commit(doc)\r\n  }\r\n\r\n  /* -------------------- 剪贴板 -------------------- */\r\n\r\n  /**\r\n   * 复制当前选区文本。\r\n   * @returns 选区纯文本\r\n   */\r\n  copy(): string {\r\n    return this.extractSelectionText()\r\n  }\r\n\r\n  /**\r\n   * 剪切当前选区文本并删除选区。\r\n   * @returns 选区纯文本\r\n   */\r\n  cut(): string {\r\n    const text = this.extractSelectionText()\r\n    this.deleteSelection()\r\n    return text\r\n  }\r\n\r\n  /**\r\n   * 粘贴文本（等同于插入文本）。\r\n   * @param text 待粘贴文本\r\n   */\r\n  paste(text: string): void {\r\n    this.insertText(text)\r\n  }\r\n\r\n  /**\r\n   * 粘贴纯文本（等同于插入文本）。\r\n   * @param text 待粘贴文本\r\n   */\r\n  pastePlain(text: string): void {\r\n    this.insertText(text)\r\n  }\r\n\r\n  /* -------------------- run 扩展样式 -------------------- */\r\n\r\n  /** 切换选区内 run 的上标样式（与下标互斥）。 */\r\n  setSuperscript(): void {\r\n    this.mutateRuns(run => {\r\n      const r = run as unknown as Record<string, unknown>\r\n      r.superscript = !r.superscript\r\n      if (r.superscript) r.subscript = false\r\n    }, 'superscript' as keyof ITextElement)\r\n  }\r\n\r\n  /** 切换选区内 run 的下标样式（与上标互斥）。 */\r\n  setSubscript(): void {\r\n    this.mutateRuns(run => {\r\n      const r = run as unknown as Record<string, unknown>\r\n      r.subscript = !r.subscript\r\n      if (r.subscript) r.superscript = false\r\n    }, 'subscript' as keyof ITextElement)\r\n  }\r\n\r\n  /**\r\n   * 设置选区内 run 的字符缩放比例。\r\n   * @param value 缩放比例\r\n   */\r\n  setCharacterScale(value: number): void {\r\n    this.mutateRuns(run => {\r\n      (run as unknown as Record<string, unknown>).characterScale = value\r\n    })\r\n  }\r\n\r\n  /** Normalize ruler positions to the layout engine's first-line/hanging model. */\r\n  setRulerIndent(first: number, left: number, right: number): void {\r\n    if (![first, left, right].every(Number.isFinite)) return\r\n    first = Math.max(0, first)\r\n    left = Math.max(0, left)\r\n    right = Math.max(0, right)\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const group = splitParagraphs(parent).find(g => cursorIdx >= g.start && cursorIdx < g.end)\r\n      if (!group) return false\r\n      const targets = group.block ? [group.block, ...group.runs] : group.runs\r\n      this.formatElements(targets, target => {\r\n        Object.assign(target, {\r\n          paragraphIndentLeft: left,\r\n          paragraphIndentRight: right,\r\n          paragraphFirstLineIndent: first - left,\r\n          indentHanging: undefined\r\n        })\r\n      })\r\n      return\r\n    })\r\n  }\r\n\r\n  /* -------------------- 段落首行缩进 -------------------- */\r\n\r\n  /**\r\n   * 设置当前段落的首行缩进。\r\n   * @param indentPx 缩进像素值\r\n   */\r\n  setParagraphFirstLineIndent(indentPx: number): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          (r as unknown as Record<string, unknown>).paragraphFirstLineIndent = indentPx\r\n          delete (r as unknown as Record<string, unknown>).indentHanging\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前段落的首行缩进值。\r\n   * @returns 首行缩进像素值\r\n   */\r\n  getFirstLineIndent(): number {\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return 0\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return 0\r\n    const cursorIdx = pos.path[pos.path.length - 1] as number\r\n    const groups = splitParagraphs(parent)\r\n    for (const g of groups) {\r\n      if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n      const target = g.block ?? g.runs[0]\r\n      if (!target) return 0\r\n      const attrs = target as unknown as Record<string, unknown>\r\n      return attrs.indentHanging != null ? -Number(attrs.indentHanging) : Number(attrs.paragraphFirstLineIndent ?? 0)\r\n    }\r\n    return 0\r\n  }\r\n\r\n  /**\r\n   * 按方向执行首行缩进步进（步长 20 像素，下限 0）。\r\n   * @param direction 方向：'add' | 'sub'\r\n   */\r\n  indentStep(direction: 'add' | 'sub'): void {\r\n    const step = 20\r\n    const current = this.getFirstLineIndent()\r\n    const next = direction === 'add' ? current + step : Math.max(0, current - step)\r\n    this.setParagraphFirstLineIndent(next)\r\n  }\r\n\r\n  /* -------------------- 段落属性通用读写 -------------------- */\r\n\r\n  /**\r\n   * 设置当前段落的指定属性值。\r\n   * @param key 属性名（如 paragraphIndentLeft）\r\n   * @param value 属性值\r\n   */\r\n  private setParagraphAttr(key: string, value: number): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          (r as unknown as Record<string, unknown>)[key] = value\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前段落的指定属性值。\r\n   * @param key 属性名\r\n   * @returns 属性数值\r\n   */\r\n  private getParagraphAttr(key: string): number {\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return 0\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return 0\r\n    const cursorIdx = pos.path[pos.path.length - 1] as number\r\n    const groups = splitParagraphs(parent)\r\n    for (const g of groups) {\r\n      if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n      const target = g.block ?? g.runs[0]\r\n      if (!target) return 0\r\n      return Number((target as unknown as Record<string, unknown>)[key] ?? 0)\r\n    }\r\n    return 0\r\n  }\r\n\r\n  /* -------------------- 左/右缩进 -------------------- */\r\n\r\n  /** 设置左缩进（px） */\r\n  setParagraphIndentLeft(px: number): void { this.setParagraphAttr('paragraphIndentLeft', px) }\r\n  /** 获取左缩进（px） */\r\n  getParagraphIndentLeft(): number { return this.getParagraphAttr('paragraphIndentLeft') }\r\n\r\n  /** 设置右缩进（px） */\r\n  setParagraphIndentRight(px: number): void { this.setParagraphAttr('paragraphIndentRight', px) }\r\n  /** 获取右缩进（px） */\r\n  getParagraphIndentRight(): number { return this.getParagraphAttr('paragraphIndentRight') }\r\n\r\n  /* -------------------- 段前/段后间距 -------------------- */\r\n\r\n  /** 设置段前间距（px） */\r\n  setParagraphSpacingBefore(px: number): void { this.setParagraphAttr('paragraphSpacingBefore', px) }\r\n  /** 获取段前间距（px） */\r\n  getParagraphSpacingBefore(): number { return this.getParagraphAttr('paragraphSpacingBefore') }\r\n\r\n  /** 设置段后间距（px） */\r\n  setParagraphSpacingAfter(px: number): void { this.setParagraphAttr('paragraphSpacingAfter', px) }\r\n  /** 获取段后间距（px） */\r\n  getParagraphSpacingAfter(): number { return this.getParagraphAttr('paragraphSpacingAfter') }\r\n\r\n  /**\r\n   * 获取当前选区范围。\r\n   * @returns 选区范围对象，无选区时返回 null\r\n   */\r\n  getRange(): IRange | null {\r\n    return this.range.getRange()\r\n  }\r\n\r\n  /**\r\n   * 获取是否只读状态。\r\n   * @returns 是否只读\r\n   */\r\n  getIsReadonly(): boolean {\r\n    return !!this.draw.getOptions().readonly\r\n  }\r\n\r\n  /**\r\n   * 获取是否禁用状态。\r\n   * @returns 是否禁用\r\n   */\r\n  getIsDisabled(): boolean {\r\n    return !!this.draw.getOptions().disabled\r\n  }\r\n\r\n  /**\r\n   * 获取是否可输入状态（非只读且非禁用）。\r\n   * @returns 是否可输入\r\n   */\r\n  getIsCanInput(): boolean {\r\n    return !this.getIsReadonly() && !this.getIsDisabled()\r\n  }\r\n\r\n  /**\r\n   * 获取当前选区样式快照（bold/italic/underline 等回显状态）\r\n   * @returns 选区样式状态对象\r\n   */\r\n  getRangeStyle(): IRangeStyle {\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus()\r\n\r\n    /** 默认样式快照 */\r\n    const defaultStyle: IRangeStyle = {\r\n      hasSelection: !this.range.isCollapsed(),\r\n      type: null, bold: false, italic: false, underline: false, strikeout: false,\r\n      doubleStrikeout: false, hidden: false, superscript: false, subscript: false,\r\n      color: '', highlight: '', font: '', size: 0, level: null,\r\n      rowFlex: 'left', lineHeight: 1.5, lineHeightRule: 'auto', paragraphFirstLineIndent: 0,\r\n      characterScale: 100, painter: !!this._paintFmt,\r\n      undo: this.getIsCanInput() && (this._historyManager?.canUndo() ?? false),\r\n      redo: this.getIsCanInput() && (this._historyManager?.canRedo() ?? false)\r\n    }\r\n\r\n    if (!pos) return defaultStyle\r\n\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return defaultStyle\r\n\r\n    const cursorIdx = pos.path[pos.path.length - 1] as number\r\n    const el = parent[cursorIdx] as Record<string, unknown> | undefined\r\n    if (!el) return defaultStyle\r\n\r\n    // 段落级属性：从段落第一个有该属性的元素获取（光标所在元素可能缺少段落级属性）\r\n    const groups = splitParagraphs(parent)\r\n    let paraEl: Record<string, unknown> = el\r\n    for (const g of groups) {\r\n      if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n      for (const r of g.runs) {\r\n        const candidate = r as Record<string, unknown>\r\n        if (candidate.rowFlex !== undefined) {\r\n          paraEl = candidate\r\n          break\r\n        }\r\n      }\r\n      break\r\n    }\r\n\r\n    const titlePath = this.getTitlePath(doc.elements, pos.path)\r\n    const title = titlePath ? getByPath(doc.elements, titlePath) as ITitleElement : null\r\n    return {\r\n      hasSelection: !this.range.isCollapsed(),\r\n      type: (el.type as string) ?? null,\r\n      bold: !!el.bold,\r\n      italic: !!el.italic,\r\n      underline: !!el.underline,\r\n      strikeout: !!el.strikeout,\r\n      doubleStrikeout: !!el.doubleStrikeout,\r\n      hidden: !!el.hidden,\r\n      superscript: !!el.superscript,\r\n      subscript: !!el.subscript,\r\n      color: (el.color as string) ?? '',\r\n      highlight: (el.highlight as string) ?? '',\r\n      font: (el.font as string) ?? '',\r\n      size: Math.round(((el.size as number) ?? 0) * (72 / 96) * 2) / 2,\r\n      level: title?.level ?? null,\r\n      rowFlex: (paraEl.rowFlex as string) ?? 'left',\r\n      lineHeight: (paraEl.lineHeight as number) ?? 1.5,\r\n      lineHeightRule: (paraEl.lineHeightRule as string) ?? 'auto',\r\n      paragraphFirstLineIndent: (paraEl.paragraphFirstLineIndent as number) ?? 0,\r\n      characterScale: (el.characterScale as number) ?? 100,\r\n      painter: !!this._paintFmt,\r\n      undo: this.getIsCanInput() && (this._historyManager?.canUndo() ?? false),\r\n      redo: this.getIsCanInput() && (this._historyManager?.canRedo() ?? false)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取光标所在行/列信息（基于布局可视行计数）\r\n   * @returns 行列信息，-1 表示无有效光标\r\n   */\r\n  getRangeContext(): { startRowNo: number; startColNo: number } {\r\n    const pos = this.range.getFocus()\r\n    const layout = this.draw.getLayout()\r\n    if (!pos || !layout) return { startRowNo: -1, startColNo: -1 }\r\n\r\n    let rowNo = 0\r\n    for (const page of layout.pages) {\r\n      const result = this.findRowColInBlocks(page.blocks, pos, rowNo)\r\n      if (result) return result\r\n    }\r\n    return { startRowNo: -1, startColNo: -1 }\r\n  }\r\n\r\n  /**\r\n   * 在布局块中查找光标所在行/列信息。\r\n   * @param blocks 布局块数组\r\n   * @param pos 光标位置\r\n   * @param startRow 起始行号\r\n   * @returns 行列信息对象；未找到时返回 null\r\n   */\r\n  private findRowColInBlocks(blocks: BlockNode[], pos: IPosition, startRow: number): { startRowNo: number; startColNo: number } | null {\r\n    let rowNo = startRow\r\n    for (const b of blocks) {\r\n      if (b.kind === 'paragraph') {\r\n        for (const line of b.lines) {\r\n          for (const inl of line.inlines) {\r\n            if (isSamePath(inl.path, pos.path) && pos.offset >= inl.startOffset && pos.offset <= inl.endOffset) {\r\n              let colNo = 0\r\n              for (const prev of line.inlines) {\r\n                if (prev === inl) {\r\n                  colNo += pos.offset - prev.startOffset\r\n                  break\r\n                }\r\n                colNo += prev.text.length\r\n              }\r\n              return { startRowNo: rowNo, startColNo: colNo }\r\n            }\r\n          }\r\n          rowNo++\r\n        }\r\n      } else if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          let maxLinesInRow = 1\r\n          for (const cell of row.cells) {\r\n            const cellLines = this.countLinesInBlocks(cell.content)\r\n            const result = this.findRowColInBlocks(cell.content, pos, rowNo)\r\n            if (result) return result\r\n            if (cellLines > maxLinesInRow) maxLinesInRow = cellLines\r\n          }\r\n          rowNo += maxLinesInRow\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 统计布局块中的行数（表格按各行最大行数累加）。\r\n   * @param blocks 布局块数组\r\n   * @returns 行数总计\r\n   */\r\n  private countLinesInBlocks(blocks: BlockNode[]): number {\r\n    let count = 0\r\n    for (const b of blocks) {\r\n      if (b.kind === 'paragraph') {\r\n        count += b.lines.length\r\n      } else if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          let maxLinesInRow = 1\r\n          for (const cell of row.cells) {\r\n            const cellLines = this.countLinesInBlocks(cell.content)\r\n            if (cellLines > maxLinesInRow) maxLinesInRow = cellLines\r\n          }\r\n          count += maxLinesInRow\r\n        }\r\n      }\r\n    }\r\n    return count\r\n  }\r\n\r\n  /**\r\n   * 获取编辑器能力状态快照（readonly/disabled/canUndo/canRedo）\r\n   * @returns 能力状态对象\r\n   */\r\n  getAbility(): IEditorAbility {\r\n    return {\r\n      readonly: this.getIsReadonly(),\r\n      disabled: this.getIsDisabled(),\r\n      canInput: this.getIsCanInput(),\r\n      canUndo: this.getIsCanInput() && (this._historyManager?.canUndo() ?? false),\r\n      canRedo: this.getIsCanInput() && (this._historyManager?.canRedo() ?? false)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置编辑器模式（paging/continuity/readonly/edit），并通知能力变更。\r\n   * @param mode 模式字符串\r\n   */\r\n  setMode(mode: string): void {\r\n    if (mode === 'paging' || mode === 'continuity') {\r\n      this.draw.updateOptions({ pageMode: mode })\r\n    } else if (mode === 'readonly') {\r\n      this._paintFmt = null\r\n      this.draw.updateOptions({ readonly: true } as Partial<IEditorOption>)\r\n    } else if (mode === 'edit') {\r\n      this.draw.updateOptions({ readonly: false } as Partial<IEditorOption>)\r\n    }\r\n    // 模式切换后通知能力变更（readonly/disabled 状态可能变化）\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /**\r\n   * 导出为 docx 文档（调用 options.exportCallback）。\r\n   * @param payload 导出参数\r\n   * @returns 完成时 resolve 的 Promise\r\n   */\r\n  async exportDocx(payload: any): Promise<void> {\r\n    const cb = this.draw.getOptions().exportCallback as ((data: any, opts?: any) => Promise<any>) | undefined\r\n    if (cb) {\r\n      await cb(toDocxExportDocument(this.draw.getDocument()), payload)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 预览 HTML 内容（调用 options.previewCallback）。\r\n   * @param payload 预览参数\r\n   */\r\n  previewHtml(payload: any): void {\r\n    const cb = this.draw.getOptions().previewCallback as ((data: any, opts?: any) => void) | undefined\r\n    if (cb) {\r\n      cb(this.draw.getDocument(), payload)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 替换当前选区范围。\r\n   * @param range 新的选区范围，可为 null\r\n   */\r\n  replaceRange(range: IRange | null): void {\r\n    this.range.setRange(range)\r\n  }\r\n\r\n  /** 将当前选区内的元素标记为同一群组，返回 groupId 或 null。 */\r\n  setGroup(update?: (doc: IDocxDocumentMeta, groupId: string) => void): string | null {\r\n    if (!this.getIsCanInput()) return null\r\n    const doc = this.draw.getActiveDocument()\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered || this.range.isCollapsed()) return null\r\n    const adjusted = this.splitBoundaryRuns(doc, ordered.start, ordered.end)\r\n    const startRun = getByPath(doc.elements, adjusted.start.path)\r\n    const endRun = getByPath(doc.elements, adjusted.end.path)\r\n    const runs = this.collectRunsInRange(doc.elements, adjusted.start, adjusted.end).filter(run =>\r\n      run.value.length > 0 &&\r\n      (run !== startRun || adjusted.start.offset < run.value.length) &&\r\n      (run !== endRun || adjusted.end.offset > 0)\r\n    )\r\n    if (!runs.length) return null\r\n\r\n    const groupId = `g_${Date.now()}`\r\n    for (const run of runs) {\r\n      run.groupIds = [...(run.groupIds ?? []), groupId]\r\n    }\r\n    this.range.setRange({ anchor: adjusted.start, focus: adjusted.end })\r\n    update?.(this.draw.getDocument(), groupId)\r\n    this._commit(doc)\r\n    return groupId\r\n  }\r\n\r\n  /**\r\n   * 定位到指定群组的第一个元素。\r\n   * @param id 群组 ID\r\n   */\r\n  locationGroup(id: string): void {\r\n    const doc = this.draw.getActiveDocument()\r\n    for (let i = 0; i < doc.elements.length; i++) {\r\n      const el = doc.elements[i]\r\n      if ((el as unknown as Record<string, unknown>).groupId === id) {\r\n        this.range.setCaret({ path: [i], offset: 0 })\r\n        return\r\n      }\r\n    }\r\n  }\r\n\r\n  /* -------------------- 表格边框 -------------------- */\r\n\r\n  /** 根据单元格跨行跨列关系枚举有效单元格的四条边，标记内外边框及边序号。 */\r\n  private tableBorderSides(table: ITableElement) {\r\n    const sides: { cell: ITd; side: 'top' | 'right' | 'bottom' | 'left'; external: boolean; index: number }[] = []\r\n    const occupied: number[] = []\r\n    table.trList.forEach((row, r) => {\r\n      let col = 0\r\n      row.tdList.forEach(cell => {\r\n        if (cell.merged) return\r\n        while ((occupied[col] ?? 0) > r) col++\r\n        const span = Math.max(1, cell.colspan || 1)\r\n        const rowSpan = Math.max(1, cell.rowspan || 1)\r\n        const external = [r === 0, col + span >= table.colgroup.length, r + rowSpan >= table.trList.length, col === 0]\r\n        ;(['top', 'right', 'bottom', 'left'] as const).forEach((side, index) => {\r\n          sides.push({ cell, side, external: external[index], index })\r\n        })\r\n        for (let c = col; c < col + span; c++) occupied[c] = r + rowSpan\r\n        col += span\r\n      })\r\n    })\r\n    return sides\r\n  }\r\n\r\n  /** 根据边的方向及内外位置，判断指定边框预设是否应显示该边。 */\r\n  private matchesBorderPreset(type: TableBorderPreset, side: 'top' | 'right' | 'bottom' | 'left', external: boolean): boolean {\r\n    if (type === 'all') return true\r\n    if (type === 'outside') return external\r\n    if (type === 'inside') return !external\r\n    if (type === 'inside-horizontal') return !external && (side === 'top' || side === 'bottom')\r\n    if (type === 'inside-vertical') return !external && (side === 'left' || side === 'right')\r\n    return external && type === side\r\n  }\r\n\r\n  /** 汇总光标所在表格的边框预设、统一颜色及内外线宽，混合属性为 undefined，无表格时返回 null。 */\r\n  getTableBorders(): { type?: TableBorderPreset; color?: string; width?: number; externalWidth?: number } | null {\r\n    const pos = this.range.getFocus()\r\n    const table = pos && this._findEnclosingTable(this.draw.getActiveDocument().elements, pos.path)\r\n    if (!table) return null\r\n    const sides = this.tableBorderSides(table)\r\n    const visible = (s: typeof sides[number]) => s.cell.borderTypes?.[s.index] !== 0 &&\r\n      !!s.cell.borderStyle?.[s.side] && s.cell.borderStyle[s.side].style !== 'none' && s.cell.borderStyle[s.side].width > 0\r\n    const uniform = <T>(values: T[]): T | undefined => values.length && values.every(v => v === values[0]) ? values[0] : undefined\r\n    const shown = sides.filter(visible)\r\n    return {\r\n      type: shown.length === 0 ? 'none' : shown.length === sides.length ? 'all'\r\n        : Object.values(TableBorder).find(type => sides.every(s => visible(s) === this.matchesBorderPreset(type, s.side, s.external))),\r\n      color: uniform(shown.map(s => s.cell.borderStyle[s.side].color.replace(/^#([\\da-f])([\\da-f])([\\da-f])$/i, '#$1$1$2$2$3$3'))),\r\n      width: uniform(shown.filter(s => !s.external).map(s => s.cell.borderStyle[s.side].width)),\r\n      externalWidth: uniform(shown.filter(s => s.external).map(s => s.cell.borderStyle[s.side].width))\r\n    }\r\n  }\r\n\r\n  /** 按补丁更新光标所在表格各边的可见性、颜色及内外线宽，并同步 Office 边框属性。 */\r\n  setTableBorders(patch: { type?: TableBorderPreset; color?: string; width?: number; externalWidth?: number }): void {\r\n    if (patch.type !== undefined && !Object.values(TableBorder).includes(patch.type)) return\r\n    if (!Object.values(patch).some(v => v !== undefined)) return\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      const table = pos && this._findEnclosingTable(doc.elements, pos.path)\r\n      if (!table) return false\r\n      for (const { cell, side, external, index } of this.tableBorderSides(table)) {\r\n        const previous = cell.borderStyle?.[side]\r\n        const border = { ...(previous ?? { width: 1, color: '#000000', style: 'solid' as const }) }\r\n        if (patch.type !== undefined) {\r\n          const show = this.matchesBorderPreset(patch.type, side, external)\r\n          border.style = show ? (border.style === 'none' ? 'solid' : border.style) : 'none'\r\n          if (show && border.width === 0) border.width = 1\r\n          if (cell.borderTypes) cell.borderTypes[index] = show ? 1 : 0\r\n          border.officeType = !show ? 'nil' : previous?.style !== 'none' && previous?.officeType && !['nil', 'none'].includes(previous.officeType)\r\n            ? previous.officeType : border.style === 'solid' ? 'single' : border.style\r\n          border.sizeEighthPoints = Math.round(border.width * 6)\r\n        }\r\n        if (patch.color !== undefined) border.color = patch.color\r\n        const width = external ? patch.externalWidth : patch.width\r\n        if (width !== undefined && Number.isFinite(width) && width >= 0) {\r\n          border.width = width\r\n          border.sizeEighthPoints = Math.round(width * 6)\r\n          if (width === 0) {\r\n            border.style = 'none'\r\n            border.officeType = 'nil'\r\n          }\r\n        }\r\n        border.source = 'cell'\r\n        cell.borderStyle = { ...cell.borderStyle, [side]: border }\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的边框类型（none/outside/all 等）。\r\n   * @param type 边框类型字符串\r\n   */\r\n  setTableBorderType(type: string): void {\r\n    const t = String(type || '').trim().toLowerCase()\r\n    const resolved =\r\n      t === 'none' || t === 'empty' || t === 'no' ? 'none'\r\n      : t === 'outside' || t === 'external' || t === 'box' ? 'outside'\r\n      : t === 'all' || t === 'full' || t === '' ? 'all'\r\n      : t\r\n    const preset = Object.values(TableBorder).find(value => value === resolved)\r\n    if (preset) this.setTableBorders({ type: preset })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的边框颜色。\r\n   * @param color 颜色值\r\n   */\r\n  setTableBorderColor(color: string): void {\r\n    this.setTableBorders({ color })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  setTableBorderWidth(width: number): void {\r\n    this.setTableBorders({ width, externalWidth: width })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的外部边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  setTableBorderExternalWidth(width: number): void {\r\n    this.setTableBorders({ externalWidth: width })\r\n  }\r\n\r\n  /**\r\n   * 沿路径查找包含指定路径的最近表格元素。\r\n   * @param elements 文档元素树\r\n   * @param path 目标路径\r\n   * @returns 包裹该路径的表格元素；不存在时返回 null\r\n   */\r\n  private _findEnclosingTable(elements: IElement[], path: Path): ITableElement | null {\r\n    for (let i = 0; i < path.length; i++) {\r\n      const subPath = path.slice(0, i + 1) as Path\r\n      const node = getByPath(elements, subPath)\r\n      if (node && node.type === 'table') return node as ITableElement\r\n    }\r\n    return null\r\n  }\r\n\r\n\r\n  /* -------------------- 图表 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入图表元素（构造 IBlockElement 嵌套结构）。\r\n   * @param payload 图表参数：chartType/subtype/dataSource/config/width/height\r\n   */\r\n  insertChart(payload: { chartType: string; subtype?: string; dataSource: any; config?: any; width?: number; height?: number }): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n      const el: IElement = {\r\n        type: 'block',\r\n        value: '',\r\n        id: `chart_${Date.now()}`,\r\n        block: {\r\n          type: 'chart',\r\n          chartBlock: {\r\n            chartType: payload.chartType,\r\n            dataSource: payload.dataSource,\r\n            config: payload.config,\r\n            subtype: payload.subtype\r\n          }\r\n        },\r\n        metrics: {\r\n          width: payload.width ?? 420,\r\n          height: payload.height ?? 320\r\n        }\r\n      } as unknown as IElement\r\n      // chart 是块级元素，始终插入到顶层 doc.elements（光标可能在 title/list/table 等嵌套结构内，\r\n      // 取 path[0] 作为顶层索引，插入到该顶层元素之后）\r\n      const topLevelIndex = (pos.path[0] as number) ?? doc.elements.length\r\n      const idx = Math.min(topLevelIndex + 1, doc.elements.length)\r\n      doc.elements.splice(idx, 0, el)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新指定图表的属性（写入 block.chartBlock）。\r\n   * @param id 图表元素 ID\r\n   * @param patch 属性补丁对象\r\n   */\r\n  updateChart(id: string, patch: Record<string, unknown>): void {\r\n    this.execute(doc => {\r\n      walkTree(doc.elements, (node) => {\r\n        const n = node as unknown as {\r\n          type: string; id?: string\r\n          block?: { type: string; chartBlock?: Record<string, unknown> }\r\n        }\r\n        if (n.type === 'block' && n.id === id && n.block?.type === 'chart' && n.block.chartBlock) {\r\n          Object.assign(n.block.chartBlock, patch)\r\n        }\r\n      })\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新指定路径图表块的尺寸（写入 metrics.width/height）。\r\n   * @param path 图表路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateChartSize(path: Path, width: number, height: number): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path)\r\n      if (!el || el.type !== 'block') return false\r\n      const metrics = (el as unknown as { metrics?: { width: number; height: number } }).metrics\r\n      if (!metrics) return false\r\n      metrics.width = Math.max(1, Math.round(width))\r\n      metrics.height = Math.max(1, Math.round(height))\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 删除指定路径的块元素（图表等）。\r\n   * @param path 块路径\r\n   */\r\n  deleteBlock(path: Path): void {\r\n    this.execute(doc => {\r\n      const parent = getParentContainer(doc.elements, path)\r\n      if (!parent) return false\r\n      const idx = path[path.length - 1]\r\n      if (typeof idx !== 'number' || idx < 0 || idx >= parent.length) return false\r\n      if (parent[idx].type !== 'block') return false\r\n      parent.splice(idx, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /* -------------------- 评论组删除 -------------------- */\r\n\r\n  /**\r\n   * 删除指定评论组。\r\n   * @param groupId 评论组 ID\r\n   */\r\n  deleteGroup(groupId: string): void {\r\n    this.execute(doc => {\r\n      walkTree(doc.elements, (node) => {\r\n        const any = node as unknown as Record<string, unknown>\r\n        const ids = any.groupIds as string[] | undefined\r\n        if (ids && ids.includes(groupId)) {\r\n          const next = ids.filter(id => id !== groupId)\r\n          if (next.length === 0) delete any.groupIds\r\n          else any.groupIds = next\r\n        }\r\n        if (any.groupId === groupId) delete any.groupId\r\n      })\r\n      const groups = (doc as unknown as { comments?: { groups?: { id: string }[] } }).comments?.groups\r\n      if (groups) {\r\n        const idx = groups.findIndex(g => g.id === groupId)\r\n        if (idx >= 0) {\r\n          groups.splice(idx, 1)\r\n        }\r\n      }\r\n    })\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Transform —— Command 门面\r\n */\r\n\r\nimport type { CommandAdapt } from './command-adapt'\r\nimport type { IElement, Path, IAutoTocResult, IBookmark, IEditorOption, IRange, IDocxDocumentMeta } from '@vervedoc/docx-editor-schema'\r\nimport type { IRangeStyle, IEditorAbility } from '@vervedoc/docx-editor-state'\r\n\r\n/**\r\n * Command 命令门面类。\r\n * 作为对外暴露的统一命令入口，将各类编辑操作委托给内部的 CommandAdapt 适配器执行。\r\n */\r\nexport class Command {\r\n  /**\r\n   * 创建 Command 实例。\r\n   * @param adapt 命令适配器实例，负责实际执行各项编辑操作\r\n   */\r\n  constructor(public adapt: CommandAdapt) {}\r\n\r\n  /**\r\n   * 在当前光标位置插入文本。\r\n   * @param text 待插入的文本内容\r\n   */\r\n  executeInsertText(text: string): void { this.adapt.insertText(text) }\r\n  /**\r\n   * 向后删除一个字符（Backspace 键行为）。\r\n   */\r\n  executeDeleteBackward(): void { this.adapt.deleteBackward() }\r\n  /**\r\n   * 向后删除一个字符（Backspace 键行为的别名）。\r\n   */\r\n  executeBackspace(): void { this.adapt.deleteBackward() }\r\n  /**\r\n   * 向前删除一个字符（Delete 键行为）。\r\n   */\r\n  executeDeleteForward(): void { this.adapt.deleteForward() }\r\n  /**\r\n   * 在当前光标处拆分段落。\r\n   */\r\n  executeSplitParagraph(): void { this.adapt.splitParagraph() }\r\n  /**\r\n   * 删除当前选区内容。\r\n   * @returns 是否成功删除\r\n   */\r\n  executeDeleteSelection(): boolean { return this.adapt.deleteSelection() }\r\n  /**\r\n   * 提取当前选区的纯文本内容。\r\n   * @returns 选区文本字符串\r\n   */\r\n  executeExtractSelectionText(): string { return this.adapt.extractSelectionText() }\r\n  /**\r\n   * 将光标向左移动一位。\r\n   */\r\n  executeMoveCaretLeft(): void { this.adapt.moveCaretLeft() }\r\n  /**\r\n   * 将光标向右移动一位。\r\n   */\r\n  executeMoveCaretRight(): void { this.adapt.moveCaretRight() }\r\n  /**\r\n   * 设置行弹性布局。\r\n   * @param f 行弹性布局参数\r\n   */\r\n  executeSetRowFlex(f: Parameters<CommandAdapt['setRowFlex']>[0]): void { this.adapt.setRowFlex(f) }\r\n  /**\r\n   * 设置或切换加粗样式。\r\n   * @param b 是否加粗，省略时为切换语义\r\n   */\r\n  executeSetBold(b?: boolean): void { this.adapt.setBold(b) }\r\n  /**\r\n   * 设置或切换斜体样式。\r\n   * @param b 是否斜体，省略时为切换语义\r\n   */\r\n  executeSetItalic(b?: boolean): void { this.adapt.setItalic(b) }\r\n  /**\r\n   * 设置文字颜色。\r\n   * @param c 颜色值字符串\r\n   */\r\n  executeSetColor(c: string): void { this.adapt.setColor(c) }\r\n  /**\r\n   * 设置字体。\r\n   * @param f 字体名称\r\n   */\r\n  executeSetFont(f: string): void { this.adapt.setFont(f) }\r\n  /**\r\n   * 设置字号。\r\n   * @param s 字号数值\r\n   */\r\n  executeSetSize(s: number): void { this.adapt.setSize(s) }\r\n  /**\r\n   * 增大字号。\r\n   */\r\n  executeSizeAdd(): void { this.adapt.setSizeAdd() }\r\n  /**\r\n   * 减小字号。\r\n   */\r\n  executeSizeMinus(): void { this.adapt.setSizeMinus() }\r\n  /**\r\n   * 设置文字高亮颜色。\r\n   * @param c 高亮颜色值\r\n   */\r\n  executeSetHighlight(c: string): void { this.adapt.setHighlight(c) }\r\n  /**\r\n   * 设置或切换删除线。\r\n   * @param v 是否显示删除线\r\n   */\r\n  executeSetStrikeout(v?: boolean): void { this.adapt.setStrikeout(v) }\r\n  /** 设置双删除线 */\r\n  executeSetDoubleStrikeout(v?: boolean): void { this.adapt.setDoubleStrikeout(v) }\r\n  /** 设置隐藏 */\r\n  executeSetHidden(v?: boolean): void { this.adapt.setHidden(v) }\r\n  /**\r\n   * 设置或切换下划线。\r\n   * @param v 是否显示下划线\r\n   */\r\n  executeSetUnderline(v?: boolean): void { this.adapt.setUnderline(v) }\r\n  /**\r\n   * 清除当前选区的格式。\r\n   */\r\n  executeClearFormat(): void { this.adapt.clearFormat() }\r\n  /**\r\n   * 使用格式刷应用格式。\r\n   */\r\n  executePaintFormat(): void { this.adapt.paintFormat() }\r\n  /**\r\n   * 设置行高。\r\n   * @param lh 行高数值\r\n   * @param rule 行高规则：'auto' | 'exact' | 'atLeast'\r\n   */\r\n  executeSetLineHeight(lh: number, rule?: 'auto' | 'exact' | 'atLeast'): void { this.adapt.setLineHeight(lh, rule) }\r\n  /**\r\n   * 设置行间距。\r\n   * @param m 行间距数值\r\n   */\r\n  executeSetRowMargin(m: number): void { this.adapt.setRowMargin(m) }\r\n  /**\r\n   * 设置标题级别。\r\n   * @param l 标题级别，null 表示取消标题\r\n   */\r\n  executeSetTitle(l: 'first' | 'second' | 'third' | 'fourth' | 'fifth' | 'sixth' | null): void { this.adapt.setTitle(l) }\r\n  /**\r\n   * 设置列表。\r\n   * @param type 列表类型\r\n   * @param style 列表样式\r\n   */\r\n  executeSetList(type: Parameters<CommandAdapt['setList']>[0], style: Parameters<CommandAdapt['setList']>[1]): void { this.adapt.setList(type, style) }\r\n  /**\r\n   * 插入表格。\r\n   * @param rows 行数\r\n   * @param cols 列数\r\n   * @param availableWidth 可用宽度，可选\r\n   */\r\n  executeInsertTable(rows: number, cols: number, availableWidth?: number): void { this.adapt.insertTable(rows, cols, availableWidth) }\r\n  /**\r\n   * 插入表格行。\r\n   * @param position 插入位置：'above' | 'below'\r\n   * @param count 插入行数，可选\r\n   */\r\n  executeInsertTableRow(position: 'above' | 'below', count?: number): void { this.adapt.insertTableRow(position, count) }\r\n  /**\r\n   * 插入表格列。\r\n   * @param position 插入位置：'left' | 'right'\r\n   * @param count 插入列数，可选\r\n   */\r\n  executeInsertTableCol(position: 'left' | 'right', count?: number): void { this.adapt.insertTableCol(position, count) }\r\n  /**\r\n   * 删除当前表格行。\r\n   */\r\n  executeDeleteTableRow(): void { this.adapt.deleteTableRow() }\r\n  /**\r\n   * 删除当前表格列。\r\n   */\r\n  executeDeleteTableCol(): void { this.adapt.deleteTableCol() }\r\n  /**\r\n   * 拆分当前表格单元格。\r\n   */\r\n  executeSplitTableCell(): void { this.adapt.splitTableCell() }\r\n  /**\r\n   * 合并选中的表格单元格。\r\n   */\r\n  executeMergeTableCells(): void { this.adapt.mergeTableCells() }\r\n  /**\r\n   * 删除整个表格。\r\n   */\r\n  executeDeleteTable(): void { this.adapt.deleteTable() }\r\n  /**\r\n   * 设置单元格垂直对齐方式。\r\n   * @param align 对齐方式：'top' | 'middle' | 'bottom'\r\n   */\r\n  executeSetCellVerticalAlign(align: 'top' | 'middle' | 'bottom'): void { this.adapt.setCellVerticalAlign(align) }\r\n  /**\r\n   * 设置单元格背景色。\r\n   * @param color 背景颜色值\r\n   */\r\n  executeSetCellBackground(color: string): void { this.adapt.setCellBackground(color) }\r\n  /**\r\n   * 切换表格重复表头状态。\r\n   */\r\n  executeToggleRepeatHeader(): void { this.adapt.toggleRepeatHeader() }\r\n  /**\r\n   * 设置表格列宽。\r\n   * @param tableIndex 表格索引\r\n   * @param colIndex 列索引\r\n   * @param width 列宽\r\n   */\r\n  executeSetTableColWidth(tableIndex: number, colIndex: number, width: number): void { this.adapt.setTableColWidth(tableIndex, colIndex, width) }\r\n  /**\r\n   * 设置表格行高。\r\n   * @param tableIndex 表格索引\r\n   * @param rowIndex 行索引\r\n   * @param height 行高\r\n   */\r\n  executeSetTableRowHeight(tableIndex: number, rowIndex: number, height: number): void { this.adapt.setTableRowHeight(tableIndex, rowIndex, height) }\r\n  /**\r\n   * 选中当前表格。\r\n   */\r\n  executeSelectTable(): void { this.adapt.selectTable() }\r\n  /**\r\n   * 插入图片。\r\n   * @param src 图片源，可以是 URL 字符串或包含 value/width/height 的对象\r\n   * @param w 宽度，可选\r\n   * @param h 高度，可选\r\n   */\r\n  executeInsertImage(src: string | { value: string; width?: number; height?: number }, w?: number, h?: number): void { this.adapt.insertImage(src, w, h) }\r\n  /**\r\n   * 插入签名图片。\r\n   * @param dataUrl 签名图片的 data URL\r\n   */\r\n  executeInsertSignature(dataUrl: string): void { this.adapt.signature(dataUrl) }\r\n  /**\r\n   * 插入条形码图片。\r\n   * @param payload 条形码参数，包含 value/width/height\r\n   */\r\n  executeInsertBarcode(payload: { value: string; width: number; height: number }): void { this.adapt.insertImage(payload) }\r\n  /**\r\n   * 插入二维码图片。\r\n   * @param payload 二维码参数，包含 value/width/height\r\n   */\r\n  executeInsertQrcode(payload: { value: string; width: number; height: number }): void { this.adapt.insertImage(payload) }\r\n  /**\r\n   * 更新图片尺寸。\r\n   * @param path 图片路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  executeUpdateImageSize(path: Path, width: number, height: number): void { this.adapt.updateImageSize(path, width, height) }\r\n  /**\r\n   * 删除图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeDeleteImage(path: Path): void { this.adapt.deleteImage(path) }\r\n  /**\r\n   * 重置图片为原始尺寸。\r\n   * @param path 图片路径\r\n   */\r\n  executeResetImageSize(path: Path): void { this.adapt.resetImageSize(path) }\r\n  /**\r\n   * 设置图片对齐方式。\r\n   * @param path 图片路径\r\n   * @param align 对齐方式：'left' | 'center' | 'right'\r\n   */\r\n  executeImageAlign(path: Path, align: 'left' | 'center' | 'right'): void { this.adapt.imageAlign(path, align) }\r\n  /**\r\n   * 替换图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeReplaceImage(path: Path): void { this.adapt.replaceImage(path) }\r\n  /**\r\n   * 旋转图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeRotateImage(path: Path): void { this.adapt.rotateImage(path) }\r\n  /**\r\n   * 保存图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeSaveImage(path: Path): Promise<void> { return this.adapt.saveImage(path) }\r\n  /**\r\n   * 设置图片环绕方式。\r\n   * @param path 图片路径\r\n   * @param mode 环绕模式：'block' | 'surround' | 'floatTop' | 'floatBottom'\r\n   */\r\n  executeImageWrap(path: Path, mode: 'block' | 'surround' | 'float-top' | 'float-bottom'): void { this.adapt.imageWrap(path, mode) }\r\n  /**\r\n   * 插入分页符。\r\n   */\r\n  executePageBreak(): void { this.adapt.insertPageBreak() }\r\n  executeInsertBlankPage(): void { this.adapt.insertBlankPage() }\r\n  /**\r\n   * 插入超链接。\r\n   * @param payload 超链接参数，包含 url 和 valueList\r\n   */\r\n  executeHyperlink(payload: { url: string; valueList: IElement[] }): boolean { return this.adapt.insertHyperlink(payload) }\r\n  getHyperlinkInsertionError() { return this.adapt.getHyperlinkInsertionError() }\r\n  /**\r\n   * 插入 LaTeX 公式。\r\n   * @param payload LaTeX 参数，包含 latex/svg/width/height\r\n   */\r\n  executeInsertLatex(payload: { latex: string; svg: string; width: number; height: number }): void { this.adapt.insertLatex(payload) }\r\n  /**\r\n   * 插入分隔线。\r\n   * @param opts 分隔线选项，可选\r\n   */\r\n  executeSeparator(opts?: { lineType?: string; lineWidth?: number; dashArray?: number[]; color?: string } | any[]): void { this.adapt.insertSeparator(opts) }\r\n  /**\r\n   * 插入换行符。\r\n   */\r\n  executeLineBreak(): void { this.adapt.lineBreak() }\r\n  /**\r\n   * 插入分栏符。\r\n   */\r\n  executeColumnBreak(): void { this.adapt.columnBreak() }\r\n  /**\r\n   * 插入连续分节符。\r\n   */\r\n  executeSectionBreakContinuous(): void { this.adapt.sectionBreakContinuous() }\r\n  executeSectionBreakNextPage(): void { this.adapt.sectionBreak('nextPage') }\r\n  executeSectionBreakEvenPage(): void { this.adapt.sectionBreak('evenPage') }\r\n  executeSectionBreakOddPage(): void { this.adapt.sectionBreak('oddPage') }\r\n  /**\r\n   * 搜索关键字。\r\n   * @param keyword 搜索关键字\r\n   * @returns 包含匹配数量 count 的结果对象\r\n   */\r\n  executeSearch(keyword: string): { count: number } { return this.adapt.search(keyword) }\r\n  /**\r\n   * 替换匹配内容。\r\n   * @param text 替换文本\r\n   * @param opts 替换选项，可指定 index\r\n   * @returns 是否成功替换\r\n   */\r\n  executeReplace(text: string, opts?: { index?: number }): boolean { return this.adapt.replace(text, opts) }\r\n  /**\r\n   * 定位到指定索引的搜索结果。\r\n   * @param idx 搜索结果索引\r\n   */\r\n  executeLocateSearchResult(idx: number): void { this.adapt.locateSearchResult(idx) }\r\n  /**\r\n   * 获取当前搜索命中列表。\r\n   * @returns 匹配项数组，每项含 index、before、match、after\r\n   */\r\n  executeGetSearchMatches(): { index: number; before: string; match: string; after: string }[] { return this.adapt.getSearchMatches() }\r\n  /**\r\n   * 全部替换。\r\n   * @param keyword 搜索关键字\r\n   * @param replacement 替换文本\r\n   * @returns 包含替换数量 count 的结果对象\r\n   */\r\n  executeReplaceAll(keyword: string, replacement: string): { count: number } { return this.adapt.replaceAll(keyword, replacement) }\r\n  /**\r\n   * 替换单个搜索结果。\r\n   * @param result 搜索结果定位信息\r\n   * @param replacement 替换文本\r\n   * @returns 包含替换数量 count 的结果对象\r\n   */\r\n  executeReplaceOne(result: { resultIndex: number; keyword: string }, replacement: string): { count: number } { return this.adapt.replaceOne(result, replacement) }\r\n  /**\r\n   * 设置纸张尺寸。\r\n   * @param w 宽度\r\n   * @param h 高度\r\n   */\r\n  executeSetPaperSize(w: number, h: number): void { this.adapt.setPaperSize(w, h) }\r\n  /**\r\n   * 设置纸张方向。\r\n   * @param d 方向：'vertical' | 'horizontal'\r\n   */\r\n  executeSetPaperDirection(d: 'vertical' | 'horizontal'): void { this.adapt.setPaperDirection(d) }\r\n  /**\r\n   * 放大页面缩放。\r\n   */\r\n  executePageScaleAdd(): void { this.adapt.pageScaleAdd() }\r\n  /**\r\n   * 缩小页面缩放。\r\n   */\r\n  executePageScaleMinus(): void { this.adapt.pageScaleMinus() }\r\n  /**\r\n   * 设置标尺可见性。\r\n   * @param visible 是否可见\r\n   */\r\n  executeSetRulerVisible(visible: boolean): void { this.adapt.setRulerVisible(visible) }\r\n  /**\r\n   * 设置页边距。\r\n   * @param margins 边距数组\r\n   */\r\n  executeSetPaperMargin(margins: number[]): void { this.adapt.setPaperMargin(margins) }\r\n  /**\r\n   * 打印文档。\r\n   */\r\n  executePrint(): void { this.adapt.print() }\r\n  /**\r\n   * 获取所有页面缩略图。\r\n   * @returns 缩略图 data URL 数组\r\n   */\r\n  getPageThumbnails(): string[] { return this.adapt.getPageThumbnails() }\r\n  /**\r\n   * 获取纸张高度。\r\n   * @returns 纸张高度数值\r\n   */\r\n  getPaperHeight(): number { return this.adapt.getPaperHeight() }\r\n  /**\r\n   * 获取编辑器选项。\r\n   * @returns 当前编辑器配置选项\r\n   */\r\n  getOptions(): IEditorOption { return this.adapt.getOptions() }\r\n  /**\r\n   * 设置页面模式。\r\n   * @param mode 页面模式字符串\r\n   */\r\n  executeSetPageMode(mode: string): void { this.adapt.setPageMode(mode) }\r\n  /**\r\n   * 设置页面缩放比例。\r\n   * @param scale 缩放比例\r\n   */\r\n  executeSetPageScale(scale: number): void { this.adapt.setPageScale(scale) }\r\n  /**\r\n   * 恢复页面缩放至默认比例。\r\n   */\r\n  executePageScaleRecovery(): void { this.adapt.setPageScaleRecovery() }\r\n  /**\r\n   * 设置分栏数。\r\n   * @param value 分栏数量\r\n   */\r\n  executeSetColumns(value: number): void { this.adapt.setColumns(value) }\r\n  /**\r\n   * 更新编辑器选项。\r\n   * @param patch 选项补丁对象\r\n   */\r\n  executeUpdateOptions(patch: Partial<IEditorOption>): void { this.adapt.updateOptions(patch) }\r\n  /**\r\n   * 添加水印。\r\n   * @param payload 水印参数，可包含 data/content/color/opacity/size/font/repeat\r\n   */\r\n  executeAddWatermark(payload: { data?: string; content?: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean } | any): void { this.adapt.addWatermark(payload) }\r\n  /**\r\n   * 删除水印。\r\n   */\r\n  executeDeleteWatermark(): void { this.adapt.deleteWatermark() }\r\n  /**\r\n   * 设置系统级水印（全页面 DOM 覆盖层）。\r\n   * @param config 水印配置，null 表示移除\r\n   */\r\n  executeSetSystemWatermark(config: { data: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | null): void { this.adapt.setSystemWatermark(config) }\r\n  /** 删除系统级水印 */\r\n  executeDeleteSystemWatermark(): void { this.adapt.deleteSystemWatermark() }\r\n  /**\r\n   * 获取文档全部元素值。\r\n   * @returns 文档元素数组\r\n   */\r\n  getValue(): IDocxDocumentMeta { return this.adapt.getValue() }\r\n  /**\r\n   * 设置文档内容。\r\n   * @param payload 文档内容，包含 main 及可选的 header/footer/comments\r\n   */\r\n  executeSetValue(payload: Parameters<CommandAdapt['setValue']>[0]): void { this.adapt.setValue(payload) }\r\n  /**\r\n   * 获取字数统计。\r\n   * @returns 字数数值\r\n   */\r\n  getWordCount(): number { return this.adapt.getWordCount() }\r\n  /**\r\n   * 获取文档目录。\r\n   * @returns 目录项数组，每项包含 id/level/name\r\n   */\r\n  getToc(): { id: string; level: number; name: string }[] { return this.adapt.getToc() }\r\n  /**\r\n   * 定位到指定目录项。\r\n   * @param id 目录项 ID\r\n   */\r\n  executeLocationToc(id: string): void { this.adapt.locationToc(id) }\r\n  /**\r\n   * 设置光标位置。\r\n   * @param path 光标路径\r\n   * @param offset 偏移量\r\n   */\r\n  executeSetCaret(path: Path, offset: number): void { this.adapt.setCaret(path, offset) }\r\n  /**\r\n   * 获取自动生成的目录结果。\r\n   * @returns 自动目录结果\r\n   */\r\n  getAutoToc(): IAutoTocResult { return this.adapt.getAutoToc() }\r\n  /**\r\n   * 插入自动目录。\r\n   * @param type Office 自动目录模板：1 | 2（均收录三级标题）\r\n   */\r\n  executeInsertAutoToc(type: 1 | 2): void { this.adapt.insertAutoToc(type) }\r\n  /**\r\n   * 撤销操作。\r\n   */\r\n  executeUndo(): void { this.adapt.undo() }\r\n  /**\r\n   * 重做操作。\r\n   */\r\n  executeRedo(): void { this.adapt.redo() }\r\n  /**\r\n   * 获取所有书签。\r\n   * @returns 书签数组\r\n   */\r\n  getBookmarks(): IBookmark[] { return this.adapt.getBookmarks() }\r\n  /**\r\n   * 添加书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  executeAddBookmark(payload: { name: string }): void { this.adapt.addBookmark(payload) }\r\n  /**\r\n   * 删除书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  executeDeleteBookmark(payload: { name: string }): void { this.adapt.deleteBookmark(payload) }\r\n  /**\r\n   * 跳转到指定书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  executeGotoBookmark(payload: { name: string }): void { this.adapt.gotoBookmark(payload) }\r\n  /**\r\n   * 插入目录（TOC）。\r\n   * @param payload 目录参数，可包含 type/mode 及其他自定义字段\r\n   */\r\n  executeInsertToc(payload: { type?: 1 | 2; mode?: string; [key: string]: unknown }): void { this.adapt.insertToc(payload) }\r\n  /** 更新整个目录，包括标题文本、层级与页码。 */\r\n  executeUpdateToc(): void { this.adapt.updateToc() }\r\n  /**\r\n   * 移除目录（TOC）。\r\n   */\r\n  executeRemoveToc(): void { this.adapt.removeToc() }\r\n  /**\r\n   * 设置当前编辑区域。\r\n   * @param zone 区域：'main' | 'header' | 'footer'\r\n   */\r\n  executeSetZone(zone: 'main' | 'header' | 'footer'): void { this.adapt.setZone(zone) }\r\n  /**\r\n   * 清空页眉内容。\r\n   */\r\n  executeClearHeader(): void { this.adapt.clearHeader() }\r\n  /**\r\n   * 清空页脚内容。\r\n   */\r\n  executeClearFooter(): void { this.adapt.clearFooter() }\r\n  /**\r\n   * 设置页码。\r\n   * @param payload 页码配置\r\n   */\r\n  executeSetPageNumber(payload: Record<string, unknown>): void { this.adapt.setPageNumber(payload) }\r\n\r\n\r\n  /**\r\n   * 获取当前编辑区域。\r\n   * @returns 区域：'main' | 'header' | 'footer'\r\n   */\r\n  getZone(): 'main' | 'header' | 'footer' { return this.adapt.getZone() }\r\n  /**\r\n   * 全选文档内容。\r\n   */\r\n  executeSelectAll(): void { this.adapt.selectAll() }\r\n  /**\r\n   * 设置选区范围。\r\n   * @param startIndex 起始索引\r\n   * @param endIndex 结束索引\r\n   */\r\n  executeSetRange(startIndex: number, endIndex: number): void { this.adapt.setRange(startIndex, endIndex) }\r\n  /**\r\n   * 插入元素列表。\r\n   * @param elements 元素数组\r\n   */\r\n  executeInsertElementList(elements: IElement[]): void { this.adapt.insertElementList(elements) }\r\n  /**\r\n   * 复制选区内容并返回可粘贴字符串。\r\n   * @returns 复制得到的数据字符串\r\n   */\r\n  executeCopy(): string { return this.adapt.copy() }\r\n  /**\r\n   * 剪切选区内容并返回可粘贴字符串。\r\n   * @returns 剪切得到的数据字符串\r\n   */\r\n  executeCut(): string { return this.adapt.cut() }\r\n  /**\r\n   * 粘贴内容。\r\n   * @param text 待粘贴的数据字符串\r\n   */\r\n  executePaste(text: string): void { this.adapt.paste(text) }\r\n  /**\r\n   * 粘贴纯文本。\r\n   * @param text 待粘贴的纯文本\r\n   */\r\n  executePastePlain(text: string): void { this.adapt.pastePlain(text) }\r\n  /**\r\n   * 粘贴时不保留格式（等同于粘贴纯文本）。\r\n   * @param text 待粘贴的文本\r\n   */\r\n  executePasteNoFormat(text: string): void { this.adapt.pastePlain(text) }\r\n  /**\r\n   * 设置上标。\r\n   */\r\n  executeSetSuperscript(): void { this.adapt.setSuperscript() }\r\n  /**\r\n   * 设置下标。\r\n   */\r\n  executeSetSubscript(): void { this.adapt.setSubscript() }\r\n  /**\r\n   * 设置字符缩放比例。\r\n   * @param value 缩放比例\r\n   */\r\n  executeSetCharacterScale(value: number): void { this.adapt.setCharacterScale(value) }\r\n  /**\r\n   * 设置段落首行缩进。\r\n   * @param indentPx 缩进像素值\r\n   */\r\n  executeSetFirstLineIndent(indentPx: number): void { this.adapt.setParagraphFirstLineIndent(indentPx) }\r\n  /** Apply ruler handle positions as one paragraph-format transaction. */\r\n  executeSetRulerIndent(first: number, left: number, right: number): void {\r\n    this.adapt.setRulerIndent(first, left, right)\r\n  }\r\n  /**\r\n   * 获取首行缩进值。\r\n   * @returns 首行缩进像素值\r\n   */\r\n  getFirstLineIndent(): number { return this.adapt.getFirstLineIndent() }\r\n  /**\r\n   * 按方向执行缩进步进。\r\n   * @param direction 方向：'add' | 'sub'\r\n   */\r\n  executeIndentStep(direction: 'add' | 'sub'): void { this.adapt.indentStep(direction) }\r\n  /** 设置左缩进（px） */\r\n  executeSetParagraphIndentLeft(px: number): void { this.adapt.setParagraphIndentLeft(px) }\r\n  /** 获取左缩进（px） */\r\n  getParagraphIndentLeft(): number { return this.adapt.getParagraphIndentLeft() }\r\n  /** 设置右缩进（px） */\r\n  executeSetParagraphIndentRight(px: number): void { this.adapt.setParagraphIndentRight(px) }\r\n  /** 获取右缩进（px） */\r\n  getParagraphIndentRight(): number { return this.adapt.getParagraphIndentRight() }\r\n  /** 设置段前间距（px） */\r\n  executeSetParagraphSpacingBefore(px: number): void { this.adapt.setParagraphSpacingBefore(px) }\r\n  /** 获取段前间距（px） */\r\n  getParagraphSpacingBefore(): number { return this.adapt.getParagraphSpacingBefore() }\r\n  /** 设置段后间距（px） */\r\n  executeSetParagraphSpacingAfter(px: number): void { this.adapt.setParagraphSpacingAfter(px) }\r\n  /** 获取段后间距（px） */\r\n  getParagraphSpacingAfter(): number { return this.adapt.getParagraphSpacingAfter() }\r\n  /**\r\n   * 获取当前选区范围。\r\n   * @returns 选区范围对象，无选区时返回 null\r\n   */\r\n  getRange(): IRange | null { return this.adapt.getRange() }\r\n  /**\r\n   * 获取是否只读状态。\r\n   * @returns 是否只读\r\n   */\r\n  getIsReadonly(): boolean { return this.adapt.getIsReadonly() }\r\n  /**\r\n   * 获取是否禁用状态。\r\n   * @returns 是否禁用\r\n   */\r\n  getIsDisabled(): boolean { return this.adapt.getIsDisabled() }\r\n  /**\r\n   * 获取是否可输入状态。\r\n   * @returns 是否可输入\r\n   */\r\n  getIsCanInput(): boolean { return this.adapt.getIsCanInput() }\r\n  /**\r\n   * 获取当前选区样式。\r\n   * @returns 选区样式对象\r\n   */\r\n  getRangeStyle(): IRangeStyle { return this.adapt.getRangeStyle() }\r\n  /**\r\n   * 获取选区上下文信息。\r\n   * @returns 包含起始行号和列号的对象\r\n   */\r\n  getRangeContext(): { startRowNo: number; startColNo: number } { return this.adapt.getRangeContext() }\r\n  /**\r\n   * 获取编辑器能力描述。\r\n   * @returns 编辑器能力对象\r\n   */\r\n  getAbility(): IEditorAbility { return this.adapt.getAbility() }\r\n  /**\r\n   * 设置编辑器模式。\r\n   * @param mode 模式字符串\r\n   */\r\n  executeSetMode(mode: string): void { this.adapt.setMode(mode) }\r\n  /**\r\n   * 导出为 docx 文档。\r\n   * @param payload 导出参数\r\n   * @returns 完成时 resolve 的 Promise\r\n   */\r\n  async executeExportDocx(payload: any): Promise<void> { await this.adapt.exportDocx(payload) }\r\n  /**\r\n   * 预览 HTML 内容。\r\n   * @param payload 预览参数\r\n   */\r\n  executePreviewHtml(payload: any): void { this.adapt.previewHtml(payload) }\r\n  /**\r\n   * 替换指定范围的内容。\r\n   * @param range 范围对象\r\n   */\r\n  executeReplaceRange(range: any): void { this.adapt.replaceRange(range) }\r\n  /**\r\n   * 设置群组，返回 groupId 或 null。\r\n   */\r\n  executeSetGroup(update?: Parameters<CommandAdapt['setGroup']>[0]): string | null { return this.adapt.setGroup(update) }\r\n  /**\r\n   * 定位到指定群组。\r\n   * @param id 群组 ID\r\n   */\r\n  executeLocationGroup(id: string): void { this.adapt.locationGroup(id) }\r\n  /**\r\n   * 设置表格边框类型。\r\n   * @param type 边框类型字符串\r\n   */\r\n  executeSetTableBorderType(type: string): void { this.adapt.setTableBorderType(type) }\r\n  getCellProperties() { return this.adapt.getCellProperties() }\r\n  getTableBorders() { return this.adapt.getTableBorders() }\r\n  executeSetTableBorders(patch: Parameters<CommandAdapt['setTableBorders']>[0]): void { this.adapt.setTableBorders(patch) }\r\n  /**\r\n   * 设置表格边框颜色。\r\n   * @param color 颜色值\r\n   */\r\n  executeSetTableBorderColor(color: string): void { this.adapt.setTableBorderColor(color) }\r\n  /**\r\n   * 设置表格边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  executeSetTableBorderWidth(width: number): void { this.adapt.setTableBorderWidth(width) }\r\n  /**\r\n   * 设置表格外部边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  executeSetTableBorderExternalWidth(width: number): void { this.adapt.setTableBorderExternalWidth(width) }\r\n  /**\r\n\r\n   * 插入图表。\r\n   * @param payload 图表参数：chartType/subtype/dataSource/config/width/height\r\n   */\r\n  executeInsertChart(payload: { chartType: string; subtype?: string; dataSource: any; config?: any; width?: number; height?: number }): void { this.adapt.insertChart(payload) }\r\n  /**\r\n   * 更新图表属性。\r\n   * @param id 图表 ID\r\n   * @param patch 属性补丁对象\r\n   */\r\n  executeUpdateChart(id: string, patch: Record<string, unknown>): void { this.adapt.updateChart(id, patch) }\r\n  /**\r\n   * 更新图表尺寸。\r\n   * @param path 图表路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  executeUpdateChartSize(path: Path, width: number, height: number): void { this.adapt.updateChartSize(path, width, height) }\r\n  /**\r\n   * 删除块元素（图表等）。\r\n   * @param path 块路径\r\n   */\r\n  executeDeleteBlock(path: Path): void { this.adapt.deleteBlock(path) }\r\n  /**\r\n   * 删除指定群组。\r\n   * @param groupId 群组 ID\r\n   */\r\n  executeDeleteGroup(groupId: string): void { this.adapt.deleteGroup(groupId) }\r\n  /**\r\n   * 获取文档全文纯文本（所有 text run 的 value 拼接）。\r\n   * @returns 文档全文字符串\r\n   */\r\n  executeGetFullText(): string { return this.adapt.getFullText() }\r\n  /**\r\n   * 跳转到指定页码（通过设置滚动位置）。\r\n   * @param pageNo 页码索引（从 0 开始）\r\n   */\r\n  executeJumpToPage(pageNo: number): void { this.adapt.jumpToPage(pageNo) }\r\n  /**\r\n   * 定位到指定修订 ID 的首个元素位置。\r\n   * @param id 修订唯一标识\r\n   * @returns 是否找到并定位成功\r\n   */\r\n  executeLocateRevision(id: string): boolean { return this.adapt.locateRevision(id) }\r\n}\r\n","/**\r\n * docx-editor-commands 内部共享常量\r\n *\r\n * verve schema 未导出这些符号，在此定义以保持 commands 模块自洽。\r\n */\r\n\r\nimport type { IElementBase } from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 commands 包 API 兼容\r\nexport type { IElementPosition } from '@vervedoc/docx-editor-schema'\r\n\r\n/** CSS 类名前缀，与 verve view 的 container 前缀保持一致 */\r\nexport const EDITOR_PREFIX = 'vervedocs'\r\n\r\n/** 嵌入块类型 */\r\nexport enum BlockType {\r\n  IFRAME = 'iframe'\r\n}\r\n\r\n/** 文本类元素类型集合（用于 Search 匹配） */\r\nexport const TEXTLIKE_ELEMENT_TYPE = new Set(['text', 'hyperlink', 'date', 'control'])\r\n\r\n/** 零值常量 */\r\nexport const ZERO = 0\r\n\r\n/** 组件 data 属性名 */\r\nexport const EDITOR_COMPONENT = 'data-vervedoc-component'\r\n\r\n/** 组件类型枚举 */\r\nexport enum EditorComponent {\r\n  POPUP = 'popup',\r\n  CONTROL = 'control',\r\n  DATE = 'date'\r\n}\r\n\r\n/* ========== 嵌入块元素类型 ========== */\r\n\r\n/** iframe 块数据 */\r\nexport interface IIFrameBlockData {\r\n  src?: string\r\n  srcdoc?: string\r\n}\r\n\r\n/** 图表块数据 */\r\nexport interface IChartBlockData {\r\n  chartType: string\r\n  dataSource: any\r\n  config?: any\r\n  subtype?: string\r\n}\r\n\r\n/** 块内嵌结构 */\r\nexport interface IBlockContent {\r\n  type: BlockType\r\n  iframeBlock?: IIFrameBlockData\r\n  chartBlock?: IChartBlockData\r\n}\r\n\r\n/** 块元素度量 */\r\nexport interface IBlockMetrics {\r\n  width: number\r\n  height: number\r\n}\r\n\r\n/** block 类型元素（type === 'block'） */\r\nexport interface IBlockElement extends IElementBase {\r\n  type: 'block'\r\n  id?: string\r\n  block?: IBlockContent\r\n  metrics?: IBlockMetrics\r\n}\r\n\r\n/* ========== LaTeX 元素类型 ========== */\r\n\r\n/** latex 类型元素（type === 'latex'） */\r\nexport interface ILatexElement extends IElementBase {\r\n  type: 'latex'\r\n  laTexSVG: string\r\n  width: number\r\n  height: number\r\n}\r\n\r\n/* ========== 日期元素类型 ========== */\r\n\r\n/** 日期值项 */\r\nexport interface IDateValueItem {\r\n  value: string\r\n}\r\n\r\n/** date 类型元素（type === 'date'） */\r\nexport interface IDateElement extends IElementBase {\r\n  type: 'date'\r\n  dateId?: string\r\n  dateFormat?: string\r\n  valueList?: IDateValueItem[]\r\n}","import {\r\n  EDITOR_COMPONENT,\r\n  EDITOR_PREFIX,\r\n  EditorComponent,\r\n  type IElementPosition\r\n} from './constants'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\n\r\n/** 日期选择器多语言文案接口 */\r\nexport interface IDatePickerLang {\r\n  /** \"现在\"按钮文案 */\r\n  now: string\r\n  /** \"确定\"按钮文案 */\r\n  confirm: string\r\n  /** \"返回\"按钮文案 */\r\n  return: string\r\n  /** \"选择时间\"按钮文案 */\r\n  timeSelect: string\r\n  /** 星期文案 */\r\n  weeks: {\r\n    /** 周日文案 */\r\n    sun: string\r\n    /** 周一文案 */\r\n    mon: string\r\n    /** 周二文案 */\r\n    tue: string\r\n    /** 周三文案 */\r\n    wed: string\r\n    /** 周四文案 */\r\n    thu: string\r\n    /** 周五文案 */\r\n    fri: string\r\n    /** 周六文案 */\r\n    sat: string\r\n  }\r\n  /** \"年\"文案 */\r\n  year: string\r\n  /** \"月\"文案 */\r\n  month: string\r\n  /** \"时\"文案 */\r\n  hour: string\r\n  /** \"分\"文案 */\r\n  minute: string\r\n  /** \"秒\"文案 */\r\n  second: string\r\n}\r\n\r\n/** 日期选择器选项接口 */\r\nexport interface IDatePickerOption {\r\n  /** 用户提交日期时的回调函数 */\r\n  onSubmit?: (date: string) => any\r\n}\r\n\r\n/** 日期选择器内部 DOM 结构引用 */\r\ninterface IDatePickerDom {\r\n  /** 最外层容器 */\r\n  container: HTMLDivElement\r\n  /** 日期面板包裹元素 */\r\n  dateWrap: HTMLDivElement\r\n  /** 星期标题行 */\r\n  datePickerWeek: HTMLDivElement\r\n  /** 时间面板包裹元素 */\r\n  timeWrap: HTMLUListElement\r\n  /** 标题栏（年月切换按钮） */\r\n  title: {\r\n    /** 上一年按钮 */\r\n    preYear: HTMLSpanElement\r\n    /** 上一月按钮 */\r\n    preMonth: HTMLSpanElement\r\n    /** 当前年月显示 */\r\n    now: HTMLSpanElement\r\n    /** 下一月按钮 */\r\n    nextMonth: HTMLSpanElement\r\n    /** 下一年按钮 */\r\n    nextYear: HTMLSpanElement\r\n  }\r\n  /** 日期网格容器 */\r\n  day: HTMLDivElement\r\n  /** 时分秒选择列表 */\r\n  time: {\r\n    /** 小时列表 */\r\n    hour: HTMLOListElement\r\n    /** 分钟列表 */\r\n    minute: HTMLOListElement\r\n    /** 秒列表 */\r\n    second: HTMLOListElement\r\n  }\r\n  /** 底部菜单按钮 */\r\n  menu: {\r\n    /** 切换时间选择按钮 */\r\n    time: HTMLButtonElement\r\n    /** \"现在\"按钮 */\r\n    now: HTMLButtonElement\r\n    /** \"确定\"按钮 */\r\n    submit: HTMLButtonElement\r\n  }\r\n}\r\n\r\n/** 渲染选项 */\r\ninterface IRenderOption {\r\n  /** 当前日期值 */\r\n  value: string\r\n  /** 元素位置信息 */\r\n  position: IElementPosition\r\n  /** 日期格式化模板 */\r\n  dateFormat?: string\r\n}\r\n\r\n/** 日期选择器组件，提供日期/时间选择能力并写回文档 */\r\nexport class DatePicker {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 外部传入的选项 */\r\n  private options: IDatePickerOption\r\n  /** 当前浏览的日期（用于面板显示年月） */\r\n  private now: Date\r\n  /** DOM 引用 */\r\n  private dom: IDatePickerDom\r\n  /** 当前渲染选项 */\r\n  private renderOptions: IRenderOption | null\r\n  /** 是否处于日期选择模式（true=日期，false=时间） */\r\n  private isDatePicker: boolean\r\n  /** 用户已选定的日期 */\r\n  private pickDate: Date | null\r\n  /** 多语言文案 */\r\n  private lang: IDatePickerLang\r\n\r\n  /**\r\n   * 创建日期选择器实例\r\n   * @param draw 编辑器绘制实例\r\n   * @param options 选项\r\n   */\r\n  constructor(draw: Draw, options: IDatePickerOption = {}) {\r\n    this.draw = draw\r\n    this.options = options\r\n    this.lang = this._getLang()\r\n    this.now = new Date()\r\n    this.dom = this._createDom()\r\n    this.renderOptions = null\r\n    this.isDatePicker = true\r\n    this.pickDate = null\r\n    this._bindEvent()\r\n  }\r\n\r\n  /**\r\n   * 构建日期选择器 DOM 结构\r\n   * @returns DOM 引用对象\r\n   */\r\n  private _createDom(): IDatePickerDom {\r\n    const datePickerContainer = document.createElement('div')\r\n    datePickerContainer.classList.add(`${EDITOR_PREFIX}-date-container`)\r\n    datePickerContainer.setAttribute(EDITOR_COMPONENT, EditorComponent.POPUP)\r\n    // title-切换年月、年月显示\r\n    const dateWrap = document.createElement('div')\r\n    dateWrap.classList.add(`${EDITOR_PREFIX}-date-wrap`)\r\n    const datePickerTitle = document.createElement('div')\r\n    datePickerTitle.classList.add(`${EDITOR_PREFIX}-date-title`)\r\n    const preYearTitle = document.createElement('span')\r\n    preYearTitle.classList.add(`${EDITOR_PREFIX}-date-title__pre-year`)\r\n    preYearTitle.innerText = `<<`\r\n    const preMonthTitle = document.createElement('span')\r\n    preMonthTitle.classList.add(`${EDITOR_PREFIX}-date-title__pre-month`)\r\n    preMonthTitle.innerText = `<`\r\n    const nowTitle = document.createElement('span')\r\n    nowTitle.classList.add(`${EDITOR_PREFIX}-date-title__now`)\r\n    const nextMonthTitle = document.createElement('span')\r\n    nextMonthTitle.classList.add(`${EDITOR_PREFIX}-date-title__next-month`)\r\n    nextMonthTitle.innerText = `>`\r\n    const nextYearTitle = document.createElement('span')\r\n    nextYearTitle.classList.add(`${EDITOR_PREFIX}-date-title__next-year`)\r\n    nextYearTitle.innerText = `>>`\r\n    datePickerTitle.append(preYearTitle)\r\n    datePickerTitle.append(preMonthTitle)\r\n    datePickerTitle.append(nowTitle)\r\n    datePickerTitle.append(nextMonthTitle)\r\n    datePickerTitle.append(nextYearTitle)\r\n    // week-星期显示\r\n    const datePickerWeek = document.createElement('div')\r\n    datePickerWeek.classList.add(`${EDITOR_PREFIX}-date-week`)\r\n    const {\r\n      weeks: { sun, mon, tue, wed, thu, fri, sat }\r\n    } = this.lang\r\n    const weekList = [sun, mon, tue, wed, thu, fri, sat]\r\n    weekList.forEach(week => {\r\n      const weekDom = document.createElement('span')\r\n      weekDom.innerText = `${week}`\r\n      datePickerWeek.append(weekDom)\r\n    })\r\n    // day-天数显示\r\n    const datePickerDay = document.createElement('div')\r\n    datePickerDay.classList.add(`${EDITOR_PREFIX}-date-day`)\r\n    // 日期内容构建\r\n    dateWrap.append(datePickerTitle)\r\n    dateWrap.append(datePickerWeek)\r\n    dateWrap.append(datePickerDay)\r\n    // time-时间选择\r\n    const timeWrap = document.createElement('ul')\r\n    timeWrap.classList.add(`${EDITOR_PREFIX}-time-wrap`)\r\n    let hourTime: HTMLOListElement\r\n    let minuteTime: HTMLOListElement\r\n    let secondTime: HTMLOListElement\r\n    const timeList = [this.lang.hour, this.lang.minute, this.lang.second]\r\n    timeList.forEach((t, i) => {\r\n      const li = document.createElement('li')\r\n      const timeText = document.createElement('span')\r\n      timeText.innerText = t\r\n      li.append(timeText)\r\n      const ol = document.createElement('ol')\r\n      const isHour = i === 0\r\n      const isMinute = i === 1\r\n      const endIndex = isHour ? 24 : 60\r\n      for (let i = 0; i < endIndex; i++) {\r\n        const time = document.createElement('li')\r\n        time.innerText = `${String(i).padStart(2, '0')}`\r\n        time.setAttribute('data-id', `${i}`)\r\n        ol.append(time)\r\n      }\r\n      if (isHour) {\r\n        hourTime = ol\r\n      } else if (isMinute) {\r\n        minuteTime = ol\r\n      } else {\r\n        secondTime = ol\r\n      }\r\n      li.append(ol)\r\n      timeWrap.append(li)\r\n    })\r\n    // menu-选择时间、现在、确定\r\n    const datePickerMenu = document.createElement('div')\r\n    datePickerMenu.classList.add(`${EDITOR_PREFIX}-date-menu`)\r\n    const timeMenu = document.createElement('button')\r\n    timeMenu.classList.add(`${EDITOR_PREFIX}-date-menu__time`)\r\n    timeMenu.innerText = this.lang.timeSelect\r\n    const nowMenu = document.createElement('button')\r\n    nowMenu.classList.add(`${EDITOR_PREFIX}-date-menu__now`)\r\n    nowMenu.innerText = this.lang.now\r\n    const submitMenu = document.createElement('button')\r\n    submitMenu.classList.add(`${EDITOR_PREFIX}-date-menu__submit`)\r\n    submitMenu.innerText = this.lang.confirm\r\n    datePickerMenu.append(timeMenu)\r\n    datePickerMenu.append(nowMenu)\r\n    datePickerMenu.append(submitMenu)\r\n    // 构建\r\n    datePickerContainer.append(dateWrap)\r\n    datePickerContainer.append(timeWrap)\r\n    datePickerContainer.append(datePickerMenu)\r\n\r\n    return {\r\n      container: datePickerContainer,\r\n      dateWrap,\r\n      datePickerWeek,\r\n      timeWrap,\r\n      title: {\r\n        preYear: preYearTitle,\r\n        preMonth: preMonthTitle,\r\n        now: nowTitle,\r\n        nextMonth: nextMonthTitle,\r\n        nextYear: nextYearTitle\r\n      },\r\n      day: datePickerDay,\r\n      time: {\r\n        hour: hourTime!,\r\n        minute: minuteTime!,\r\n        second: secondTime!\r\n      },\r\n      menu: {\r\n        time: timeMenu,\r\n        now: nowMenu,\r\n        submit: submitMenu\r\n      }\r\n    }\r\n  }\r\n\r\n  /** 绑定 DOM 事件监听 */\r\n  private _bindEvent() {\r\n    this.dom.title.preYear.onclick = () => {\r\n      this._preYear()\r\n    }\r\n    this.dom.title.preMonth.onclick = () => {\r\n      this._preMonth()\r\n    }\r\n    this.dom.title.nextMonth.onclick = () => {\r\n      this._nextMonth()\r\n    }\r\n    this.dom.title.nextYear.onclick = () => {\r\n      this._nextYear()\r\n    }\r\n    this.dom.menu.time.onclick = () => {\r\n      this.isDatePicker = !this.isDatePicker\r\n      this._toggleDateTimePicker()\r\n    }\r\n    this.dom.menu.now.onclick = () => {\r\n      this._now()\r\n      this._submit()\r\n    }\r\n    this.dom.menu.submit.onclick = () => {\r\n      this.dispose()\r\n      this._submit()\r\n    }\r\n    this.dom.time.hour.onclick = evt => {\r\n      if (!this.pickDate) return\r\n      const li = <HTMLLIElement>evt.target\r\n      const id = li.dataset.id\r\n      if (!id) return\r\n      this.pickDate.setHours(Number(id))\r\n      this._setTimePick(false)\r\n    }\r\n    this.dom.time.minute.onclick = evt => {\r\n      if (!this.pickDate) return\r\n      const li = <HTMLLIElement>evt.target\r\n      const id = li.dataset.id\r\n      if (!id) return\r\n      this.pickDate.setMinutes(Number(id))\r\n      this._setTimePick(false)\r\n    }\r\n    this.dom.time.second.onclick = evt => {\r\n      if (!this.pickDate) return\r\n      const li = <HTMLLIElement>evt.target\r\n      const id = li.dataset.id\r\n      if (!id) return\r\n      this.pickDate.setSeconds(Number(id))\r\n      this._setTimePick(false)\r\n    }\r\n  }\r\n\r\n  /** 根据元素位置计算并设置选择器在容器中的坐标 */\r\n  private _setPosition() {\r\n    if (!this.renderOptions) return\r\n    const {\r\n      position: {\r\n        coordinate: {\r\n          leftTop: [left, top]\r\n        },\r\n        lineHeight,\r\n        pageNo\r\n      }\r\n    } = this.renderOptions\r\n    const layout = this.draw.getLayout()\r\n    const height = layout?.pages?.[0]?.rect?.height\r\n      ?? this.draw.getOptions().pageHeight\r\n      ?? 1123\r\n    const pageGap = (this.draw.getOptions() as { pageGap?: number }).pageGap ?? 24\r\n    const currentPageNo = pageNo ?? 0\r\n    const preY = currentPageNo * (height + pageGap)\r\n    // 位置\r\n    this.dom.container.style.left = `${left}px`\r\n    this.dom.container.style.top = `${top + preY + lineHeight}px`\r\n  }\r\n\r\n  /**\r\n   * 判断日期是否无效\r\n   * @param value 待校验日期\r\n   * @returns 是否为无效日期\r\n   */\r\n  public isInvalidDate(value: Date): boolean {\r\n    return value.toDateString() === 'Invalid Date'\r\n  }\r\n\r\n  /** 根据渲染选项初始化当前日期与已选日期 */\r\n  private _setValue() {\r\n    const value = this.renderOptions?.value\r\n    if (value) {\r\n      const setDate = new Date(value)\r\n      this.now = this.isInvalidDate(setDate) ? new Date() : setDate\r\n    } else {\r\n      this.now = new Date()\r\n    }\r\n    this.pickDate = new Date(this.now)\r\n  }\r\n\r\n  /** 获取多语言文案，支持从 i18n 实例取值或回退到默认中文 */\r\n  private _getLang() {\r\n    const i18n = (this.draw as any).getI18n?.()\r\n    const defaults: Record<string, string> = {\r\n      'datePicker.now': '现在',\r\n      'datePicker.confirm': '确定',\r\n      'datePicker.return': '返回',\r\n      'datePicker.timeSelect': '选择时间',\r\n      'datePicker.weeks.sun': '日',\r\n      'datePicker.weeks.mon': '一',\r\n      'datePicker.weeks.tue': '二',\r\n      'datePicker.weeks.wed': '三',\r\n      'datePicker.weeks.thu': '四',\r\n      'datePicker.weeks.fri': '五',\r\n      'datePicker.weeks.sat': '六',\r\n      'datePicker.year': '年',\r\n      'datePicker.month': '月',\r\n      'datePicker.hour': '时',\r\n      'datePicker.minute': '分',\r\n      'datePicker.second': '秒'\r\n    }\r\n    const t = i18n?.t ? i18n.t.bind(i18n) : (key: string) => defaults[key] ?? key\r\n    return {\r\n      now: t('datePicker.now'),\r\n      confirm: t('datePicker.confirm'),\r\n      return: t('datePicker.return'),\r\n      timeSelect: t('datePicker.timeSelect'),\r\n      weeks: {\r\n        sun: t('datePicker.weeks.sun'),\r\n        mon: t('datePicker.weeks.mon'),\r\n        tue: t('datePicker.weeks.tue'),\r\n        wed: t('datePicker.weeks.wed'),\r\n        thu: t('datePicker.weeks.thu'),\r\n        fri: t('datePicker.weeks.fri'),\r\n        sat: t('datePicker.weeks.sat')\r\n      },\r\n      year: t('datePicker.year'),\r\n      month: t('datePicker.month'),\r\n      hour: t('datePicker.hour'),\r\n      minute: t('datePicker.minute'),\r\n      second: t('datePicker.second')\r\n    }\r\n  }\r\n\r\n  /** 语言变更后刷新 DOM 文案 */\r\n  private _setLangChange() {\r\n    this.dom.menu.time.innerText = this.lang.timeSelect\r\n    this.dom.menu.now.innerText = this.lang.now\r\n    this.dom.menu.submit.innerText = this.lang.confirm\r\n    const {\r\n      weeks: { sun, mon, tue, wed, thu, fri, sat }\r\n    } = this.lang\r\n    const weekList = [sun, mon, tue, wed, thu, fri, sat]\r\n    this.dom.datePickerWeek.childNodes.forEach((child, i) => {\r\n      const childElement = <HTMLSpanElement>child\r\n      childElement.innerText = weekList[i]\r\n    })\r\n    const hourTitle = <HTMLSpanElement>this.dom.time.hour.previousElementSibling\r\n    hourTitle.innerText = this.lang.hour\r\n    const minuteTitle = <HTMLSpanElement>(\r\n      this.dom.time.minute.previousElementSibling\r\n    )\r\n    minuteTitle.innerText = this.lang.minute\r\n    const secondTitle = <HTMLSpanElement>(\r\n      this.dom.time.second.previousElementSibling\r\n    )\r\n    secondTitle.innerText = this.lang.second\r\n  }\r\n\r\n  /** 重新渲染日期网格（包含上下月填充与高亮状态） */\r\n  private _update() {\r\n    // 本地年月日\r\n    const localDate = new Date()\r\n    const localYear = localDate.getFullYear()\r\n    const localMonth = localDate.getMonth() + 1\r\n    const localDay = localDate.getDate()\r\n    // 选择年月日\r\n    let pickYear: number | null = null\r\n    let pickMonth: number | null = null\r\n    let pickDay: number | null = null\r\n    if (this.pickDate) {\r\n      pickYear = this.pickDate.getFullYear()\r\n      pickMonth = this.pickDate.getMonth() + 1\r\n      pickDay = this.pickDate.getDate()\r\n    }\r\n    // 当前年月日\r\n    const year = this.now.getFullYear()\r\n    const month = this.now.getMonth() + 1\r\n    this.dom.title.now.innerText = `${year}${this.lang.year} ${String(\r\n      month\r\n    ).padStart(2, '0')}${this.lang.month}`\r\n    // 日期补差\r\n    const curDate = new Date(year, month, 0) // 当月日期\r\n    const curDay = curDate.getDate() // 当月总天数\r\n    let curWeek = new Date(year, month - 1, 1).getDay() // 当月第一天星期几\r\n    if (curWeek === 0) {\r\n      curWeek = 7\r\n    }\r\n    const preDay = new Date(year, month - 1, 0).getDate() // 上个月天数\r\n    this.dom.day.replaceChildren()\r\n    // 渲染上个月日期\r\n    const preStartDay = preDay - curWeek + 1\r\n    for (let i = preStartDay; i <= preDay; i++) {\r\n      const dayDom = document.createElement('div')\r\n      dayDom.classList.add('disable')\r\n      dayDom.innerText = `${i}`\r\n      dayDom.onclick = () => {\r\n        const newMonth = month - 2\r\n        this.now = new Date(year, newMonth, i)\r\n        this._setDatePick(year, newMonth, i)\r\n      }\r\n      this.dom.day.append(dayDom)\r\n    }\r\n    // 渲染当月日期\r\n    for (let i = 1; i <= curDay; i++) {\r\n      const dayDom = document.createElement('div')\r\n      if (localYear === year && localMonth === month && localDay === i) {\r\n        dayDom.classList.add('active')\r\n      }\r\n      if (\r\n        this.pickDate &&\r\n        pickYear === year &&\r\n        pickMonth === month &&\r\n        pickDay === i\r\n      ) {\r\n        dayDom.classList.add('select')\r\n      }\r\n      dayDom.innerText = `${i}`\r\n      dayDom.onclick = evt => {\r\n        const newMonth = month - 1\r\n        this.now = new Date(year, newMonth, i)\r\n        this._setDatePick(year, newMonth, i)\r\n        evt.stopPropagation()\r\n      }\r\n      this.dom.day.append(dayDom)\r\n    }\r\n    // 渲染下月日期\r\n    const nextEndDay = 6 * 7 - curWeek - curDay\r\n    for (let i = 1; i <= nextEndDay; i++) {\r\n      const dayDom = document.createElement('div')\r\n      dayDom.classList.add('disable')\r\n      dayDom.innerText = `${i}`\r\n      dayDom.onclick = () => {\r\n        this.now = new Date(year, month, i)\r\n        this._setDatePick(year, month, i)\r\n      }\r\n      this.dom.day.append(dayDom)\r\n    }\r\n  }\r\n\r\n  /** 在日期面板与时间面板之间切换显示 */\r\n  private _toggleDateTimePicker() {\r\n    if (this.isDatePicker) {\r\n      this.dom.dateWrap.classList.add('active')\r\n      this.dom.timeWrap.classList.remove('active')\r\n      this.dom.menu.time.innerText = this.lang.timeSelect\r\n    } else {\r\n      this.dom.dateWrap.classList.remove('active')\r\n      this.dom.timeWrap.classList.add('active')\r\n      this.dom.menu.time.innerText = this.lang.return\r\n      // 设置时分秒选择\r\n      this._setTimePick()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置用户选定的日期\r\n   * @param year 年\r\n   * @param month 月（0 基）\r\n   * @param day 日\r\n   */\r\n  private _setDatePick(year: number, month: number, day: number) {\r\n    this.now = new Date(year, month, day)\r\n    this.pickDate?.setFullYear(year)\r\n    this.pickDate?.setMonth(month)\r\n    this.pickDate?.setDate(day)\r\n    this._update()\r\n  }\r\n\r\n  /**\r\n   * 设置时分秒选择高亮\r\n   * @param isIntoView 是否同步滚动到选中项\r\n   */\r\n  private _setTimePick(isIntoView = true) {\r\n    const hour = this.pickDate?.getHours() || 0\r\n    const minute = this.pickDate?.getMinutes() || 0\r\n    const second = this.pickDate?.getSeconds() || 0\r\n    const {\r\n      hour: hourDom,\r\n      minute: minuteDom,\r\n      second: secondDom\r\n    } = this.dom.time\r\n    const timeDomList = [hourDom, minuteDom, secondDom]\r\n    // 清空\r\n    timeDomList.forEach(timeDom => {\r\n      timeDom\r\n        .querySelectorAll('li')\r\n        .forEach(li => li.classList.remove('active'))\r\n    })\r\n    const pickList: [HTMLOListElement, number][] = [\r\n      [hourDom, hour],\r\n      [minuteDom, minute],\r\n      [secondDom, second]\r\n    ]\r\n    pickList.forEach(([dom, time]) => {\r\n      const pickDom = dom.querySelector<HTMLLIElement>(`[data-id='${time}']`)!\r\n      pickDom.classList.add('active')\r\n      if (isIntoView) {\r\n        this._scrollIntoView(dom, pickDom)\r\n      }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 将选中元素滚动到容器可视区域\r\n   * @param container 滚动容器\r\n   * @param selected 选中的元素\r\n   */\r\n  private _scrollIntoView(container: HTMLElement, selected: HTMLElement) {\r\n    if (!selected) {\r\n      container.scrollTop = 0\r\n      return\r\n    }\r\n    const offsetParents: HTMLElement[] = []\r\n    let pointer = <HTMLElement>selected.offsetParent\r\n    while (pointer && container !== pointer && container.contains(pointer)) {\r\n      offsetParents.push(pointer)\r\n      pointer = <HTMLElement>pointer.offsetParent\r\n    }\r\n    const top =\r\n      selected.offsetTop +\r\n      offsetParents.reduce((prev, curr) => prev + curr.offsetTop, 0)\r\n    const bottom = top + selected.offsetHeight\r\n    const viewRectTop = container.scrollTop\r\n    const viewRectBottom = viewRectTop + container.clientHeight\r\n    if (top < viewRectTop) {\r\n      container.scrollTop = top\r\n    } else if (bottom > viewRectBottom) {\r\n      container.scrollTop = bottom - container.clientHeight\r\n    }\r\n  }\r\n\r\n  /** 切换到上一个月 */\r\n  private _preMonth() {\r\n    this.now.setMonth(this.now.getMonth() - 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 切换到下一个月 */\r\n  private _nextMonth() {\r\n    this.now.setMonth(this.now.getMonth() + 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 切换到上一年 */\r\n  private _preYear() {\r\n    this.now.setFullYear(this.now.getFullYear() - 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 切换到下一年 */\r\n  private _nextYear() {\r\n    this.now.setFullYear(this.now.getFullYear() + 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 选中当前时刻并关闭面板 */\r\n  private _now() {\r\n    this.pickDate = new Date()\r\n    this.dispose()\r\n  }\r\n\r\n  /**\r\n   * 切换面板可见性\r\n   * @param isVisible 是否可见\r\n   */\r\n  private _toggleVisible(isVisible: boolean) {\r\n    if (isVisible) {\r\n      this.dom.container.classList.add('active')\r\n    } else {\r\n      this.dom.container.classList.remove('active')\r\n    }\r\n  }\r\n\r\n  /** 触发 onSubmit 回调，将选定日期格式化后传出 */\r\n  private _submit() {\r\n    if (this.options.onSubmit && this.pickDate) {\r\n      const format = this.renderOptions?.dateFormat\r\n      const pickDateString = this.formatDate(this.pickDate, format)\r\n      this.options.onSubmit(pickDateString)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 按指定模板格式化日期\r\n   * @param date 待格式化日期\r\n   * @param format 格式模板，默认 yyyy-MM-dd hh:mm:ss\r\n   * @returns 格式化后的日期字符串\r\n   */\r\n  public formatDate(date: Date, format = 'yyyy-MM-dd hh:mm:ss'): string {\r\n    let dateString = format\r\n    const dateOption = {\r\n      'y+': date.getFullYear().toString(),\r\n      'M+': (date.getMonth() + 1).toString(),\r\n      'd+': date.getDate().toString(),\r\n      'h+': date.getHours().toString(),\r\n      'm+': date.getMinutes().toString(),\r\n      's+': date.getSeconds().toString()\r\n    }\r\n    for (const k in dateOption) {\r\n      const reg = new RegExp('(' + k + ')').exec(format)\r\n      const key = <keyof typeof dateOption>k\r\n      if (reg) {\r\n        dateString = dateString.replace(\r\n          reg[1],\r\n          reg[1].length === 1\r\n            ? dateOption[key]\r\n            : dateOption[key].padStart(reg[1].length, '0')\r\n        )\r\n      }\r\n    }\r\n    return dateString\r\n  }\r\n\r\n  /**\r\n   * 渲染日期选择器\r\n   * @param option 渲染选项\r\n   */\r\n  public render(option: IRenderOption) {\r\n    // 按需挂载到容器，避免初始化时就出现在页面上\r\n    if (!this.dom.container.parentElement) {\r\n      this.draw.getContainer().append(this.dom.container)\r\n    }\r\n    this.renderOptions = option\r\n    this.lang = this._getLang()\r\n    this._setLangChange()\r\n    this._setValue()\r\n    this._update()\r\n    this._setPosition()\r\n    this.isDatePicker = true\r\n    this._toggleDateTimePicker()\r\n    this._toggleVisible(true)\r\n  }\r\n\r\n  /** 隐藏并从 DOM 中移除面板 */\r\n  public dispose() {\r\n    this._toggleVisible(false)\r\n    this.dom.container.remove()\r\n  }\r\n\r\n  /** 销毁选择器，移除容器 */\r\n  public destroy() {\r\n    this.dom.container.remove()\r\n  }\r\n}\r\n","import type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport { getByPath } from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport type { IElementPosition } from './constants'\r\nimport { DatePicker } from './date-picker'\r\n\r\n/** 日期粒子管理器，负责 date 元素的日期选择器挂载与值写回 */\r\nexport class DateParticle {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 选区管理器 */\r\n  private range: RangeManager | null\r\n  /** 日期选择器实例 */\r\n  private datePicker: DatePicker\r\n\r\n  /**\r\n   * 创建日期粒子管理器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n    this.range = draw.getRange()\r\n    this.datePicker = new DatePicker(draw, {\r\n      onSubmit: this._setValue.bind(this)\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前光标所在的 date 元素（基于路径寻址）\r\n   * @returns date 元素或 null\r\n   */\r\n  private getDateElement(): IElement | null {\r\n    if (!this.range) return null\r\n    const focus = this.range.getFocus()\r\n    if (!focus) return null\r\n    const elementList = this.draw.getElementList()\r\n    return getByPath(elementList, focus.path)\r\n  }\r\n\r\n  /**\r\n   * 用户选择日期后写回：直接修改 date 元素的 valueList[0].value，再刷新文档\r\n   * @param date 用户选定的日期字符串\r\n   */\r\n  private _setValue(date: string) {\r\n    if (!date) return\r\n    const element = this.getDateElement()\r\n    if (!element || element.type !== 'date') return\r\n    const el = element as IElement & { valueList?: { value: string }[]; dateFormat?: string }\r\n    if (!el.valueList) {\r\n      el.valueList = [{ value: date }]\r\n    } else {\r\n      el.valueList[0] = { value: date }\r\n    }\r\n    // 刷新文档渲染\r\n    this.draw.setDocument(this.draw.getDocument())\r\n  }\r\n\r\n  /** 关闭日期选择器面板 */\r\n  public clearDatePicker() {\r\n    this.datePicker.dispose()\r\n  }\r\n\r\n  /**\r\n   * 渲染日期选择器面板\r\n   * @param element date 元素\r\n   * @param position 元素位置信息\r\n   */\r\n  public renderDatePicker(element: IElement, position: IElementPosition) {\r\n    const el = element as IElement & { valueList?: { value: string }[]; dateFormat?: string }\r\n    const value = el.valueList?.[0]?.value ?? ''\r\n    this.datePicker.render({\r\n      value,\r\n      position,\r\n      dateFormat: el.dateFormat\r\n    })\r\n  }\r\n}\r\n","/** Hershey 字形条目：包含包围盒与多段折线 */\r\ninterface HersheyEntry {\r\n  /** 字形宽度 */\r\n  w: number\r\n  /** X 方向最小值 */\r\n  xmin: number\r\n  /** X 方向最大值 */\r\n  xmax: number\r\n  /** Y 方向最小值 */\r\n  ymin: number\r\n  /** Y 方向最大值 */\r\n  ymax: number\r\n  /** 多段折线坐标 */\r\n  polylines: Array<Array<Array<number>>>\r\n}\r\n\r\n/** 'R' 字符的 ASCII 码，用于 Hershey 坐标解码基准 */\r\nconst ordR = 'R'.charCodeAt(0)\r\n\r\n/**\r\n * 获取指定索引的 Hershey 字形（懒编译并缓存）\r\n * @param i 字形索引\r\n * @returns 字形条目\r\n */\r\nexport function HERSHEY(i: number): HersheyEntry {\r\n  if (data[i] == null) {\r\n    compile(i)\r\n  }\r\n  return data[i]\r\n}\r\n\r\n/**\r\n * 编译原始 Hershey 字符串为字形条目并写入缓存\r\n * @param i 字形索引\r\n */\r\nfunction compile(i: number): void {\r\n  const entry: string = raw[i]\r\n  if (entry == null) {\r\n    return\r\n  }\r\n  const bound: string = entry.substring(3, 5)\r\n  const xmin: number = 1 * bound.charCodeAt(0) - ordR\r\n  const xmax: number = 1 * bound.charCodeAt(1) - ordR\r\n  const content: string = entry.substring(5)\r\n\r\n  const polylines: Array<Array<Array<number>>> = [[]]\r\n  let ymin = Infinity\r\n  let ymax = -Infinity\r\n  let zmin = Infinity\r\n  let zmax = -Infinity\r\n  let j = 0\r\n  while (j < content.length) {\r\n    const digit: string = content.substring(j, j + 2)\r\n    if (digit == ' R') {\r\n      polylines.push([])\r\n    } else {\r\n      const x: number = digit.charCodeAt(0) - ordR - xmin\r\n      const y: number = digit.charCodeAt(1) - ordR\r\n      ymin = Math.min(y, ymin)\r\n      ymax = Math.max(y, ymax)\r\n      zmin = Math.min(x, zmin)\r\n      zmax = Math.max(x, zmax)\r\n      polylines[polylines.length - 1].push([x, y])\r\n    }\r\n    j += 2\r\n  }\r\n  data[i] = {\r\n    w: xmax - xmin,\r\n    xmin: zmin,\r\n    xmax: zmax,\r\n    ymin: ymin,\r\n    ymax: ymax,\r\n    polylines: polylines\r\n  }\r\n}\r\n/** 已编译的字形缓存，按索引存取 */\r\nconst data: Record<number, HersheyEntry> = {}\r\n\r\n/** 原始 Hershey 字形字符串表 */\r\nconst raw: Record<number, string> = {\r\n  1: '  9MWRMNV RRMVV RPSTS',\r\n  2: ' 16MWOMOV ROMSMUNUPSQ ROQSQURUUSVOV',\r\n  3: ' 11MXVNTMRMPNOPOSPURVTVVU',\r\n  4: ' 12MWOMOV ROMRMTNUPUSTURVOV',\r\n  5: ' 12MWOMOV ROMUM ROQSQ ROVUV',\r\n  6: '  9MVOMOV ROMUM ROQSQ',\r\n  7: ' 15MXVNTMRMPNOPOSPURVTVVUVR RSRVR',\r\n  8: '  9MWOMOV RUMUV ROQUQ',\r\n  9: '  3PTRMRV',\r\n  10: '  7NUSMSTRVPVOTOS',\r\n  11: '  9MWOMOV RUMOS RQQUV',\r\n  12: '  6MVOMOV ROVUV',\r\n  13: ' 12LXNMNV RNMRV RVMRV RVMVV',\r\n  14: '  9MWOMOV ROMUV RUMUV',\r\n  15: ' 14MXRMPNOPOSPURVSVUUVSVPUNSMRM',\r\n  16: ' 10MWOMOV ROMSMUNUQSROR',\r\n  17: ' 17MXRMPNOPOSPURVSVUUVSVPUNSMRM RSTVW',\r\n  18: ' 13MWOMOV ROMSMUNUQSROR RRRUV',\r\n  19: ' 13MWUNSMQMONOOPPTRUSUUSVQVOU',\r\n  20: '  6MWRMRV RNMVM',\r\n  21: '  9MXOMOSPURVSVUUVSVM',\r\n  22: '  6MWNMRV RVMRV',\r\n  23: ' 12LXNMPV RRMPV RRMTV RVMTV',\r\n  24: '  6MWOMUV RUMOV',\r\n  25: '  7MWNMRQRV RVMRQ',\r\n  26: '  9MWUMOV ROMUM ROVUV',\r\n  27: '  9MWRMNV RRMVV RPSTS',\r\n  28: ' 16MWOMOV ROMSMUNUPSQ ROQSQURUUSVOV',\r\n  29: '  6MVOMOV ROMUM',\r\n  30: '  9MWRMNV RRMVV RNVVV',\r\n  31: ' 12MWOMOV ROMUM ROQSQ ROVUV',\r\n  32: '  9MWUMOV ROMUM ROVUV',\r\n  33: '  9MWOMOV RUMUV ROQUQ',\r\n  34: ' 20MXRMPNOPOSPURVSVUUVSVPUNSMRM RQQTR RTQQR',\r\n  35: '  3PTRMRV',\r\n  36: '  9MWOMOV RUMOS RQQUV',\r\n  37: '  6MWRMNV RRMVV',\r\n  38: ' 12LXNMNV RNMRV RVMRV RVMVV',\r\n  39: '  9MWOMOV ROMUV RUMUV',\r\n  40: ' 12MWOMUM RPQTR RTQPR ROVUV',\r\n  41: ' 14MXRMPNOPOSPURVSVUUVSVPUNSMRM',\r\n  42: '  9MWOMOV RUMUV ROMUM',\r\n  43: ' 10MWOMOV ROMSMUNUQSROR',\r\n  44: ' 10MWOMRQOV ROMUM ROVUV',\r\n  45: '  6MWRMRV RNMVM',\r\n  46: ' 15MWNONNOMPMQNRPRV RVOVNUMTMSNRP',\r\n  47: ' 13LXRMRV RPONPNSPTTTVSVPTOPO',\r\n  48: '  6MWOMUV RUMOV',\r\n  49: ' 12LXRMRV RNOOPOSQTSTUSUPVO',\r\n  50: ' 13MXOVQVOROPPNRMSMUNVPVRTVVV',\r\n  200: ' 12MWRMPNOPOSPURVTUUSUPTNRM',\r\n  201: '  4MWPORMRV',\r\n  202: '  9MWONQMSMUNUPTROVUV',\r\n  203: ' 15MWONQMSMUNUPSQ RRQSQURUUSVQVOU',\r\n  204: '  7MWSMSV RSMNSVS',\r\n  205: ' 14MWPMOQQPRPTQUSTURVQVOU RPMTM',\r\n  206: ' 14MWTMRMPNOPOSPURVTUUSTQRPPQOS',\r\n  207: '  6MWUMQV ROMUM',\r\n  208: ' 19MWQMONOPQQSQUPUNSMQM RQQOROUQVSVUUURSQ',\r\n  209: ' 14MWUPTRRSPROPPNRMTNUPUSTURVPV',\r\n  210: '  6PURURVSVSURU',\r\n  211: '  7PUSVRVRUSUSWRY',\r\n  212: ' 12PURPRQSQSPRP RRURVSVSURU',\r\n  213: ' 13PURPRQSQSPRP RSVRVRUSUSWRY',\r\n  214: ' 12PURMRR RSMSR RRURVSVSURU',\r\n  215: ' 17NWPNRMSMUNUPRQRRSRSQUP RRURVSVSURU',\r\n  216: '  3PTRMRQ',\r\n  217: '  6NVPMPQ RTMTQ',\r\n  218: ' 10NVQMPNPPQQSQTPTNSMQM',\r\n  219: ' 16MWUNSMQMONOPQQTRUSUUSVQVOU RRLRW',\r\n  220: '  3MWVLNW',\r\n  221: '  7OVTLRNQPQSRUTW',\r\n  222: '  7NUPLRNSPSSRUPW',\r\n  223: '  3PTRLRW',\r\n  224: '  3LXNRVR',\r\n  225: '  6LXRNRV RNRVR',\r\n  226: '  6LXNPVP RNTVT',\r\n  227: '  6MWOOUU RUOOU',\r\n  228: '  9MWRORU ROPUT RUPOT',\r\n  229: '  6PURQRRSRSQRQ',\r\n  230: '  7PUSMRORQSQSPRP',\r\n  231: '  7PUSNRNRMSMSORQ',\r\n  232: '  7LXSOVRSU RNRVR',\r\n  233: ' 12MXRLPW RULSW ROPVP ROSVS',\r\n  234: ' 21LXVRURTSSURVOVNUNSORRQSPSNRMPMONOPQSSUUVVV',\r\n  235: ' 20LXNNOQOSNV RVNUQUSVV RNNQOSOVN RNVQUSUVV',\r\n  501: '  9I[RFJ[ RRFZ[ RMTWT',\r\n  502: ' 24G\\\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[',\r\n  503: ' 19H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV',\r\n  504: ' 16G\\\\KFK[ RKFRFUGWIXKYNYSXVWXUZR[K[',\r\n  505: ' 12H[LFL[ RLFYF RLPTP RL[Y[',\r\n  506: '  9HZLFL[ RLFYF RLPTP',\r\n  507: ' 23H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS RUSZS',\r\n  508: '  9G]KFK[ RYFY[ RKPYP',\r\n  509: '  3NVRFR[',\r\n  510: ' 11JZVFVVUYTZR[P[NZMYLVLT',\r\n  511: '  9G\\\\KFK[ RYFKT RPOY[',\r\n  512: '  6HYLFL[ RL[X[',\r\n  513: ' 12F^JFJ[ RJFR[ RZFR[ RZFZ[',\r\n  514: '  9G]KFK[ RKFY[ RYFY[',\r\n  515: ' 22G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF',\r\n  516: ' 14G\\\\KFK[ RKFTFWGXHYJYMXOWPTQKQ',\r\n  517: ' 25G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RSWY]',\r\n  518: ' 17G\\\\KFK[ RKFTFWGXHYJYLXNWOTPKP RRPY[',\r\n  519: ' 21H\\\\YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX',\r\n  520: '  6JZRFR[ RKFYF',\r\n  521: ' 11G]KFKULXNZQ[S[VZXXYUYF',\r\n  522: '  6I[JFR[ RZFR[',\r\n  523: ' 12F^HFM[ RRFM[ RRFW[ R\\\\FW[',\r\n  524: '  6H\\\\KFY[ RYFK[',\r\n  525: '  7I[JFRPR[ RZFRP',\r\n  526: '  9H\\\\YFK[ RKFYF RK[Y[',\r\n  527: '  9I[RFJ[ RRFZ[ RMTWT',\r\n  528: ' 24G\\\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[',\r\n  529: '  6HYLFL[ RLFXF',\r\n  530: '  9I[RFJ[ RRFZ[ RJ[Z[',\r\n  531: ' 12H[LFL[ RLFYF RLPTP RL[Y[',\r\n  532: '  9H\\\\YFK[ RKFYF RK[Y[',\r\n  533: '  9G]KFK[ RYFY[ RKPYP',\r\n  534: ' 25G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF ROPUP',\r\n  535: '  3NVRFR[',\r\n  536: '  9G\\\\KFK[ RYFKT RPOY[',\r\n  537: '  6I[RFJ[ RRFZ[',\r\n  538: ' 12F^JFJ[ RJFR[ RZFR[ RZFZ[',\r\n  539: '  9G]KFK[ RKFY[ RYFY[',\r\n  540: '  9I[KFYF ROPUP RK[Y[',\r\n  541: ' 22G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF',\r\n  542: '  9G]KFK[ RYFY[ RKFYF',\r\n  543: ' 14G\\\\KFK[ RKFTFWGXHYJYMXOWPTQKQ',\r\n  544: ' 10I[KFRPK[ RKFYF RK[Y[',\r\n  545: '  6JZRFR[ RKFYF',\r\n  546: ' 19I[KKKILGMFOFPGQIRMR[ RYKYIXGWFUFTGSIRM',\r\n  547: ' 21H\\\\RFR[ RPKMLLMKOKRLTMUPVTVWUXTYRYOXMWLTKPK',\r\n  548: '  6H\\\\KFY[ RK[YF',\r\n  549: ' 18G]RFR[ RILJLKMLQMSNTQUSUVTWSXQYMZL[L',\r\n  550: ' 17H\\\\K[O[LTKPKLLINGQFSFVGXIYLYPXTU[Y[',\r\n  551: ' 20G[G[IZLWOSSLVFV[UXSUQSNQLQKRKTLVNXQZT[Y[',\r\n  552: ' 41F]SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFXFZG[I[KZMYNWOTP RSPTPWQXRYTYWXYWZU[R[PZOX',\r\n  553: ' 24H\\\\TLTMUNWNYMZKZIYGWFTFQGOIMLLNKRKVLYMZO[Q[TZVXWV',\r\n  554: ' 35G^TFRGQIPMOSNVMXKZI[G[FZFXGWIWKXMZP[S[VZXXZT[O[KZHYGWFTFRHRJSMUPWRZT\\\\U',\r\n  555: ' 28H\\\\VJVKWLYLZKZIYGVFRFOGNINLONPOSPPPMQLRKTKWLYMZP[S[VZXXYV',\r\n  556: ' 28H\\\\RLPLNKMINGQFTFXG[G]F RXGVNTTRXPZN[L[JZIXIVJULUNV RQPZP',\r\n  557: ' 29G^G[IZMVPQQNRJRGQFPFOGNINLONQOUOXNYMZKZQYVXXVZS[O[LZJXIVIT',\r\n  558: ' 38F^MMKLJJJIKGMFNFPGQIQKPONULYJ[H[GZGX RMRVOXN[L]J^H^G]F\\\\FZHXLVRUWUZV[W[YZZY\\\\V',\r\n  559: ' 25IZWVUTSQROQLQIRGSFUFVGWIWLVQTVSXQZO[M[KZJXJVKUMUOV',\r\n  560: ' 25JYT^R[PVOPOJPGRFTFUGVJVMURR[PaOdNfLgKfKdLaN^P\\\\SZWX',\r\n  561: ' 39F^MMKLJJJIKGMFNFPGQIQKPONULYJ[H[GZGX R^I^G]F\\\\FZGXIVLTNROPO RROSQSXTZU[V[XZYY[V',\r\n  562: ' 29I\\\\MRORSQVOXMYKYHXFVFUGTISNRSQVPXNZL[J[IZIXJWLWNXQZT[V[YZ[X',\r\n  563: ' 45@aEMCLBJBICGEFFFHGIIIKHPGTE[ RGTJLLHMGOFPFRGSISKRPQTO[ RQTTLVHWGYFZF\\\\G]I]K\\\\PZWZZ[[\\\\[^Z_YaV',\r\n  564: ' 32E]JMHLGJGIHGJFKFMGNINKMPLTJ[ RLTOLQHRGTFVFXGYIYKXPVWVZW[X[ZZ[Y]V',\r\n  565: ' 29H]TFQGOIMLLNKRKVLYMZO[Q[TZVXXUYSZOZKYHXGVFTFRHRKSNUQWSZU\\\\V',\r\n  566: ' 31F_SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFZF\\\\G]H^J^M]O\\\\PZQWQUPTO',\r\n  567: ' 32H^ULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWSSWPYNZK[I[HZHXIWKWMXPZS[V[YZ[X',\r\n  568: ' 38F_SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFYF[G\\\\H]J]M\\\\O[PYQVQSPTQUSUXVZX[ZZ[Y]V',\r\n  569: ' 28H\\\\H[JZLXOTQQSMTJTGSFRFQGPIPKQMSOVQXSYUYWXYWZT[P[MZKXJVJT',\r\n  570: ' 25H[RLPLNKMINGQFTFXG[G]F RXGVNTTRXPZN[L[JZIXIVJULUNV',\r\n  571: ' 33E]JMHLGJGIHGJFKFMGNINKMOLRKVKXLZN[P[RZSYUUXMZF RXMWQVWVZW[X[ZZ[Y]V',\r\n  572: ' 32F]KMILHJHIIGKFLFNGOIOKNOMRLVLYM[O[QZTWVTXPYMZIZGYFXFWGVIVKWNYP[Q',\r\n  573: ' 25C_HMFLEJEIFGHFIFKGLILLK[ RUFK[ RUFS[ RaF_G\\\\JYNVTS[',\r\n  574: ' 36F^NLLLKKKILGNFPFRGSISLQUQXRZT[V[XZYXYVXUVU R]I]G\\\\FZFXGVITLPUNXLZJ[H[GZGX',\r\n  575: ' 38F]KMILHJHIIGKFLFNGOIOKNOMRLVLXMZN[P[RZTXVUWSYM R[FYMVWT]RbPfNgMfMdNaP^S[VY[V',\r\n  576: ' 40H]ULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWTTWPZN[K[JZJXKWNWPXQYR[R^QaPcNfLgKfKdLaN^Q[TYZV',\r\n  583: '  9I[JFR[ RZFR[ RJFZF',\r\n  601: ' 18I\\\\XMX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  602: ' 18H[LFL[ RLPNNPMSMUNWPXSXUWXUZS[P[NZLX',\r\n  603: ' 15I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  604: ' 18I\\\\XFX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  605: ' 18I[LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  606: '  9MYWFUFSGRJR[ ROMVM',\r\n  607: ' 23I\\\\XMX]W`VaTbQbOa RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  608: ' 11I\\\\MFM[ RMQPNRMUMWNXQX[',\r\n  609: '  9NVQFRGSFREQF RRMR[',\r\n  610: ' 12MWRFSGTFSERF RSMS^RaPbNb',\r\n  611: '  9IZMFM[ RWMMW RQSX[',\r\n  612: '  3NVRFR[',\r\n  613: ' 19CaGMG[ RGQJNLMOMQNRQR[ RRQUNWMZM\\\\N]Q][',\r\n  614: ' 11I\\\\MMM[ RMQPNRMUMWNXQX[',\r\n  615: ' 18I\\\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM',\r\n  616: ' 18H[LMLb RLPNNPMSMUNWPXSXUWXUZS[P[NZLX',\r\n  617: ' 18I\\\\XMXb RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  618: '  9KXOMO[ ROSPPRNTMWM',\r\n  619: ' 18J[XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX',\r\n  620: '  9MYRFRWSZU[W[ ROMVM',\r\n  621: ' 11I\\\\MMMWNZP[S[UZXW RXMX[',\r\n  622: '  6JZLMR[ RXMR[',\r\n  623: ' 12G]JMN[ RRMN[ RRMV[ RZMV[',\r\n  624: '  6J[MMX[ RXMM[',\r\n  625: ' 10JZLMR[ RXMR[P_NaLbKb',\r\n  626: '  9J[XMM[ RMMXM RM[X[',\r\n  627: ' 24H]QMONMPLRKUKXLZN[P[RZUWWTYPZM RQMSMTNUPWXXZY[Z[',\r\n  628: ' 31I\\\\UFSGQIOMNPMTLZKb RUFWFYHYKXMWNUORO RROTPVRWTWWVYUZS[Q[OZNYMV',\r\n  629: ' 17I\\\\JPLNNMOMQNROSRSVR[ RZMYPXRR[P_Ob',\r\n  630: ' 24I[TMQMONMPLSLVMYNZP[R[TZVXWUWRVOTMRKQIQGRFTFVGXI',\r\n  631: ' 19JZWOVNTMQMONOPPRSS RSSOTMVMXNZP[S[UZWX',\r\n  632: ' 23JYTFRGQHQIRJUKXK RXKTMQONRMUMWNYP[S]T_TaSbQbP`',\r\n  633: ' 19H\\\\IQJOLMNMONOPNTL[ RNTPPRNTMVMXOXRWWTb',\r\n  634: ' 27G\\\\HQIOKMMMNNNPMUMXNZO[Q[SZUWVUWRXMXJWGUFSFRHRJSMUPWRZT',\r\n  635: '  9LWRMPTOXOZP[R[TYUW',\r\n  636: ' 19I[OMK[ RYNXMWMUNQROSNS RNSPTQUSZT[U[VZ',\r\n  637: '  9JZKFMFOGPHX[ RRML[',\r\n  638: ' 21H]OMIb RNQMVMYO[Q[SZUXWT RYMWTVXVZW[Y[[Y\\\\W',\r\n  639: ' 14I[LMOMNSMXL[ RYMXPWRUURXOZL[',\r\n  640: ' 29JZTFRGQHQIRJUKXK RUKRLPMOOOQQSTTVT RTTPUNVMXMZO\\\\S^T_TaRbPb',\r\n  641: ' 18J[RMPNNPMSMVNYOZQ[S[UZWXXUXRWOVNTMRM',\r\n  642: ' 13G]PML[ RUMVSWXX[ RIPKNNM[M',\r\n  643: ' 19I[MSMVNYOZQ[S[UZWXXUXRWOVNTMRMPNNPMSIb',\r\n  644: ' 18I][MQMONMPLSLVMYNZP[R[TZVXWUWRVOUNSM',\r\n  645: '  8H\\\\SMP[ RJPLNOMZM',\r\n  646: ' 16H\\\\IQJOLMNMONOPMVMYO[Q[TZVXXTYPYM',\r\n  647: ' 21G]ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb',\r\n  648: ' 14I[KMMMOOU`WbYb RZMYOWRM]K`Jb',\r\n  649: ' 20F]VFNb RGQHOJMLMMNMPLULXMZO[Q[TZVXXUZP[M',\r\n  650: ' 23F]NMLNJQITIWJZK[M[OZQW RRSQWRZS[U[WZYWZTZQYNXM',\r\n  651: ' 22L\\\\UUTSRRPRNSMTLVLXMZO[Q[SZTXVRUWUZV[W[YZZY\\\\V',\r\n  652: ' 23M[MVOSRNSLTITGSFQGPIOMNTNZO[P[RZTXUUURVVWWYW[V',\r\n  653: ' 14MXTTTSSRQROSNTMVMXNZP[S[VYXV',\r\n  654: ' 24L\\\\UUTSRRPRNSMTLVLXMZO[Q[SZTXZF RVRUWUZV[W[YZZY\\\\V',\r\n  655: ' 17NXOYQXRWSUSSRRQROSNUNXOZQ[S[UZVYXV',\r\n  656: ' 24OWOVSQUNVLWIWGVFTGSIQQNZKaJdJfKgMfNcOZP[R[TZUYWV',\r\n  657: ' 28L[UUTSRRPRNSMTLVLXMZO[Q[SZTY RVRTYPdOfMgLfLdMaP^S\\\\U[XY[V',\r\n  658: ' 29M\\\\MVOSRNSLTITGSFQGPIOMNSM[ RM[NXOVQSSRURVSVUUXUZV[W[YZZY\\\\V',\r\n  659: ' 16PWSMSNTNTMSM RPVRRPXPZQ[R[TZUYWV',\r\n  660: ' 20PWSMSNTNTMSM RPVRRLdKfIgHfHdIaL^O\\\\Q[TYWV',\r\n  661: ' 33M[MVOSRNSLTITGSFQGPIOMNSM[ RM[NXOVQSSRURVSVUTVQV RQVSWTZU[V[XZYY[V',\r\n  662: ' 18OWOVQSTNULVIVGUFSGRIQMPTPZQ[R[TZUYWV',\r\n  663: ' 33E^EVGSIRJSJTIXH[ RIXJVLSNRPRQSQTPXO[ RPXQVSSURWRXSXUWXWZX[Y[[Z\\\\Y^V',\r\n  664: ' 23J\\\\JVLSNROSOTNXM[ RNXOVQSSRURVSVUUXUZV[W[YZZY\\\\V',\r\n  665: ' 23LZRRPRNSMTLVLXMZO[Q[SZTYUWUUTSRRQSQURWTXWXYWZV',\r\n  666: ' 24KZKVMSNQMUGg RMUNSPRRRTSUUUWTYSZQ[ RMZO[R[UZWYZV',\r\n  667: ' 27L[UUTSRRPRNSMTLVLXMZO[Q[SZ RVRUUSZPaOdOfPgRfScS\\\\U[XY[V',\r\n  668: ' 15MZMVOSPQPSSSTTTVSYSZT[U[WZXYZV',\r\n  669: ' 16NYNVPSQQQSSVTXTZR[ RNZP[T[VZWYYV',\r\n  670: ' 16OXOVQSSO RVFPXPZQ[S[UZVYXV RPNWN',\r\n  671: ' 19L[LVNRLXLZM[O[QZSXUU RVRTXTZU[V[XZYY[V',\r\n  672: ' 17L[LVNRMWMZN[O[RZTXUUUR RURVVWWYW[V',\r\n  673: ' 25I^LRJTIWIYJ[L[NZPX RRRPXPZQ[S[UZWXXUXR RXRYVZW\\\\W^V',\r\n  674: ' 20JZJVLSNRPRQSQZR[U[XYZV RWSVRTRSSOZN[L[KZ',\r\n  675: ' 23L[LVNRLXLZM[O[QZSXUU RVRPdOfMgLfLdMaP^S\\\\U[XY[V',\r\n  676: ' 23LZLVNSPRRRTTTVSXQZN[P\\\\Q^QaPdOfMgLfLdMaP^S\\\\WYZV',\r\n  677: ' 22J\\\\K[NZQXSVUSWOXKXIWGUFSGRHQJPOPTQXRZT[V[XZYY',\r\n  683: ' 26I[WUWRVOUNSMQMONMPLSLVMYNZP[R[TZVXWUXPXKWHVGTFRFPGNI',\r\n  684: ' 16JZWNUMRMPNNPMSMVNYOZQ[T[VZ RMTUT',\r\n  685: ' 23J[TFRGPJOLNOMTMXNZO[Q[SZUWVUWRXMXIWGVFTF RNPWP',\r\n  686: ' 21H\\\\VFNb RQMNNLPKSKVLXNZQ[S[VZXXYUYRXPVNSMQM',\r\n  687: ' 16I[XOWNTMQMNNMOLQLSMUOWSZT\\\\T^S_Q_',\r\n  700: ' 18H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF',\r\n  701: '  5H\\\\NJPISFS[',\r\n  702: ' 15H\\\\LKLJMHNGPFTFVGWHXJXLWNUQK[Y[',\r\n  703: ' 16H\\\\MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW',\r\n  704: '  7H\\\\UFKTZT RUFU[',\r\n  705: ' 18H\\\\WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW',\r\n  706: ' 24H\\\\XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT',\r\n  707: '  6H\\\\YFO[ RKFYF',\r\n  708: ' 30H\\\\PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF',\r\n  709: ' 24H\\\\XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX',\r\n  710: '  6MWRYQZR[SZRY',\r\n  711: '  9MWSZR[QZRYSZS\\\\R^Q_',\r\n  712: ' 12MWRMQNROSNRM RRYQZR[SZRY',\r\n  713: ' 15MWRMQNROSNRM RSZR[QZRYSZS\\\\R^Q_',\r\n  714: '  9MWRFRT RRYQZR[SZRY',\r\n  715: ' 21I[LKLJMHNGPFTFVGWHXJXLWNVORQRT RRYQZR[SZRY',\r\n  716: '  3NVRFRM',\r\n  717: '  6JZNFNM RVFVM',\r\n  718: ' 14KYQFOGNINKOMQNSNUMVKVIUGSFQF',\r\n  719: ' 27H\\\\PBP_ RTBT_ RYIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX',\r\n  720: '  3G][BIb',\r\n  721: ' 11KYVBTDRGPKOPOTPYR]T`Vb',\r\n  722: ' 11KYNBPDRGTKUPUTTYR]P`Nb',\r\n  723: '  3NVRBRb',\r\n  724: '  3E_IR[R',\r\n  725: '  6E_RIR[ RIR[R',\r\n  726: '  6E_IO[O RIU[U',\r\n  727: '  6G]KKYY RYKKY',\r\n  728: '  9JZRLRX RMOWU RWOMU',\r\n  729: '  6MWRQQRRSSRRQ',\r\n  730: '  8MWSFRGQIQKRLSKRJ',\r\n  731: '  8MWRHQGRFSGSIRKQL',\r\n  732: '  9E_UMXP[RXTUW RIR[R',\r\n  733: ' 12H]SBLb RYBRb RLOZO RKUYU',\r\n  734: ' 35E_\\\\O\\\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\\\Z\\\\Y',\r\n  735: ' 28G]IIJKKOKUJYI[ R[IZKYOYUZY[[ RIIKJOKUKYJ[I RI[KZOYUYYZ[[',\r\n  737: '  6KYOBO[ RUBU[',\r\n  738: '  6F^RBR[ RI[[[',\r\n  739: '  4F^[BI[[[',\r\n  740: ' 18E_RIQJRKSJRI RIYHZI[JZIY R[YZZ[[\\\\Z[Y',\r\n  741: ' 33F^RHNLKPJSJUKWMXOXQWRU RRHVLYPZSZUYWWXUXSWRU RRUQYP\\\\ RRUSYT\\\\ RP\\\\T\\\\',\r\n  742: ' 26F^RNQKPINHMHKIJKJOKRLTNWR\\\\ RRNSKTIVHWHYIZKZOYRXTVWR\\\\',\r\n  743: ' 20F^RGPJLOIR RRGTJXO[R RIRLUPZR] R[RXUTZR]',\r\n  744: ' 48F^RTTWVXXXZW[U[SZQXPVPSQ RSQUOVMVKUISHQHOINKNMOOQQ RQQNPLPJQISIUJWLXNXPWRT RRTQYP\\\\ RRTSYT\\\\ RP\\\\T\\\\',\r\n  745: ' 55F^RRR[Q\\\\ RRVQ\\\\ RRIQHOHNINKONRR RRISHUHVIVKUNRR RRRNOLNJNIOIQJR RRRVOXNZN[O[QZR RRRNULVJVIUISJR RRRVUXVZV[U[SZR',\r\n  746: ' 55F^ISJSLTMVMXLZ RISIRJQLQMRNTNWMYLZ RRGPIOLOOQUQXPZR\\\\ RRGTIULUOSUSXTZR\\\\ R[S[RZQXQWRVTVWWYXZ R[SZSXTWVWXXZ RKVYV',\r\n  750: ' 18PSSRRSQSPRPQQPRPSQSSRUQV RQQQRRRRQQQ',\r\n  751: ' 16PTQPPQPSQTSTTSTQSPQP RRQQRRSSRRQ',\r\n  752: '  9NVPOTU RTOPU RNRVR',\r\n  753: ' 28MWRKQMOPMR RRKSMUPWR RRMOQ RRMUQ RROPQ RROTQ RQQSQ RMRWR',\r\n  754: ' 26MWMRMQNOONQMSMUNVOWQWR RPNTN ROOUO RNPVP RNQVQ RMRWR',\r\n  755: ' 14LRLFLRRRLF RLIPQ RLLOR RLOMQ',\r\n  756: ' 10MWRKQMOPMR RRKSMUPWR',\r\n  757: ' 11MWWRWQVOUNSMQMONNOMQMR',\r\n  758: ' 13G]]R]P\\\\MZJWHTGPGMHJJHMGPGR',\r\n  759: ' 11MWMRMSNUOVQWSWUVVUWSWR',\r\n  760: '  7LXLPNRQSSSVRXP',\r\n  761: '  6RURUTTURTPRO',\r\n  762: '  7RVRRUPVNVLUKTK',\r\n  763: '  7NRRROPNNNLOKPK',\r\n  764: ' 21MWWHVGTFQFOGNHMJMLNNOOUSVTWVWXVZU[S\\\\P\\\\N[MZ',\r\n  765: ' 21G]IWHVGTGQHOINKMMMONPOTUUVWWYW[V\\\\U]S]P\\\\N[M',\r\n  766: ' 31G]RRTUUVWWYW[V\\\\U]S]Q\\\\O[NYMWMUNTOPUOVMWKWIVHUGSGQHOINKMMMONPORR',\r\n  767: ' 22H\\\\KFK[ RHF[FQP[Z RZV[Y\\\\[ RZVZY RWYZY RWYZZ\\\\[',\r\n  768: ' 30KYUARBPCNELHKLKRLUNWQXSXVWXUYR RKPLMNKQJSJVKXMYPYVXZV]T_R`Oa',\r\n  796: '  3>f>RfR',\r\n  797: '  3D`D``D',\r\n  798: '  3RRR>Rf',\r\n  799: '  3D`DD``',\r\n  800: '  3D`DR`R',\r\n  801: '  3F^FY^K',\r\n  802: '  3KYK^YF',\r\n  803: '  3RRRDR`',\r\n  804: '  3KYKFY^',\r\n  805: '  3F^FK^Y',\r\n  806: '  3KYKRYR',\r\n  807: '  3MWMWWM',\r\n  808: '  3RRRKRY',\r\n  809: '  3MWMMWW',\r\n  810: '  8GRRGPGMHJJHMGPGR',\r\n  811: '  8GRGRGTHWJZM\\\\P]R]',\r\n  812: '  8R]R]T]W\\\\ZZ\\\\W]T]R',\r\n  813: '  8R]]R]P\\\\MZJWHTGRG',\r\n  814: '  9D`DOGQKSPTTTYS]Q`O',\r\n  815: '  9PUUDSGQKPPPTQYS]U`',\r\n  816: '  9OTODQGSKTPTTSYQ]O`',\r\n  817: '  9D`DUGSKQPPTPYQ]S`U',\r\n  818: '  5KYRJYNKVRZ',\r\n  819: '  5JZJRNKVYZR',\r\n  820: '  5KYKVKNYVYN',\r\n  821: '  5JZLXJPZTXL',\r\n  822: ' 23JZJ]L]O\\\\Q[TXUVVSVOULTJSIQIPJOLNONSOVPXS[U\\\\X]Z]',\r\n  823: ' 23I]]Z]X\\\\U[SXPVOSNONLOJPIQISJTLUOVSVVUXT[Q\\\\O]L]J',\r\n  824: ' 23JZZGXGUHSIPLONNQNUOXPZQ[S[TZUXVUVQUNTLQIOHLGJG',\r\n  825: ' 23G[GJGLHOIQLTNUQVUVXUZT[S[QZPXOUNQNNOLPISHUGXGZ',\r\n  826: ' 21E[EPFRHTJUMVQVUUXSZP[NZLWLSMQNNPLSKVKYL\\\\M^',\r\n  827: ' 19EYETHVKWPWSVVTXQYNYLXKVKSLPNNQMTMYN\\\\P_',\r\n  828: ' 26OUQOOQOSQUSUUSUQSOQO RQPPQPSQTSTTSTQSPQP RRQQRRSSRRQ',\r\n  829: ' 11RWRMSMUNVOWQWSVUUVSWRW',\r\n  830: '  9D`DRJR RORUR RZR`R',\r\n  831: '  5D`DUDO`O`U',\r\n  832: '  6JZRDJR RRDZR',\r\n  833: '  9D`DR`R RJYZY RP`T`',\r\n  834: '  9D`DR`R RDRRb R`RRb',\r\n  840: ' 18KYQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK',\r\n  841: '  6LXLLLXXXXLLL',\r\n  842: '  5KYRJKVYVRJ',\r\n  843: '  6LXRHLRR\\\\XRRH',\r\n  844: ' 12JZRIPOJOOSMYRUWYUSZOTORI',\r\n  845: '  6KYRKRY RKRYR',\r\n  846: '  6MWMMWW RWMMW',\r\n  847: '  9MWRLRX RMOWU RWOMU',\r\n  850: ' 35NVQNOONQNSOUQVSVUUVSVQUOSNQN ROQOS RPPPT RQOQU RRORU RSOSU RTPTT RUQUS',\r\n  851: ' 27NVNNNVVVVNNN ROOOU RPOPU RQOQU RRORU RSOSU RTOTU RUOUU',\r\n  852: ' 17MWRLMUWURL RROOT RROUT RRRQT RRRST',\r\n  853: ' 17LULRUWUMLR RORTU RORTO RRRTS RRRTQ',\r\n  854: ' 17MWRXWOMORX RRUUP RRUOP RRRSP RRRQP',\r\n  855: ' 17OXXROMOWXR RURPO RURPU RRRPQ RRRPS',\r\n  856: ' 22LXRLNWXPLPVWRL RRRRL RRRLP RRRNW RRRVW RRRXP',\r\n  857: ' 11RYRKRY RRKYNRQ RSMVNSO',\r\n  860: ' 13MWRLRX ROOUO RMUOWQXSXUWWU',\r\n  861: ' 11LXRLRX RLQMOWOXQ RPWTW',\r\n  862: ' 14KYMNWX RWNMX ROLLOKQ RULXOYQ',\r\n  863: ' 18I[NII[ RVI[[ RMM[[ RWMI[ RNIVI RMMWM',\r\n  864: ' 21I[RGRV RMJWP RWJMP RIVL\\\\ R[VX\\\\ RIV[V RL\\\\X\\\\',\r\n  865: ' 11G[MJSV RKPSL RG\\\\[\\\\[RG\\\\',\r\n  866: ' 14LXPLPPLPLTPTPXTXTTXTXPTPTLPL',\r\n  867: ' 32KYYPXNVLSKQKNLLNKQKSLVNXQYSYVXXVYT RYPWNUMSMQNPOOQOSPUQVSWUWWVYT',\r\n  868: ' 10KYRJKVYVRJ RRZYNKNRZ',\r\n  869: ' 34G]PIPGQFSFTGTI RGZHXJVKTLPLKMJOIUIWJXKXPYTZV\\\\X]Z RGZ]Z RQZP[Q\\\\S\\\\T[SZ',\r\n  870: ' 64JZRMRS RRSQ\\\\ RRSS\\\\ RQ\\\\S\\\\ RRMQJPHNG RQJNG RRMSJTHVG RSJVG RRMNKLKJM RPLLLJM RRMVKXKZM RTLXLZM RRMPNOOOR RRMPOOR RRMTNUOUR RRMTOUR',\r\n  871: ' 94JZRIRK RRNRP RRSRU RRYQ\\\\ RRYS\\\\ RQ\\\\S\\\\ RRGQIPJ RRGSITJ RPJRITJ RRKPNNOMN RRKTNVOWN RNOPORNTOVO RRPPSNTLTKRKSLT RRPTSVTXTYRYSXT RNTPTRSTTVT RRUPXOYMZLZKYJWJYLZ RRUTXUYWZXZYYZWZYXZ RMZOZRYUZWZ',\r\n  872: ' 40JZRYQ\\\\ RRYS\\\\ RQ\\\\S\\\\ RRYUZXZZXZUYTWTYRZOYMWLUMVJUHSGQGOHNJOMMLKMJOKRMTKTJUJXLZOZRY',\r\n  873: ' 32JZRYQ\\\\ RRYS\\\\ RQ\\\\S\\\\ RRYVXVVXUXRZQZLYIXHVHTGPGNHLHKIJLJQLRLUNVNXRY',\r\n  874: ' 15I[IPKR RLKNP RRGRO RXKVP R[PYR',\r\n  899: '  6QSRQQRRSSRRQ',\r\n  900: ' 10PTQPPQPSQTSTTSTQSPQP',\r\n  901: ' 14NVQNOONQNSOUQVSVUUVSVQUOSNQN',\r\n  902: ' 18MWQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM',\r\n  903: ' 18KYQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK',\r\n  904: ' 22G]PGMHJJHMGPGTHWJZM\\\\P]T]W\\\\ZZ\\\\W]T]P\\\\MZJWHTGPG',\r\n  905: ' 34AcPALBJCGEEGCJBLAPATBXCZE]G_JaLbPcTcXbZa]__]aZbXcTcPbLaJ_G]EZCXBTAPA',\r\n  906: ' 34<hP<K=G?DAAD?G=K<P<T=Y?]A`DcGeKgPhThYg]e`cc`e]gYhThPgKeGcD`A]?Y=T<P<',\r\n  907: ' 50){O)I*E+@-;073370;-@+E*I)O)U*[+_-d0i3m7q;t@wEyIzO{U{[z_ydwitmqqmtiwdy_z[{U{OzIyEw@t;q7m3i0d-_+[*U)O)',\r\n  908: ' 34>fRAPCMDJDGCEA>H@JAMAZB]D_G`M`PaRc RRATCWDZD]C_AfHdJcMcZb]`_]`W`TaRc',\r\n  909: ' 33AcRAPCMDJDGCEABGAKAPBTDXG\\\\L`Rc RRATCWDZD]C_AbGcKcPbT`X]\\\\X`Rc RBHbH',\r\n  997: '  3MWMXWX',\r\n  998: '  3JZJZZZ',\r\n  999: '  3JZJ]Z]',\r\n  1001: ' 18KYRKMX RRNVX RRKWX ROTTT RKXPX RTXYX',\r\n  1002: ' 35JZNKNX ROKOX RLKSKVLWNVPSQ RSKULVNUPSQ ROQSQVRWTWUVWSXLX RSQURVTVUUWSX',\r\n  1003: ' 24KYVLWKWOVLTKQKOLNMMPMSNVOWQXTXVWWU RQKOMNPNSOVQX',\r\n  1004: ' 26JZNKNX ROKOX RLKSKVLWMXPXSWVVWSXLX RSKULVMWPWSVVUWSX',\r\n  1005: ' 22JYNKNX ROKOX RSOSS RLKVKVOUK ROQSQ RLXVXVTUX',\r\n  1006: ' 20JXNKNX ROKOX RSOSS RLKVKVOUK ROQSQ RLXQX',\r\n  1007: ' 36K[VLWKWOVLTKQKOLNMMPMSNVOWQXTXVW RQKOMNPNSOVQX RTXUWVU RVSVX RWSWX RTSYS',\r\n  1008: ' 27J[NKNX ROKOX RVKVX RWKWX RLKQK RTKYK ROQVQ RLXQX RTXYX',\r\n  1009: ' 12NWRKRX RSKSX RPKUK RPXUX',\r\n  1010: ' 19LXSKSURWQX RTKTUSWQXPXNWMUNTOUNV RQKVK',\r\n  1011: ' 27JZNKNX ROKOX RWKOS RQQVX RRQWX RLKQK RTKYK RLXQX RTXYX',\r\n  1012: ' 14KXOKOX RPKPX RMKRK RMXWXWTVX',\r\n  1013: ' 30I\\\\MKMX RNNRX RNKRU RWKRX RWKWX RXKXX RKKNK RWKZK RKXOX RUXZX',\r\n  1014: ' 21JZNKNX ROMVX ROKVV RVKVX RLKOK RTKXK RLXPX',\r\n  1015: ' 32KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK',\r\n  1016: ' 25JYNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXQX',\r\n  1017: ' 47KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK RPWPUQTSTTUUZV[W[XZ RTUUXVZW[',\r\n  1018: ' 37JZNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXQX RSRTSUWVXWXXW RSRUSVWWX',\r\n  1019: ' 32KZVMWKWOVMULSKQKOLNMNOOPQQTRVSWT RNNOOQPTQVRWSWVVWTXRXPWOVNTNXOV',\r\n  1020: ' 16KZRKRX RSKSX RNKMOMKXKXOWK RPXUX',\r\n  1021: ' 20J[NKNUOWQXTXVWWUWK ROKOUPWQX RLKQK RUKYK',\r\n  1022: ' 15KYMKRX RNKRU RWKRX RKKPK RTKYK',\r\n  1023: ' 24I[LKOX RMKOT RRKOX RRKUX RSKUT RXKUX RJKOK RVKZK',\r\n  1024: ' 21KZNKVX ROKWX RWKNX RLKQK RTKYK RLXQX RTXYX',\r\n  1025: ' 20LYNKRRRX ROKSR RWKSRSX RLKQK RTKYK RPXUX',\r\n  1026: ' 16LYVKNX RWKOX ROKNONKWK RNXWXWTVX',\r\n  1027: ' 18KYRKMX RRNVX RRKWX ROTTT RKXPX RTXYX',\r\n  1028: ' 35JZNKNX ROKOX RLKSKVLWNVPSQ RSKULVNUPSQ ROQSQVRWTWUVWSXLX RSQURVTVUUWSX',\r\n  1029: ' 14KXOKOX RPKPX RMKWKWOVK RMXRX',\r\n  1030: ' 15KYRKLX RRMWX RRKXX RMWVW RLXXX',\r\n  1031: ' 22JYNKNX ROKOX RSOSS RLKVKVOUK ROQSQ RLXVXVTUX',\r\n  1032: ' 16LYVKNX RWKOX ROKNONKWK RNXWXWTVX',\r\n  1033: ' 27J[NKNX ROKOX RVKVX RWKWX RLKQK RTKYK ROQVQ RLXQX RTXYX',\r\n  1034: ' 44KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK RQOQT RTOTT RQQTQ RQRTR',\r\n  1035: ' 12NWRKRX RSKSX RPKUK RPXUX',\r\n  1036: ' 27JZNKNX ROKOX RWKOS RQQVX RRQWX RLKQK RTKYK RLXQX RTXYX',\r\n  1037: ' 15KYRKMX RRNVX RRKWX RKXPX RTXYX',\r\n  1038: ' 30I\\\\MKMX RNNRX RNKRU RWKRX RWKWX RXKXX RKKNK RWKZK RKXOX RUXZX',\r\n  1039: ' 21JZNKNX ROMVX ROKVV RVKVX RLKOK RTKXK RLXPX',\r\n  1040: ' 36JZMJLM RXJWM RPPOS RUPTS RMVLY RXVWY RMKWK RMLWL RPQTQ RPRTR RMWWW RMXWX',\r\n  1041: ' 32KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK',\r\n  1042: ' 21J[NKNX ROKOX RVKVX RWKWX RLKYK RLXQX RTXYX',\r\n  1043: ' 25JYNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXQX',\r\n  1044: ' 20K[MKRQ RNKSQMX RMKWKXOVK RNWWW RMXWXXTVX',\r\n  1045: ' 16KZRKRX RSKSX RNKMOMKXKXOWK RPXUX',\r\n  1046: ' 33KZMONLOKPKQLRORX RXOWLVKUKTLSOSX RMONMOLPLQMRO RXOWMVLULTMSO RPXUX',\r\n  1047: ' 40KZRKRX RSKSX RQNNOMQMRNTQUTUWTXRXQWOTNQN RQNOONQNROTQU RTUVTWRWQVOTN RPKUK RPXUX',\r\n  1048: ' 21KZNKVX ROKWX RWKNX RLKQK RTKYK RLXQX RTXYX',\r\n  1049: ' 33J[RKRX RSKSX RLPMONOOSQU RTUVSWOXOYP RMONROTQUTUVTWRXO RPKUK RPXUX',\r\n  1050: ' 35KZMVNXQXMRMONMOLQKTKVLWMXOXRTXWXXV ROUNRNOOMQK RTKVMWOWRVU RNWPW RUWWW',\r\n  1051: ' 18KYTKKX RSMTX RTKUX RNTTT RIXNX RRXWX',\r\n  1052: ' 34JYPKLX RQKMX RNKUKWLWNVPSQ RUKVLVNUPSQ ROQRQTRUSUUTWQXJX RRQTSTUSWQX',\r\n  1053: ' 25KXVLWLXKWNVLTKRKPLOMNOMRMUNWPXRXTWUU RRKPMOONRNVPX',\r\n  1054: ' 26JYPKLX RQKMX RNKTKVLWNWQVTUVTWQXJX RTKULVNVQUTTVSWQX',\r\n  1055: ' 22JYPKLX RQKMX RSORS RNKXKWNWK ROQRQ RJXTXUUSX',\r\n  1056: ' 20JXPKLX RQKMX RSORS RNKXKWNWK ROQRQ RJXOX',\r\n  1057: ' 33KYVLWLXKWNVLTKRKPLOMNOMRMUNWPXRXTWUVVS RRKPMOONRNVPX RRXTVUS RSSXS',\r\n  1058: ' 27J[PKLX RQKMX RXKTX RYKUX RNKSK RVK[K ROQVQ RJXOX RRXWX',\r\n  1059: ' 12NWTKPX RUKQX RRKWK RNXSX',\r\n  1060: ' 19LXUKRUQWPX RVKSURWPXOXMWLUMTNUMV RSKXK',\r\n  1061: ' 27JZPKLX RQKMX RYKOR RRPTX RSPUX RNKSK RVK[K RJXOX RRXWX',\r\n  1062: ' 14KXQKMX RRKNX ROKTK RKXUXVUTX',\r\n  1063: ' 30I\\\\OKKX ROMPX RPKQV RYKPX RYKUX RZKVX RMKPK RYK\\\\K RIXMX RSXXX',\r\n  1064: ' 21JZPKLX RPKTX RQKTU RXKTX RNKQK RVKZK RJXNX',\r\n  1065: ' 32KYRKPLOMNOMRMUNWPXRXTWUVVTWQWNVLTKRK RRKPMOONRNVPX RRXTVUTVQVMTK',\r\n  1066: ' 24JYPKLX RQKMX RNKUKWLXMXOWQTROR RUKWMWOVQTR RJXOX',\r\n  1067: ' 46KYRKPLOMNOMRMUNWPXRXTWUVVTWQWNVLTKRK RRKPMOONRNVPX RRXTVUTVQVMTK ROWOVPUQURVRZS[T[UZ RRVSZT[',\r\n  1068: ' 35JZPKLX RQKMX RNKUKWLXMXOWQTROR RUKWMWOVQTR RSRTWUXVXWW RSRTSUWVX RJXOX',\r\n  1069: ' 28KZWLXLYKXNWLUKRKPLOMOOPPUSVT RONPOURVSVVUWSXPXNWMULXMWNW',\r\n  1070: ' 16KZTKPX RUKQX RPKNNOKZKYNYK RNXSX',\r\n  1071: ' 20J[PKMUMWOXSXUWVUYK RQKNUNWOX RNKSK RWK[K',\r\n  1072: ' 15KYOKPX RPKQV RYKPX RMKRK RVK[K',\r\n  1073: ' 24I[NKMX ROKNV RTKMX RTKSX RUKTV RZKSX RLKQK RXK\\\\K',\r\n  1074: ' 21KZPKTX RQKUX RYKLX RNKSK RVK[K RJXOX RRXWX',\r\n  1075: ' 20LYPKRQPX RQKSQ RYKSQQX RNKSK RVK[K RNXSX',\r\n  1076: ' 16LYXKLX RYKMX RQKONPKYK RLXUXVUTX',\r\n  1101: ' 32LZQOPPPQOQOPQOTOVQVWWXXX RTOUQUWWX RURRSPTOUOWPXSXTWUU RRSPUPWQX',\r\n  1102: ' 29JYNKNX ROKOX RORPPROTOVPWRWUVWTXRXPWOU RTOUPVRVUUWTX RLKOK',\r\n  1103: ' 24LXVQUQURVRVQUPSOQOOPNRNUOWQXSXUWVV RQOPPOROUPWQX',\r\n  1104: ' 32L[VKVX RWKWX RVRUPSOQOOPNRNUOWQXSXUWVU RQOPPOROUPWQX RTKWK RVXYX',\r\n  1105: ' 26LXOSVSVRUPSOQOOPNRNUOWQXSXUWVV RUSUQSO RQOPPOROUPWQX',\r\n  1106: ' 20LWTKULUMVMVLTKRKPMPX RRKQMQX RNOSO RNXSX',\r\n  1107: ' 42LYQOOQOSQUSUUSUQSOQO RQOPQPSQU RSUTSTQSO RTPUOVO RPTOUOXPYTYVZ ROWPXTXVYV[T\\\\P\\\\N[NYPX',\r\n  1108: ' 28J[NKNX ROKOX RORPPROTOVPWRWX RTOUPVRVX RLKOK RLXQX RTXYX',\r\n  1109: ' 18NWRKRLSLSKRK RRORX RSOSX RPOSO RPXUX',\r\n  1110: ' 23NWSKSLTLTKSK RSOSZR\\\\ RTOTZR\\\\P\\\\O[OZPZP[O[ RQOTO',\r\n  1111: ' 27JZNKNX ROKOX RWOOU RRSVX RSSWX RLKOK RTOYO RLXQX RTXYX',\r\n  1112: ' 12NWRKRX RSKSX RPKSK RPXUX',\r\n  1113: ' 44F_JOJX RKOKX RKRLPNOPORPSRSX RPOQPRRRX RSRTPVOXOZP[R[X RXOYPZRZX RHOKO RHXMX RPXUX RXX]X',\r\n  1114: ' 28J[NONX ROOOX RORPPROTOVPWRWX RTOUPVRVX RLOOO RLXQX RTXYX',\r\n  1115: ' 28LYQOOPNRNUOWQXTXVWWUWRVPTOQO RQOPPOROUPWQX RTXUWVUVRUPTO',\r\n  1116: ' 32JYNON\\\\ ROOO\\\\ RORPPROTOVPWRWUVWTXRXPWOU RTOUPVRVUUWTX RLOOO RL\\\\Q\\\\',\r\n  1117: ' 29KYUOU\\\\ RVOV\\\\ RURTPROPONPMRMUNWPXRXTWUU RPOOPNRNUOWPX RS\\\\X\\\\',\r\n  1118: ' 22KXOOOX RPOPX RPRQPSOUOVPVQUQUPVP RMOPO RMXRX',\r\n  1119: ' 26LYTOUPUQVQVPTOQOOPORQSTTVU ROQQRTSVTVWTXQXOWOVPVPWQX',\r\n  1120: ' 14LWPKPVRXTXUWUV RQKQVRX RNOTO',\r\n  1121: ' 28J[NONUOWQXSXUWVU ROOOUPWQX RVOVX RWOWX RLOOO RTOWO RVXYX',\r\n  1122: ' 15KYNORX ROORV RVORX RLOQO RTOXO',\r\n  1123: ' 24I[LOOX RMOOU RROOX RROUX RSOUU RXOUX RJOOO RVOZO',\r\n  1124: ' 21KYNOUX ROOVX RVONX RLOQO RTOXO RLXPX RSXXX',\r\n  1125: ' 23KYNORX ROORV RVORXP[N\\\\M\\\\L[LZMZM[L[ RLOQO RTOXO',\r\n  1126: ' 16LXUONX RVOOX ROONQNOVO RNXVXVVUX',\r\n  1127: ' 32K[QOOPNQMSMUNWPXQXSWUUWRXO RQOOQNSNUOWPX RQOSOUPWWXX RSOTPVWXXYX',\r\n  1128: ' 40KXRKPMOOMUK\\\\ RQLPNNTL\\\\ RRKTKVLVNUPRQ RTKULUNTPRQ RRQTRUTUVTWRXQXOWNT RRQSRTTTVRX',\r\n  1129: ' 19KYLQNOPORPSSSXR\\\\ RLQNPPPRQSS RWOVRSXQ\\\\',\r\n  1130: ' 39KYSOQOOPNQMSMUNWPXRXTWUVVTVRUPRNQLQKRJTJUKVM RQOOQNSNVPX RRXTVUTUQSO RQLRKTKVM',\r\n  1131: ' 27LXVPTOQOOPOQPRRS RQOPPPQRS RRSOTNUNWPXSXUW RRSPTOUOWPX',\r\n  1132: ' 28LWRKQLQMSNVNVMSNPOOPNRNTOVPWRXSYS[R\\\\P\\\\O[ RSNQOPPOROTPVRX',\r\n  1133: ' 26IYJRKPLONOOPOQMX RMONPNQLX ROQPPROTOVPVRS\\\\ RTOUPURR\\\\',\r\n  1134: ' 35IYJSKQLPNPOQOVPX RMPNQNUOWPXQXSWTVUTVQVNULTKRKQLQNRPURWS RQXSVTTUQUNTK',\r\n  1135: ' 13NWROPVPWQXSXUWVU RSOQVQWRX',\r\n  1136: ' 26KYOOLX RPOMX RUOVPWPVOTORQOR RORPSRWTXVWWU RORQSSWTX',\r\n  1137: ' 15LXLKNKPLWX RNKOLVX RRPMX RRPNX',\r\n  1138: ' 26KZOOK\\\\ RPOL\\\\ RNUNWOXQXSWTV RVOTVTWUXWXXWYU RWOUVUWVX',\r\n  1139: ' 19JYNOMX ROONUMX RVRVOWOVRTUQWNXMX RLOOO',\r\n  1140: ' 36MXRKQLQMSNVN RTNQOPPPRRSUS RTNROQPQRRS RSSPTOUOWQXSYTZT[S\\\\Q\\\\ RSSQTPUPWQX',\r\n  1141: ' 28KXQOOPNQMSMUNWPXRXTWUVVTVRUPSOQO RQOOQNSNVPX RRXTVUTUQSO',\r\n  1142: ' 20IZPPMX RPPNX RTPSX RTPTX RKQMOXO RKQMPXP',\r\n  1143: ' 29JXSOQOOPNQMSJ\\\\ RQOOQNSK\\\\ RSOUPVRVTUVTWRXPXNWMU RSOUQUTTVRX',\r\n  1144: ' 28K[YOQOOPNQMSMUNWPXRXTWUVVTVRUPYP RQOOQNSNVPX RRXTVUTUQSO',\r\n  1145: ' 14KZSPQX RSPRX RMQOOXO RMQOPXP',\r\n  1146: ' 24JXKRLPMOOOPPPROUOWPX RNOOPORNUNWPXQXSWUUVRVOUOVP',\r\n  1147: ' 35KZOPNQMSMUNWPXRXUWWUXRXPWOUOTPSRRUO\\\\ RMUNVPWRWUVWTXR RXQWPUPSR RRUQXP\\\\',\r\n  1148: ' 17KXMONOPPS[T\\\\ RNOOPR[T\\\\U\\\\ RVOTRNYL\\\\',\r\n  1149: ' 28I[TKQ\\\\ RUKP\\\\ RJRKPLONOOPOVPWSWUVWT RMONPNTOWPXSXUWWTXRYO',\r\n  1150: ' 36JZNPPPPONPMQLSLUMWNXPXQWRUSR RLUNWPWRU RRRRWSXUXWVXTXRWPVOVPWP RRUSWUWWV',\r\n  1151: ' 32KZVOTVTWUXWXXWYU RWOUVUWVX RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX',\r\n  1152: ' 32JXOKMR RPKNRNVPX RNROPQOSOUPVRVTUVTWRXPXNWMUMR RSOUQUTTVRX RMKPK',\r\n  1153: ' 22KXUPUQVQUPSOQOOPNQMSMUNWPXRXTWUV RQOOQNSNVPX',\r\n  1154: ' 35KZWKTVTWUXWXXWYU RXKUVUWVX RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX RUKXK',\r\n  1155: ' 23KWNURTTSURUPSOQOOPNQMSMUNWPXRXTWUV RQOOQNSNVPX',\r\n  1156: ' 23MXWKXLXKVKTLSNPYO[N\\\\ RVKULTNQYP[N\\\\L\\\\L[M\\\\ RPOVO',\r\n  1157: ' 34KYVOTVSYR[ RWOUVTYR[P\\\\M\\\\L[M[N\\\\ RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX',\r\n  1158: ' 29KZPKLX RQKMX ROQPPROTOVPVRUUUWVX RTOUPURTUTWUXWXXWYU RNKQK',\r\n  1159: ' 26MWSKSLTLTKSK RNROPPOROSPSRRURWSX RQORPRRQUQWRXTXUWVU',\r\n  1160: ' 26MWTKTLULUKTK RORPPQOSOTPTRRYQ[O\\\\M\\\\M[N\\\\ RROSPSRQYP[O\\\\',\r\n  1161: ' 32KXPKLX RQKMX RVPUQVQVPUOTORQPROR RORPSQWRXTXUWVU RORQSRWSX RNKQK',\r\n  1162: ' 16NVSKPVPWQXSXTWUU RTKQVQWRX RQKTK',\r\n  1163: ' 46F^GRHPIOKOLPLQJX RJOKPKQIX RLQMPOOQOSPSQQX RQORPRQPX RSQTPVOXOZPZRYUYWZX RXOYPYRXUXWYX[X\\\\W]U',\r\n  1164: ' 33J[KRLPMOOOPPPQNX RNOOPOQMX RPQQPSOUOWPWRVUVWWX RUOVPVRUUUWVXXXYWZU',\r\n  1165: ' 28KXQOOPNQMSMUNWPXRXTWUVVTVRUPSOQO RQOOQNSNVPX RRXTVUTUQSO',\r\n  1166: ' 35JYKRLPMOOOPPPQM\\\\ RNOOPOQL\\\\ RPQROTOVPWRWTVVUWSXQXOVOT RTOVQVTUVSX RJ\\\\O\\\\',\r\n  1167: ' 28KYVOR\\\\ RWOS\\\\ RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX RP\\\\U\\\\',\r\n  1168: ' 22LXMRNPOOQORPRQPX RPOQPQQOX RRQSPUOVOWPWQVQWP',\r\n  1169: ' 24LYVPVQWQVPTOQOOPORQSTTVU ROQQRTSVTVWTXQXOWNVOVOW',\r\n  1170: ' 16NWSKPVPWQXSXTWUU RTKQVQWRX RPOUO',\r\n  1171: ' 33IZJRKPLONOOPORNUNWOX RMONPNRMUMWOXQXSWTV RVOTVTWUXWXXWYU RWOUVUWVX',\r\n  1172: ' 24JXKRLPMOOOPPPROUOWPX RNOOPORNUNWPXQXSWUUVRVOUOVP',\r\n  1173: ' 37H\\\\IRJPKOMONPNRMUMWNX RLOMPMRLULWNXOXQWRV RTORVRWTX RUOSVSWTXUXWWYUZRZOYOZP',\r\n  1174: ' 38JZMRNPPOROSPSR RQORPRRQUPWNXMXLWLVMVLW RXPWQXQXPWOVOTPSRRURWSX RQUQWRXTXVWWU',\r\n  1175: ' 35IYJRKPLONOOPORNUNWOX RMONPNRMUMWOXQXSWTV RVOTVSYR[ RWOUVTYR[P\\\\M\\\\L[M[N\\\\',\r\n  1176: ' 27KYWOWPVQNVMWMX RNQOOROUQ ROPRPUQVQ RNVOVRWUW ROVRXUXVV',\r\n  1177: ' 39H[RKSLSMTMTLRKOKMLLNLX ROKNLMNMX RXKYLYMZMZLXKVKTMTX RVKUMUX RJOWO RJXOX RRXWX',\r\n  1178: ' 29J[UKVLWLWKQKOLNNNX RQKPLONOX RVOVX RWOWX RLOWO RLXQX RTXYX',\r\n  1179: ' 27J[WKQKOLNNNX RQKPLONOX RUKVLVX RWKWX RLOVO RLXQX RTXYX',\r\n  1180: ' 48F_PKQLQMRMRLPKMKKLJNJX RMKLLKNKX RYKZL[L[KUKSLRNRX RUKTLSNSX RZOZX R[O[X RHO[O RHXMX RPXUX RXX]X',\r\n  1181: ' 46F_PKQLQMRMRLPKMKKLJNJX RMKLLKNKX R[KUKSLRNRX RUKTLSNSX RYKZLZX R[K[X RHOZO RHXMX RPXUX RXX]X',\r\n  1182: ' 12NWRORX RSOSX RPOSO RPXUX',\r\n  1184: ' 21LXVPTOROPPOQNSNUOWQXSXUW RROPQOSOVQX ROSSS',\r\n  1185: ' 35LYSKQLPMOONRNUOWPXRXTWUVVTWQWNVLUKSK RSKQMPOOSOVPX RRXTVUTVPVMUK ROQVQ',\r\n  1186: ' 34KZTKQ\\\\ RUKP\\\\ RQONPMRMUNWQXTXWWXUXRWPTOQO RQOOPNRNUOWQX RTXVWWUWRVPTO',\r\n  1187: ' 22LXUPVRVQUPSOQOOPNRNTOVRX RQOOQOTPVRXSYS[R\\\\P\\\\',\r\n  1191: ' 45I[VKWLXLVKSKQLPMOOLYK[J\\\\ RSKQMPOMYL[J\\\\H\\\\H[I\\\\ RZK[L[KYKWLVNSYR[Q\\\\ RYKXLWNTYS[Q\\\\O\\\\O[P\\\\ RLOYO',\r\n  1192: ' 38IZVKWLXLXKSKQLPMOOLYK[J\\\\ RSKQMPOMYL[J\\\\H\\\\H[I\\\\ RVOTVTWUXWXXWYU RWOUVUWVX RLOWO',\r\n  1193: ' 38IZVKWL RXKSKQLPMOOLYK[J\\\\ RSKQMPOMYL[J\\\\H\\\\H[I\\\\ RWKTVTWUXWXXWYU RXKUVUWVX RLOVO',\r\n  1194: ' 63F^SKTLTM RULSKPKNLMMLOIYH[G\\\\ RPKNMMOJYI[G\\\\E\\\\E[F\\\\ RZK[L\\\\L\\\\KWKUL RTMSOPYO[N\\\\ RWKUMTOQYP[N\\\\L\\\\L[M\\\\ RZOXVXWYX[X\\\\W]U R[OYVYWZX RIO[O',\r\n  1195: ' 63F^SKTLTM RULSKPKNLMMLOIYH[G\\\\ RPKNMMOJYI[G\\\\E\\\\E[F\\\\ RZK[L R\\\\KWKUL RTMSOPYO[N\\\\ RWKUMTOQYP[N\\\\L\\\\L[M\\\\ R[KXVXWYX[X\\\\W]U R\\\\KYVYWZX RIOZO',\r\n  1196: ' 20MWNROPPOROSPSRRURWSX RQORPRRQUQWRXTXUWVU',\r\n  1200: ' 28LYQKOLNONTOWQXTXVWWTWOVLTKQK RQKPLOOOTPWQX RTXUWVTVOULTK',\r\n  1201: ' 10LYPNSKSX RRLRX ROXVX',\r\n  1202: ' 35LYOMONNNNMOLQKTKVLWNVPTQQROSNUNX RTKULVNUPTQ RNWOVPVSWVWWV RPVSXVXWVWU',\r\n  1203: ' 39LYOMONNNNMOLQKTKVLWNVPTQ RTKULVNUPTQ RRQTQVRWTWUVWTXQXOWNVNUOUOV RTQURVTVUUWTX',\r\n  1204: ' 13LYSMSX RTKTX RTKMTXT RQXVX',\r\n  1205: ' 33LYOKNQ ROKVK ROLSLVK RNQOPQOTOVPWRWUVWTXQXOWNVNUOUOV RTOUPVRVUUWTX',\r\n  1206: ' 36LYVMVNWNWMVLTKRKPLOMNPNUOWQXTXVWWUWSVQTPQPNR RRKPMOPOUPWQX RTXUWVUVSUQTP',\r\n  1207: ' 22LYNKNO RVMRTPX RWKTQQX RNMPKRKUM RNMPLRLUMVM',\r\n  1208: ' 51LYQKOLNNOPQQTQVPWNVLTKQK RQKPLONPPQQ RTQUPVNULTK RQQORNTNUOWQXTXVWWUWTVRTQ RQQPROTOUPWQX RTXUWVUVTURTQ',\r\n  1209: ' 36LYOVOUNUNVOWQXSXUWVVWSWNVLTKQKOLNNNPORQSTSWQ RSXUVVSVNULTK RQKPLONOPPRQS',\r\n  1210: '  6NVRVQWRXSWRV',\r\n  1211: '  8NVSWRXQWRVSWSYQ[',\r\n  1212: ' 12NVROQPRQSPRO RRVQWRXSWRV',\r\n  1213: ' 14NVROQPRQSPRO RSWRXQWRVSWSYQ[',\r\n  1214: ' 15NVRKQLRSSLRK RRLRO RRVQWRXSWRV',\r\n  1215: ' 29LYNNONOONONNOLQKTKVLWNWOVQSRRSRTST RTKVMVPUQSR RRWRXSXSWRW',\r\n  1216: '  6OVRKRP RSKRP',\r\n  1217: ' 12LXOKOP RPKOP RUKUP RVKUP',\r\n  1218: ' 10MWQKPLPNQOSOTNTLSKQK',\r\n  1219: '  9MWRJRP ROKUO RUKOO',\r\n  1220: '  3KZXHM\\\\',\r\n  1221: ' 16MWUHSJQMPPPTQWSZU\\\\ RSJRLQPQTRXSZ',\r\n  1222: ' 16MWOHQJSMTPTTSWQZO\\\\ RQJRLSPSTRXQZ',\r\n  1223: ' 12MWPHP\\\\ RQHQ\\\\ RPHUH RP\\\\U\\\\',\r\n  1224: ' 12MWSHS\\\\ RTHT\\\\ ROHTH RO\\\\T\\\\',\r\n  1225: ' 38LWSHQIPJPLRNSP RQIPL RSNRQ RPJQLSNSPRQPRRSSTSVQXPZ RRSSV RPXQ[ RSTRVPXPZQ[S\\\\',\r\n  1226: ' 38MXQHSITJTLRNQP RSITL RQNRQ RTJSLQNQPRQTRRSQTQVSXTZ RRSQV RTXS[ RQTRVTXTZS[Q\\\\',\r\n  1227: '  4MWTHPRT\\\\',\r\n  1228: '  4MWPHTRP\\\\',\r\n  1229: '  3OURHR\\\\',\r\n  1230: '  6MWPHP\\\\ RTHT\\\\',\r\n  1231: '  3I[LRXR',\r\n  1232: '  6I[RLRX RLRXR',\r\n  1233: '  9JZRMRX RMRWR RMXWX',\r\n  1234: '  9JZRMRX RMMWM RMRWR',\r\n  1235: '  6JZMMWW RWMMW',\r\n  1236: '  6NVRQQRRSSRRQ',\r\n  1237: ' 15I[RLQMRNSMRL RLRXR RRVQWRXSWRV',\r\n  1238: '  6I[LPXP RLTXT',\r\n  1239: '  9I[WLMX RLPXP RLTXT',\r\n  1240: '  9I[LNXN RLRXR RLVXV',\r\n  1241: '  4JZWLMRWX',\r\n  1242: '  4JZMLWRMX',\r\n  1243: ' 10JZWKMOWS RMTWT RMXWX',\r\n  1244: ' 10JZMKWOMS RMTWT RMXWX',\r\n  1245: ' 21H[YUWUUTTSRPQOONNNLOKQKRLTNUOUQTRSTPUOWNYN',\r\n  1246: ' 16JZLTLRMPOPUSWSXR RLRMQOQUTWTXRXP',\r\n  1247: '  8JZMSRPWS RMSRQWS',\r\n  1248: '  7NVSKPO RSKTLPO',\r\n  1249: '  7NVQKTO RQKPLTO',\r\n  1250: ' 14LXNKOMQNSNUMVK RNKONQOSOUNVK',\r\n  1251: '  8NVSLRMQLRKSLSNQP',\r\n  1252: '  8NVSKQMQORPSORNQO',\r\n  1253: '  8NVQLRMSLRKQLQNSP',\r\n  1254: '  8NVQKSMSORPQORNSO',\r\n  1256: ' 11JZWMQMONNOMQMSNUOVQWWW',\r\n  1257: ' 11JZMMMSNUOVQWSWUVVUWSWM',\r\n  1258: ' 11JZMMSMUNVOWQWSVUUVSWMW',\r\n  1259: ' 11JZMWMQNOONQMSMUNVOWQWW',\r\n  1260: ' 14JZWMQMONNOMQMSNUOVQWWW RMRUR',\r\n  1261: ' 13I[TOUPXRUTTU RUPWRUT RLRWR',\r\n  1262: ' 13MWRMRX ROPPORLTOUP RPORMTO',\r\n  1263: ' 13I[POOPLROTPU ROPMROT RMRXR',\r\n  1264: ' 13MWRLRW ROTPURXTUUT RPURWTU',\r\n  1265: ' 37KYVSUPSOQOOPNQMSMUNWPXRXTWUVVTWQWNVLTKQKPLQLRK RQOOQNSNVPX RRXTVUTVQVNULTK',\r\n  1266: ' 15JZLKRX RMKRV RXKRX RLKXK RNLWL',\r\n  1267: ' 10G[IOLORW RKORX R[FRX',\r\n  1268: ' 26I[XIXJYJYIXHVHTJSLROQUPYO[ RUITKSORUQXPZN\\\\L\\\\K[KZLZL[',\r\n  1269: ' 40I[XIXJYJYIXHVHTJSLROQUPYO[ RUITKSORUQXPZN\\\\L\\\\K[KZLZL[ RQNOONQNSOUQVSVUUVSVQUOSNQN',\r\n  1270: ' 26H\\\\ZRYTWUVUTTSSQPPONNMNKOJQJRKTMUNUPTQSSPTOVNWNYOZQZR',\r\n  1271: ' 26JZXKLX ROKPLPNOOMOLNLLMKOKSLVLXK RUTTUTWUXWXXWXUWTUT',\r\n  1272: ' 41J[YPXPXQYQYPXOWOVPUTTVSWQXOXMWLVLTMSORRPSNSLRKPKOLONPQUWWXXXYW ROXMVMTOR RONPPVWWX',\r\n  1273: ' 29J[UPSOQOPQPRQTSTUS RUOUSVTXTYRYQXNVLSKRKOLMNLQLRMUOWRXSXVW',\r\n  1274: ' 34KZQHQ\\\\ RTHT\\\\ RWLVLVMWMWLUKPKNLNNOPVSWT RNNOOVRWTWVVWTXQXOWNVNUOUOVNV',\r\n  1275: ' 12KYRKN\\\\ RVKR\\\\ RNQWQ RMVVV',\r\n  1276: ' 40LXTLSLSMTMTLSKQKPLPNQPTRUS RPNQOTQUSUUSW RQPOROTPVSXTY ROTPUSWTYT[S\\\\Q\\\\P[PZQZQ[P[',\r\n  1277: ' 29LXRKQLRMSLRK RRMRQ RRQQSRVSSRQ RRVR\\\\ RPOONNOOPPOTOUNVOUPTO',\r\n  1278: ' 42LXRMSLRKQLRMRQQRSURV RRQSRQURVRZQ[R\\\\S[RZ RPOONNOOPPOTOUNVOUPTO RPXOWNXOYPXTXUWVXUYTX',\r\n  1279: ' 12LYVKVX RNKVK RQQVQ RNXVX',\r\n  1281: ' 24H\\\\QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK RRQQRRSSRRQ',\r\n  1282: ' 33LYQKPLPMQN RTKULUMTN RRNPOOQORPTRUSUUTVRVQUOSNRN RRURY RSUSY ROWVW',\r\n  1283: ' 23LYRKPLONOOPQRRSRUQVOVNULSKRK RRRRX RSRSX ROUVU',\r\n  1284: ' 24H\\\\QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK RRKRY RKRYR',\r\n  1285: ' 25JYRRPQOQMRLTLUMWOXPXRWSUSTRR RWMRR RRMWMWR RRMVNWR',\r\n  1286: ' 25JZLLMKOKQLRNRPQRPSNT ROKPLQNQQPS RVKUX RWKTX RNTXT',\r\n  1287: ' 27JYNKNU ROKNR RNROPQOSOUPVQVTTVTXUYVYWX RSOUQUTTV RLKOK',\r\n  1288: ' 27LYONRKRQ RVNSKSQ RRQPROTOUPWRXSXUWVUVTURSQ RRTRUSUSTRT',\r\n  1289: ' 27JZRKRY RMKMPNRPSTSVRWPWK RLMMKNM RQMRKSM RVMWKXM ROVUV',\r\n  1290: ' 27JYNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXVXVUUX',\r\n  1291: ' 20LYWKTKQLONNQNSOVQXTYWY RWKTLRNQQQSRVTXWY',\r\n  1292: ' 23JZRRPQOQMRLTLUMWOXPXRWSUSTRR RSLQQ RWMRR RXQSS',\r\n  1293: ' 12KYPMTW RTMPW RMPWT RWPMT',\r\n  1294: ' 34J[OUMULVLXMYOYPXPVNTMRMONMOLQKTKVLWMXOXRWTUVUXVYXYYXYVXUVU RNMPLULWM',\r\n  1295: ' 34J[OOMOLNLLMKOKPLPNNPMRMUNWOXQYTYVXWWXUXRWPUNULVKXKYLYNXOVO RNWPXUXWW',\r\n  1401: ' 21F^KHK\\\\ RLHL\\\\ RXHX\\\\ RYHY\\\\ RHH\\\\H RH\\\\O\\\\ RU\\\\\\\\\\\\',\r\n  1402: ' 20H]KHRQJ\\\\ RJHQQ RJHYHZMXH RK[X[ RJ\\\\Y\\\\ZWX\\\\',\r\n  1403: ' 20KYVBTDRGPKOPOTPYR]T`Vb RTDRHQKPPPTQYR\\\\T`',\r\n  1404: ' 20KYNBPDRGTKUPUTTYR]P`Nb RPDRHSKTPTTSYR\\\\P`',\r\n  1405: ' 12KYOBOb RPBPb ROBVB RObVb',\r\n  1406: ' 12KYTBTb RUBUb RNBUB RNbUb',\r\n  1407: ' 40KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\\\P^Q`RaTb',\r\n  1408: ' 40KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\\\T^S`RaPb',\r\n  1409: ' 24KYU@RCPFOIOLPOSVTYT\\\\S_Ra RRCQEPHPKQNTUUXU[T^RaOd',\r\n  1410: ' 24KYO@RCTFUIULTOQVPYP\\\\Q_Ra RRCSETHTKSNPUOXO[P^RaUd',\r\n  1411: ' 13AXCRGRR` RGSRa RFSRb RX:Rb',\r\n  1412: ' 32F^[CZD[E\\\\D\\\\C[BYBWCUETGSJRNPZO^N` RVDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia',\r\n  2001: ' 18H\\\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[',\r\n  2002: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2003: ' 32G\\\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV RQFOGMILKKNKSLVMXOZQ[',\r\n  2004: ' 30G]LFL[ RMFM[ RIFSFVGXIYKZNZSYVXXVZS[I[ RSFUGWIXKYNYSXVWXUZS[',\r\n  2005: ' 22G\\\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[',\r\n  2006: ' 20G[LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[P[',\r\n  2007: ' 40G^XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXX RQFOGMILKKNKSLVMXOZQ[ RXSX[ RYSY[ RUS\\\\S',\r\n  2008: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RLPXP RH[O[ RU[\\\\[',\r\n  2009: ' 12MXRFR[ RSFS[ ROFVF RO[V[',\r\n  2010: ' 20KZUFUWTZR[P[NZMXMVNUOVNW RTFTWSZR[ RQFXF',\r\n  2011: ' 27F\\\\KFK[ RLFL[ RYFLS RQOY[ RPOX[ RHFOF RUF[F RH[O[ RU[[[',\r\n  2012: ' 14I[NFN[ ROFO[ RKFRF RK[Z[ZUY[',\r\n  2013: ' 30F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][',\r\n  2014: ' 21G^LFL[ RMFYY RMHY[ RYFY[ RIFMF RVF\\\\F RI[O[',\r\n  2015: ' 44G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF',\r\n  2016: ' 29G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[',\r\n  2017: ' 64G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF RNYNXOVQURUTVUXV_W`Y`Z^Z] RUXV\\\\W^X_Y_Z^',\r\n  2018: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUPMP RUFWGXHYJYLXNWOUP RI[P[ RRPTQURXYYZZZ[Y RTQUSWZX[Z[[Y[X',\r\n  2019: ' 34H\\\\XIYFYLXIVGSFPFMGKIKKLMMNOOUQWRYT RKKMMONUPWQXRYTYXWZT[Q[NZLXKUK[LX',\r\n  2020: ' 16I\\\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[',\r\n  2021: ' 23F^KFKULXNZQ[S[VZXXYUYF RLFLUMXOZQ[ RHFOF RVF\\\\F',\r\n  2022: ' 15H\\\\KFR[ RLFRX RYFR[ RIFOF RUF[F',\r\n  2023: ' 24F^JFN[ RKFNV RRFN[ RRFV[ RSFVV RZFV[ RGFNF RWF]F',\r\n  2024: ' 21H\\\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[',\r\n  2025: ' 20H]KFRQR[ RLFSQS[ RZFSQ RIFOF RVF\\\\F RO[V[',\r\n  2026: ' 16H\\\\XFK[ RYFL[ RLFKLKFYF RK[Y[YUX[',\r\n  2027: ' 18H\\\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[',\r\n  2028: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2029: ' 14I[NFN[ ROFO[ RKFZFZLYF RK[R[',\r\n  2030: ' 15H\\\\RFJ[ RRFZ[ RRIY[ RKZYZ RJ[Z[',\r\n  2031: ' 22G\\\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[',\r\n  2032: ' 16H\\\\XFK[ RYFL[ RLFKLKFYF RK[Y[YUX[',\r\n  2033: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RLPXP RH[O[ RU[\\\\[',\r\n  2034: ' 56G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF ROMOT RUMUT ROPUP ROQUQ',\r\n  2035: ' 12MXRFR[ RSFS[ ROFVF RO[V[',\r\n  2036: ' 27F\\\\KFK[ RLFL[ RYFLS RQOY[ RPOX[ RHFOF RUF[F RH[O[ RU[[[',\r\n  2037: ' 15H\\\\RFK[ RRFY[ RRIX[ RI[O[ RU[[[',\r\n  2038: ' 30F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][',\r\n  2039: ' 21G^LFL[ RMFYY RMHY[ RYFY[ RIFMF RVF\\\\F RI[O[',\r\n  2040: ' 36G]KEJJ RZEYJ RONNS RVNUS RKWJ\\\\ RZWY\\\\ RKGYG RKHYH ROPUP ROQUQ RKYYY RKZYZ',\r\n  2041: ' 44G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF',\r\n  2042: ' 21F^KFK[ RLFL[ RXFX[ RYFY[ RHF\\\\F RH[O[ RU[\\\\[',\r\n  2043: ' 29G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[',\r\n  2044: ' 20H]KFRPJ[ RJFQP RJFYFZLXF RKZXZ RJ[Y[ZUX[',\r\n  2045: ' 16I\\\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[',\r\n  2046: ' 33I\\\\KKKILGMFOFPGQIRMR[ RKIMGOGQI RZKZIYGXFVFUGTISMS[ RZIXGVGTI RO[V[',\r\n  2047: ' 48H]RFR[ RSFS[ RPKMLLMKOKRLTMUPVUVXUYTZRZOYMXLUKPK RPKNLMMLOLRMTNUPV RUVWUXTYRYOXMWLUK ROFVF RO[V[',\r\n  2048: ' 21H\\\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[',\r\n  2049: ' 41G^RFR[ RSFS[ RIMJLLMMQNSOTQU RJLKMLQMSNTQUTUWTXSYQZM[L RTUVTWSXQYM[L\\\\M ROFVF RO[V[',\r\n  2050: ' 43G]JXK[O[MWKSJPJLKIMGPFTFWGYIZLZPYSWWU[Y[ZX RMWLTKPKLLINGPF RTFVGXIYLYPXTWW RKZNZ RVZYZ',\r\n  2051: ' 18H\\\\UFH[ RUFV[ RTHU[ RLUUU RF[L[ RR[X[',\r\n  2052: ' 41F^OFI[ RPFJ[ RLFWFZG[I[KZNYOVP RWFYGZIZKYNXOVP RMPVPXQYSYUXXVZR[F[ RVPWQXSXUWXUZR[',\r\n  2053: ' 34H]ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[S[UZWXXV RTFRGPINLMOLSLVMYNZP[',\r\n  2054: ' 30F]OFI[ RPFJ[ RLFUFXGYHZKZOYSWWUYSZO[F[ RUFWGXHYKYOXSVWTYRZO[',\r\n  2055: ' 22F]OFI[ RPFJ[ RTLRT RLF[FZLZF RMPSP RF[U[WVT[',\r\n  2056: ' 20F\\\\OFI[ RPFJ[ RTLRT RLF[FZLZF RMPSP RF[M[',\r\n  2057: ' 42H^ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[R[UZWXYT RTFRGPINLMOLSLVMYNZP[ RR[TZVXXT RUT\\\\T',\r\n  2058: ' 27E_NFH[ ROFI[ R[FU[ R\\\\FV[ RKFRF RXF_F RLPXP RE[L[ RR[Y[',\r\n  2059: ' 12LYUFO[ RVFP[ RRFYF RL[S[',\r\n  2060: ' 21I[XFSWRYQZO[M[KZJXJVKULVKW RWFRWQYO[ RTF[F',\r\n  2061: ' 27F]OFI[ RPFJ[ R]FLS RSOW[ RROV[ RLFSF RYF_F RF[M[ RS[Y[',\r\n  2062: ' 14H\\\\QFK[ RRFL[ RNFUF RH[W[YUV[',\r\n  2063: ' 30E`NFH[ RNFO[ ROFPY R\\\\FO[ R\\\\FV[ R]FW[ RKFOF R\\\\F`F RE[K[ RS[Z[',\r\n  2064: ' 21F_OFI[ ROFVX ROIV[ R\\\\FV[ RLFOF RYF_F RF[L[',\r\n  2065: ' 42G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF RSFQGOIMLLOKSKVLYN[ RQ[SZUXWUXRYNYKXHVF',\r\n  2066: ' 27F]OFI[ RPFJ[ RLFXF[G\\\\I\\\\K[NYPUQMQ RXFZG[I[KZNXPUQ RF[M[',\r\n  2067: ' 61G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF RSFQGOIMLLOKSKVLYN[ RQ[SZUXWUXRYNYKXHVF RLYLXMVOUPURVSXS_T`V`W^W] RSXT^U_V_W^',\r\n  2068: ' 42F^OFI[ RPFJ[ RLFWFZG[I[KZNYOVPMP RWFYGZIZKYNXOVP RRPTQURVZW[Y[ZYZX RURWYXZYZZY RF[M[',\r\n  2069: ' 35G^ZH[H\\\\F[L[JZHYGVFRFOGMIMKNMONVRXT RMKOMVQWRXTXWWYVZS[O[LZKYJWJUI[JYKY',\r\n  2070: ' 16H]UFO[ RVFP[ ROFLLNF]F\\\\L\\\\F RL[S[',\r\n  2071: ' 25F_NFKQJUJXKZN[R[UZWXXU\\\\F ROFLQKUKXLZN[ RKFRF RYF_F',\r\n  2072: ' 15H\\\\NFO[ ROFPY R\\\\FO[ RLFRF RXF^F',\r\n  2073: ' 24E_MFK[ RNFLY RUFK[ RUFS[ RVFTY R]FS[ RJFQF RZF`F',\r\n  2074: ' 21G]NFU[ ROFV[ R\\\\FH[ RLFRF RXF^F RF[L[ RR[X[',\r\n  2075: ' 20H]NFRPO[ ROFSPP[ R]FSP RLFRF RYF_F RL[S[',\r\n  2076: ' 16G][FH[ R\\\\FI[ ROFLLNF\\\\F RH[V[XUU[',\r\n  2077: ' 46H\\\\KILKXWYYY[ RLLXX RKIKKLMXYY[ RPPLTKVKXLZK[ RKVMZ RLTLVMXMZK[ RSSXN RVIVLWNYNYLWKVI RVIWLYN',\r\n  2101: ' 39I]NONPMPMONNPMTMVNWOXQXXYZZ[ RWOWXXZZ[[[ RWQVRPSMTLVLXMZP[S[UZWX RPSNTMVMXNZP[',\r\n  2102: ' 33G\\\\LFL[ RMFM[ RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIFMF',\r\n  2103: ' 28H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX RQMONMPLSLUMXOZQ[',\r\n  2104: ' 36H]WFW[ RXFX[ RWPUNSMQMNNLPKSKULXNZQ[S[UZWX RQMONMPLSLUMXOZQ[ RTFXF RW[[[',\r\n  2105: ' 31H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX RWSWPVN RQMONMPLSLUMXOZQ[',\r\n  2106: ' 22KXUGTHUIVHVGUFSFQGPIP[ RSFRGQIQ[ RMMUM RM[T[',\r\n  2107: ' 60I\\\\QMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM RONNPNTOV RUVVTVPUN RVOWNYMYNWN RNUMVLXLYM[P\\\\U\\\\X]Y^ RLYMZP[U[X\\\\Y^Y_XaUbObLaK_K^L\\\\O[',\r\n  2108: ' 28G]LFL[ RMFM[ RMPONRMTMWNXPX[ RTMVNWPW[ RIFMF RI[P[ RT[[[',\r\n  2109: ' 18MXRFQGRHSGRF RRMR[ RSMS[ ROMSM RO[V[',\r\n  2110: ' 25MXSFRGSHTGSF RTMT_SaQbObNaN`O_P`Oa RSMS_RaQb RPMTM',\r\n  2111: ' 27G\\\\LFL[ RMFM[ RWMMW RRSX[ RQSW[ RIFMF RTMZM RI[P[ RT[Z[',\r\n  2112: ' 12MXRFR[ RSFS[ ROFSF RO[V[',\r\n  2113: ' 44BcGMG[ RHMH[ RHPJNMMOMRNSPS[ ROMQNRPR[ RSPUNXMZM]N^P^[ RZM\\\\N]P][ RDMHM RD[K[ RO[V[ RZ[a[',\r\n  2114: ' 28G]LML[ RMMM[ RMPONRMTMWNXPX[ RTMVNWPW[ RIMMM RI[P[ RT[[[',\r\n  2115: ' 36H\\\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM',\r\n  2116: ' 36G\\\\LMLb RMMMb RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIMMM RIbPb',\r\n  2117: ' 33H\\\\WMWb RXMXb RWPUNSMQMNNLPKSKULXNZQ[S[UZWX RQMONMPLSLUMXOZQ[ RTb[b',\r\n  2118: ' 23IZNMN[ ROMO[ ROSPPRNTMWMXNXOWPVOWN RKMOM RK[R[',\r\n  2119: ' 32J[WOXMXQWOVNTMPMNNMOMQNRPSUUWVXW RMPNQPRUTWUXVXYWZU[Q[OZNYMWM[NY',\r\n  2120: ' 16KZPFPWQZS[U[WZXX RQFQWRZS[ RMMUM',\r\n  2121: ' 28G]LMLXMZP[R[UZWX RMMMXNZP[ RWMW[ RXMX[ RIMMM RTMXM RW[[[',\r\n  2122: ' 15I[LMR[ RMMRY RXMR[ RJMPM RTMZM',\r\n  2123: ' 24F^JMN[ RKMNX RRMN[ RRMV[ RSMVX RZMV[ RGMNM RWM]M',\r\n  2124: ' 21H\\\\LMW[ RMMX[ RXML[ RJMPM RTMZM RJ[P[ RT[Z[',\r\n  2125: ' 22H[LMR[ RMMRY RXMR[P_NaLbKbJaK`La RJMPM RTMZM',\r\n  2126: ' 16I[WML[ RXMM[ RMMLQLMXM RL[X[XWW[',\r\n  2127: ' 40G^QMNNLPKRJUJXKZN[P[RZUWWTYPZM RQMONMPLRKUKXLZN[ RQMSMUNVPXXYZZ[ RSMTNUPWXXZZ[[[',\r\n  2128: ' 57G\\\\TFQGOIMMLPKTJZIb RTFRGPINMMPLTKZJb RTFVFXGYHYKXMWNTOPO RVFXHXKWMVNTO RPOTPVRWTWWVYUZR[P[NZMYLV RPOSPURVTVWUYTZR[',\r\n  2129: ' 28H\\\\IPKNMMOMQNROSRSVRZOb RJOLNPNRO RZMYPXRSYP^Nb RYMXPWRSY',\r\n  2130: ' 44I\\\\VNTMRMONMQLTLWMYNZP[R[UZWWXTXQWOSJRHRFSEUEWFYH RRMPNNQMTMXNZ RR[TZVWWTWPVNTKSISGTFVFYH',\r\n  2131: ' 32I[XPVNTMPMNNNPPRSS RPMONOPQRSS RSSNTLVLXMZP[S[UZWX RSSOTMVMXNZP[',\r\n  2132: ' 31I[TFRGQHQIRJUKZKZJWKSMPOMRLULWMYP[S]T_TaSbQbPa RULQONRMUMWNYP[',\r\n  2133: ' 32G]HQIOKMNMONOPNTL[ RMMNNNPMTK[ RNTPPRNTMVMXNYOYRXWUb RVMXOXRWWTb',\r\n  2134: ' 44F]GQHOJMMMNNNPMUMXNZO[ RLMMNMPLULXMZO[Q[SZUXWUXRYMYIXGVFTFRHRJSMUPWRZT RSZUWVUWRXMXIWGVF',\r\n  2135: ' 15LXRMPTOXOZP[S[UYVW RSMQTPXPZQ[',\r\n  2136: ' 29H\\\\NMJ[ ROMK[ RXMYNZNYMWMUNQROSMS ROSQTSZT[ ROSPTRZS[U[WZYW',\r\n  2137: ' 23H\\\\KFMFOGPHQJWXXZY[ RMFOHPJVXWZY[Z[ RRMJ[ RRMK[',\r\n  2138: ' 28F]MMGb RNMHb RMPLVLYN[P[RZTXVU RXMUXUZV[Y[[Y\\\\W RYMVXVZW[',\r\n  2139: ' 24H\\\\NML[ ROMNSMXL[ RYMXQVU RZMYPXRVUTWQYOZL[ RKMOM',\r\n  2140: ' 45IZTFRGQHQIRJUKXK RUKQLOMNONQPSSTVT RUKRLPMOOOQQSST RSTOUMVLXLZN\\\\S^T_TaRbPb RSTPUNVMXMZO\\\\S^',\r\n  2141: ' 32I[RMONMQLTLWMYNZP[R[UZWWXTXQWOVNTMRM RRMPNNQMTMXNZ RR[TZVWWTWPVN',\r\n  2142: ' 22G]PNL[ RPNM[ RVNV[ RVNW[ RIPKNNM[M RIPKONN[N',\r\n  2143: ' 31H[LVMYNZP[R[UZWWXTXQWOVNTMRMONMQLTHb RR[TZVWWTWPVN RRMPNNQMTIb',\r\n  2144: ' 35H][MQMNNLQKTKWLYMZO[Q[TZVWWTWQVOUNSM RQMONMQLTLXMZ RQ[SZUWVTVPUN RUN[N',\r\n  2145: ' 16H\\\\SNP[ RSNQ[ RJPLNOMZM RJPLOONZN',\r\n  2146: ' 31H\\\\IQJOLMOMPNPPNVNYP[ RNMONOPMVMYNZP[Q[TZVXXUYRYOXMWNXOYR RXUYO',\r\n  2147: ' 37G]ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb RJWLYNZQZTYWWYU RZOXNVNTPRSPYNb',\r\n  2148: ' 23I[KMMMONPPU_VaWb RMMNNOPT_UaWbYb RZMYOWRM]K`Jb',\r\n  2149: ' 34F]UFOb RVFNb RGQHOJMMMNNNPMUMXOZRZTYWVYS RLMMNMPLULXMZO[R[TZVXXUYS[M',\r\n  2150: ' 44F]JQLOONNMLNJQITIWJZK[M[OZQWRT RIWJYKZMZOYQW RQTQWRZS[U[WZYWZTZQYNXMWNYOZQ RQWRYSZUZWYYW',\r\n  2151: ' 39H]XMVTUXUZV[Y[[Y\\\\W RYMWTVXVZW[ RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ',\r\n  2152: ' 36H[PFLSLVMYNZ RQFMS RMSNPPNRMTMVNWOXQXTWWUZR[P[NZMWMS RVNWPWTVWTZR[ RMFQF',\r\n  2153: ' 25I[WPWQXQXPWNUMRMONMQLTLWMYNZP[R[UZWW RRMPNNQMTMXNZ',\r\n  2154: ' 42H]ZFVTUXUZV[Y[[Y\\\\W R[FWTVXVZW[ RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ RWF[F',\r\n  2155: ' 26I[MVQUTTWRXPWNUMRMONMQLTLWMYNZP[R[UZWX RRMPNNQMTMXNZ',\r\n  2156: ' 35KZZGYHZI[H[GZFXFVGUHTJSMP[O_Na RXFVHUJTNRWQ[P^O`NaLbJbIaI`J_K`Ja ROMYM',\r\n  2157: ' 43H\\\\YMU[T^RaObLbJaI`I_J^K_J` RXMT[S^QaOb RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ',\r\n  2158: ' 31H]PFJ[ RQFK[ RMTOPQNSMUMWNXOXQVWVZW[ RUMWOWQUWUZV[Y[[Y\\\\W RMFQF',\r\n  2159: ' 26LYUFTGUHVGUF RMQNOPMSMTNTQRWRZS[ RRMSNSQQWQZR[U[WYXW',\r\n  2160: ' 32LYVFUGVHWGVF RNQOOQMTMUNUQR[Q^P`OaMbKbJaJ`K_L`Ka RSMTNTQQ[P^O`Mb',\r\n  2161: ' 34H\\\\PFJ[ RQFK[ RXNWOXPYOYNXMWMUNQROSMS ROSQTSZT[ ROSPTRZS[U[WZYW RMFQF',\r\n  2162: ' 18MYUFQTPXPZQ[T[VYWW RVFRTQXQZR[ RRFVF',\r\n  2163: ' 52AbBQCOEMHMINIPHTF[ RGMHNHPGTE[ RHTJPLNNMPMRNSOSQP[ RPMRORQO[ RRTTPVNXMZM\\\\N]O]Q[W[Z\\\\[ RZM\\\\O\\\\QZWZZ[[^[`YaW',\r\n  2164: ' 37F]GQHOJMMMNNNPMTK[ RLMMNMPLTJ[ RMTOPQNSMUMWNXOXQVWVZW[ RUMWOWQUWUZV[Y[[Y\\\\W',\r\n  2165: ' 32I[RMONMQLTLWMYNZP[R[UZWWXTXQWOVNTMRM RRMPNNQMTMXNZ RR[TZVWWTWPVN',\r\n  2166: ' 42G\\\\HQIOKMNMONOPNTJb RMMNNNPMTIb RNTOQQNSMUMWNXOYQYTXWVZS[Q[OZNWNT RWNXPXTWWUZS[ RFbMb',\r\n  2167: ' 33H\\\\XMRb RYMSb RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ RObVb',\r\n  2168: ' 26IZJQKOMMPMQNQPPTN[ ROMPNPPOTM[ RPTRPTNVMXMYNYOXPWOXN',\r\n  2169: ' 28J[XOXPYPYOXNUMRMONNONQORVVWW RNPOQVUWVWYVZS[P[MZLYLXMXMY',\r\n  2170: ' 18KYTFPTOXOZP[S[UYVW RUFQTPXPZQ[ RNMWM',\r\n  2171: ' 37F]GQHOJMMMNNNQLWLYN[ RLMMNMQKWKYLZN[P[RZTXVT RXMVTUXUZV[Y[[Y\\\\W RYMWTVXVZW[',\r\n  2172: ' 26H\\\\IQJOLMOMPNPQNWNYP[ RNMONOQMWMYNZP[Q[TZVXXUYQYMXMYO',\r\n  2173: ' 41C`DQEOGMJMKNKQIWIYK[ RIMJNJQHWHYIZK[M[OZQXRV RTMRVRYSZU[W[YZ[X\\\\V]R]M\\\\M]O RUMSVSYU[',\r\n  2174: ' 42H\\\\KQMNOMRMSOSR RQMRORRQVPXNZL[K[JZJYKXLYKZ RQVQYR[U[WZYW RYNXOYPZOZNYMXMVNTPSRRVRYS[',\r\n  2175: ' 41G\\\\HQIOKMNMONOQMWMYO[ RMMNNNQLWLYMZO[Q[SZUXWT RZMV[U^SaPbMbKaJ`J_K^L_K` RYMU[T^RaPb',\r\n  2176: ' 31H\\\\YMXOVQNWLYK[ RLQMOOMRMVO RMOONRNVOXO RLYNYRZUZWY RNYR[U[WYXW',\r\n  2177: ' 43G^VGUHVIWHWGUFRFOGMILLL[ RRFPGNIMLM[ R\\\\G[H\\\\I]H]G\\\\FZFXGWIW[ RZFYGXIX[ RIM[M RI[P[ RT[[[',\r\n  2178: ' 33G]WGVHWIXHWGUFRFOGMILLL[ RRFPGNIMLM[ RWMW[ RXMX[ RIMXM RI[P[ RT[[[',\r\n  2179: ' 35G]VGUHVIWHWGUF RXFRFOGMILLL[ RRFPGNIMLM[ RWHW[ RXFX[ RIMWM RI[P[ RT[[[',\r\n  2180: ' 54BcRGQHRISHRGPFMFJGHIGLG[ RMFKGIIHLH[ R]G\\\\H]I^H]G[FXFUGSIRLR[ RXFVGTISLS[ R]M][ R^M^[ RDM^M RD[K[ RO[V[ RZ[a[',\r\n  2181: ' 56BcRGQHRISHRGPFMFJGHIGLG[ RMFKGIIHLH[ R\\\\G[H\\\\I]H]G[F R^FXFUGSIRLR[ RXFVGTISLS[ R]H][ R^F^[ RDM]M RD[K[ RO[V[ RZ[a[',\r\n  2182: ' 12MXRMR[ RSMS[ ROMSM RO[V[',\r\n  2184: ' 25IZWNUMRMONMPLSLVMYNZQ[T[VZ RRMPNNPMSMVNYOZQ[ RMTUT',\r\n  2185: ' 43I\\\\TFQGOJNLMOLTLXMZO[Q[TZVWWUXRYMYIXGVFTF RTFRGPJOLNOMTMXNZO[ RQ[SZUWVUWRXMXIWGVF RNPWP',\r\n  2186: ' 42G]UFOb RVFNb RQMMNKPJSJVKXMZP[S[WZYXZUZRYPWNTMQM RQMNNLPKSKVLXNZP[ RS[VZXXYUYRXPVNTM',\r\n  2187: ' 27I[TMVNXPXOWNTMQMNNMOLQLSMUOWSZ RQMONNOMQMSNUSZT\\\\T^S_Q_',\r\n  2190: ' 45G]LMKNJPJRKUOYP[ RJRKTOXP[P]O`MbLbKaJ_J\\\\KXMTOQRNTMVMYNZPZTYXWZU[T[SZSXTWUXTY RVMXNYPYTXXWZ',\r\n  2191: ' 69E_YGXHYIZHYGWFTFQGOINKMNLRJ[I_Ha RTFRGPIOKNNLWK[J^I`HaFbDbCaC`D_E`Da R_G^H_I`H`G_F]F[GZHYJXMU[T_Sa R]F[HZJYNWWV[U^T`SaQbObNaN`O_P`Oa RIM^M',\r\n  2192: ' 52F^[GZH[I\\\\H[GXFUFRGPIOKNNMRK[J_Ia RUFSGQIPKONMWL[K^J`IaGbEbDaD`E_F`Ea RYMWTVXVZW[Z[\\\\Y]W RZMXTWXWZX[ RJMZM',\r\n  2193: ' 54F^YGXHYIZHZGXF R\\\\FUFRGPIOKNNMRK[J_Ia RUFSGQIPKONMWL[K^J`IaGbEbDaD`E_F`Ea R[FWTVXVZW[Z[\\\\Y]W R\\\\FXTWXWZX[ RJMYM',\r\n  2194: ' 86@cTGSHTIUHTGRFOFLGJIIKHNGRE[D_Ca ROFMGKIJKINGWF[E^D`CaAb?b>a>`?_@`?a R`G_H`IaH`G]FZFWGUITKSNRRP[O_Na RZFXGVIUKTNRWQ[P^O`NaLbJbIaI`J_K`Ja R^M\\\\T[X[Z\\\\[_[aYbW R_M]T\\\\X\\\\Z][ RDM_M',\r\n  2195: ' 88@cTGSHTIUHTGRFOFLGJIIKHNGRE[D_Ca ROFMGKIJKINGWF[E^D`CaAb?b>a>`?_@`?a R^G]H^I_H_G]F RaFZFWGUITKSNRRP[O_Na RZFXGVIUKTNRWQ[P^O`NaLbJbIaI`J_K`Ja R`F\\\\T[X[Z\\\\[_[aYbW RaF]T\\\\X\\\\Z][ RDM^M',\r\n  2196: ' 20LYMQNOPMSMTNTQRWRZS[ RRMSNSQQWQZR[U[WYXW',\r\n  2200: ' 40H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RQFOGNHMJLOLRMWNYOZQ[ RS[UZVYWWXRXOWJVHUGSF',\r\n  2201: ' 11H\\\\NJPISFS[ RRGR[ RN[W[',\r\n  2202: ' 45H\\\\LJMKLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RTFVGWHXJXLWNTPPR RKYLXNXSZVZXYYX RNXS[W[XZYXYV',\r\n  2203: ' 47H\\\\LJMKLLKKKJLHMGPFTFWGXIXLWNTOQO RTFVGWIWLVNTO RTOVPXRYTYWXYWZT[P[MZLYKWKVLUMVLW RWQXTXWWYVZT[',\r\n  2204: ' 13H\\\\THT[ RUFU[ RUFJUZU RQ[X[',\r\n  2205: ' 39H\\\\MFKP RKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMVLW RSMUNWPXSXUWXUZS[ RMFWF RMGRGWF',\r\n  2206: ' 48H\\\\WIVJWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNRNOOMQLT RRFPGNIMKLOLUMXOZQ[ RS[UZWXXUXTWQUOSN',\r\n  2207: ' 31H\\\\KFKL RKJLHNFPFUIWIXHYF RLHNGPGUI RYFYIXLTQSSRVR[ RXLSQRSQVQ[',\r\n  2208: ' 63H\\\\PFMGLILLMNPOTOWNXLXIWGTFPF RPFNGMIMLNNPO RTOVNWLWIVGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RPONPMQLSLWMYNZP[ RT[VZWYXWXSWQVPTO',\r\n  2209: ' 48H\\\\XMWPURRSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNWMX RQSORMPLMLLMIOGQF RSFUGWIXLXRWVVXTZR[',\r\n  2210: '  6MWRYQZR[SZRY',\r\n  2211: '  8MWR[QZRYSZS\\\\R^Q_',\r\n  2212: ' 12MWRMQNROSNRM RRYQZR[SZRY',\r\n  2213: ' 14MWRMQNROSNRM RR[QZRYSZS\\\\R^Q_',\r\n  2214: ' 15MWRFQHRTSHRF RRHRN RRYQZR[SZRY',\r\n  2215: ' 32I[MJNKMLLKLJMHNGPFSFVGWHXJXLWNVORQRT RSFUGVHWJWLVNTP RRYQZR[SZRY',\r\n  2216: '  6NVRFQM RSFQM',\r\n  2217: ' 12JZNFMM ROFMM RVFUM RWFUM',\r\n  2218: ' 14KYQFOGNINKOMQNSNUMVKVIUGSFQF',\r\n  2219: '  9JZRFRR RMIWO RWIMO',\r\n  2220: '  3G][BIb',\r\n  2221: ' 20KYVBTDRGPKOPOTPYR]T`Vb RTDRHQKPPPTQYR\\\\T`',\r\n  2222: ' 20KYNBPDRGTKUPUTTYR]P`Nb RPDRHSKTPTTSYR\\\\P`',\r\n  2223: ' 12KYOBOb RPBPb ROBVB RObVb',\r\n  2224: ' 12KYTBTb RUBUb RNBUB RNbUb',\r\n  2225: ' 40KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\\\P^Q`RaTb',\r\n  2226: ' 40KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\\\T^S`RaPb',\r\n  2227: '  4KYUBNRUb',\r\n  2228: '  4KYOBVROb',\r\n  2229: '  3NVRBRb',\r\n  2230: '  6KYOBOb RUBUb',\r\n  2231: '  3E_IR[R',\r\n  2232: '  6E_RIR[ RIR[R',\r\n  2233: '  9F^RJR[ RJRZR RJ[Z[',\r\n  2234: '  9F^RJR[ RJJZJ RJRZR',\r\n  2235: '  6G]KKYY RYKKY',\r\n  2236: '  6MWRQQRRSSRRQ',\r\n  2237: ' 15E_RIQJRKSJRI RIR[R RRYQZR[SZRY',\r\n  2238: '  6E_IO[O RIU[U',\r\n  2239: '  9E_YIK[ RIO[O RIU[U',\r\n  2240: '  9E_IM[M RIR[R RIW[W',\r\n  2241: '  4F^ZIJRZ[',\r\n  2242: '  4F^JIZRJ[',\r\n  2243: ' 10F^ZFJMZT RJVZV RJ[Z[',\r\n  2244: ' 10F^JFZMJT RJVZV RJ[Z[',\r\n  2245: ' 21F_[WYWWVUTRPQOONMNKOJQJSKUMVOVQURTUPWNYM[M',\r\n  2246: ' 24F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O',\r\n  2247: '  8G]JTROZT RJTRPZT',\r\n  2248: '  7LXTFOL RTFUGOL',\r\n  2249: '  7LXPFUL RPFOGUL',\r\n  2250: ' 18H\\\\KFLHNJQKSKVJXHYF RKFLINKQLSLVKXIYF',\r\n  2251: '  8MWRHQGRFSGSIRKQL',\r\n  2252: '  8MWSFRGQIQKRLSKRJ',\r\n  2253: '  8MWRHSGRFQGQIRKSL',\r\n  2254: '  8MWQFRGSISKRLQKRJ',\r\n  2255: ' 10E[HMLMRY RKMR[ R[BR[',\r\n  2256: ' 13F^ZJSJOKMLKNJQJSKVMXOYSZZZ',\r\n  2257: ' 13F^JJJQKULWNYQZSZVYXWYUZQZJ',\r\n  2258: ' 13F^JJQJUKWLYNZQZSYVWXUYQZJZ',\r\n  2259: ' 13F^JZJSKOLMNKQJSJVKXMYOZSZZ',\r\n  2260: ' 16F^ZJSJOKMLKNJQJSKVMXOYSZZZ RJRVR',\r\n  2261: ' 11E_XP[RXT RUMZRUW RIRZR',\r\n  2262: ' 11JZPLRITL RMORJWO RRJR[',\r\n  2263: ' 11E_LPIRLT ROMJROW RJR[R',\r\n  2264: ' 11JZPXR[TX RMURZWU RRIRZ',\r\n  2265: ' 44I\\\\XRWOVNTMRMONMQLTLWMYNZP[R[UZWXXUYPYKXHWGUFRFPGOHOIPIPH RRMPNNQMTMXNZ RR[TZVXWUXPXKWHUF',\r\n  2266: ' 15H\\\\JFR[ RKFRY RZFR[ RJFZF RKGYG',\r\n  2267: ' 10AbDMIMRY RHNR[ Rb:R[',\r\n  2268: ' 32F^[CZD[E\\\\D\\\\C[BYBWCUETGSJRNPZO^N` RVDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia',\r\n  2269: ' 50F^[CZD[E\\\\D\\\\C[BYBWCUETGSJRNPZO^N` RVDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia RQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK',\r\n  2270: ' 26F_\\\\S[UYVWVUUTTQPPONNLNJOIQISJULVNVPUQTTPUOWNYN[O\\\\Q\\\\S',\r\n  2271: ' 32F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT',\r\n  2272: ' 49F_[NZO[P\\\\O\\\\N[MZMYNXPVUTXRZP[M[JZIXIUJSPORMSKSIRGPFNGMIMKNNPQUXWZZ[[[\\\\Z\\\\Y RM[KZJXJUKSMQ RMKNMVXXZZ[',\r\n  2273: ' 56E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\\\T]Q]O\\\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV',\r\n  2274: ' 42H\\\\PBP_ RTBT_ RXIWJXKYJYIWGTFPFMGKIKKLMMNOOUQWRYT RKKMMONUPWQXRYTYXWZT[P[MZKXKWLVMWLX',\r\n  2275: ' 12H]SFLb RYFRb RLQZQ RKWYW',\r\n  2276: ' 46JZUITJUKVJVIUGSFQFOGNINKOMQOVR ROMTPVRWTWVVXTZ RPNNPMRMTNVPXU[ RNVSYU[V]V_UaSbQbOaN_N^O]P^O_',\r\n  2277: ' 30JZRFQHRJSHRF RRFRb RRQQTRbSTRQ RLMNNPMNLLM RLMXM RTMVNXMVLTM',\r\n  2278: ' 56JZRFQHRJSHRF RRFRT RRPQRSVRXQVSRRP RRTRb RR^Q`RbS`R^ RLMNNPMNLLM RLMXM RTMVNXMVLTM RL[N\\\\P[NZL[ RL[X[ RT[V\\\\X[VZT[',\r\n  2279: ' 12I\\\\XFX[ RKFXF RPPXP RK[X[',\r\n  2281: ' 38E`QFNGKIILHOHRIUKXNZQ[T[WZZX\\\\U]R]O\\\\LZIWGTFQF RROQPQQRRSRTQTPSORO RRPRQSQSPRP',\r\n  2282: ' 45J[PFNGOIQJ RPFOGOI RUFWGVITJ RUFVGVI RQJOKNLMNMQNSOTQUTUVTWSXQXNWLVKTJQJ RRUR[ RSUS[ RNXWX',\r\n  2283: ' 27I\\\\RFOGMILLLMMPORRSSSVRXPYMYLXIVGSFRF RRSR[ RSSS[ RNWWW',\r\n  2284: ' 28D`PFMGJIHLGOGSHVJYM[P\\\\T\\\\W[ZY\\\\V]S]O\\\\LZIWGTFPF RRFR\\\\ RGQ]Q',\r\n  2285: ' 31G`PMMNKPJSJTKWMYPZQZTYVWWTWSVPTNQMPM R]GWG[HUN R]G]M\\\\IVO R\\\\HVN',\r\n  2286: ' 28F\\\\IIJGLFOFQGRIRLQOPQNSKU ROFPGQIQMPPNS RVFT[ RWFS[ RKUYU',\r\n  2287: ' 30I\\\\MFMU RNFMQ RMQNOONQMTMWNXPXRWTUV RTMVNWPWRTXTZU[W[YY RKFNF',\r\n  2288: ' 44I\\\\RNOOMQLTLUMXOZR[S[VZXXYUYTXQVOSNRN RRHNJRFRN RSHWJSFSN RRSQTQURVSVTUTTSSRS RRTRUSUSTRT',\r\n  2289: ' 37G^QHRFR[ RTHSFS[ RJHKFKMLPNRQSRS RMHLFLNMQ R[HZFZMYPWRTSSS RXHYFYNXQ RNWWW',\r\n  2290: ' 31G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[Y[YVX[',\r\n  2291: ' 24H[YGUGQHNJLMKPKSLVNYQ[U\\\\Y\\\\ RYGVHSJQMPPPSQVSYV[Y\\\\',\r\n  2292: ' 27F_OQMQKRJSIUIWJYKZM[O[QZRYSWSURSQROQ RSHPQ RZJRR R\\\\QST',\r\n  2293: ' 12H\\\\OKUY RUKOY RKOYU RYOKU',\r\n  2294: ' 48F^NVLUKUIVHXHYI[K\\\\L\\\\N[OYOXNVKRJOJMKJMHPGTGWHYJZMZOYRVVUXUYV[X\\\\Y\\\\[[\\\\Y\\\\X[VYUXUVV RJMKKMIPHTHWIYKZM',\r\n  2295: ' 48F^NMLNKNIMHKHJIHKGLGNHOJOKNMKQJTJVKYM[P\\\\T\\\\W[YYZVZTYQVMUKUJVHXGYG[H\\\\J\\\\K[MYNXNVM RJVKXMZP[T[WZYXZV',\r\n  2301: ' 40F_JMILIJJHLGNGPHQIRKSP RIJKHMHOIPJQLRPR[ R[M\\\\L\\\\J[HYGWGUHTISKRP R\\\\JZHXHVIUJTLSPS[',\r\n  2302: ' 51F^IGJKKMMOPPTPWOYMZK[G RIGJJKLMNPOTOWNYLZJ[G RPONPMQLSLVMXOZQ[S[UZWXXVXSWQVPTO RPPNQMSMVNY RVYWVWSVQTP',\r\n  2303: ' 30F^MJMV RNKNU RVKVU RWJWV RIGKIMJPKTKWJYI[G RIYKWMVPUTUWVYW[Y',\r\n  2304: ' 48F^[ILIJJILINJPLQNQPPQNQLPJ[J RIMJOKPMQ RQMPKOJMI RIXXXZW[U[SZQXPVPTQSSSUTWIW R[TZRYQWP RSTTVUWWX',\r\n  2305: ' 48F]OUMTLTJUIWIXJZL[M[OZPXPWOUJPINIKJILHOGSGWHYJZLZOYRVUUWUYV[X[YZZX RMSKPJNJKKILH RSGVHXJYLYOXRVU',\r\n  2306: ' 48G_HKKHMKMV RJILLLV RMKPHRKRU ROIQLQU RRKUHWKW[ RTIVLV[ RWKZH[J\\\\M\\\\P[SZUXWUYP[ RYIZJ[M[PZSYUWWTYP[',\r\n  2307: ' 41F^ISMSLRKOKMLJNHQGSGVHXJYMYOXRWS[S RITOTMRLOLMMJOHQG RSGUHWJXMXOWRUT[T RKXYX RKYYY',\r\n  2308: ' 30F_GLJIMLMX RIJLMLX RMLPISLSX ROJRMRX RSLVIYLYW[Y RUJXMXXZZ]W',\r\n  2309: ' 33G]ZIJY RZIWJQJ RXKUKQJ RZIYLYR RXKXNYR RQRJR RPSMSJR RQRQY RPSPVQY',\r\n  2310: ' 33F^HOJKOU RJMOWRPWPZO[M[KZIXHWHUITKTMUPVRWUWXUZ RWHVIUKUMWQXTXWWYUZ',\r\n  2311: ' 36F^IOLLPN RKMOORLUN RQMTOWLYN RVMXO[L RIULRPT RKSOURRUT RQSTUWRYT RVSXU[R',\r\n  2312: ' 48F^JHNJPLQOQRPUNWJY RJHMIOJQLRO RRRQUOWMXJY RZHWIUJSLRO RRRSUUWWXZY RZHVJTLSOSRTUVWZY RIP[P RIQ[Q',\r\n  2317: ' 12NVQQQSSSSQQQ RQQSS RSQQS',\r\n  2318: ' 18JZMPQRTTVVWYW[V]U^ RMQST RMRPSTUVWWY',\r\n  2319: ' 18JZWKVMTOPQMR RSPMS RUFVGWIWKVNTPQRMT',\r\n  2320: ' 36H\\\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM RXNSM RVMQNLP RONKR RLVQW RNWSVXT RUVYR',\r\n  2321: ' 36H\\\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM RXNSM RVMQNLP RONKR RLVQW RNWSVXT RUVYR',\r\n  2322: ' 34J[SMPNNPMRMTNVPWRWUVWTXRXPWNUMSM ROPUM RNRVN RMTWO RNUXP ROVWR RPWVT',\r\n  2323: ' 18JZOGO^ RUFU] RMNWL RMOWM RMWWU RMXWV',\r\n  2324: ' 18JZNFNX RVLV^ RNNVL RNOVM RNWVU RNXVV',\r\n  2325: ' 25JZNBNW RNNQLTLVMWOWQVSSUQVNW RNNQMTMVN RUMVOVQUSSU',\r\n  2326: ' 18E_HIHL R\\\\I\\\\L RHI\\\\I RHJ\\\\J RHK\\\\K RHL\\\\L',\r\n  2327: ' 18JZMNMQ RWNWQ RMNWN RMOWO RMPWP RMQWQ',\r\n  2328: ' 49JZMLWX RMLONQOTOVNWMWKUKUMTO RONTO RQOWM RVKVN RULWL RWXUVSUPUNVMWMYOYOWPU RUVPU RSUMW RNVNY RMXOX',\r\n  2329: ' 26JZPOOMOKMKMMNNPOSOUNWL RNKNN RMLOL RMMSO RPOUN RWLWY',\r\n  2330: ' 86A^GfHfIeIdHcGcFdFfGhIiKiNhPfQdR`RUQ;Q4R/S-U,V,X-Y/Y3X6W8U;P?JCHEFHEJDNDREVGYJ[N\\\\R\\\\V[XZZW[T[PZMYKWITHPHMIKKJNJRKUMW RGdGeHeHdGd RU;Q?LCIFGIFKENERFVGXJ[ RR\\\\U[WZYWZTZPYMXKVITH',\r\n  2331: '103EfNSOUQVSVUUVSVQUOSNQNOONPMSMVNYP[S\\\\V\\\\Y[[Y\\\\W]T]P\\\\MZJXIUHRHOIMJKLIOHSHXI]KaMcPeTfYf]e`cba RKLJNIRIXJ\\\\L`NbQdUeYe]d_cba RPOTO ROPUP RNQVQ RNRVR RNSVS ROTUT RPUTU RaLaNcNcLaL RbLbN RaMcM RaVaXcXcVaV RbVbX RaWcW',\r\n  2332: ' 30D`H@Hd RM@Md RW@Wd R\\\\@\\\\d RMMWK RMNWL RMOWM RMWWU RMXWV RMYWW',\r\n  2367: ' 12NVQQQSSSSQQQ RQQSS RSQQS',\r\n  2368: ' 18JZMPQRTTVVWYW[V]U^ RMQST RMRPSTUVWWY',\r\n  2369: ' 18JZWKVMTOPQMR RSPMS RUFVGWIWKVNTPQRMT',\r\n  2370: ' 32H\\\\PMMNLOKQKSLUMVPWTWWVXUYSYQXOWNTMPM RMNLPLSMUNVPW RWVXTXQWOVNTM',\r\n  2371: ' 36H\\\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM RXNSM RVMQNLP RONKR RLVQW RNWSVXT RUVYR',\r\n  2372: ' 34J[SMPNNPMRMTNVPWRWUVWTXRXPWNUMSM ROPUM RNRVN RMTWO RNUXP ROVWR RPWVT',\r\n  2373: ' 18JZOGO^ RUFU] RMNWL RMOWM RMWWU RMXWV',\r\n  2374: ' 18JZNFNX RVLV^ RNNVL RNOVM RNWVU RNXVV',\r\n  2375: ' 25JZNBNW RNNQLTLVMWOWQVSSUQVNW RNNQMTMVN RUMVOVQUSSU',\r\n  2376: ' 18E_HIHL R\\\\I\\\\L RHI\\\\I RHJ\\\\J RHK\\\\K RHL\\\\L',\r\n  2377: ' 18JZMNMQ RWNWQ RMNWN RMOWO RMPWP RMQWQ',\r\n  2378: ' 36JZQCVMRTRU RULQS RTITKPRRUUY RW\\\\UYSXQXOYN[N]O_Ra RW\\\\UZSYOYO]P_Ra RSXPZN]',\r\n  2379: ' 26JZPOOMOKMKMMNNPOSOUNWL RNKNN RMLOL RMMSO RPOUN RWLSY',\r\n  2380: ' 86A^GfHfIeIdHcGcFdFfGhIiKiNhPfQdR`RUQ;Q4R/S-U,V,X-Y/Y3X6W8U;P?JCHEFHEJDNDREVGYJ[N\\\\R\\\\V[XZZW[T[PZMYKWITHPHMIKKJNJRKUMW RGdGeHeHdGd RU;Q?LCIFGIFKENERFVGXJ[ RR\\\\U[WZYWZTZPYMXKVITH',\r\n  2381: ' 89IjNQOOQNSNUOVQVSUUSVQVOUNTMQMNNKPISHWH[I^K`NaRaW`[_]]`ZcVfQiMk RWHZI]K_N`R`W_[^]\\\\`YcTgQi RPOTO ROPUP RNQVQ RNRVR RNSVS ROTUT RPUTU ReLeNgNgLeL RfLfN ReMgM ReVeXgXgVeV RfVfX ReWgW',\r\n  2382: ' 85D`H>Hf RI>If RM>Mf RQBSBSDQDQAR?T>W>Y?[A\\\\D\\\\I[LYNWOUOSNRLQNOQNROSQVRXSVUUWUYV[X\\\\[\\\\`[cYeWfTfReQcQ`S`SbQb RRBRD RQCSC RY?ZA[D[IZLYN RRLRNPQNRPSRVRX RYVZX[[[`ZcYe RR`Rb RQaSa',\r\n  2401: ' 21AcHBHb RIBIb R[B[b R\\\\B\\\\b RDB`B RDbMb RWb`b',\r\n  2402: ' 23BaGBQPFb RFBPP REBPQ REB\\\\B^I[B RGa\\\\a RFb\\\\b^[[b',\r\n  2403: ' 28I[X+U1R8P=OANFMNMVN^OcPgRlUsXy RU1S6Q<P@OFNNNVO^PdQhSnUs',\r\n  2404: ' 28I[L+O1R8T=UAVFWNWVV^UcTgRlOsLy RO1Q6S<T@UFVNVVU^TdShQnOs',\r\n  2405: ' 14I[M+MRMy RN+NRNy RM+X+ RMyXy',\r\n  2406: ' 14I[V+VRVy RW+WRWy RL+W+ RLyWy',\r\n  2407: ' 48I[V+S-Q/P1O4O8P<TDUGUJTMRP RS-Q0P4P8Q;UCVGVJUMRPNRRTUWVZV]UaQiPlPpQtSw RRTTWUZU]T`PhOlOpPsQuSwVy',\r\n  2408: ' 48I[N+Q-S/T1U4U8T<PDOGOJPMRP RQ-S0T4T8S;OCNGNJOMRPVRRTOWNZN]OaSiTlTpStQw RRTPWOZO]P`ThUlUpTsSuQwNy',\r\n  2409: ' 32I[V.S1Q4O8N=NCOIPMSXT\\\\UbUgTlSoQs RS1Q5P8O=OBPHQLTWU[VaVgUlSpQsNv',\r\n  2410: ' 32I[N.Q1S4U8V=VCUITMQXP\\\\ObOgPlQoSs RQ1S5T8U=UBTHSLPWO[NaNgOlQpSsVv',\r\n  2411: ' 147Z:RARRo R@RQo R?RRr RZ\"VJRr',\r\n  2412: ' 57Ca].\\\\.[/[0\\\\1]1^0^.],[+Y+W,U.T0S3R:QJQjPsOv R\\\\/\\\\0]0]/\\\\/ RR:Rj RU.T1S:SZRjQqPtOvMxKyIyGxFvFtGsHsItIuHvGv RGtGuHuHtGt',\r\n  2501: ' 20H\\\\RFJ[ RRIK[J[ RRIY[Z[ RRFZ[ RMUWU RLVXV',\r\n  2502: ' 44H\\\\LFL[ RMGMZ RLFTFWGXHYJYMXOWPTQ RMGTGWHXJXMWOTP RMPTPWQXRYTYWXYWZT[L[ RMQTQWRXTXWWYTZMZ',\r\n  2503: ' 38H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV RZKYKXIWHUGQGOHMKLNLSMVOYQZUZWYXXYVZV',\r\n  2504: ' 32H]LFL[ RMGMZ RLFSFVGXIYKZNZSYVXXVZS[L[ RMGSGVHWIXKYNYSXVWXVYSZMZ',\r\n  2505: ' 27I\\\\MFM[ RNGNZ RMFYF RNGYGYF RNPTPTQ RNQTQ RNZYZY[ RM[Y[',\r\n  2506: ' 21I[MFM[ RNGN[M[ RMFYF RNGYGYF RNPTPTQ RNQTQ',\r\n  2507: ' 44H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZRUR RZKYKXIWHUGQGOHNIMKLNLSMVNXOYQZUZWYXXYVYSUSUR',\r\n  2508: ' 22G]KFK[ RKFLFL[K[ RYFXFX[Y[ RYFY[ RLPXP RLQXQ',\r\n  2509: '  8NWRFR[S[ RRFSFS[',\r\n  2510: ' 20J[VFVVUYSZQZOYNVMV RVFWFWVVYUZS[Q[OZNYMV',\r\n  2511: ' 22H]LFL[M[ RLFMFM[ RZFYFMR RZFMS RPOY[Z[ RQOZ[',\r\n  2512: ' 14IZMFM[ RMFNFNZ RNZYZY[ RM[Y[',\r\n  2513: ' 26F^JFJ[ RKKK[J[ RKKR[ RJFRX RZFRX RYKR[ RYKY[Z[ RZFZ[',\r\n  2514: ' 20G]KFK[ RLIL[K[ RLIY[ RKFXX RXFXX RXFYFY[',\r\n  2515: ' 40G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG',\r\n  2516: ' 27H\\\\LFL[ RMGM[L[ RLFUFWGXHYJYMXOWPUQMQ RMGUGWHXJXMWOUPMP',\r\n  2517: ' 48G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG RSXX]Y] RSXTXY]',\r\n  2518: ' 34H\\\\LFL[ RMGM[L[ RLFTFWGXHYJYMXOWPTQMQ RMGTGWHXJXMWOTPMP RRQX[Y[ RSQY[',\r\n  2519: ' 43H\\\\YIWGTFPFMGKIKKLMMNOOTQVRWSXUXXWYTZPZNYMXKX RYIWIVHTGPGMHLILKMMONTPVQXSYUYXWZT[P[MZKX',\r\n  2520: ' 15J[RGR[ RSGS[R[ RLFYFYG RLFLGYG',\r\n  2521: ' 24G]KFKULXNZQ[S[VZXXYUYF RKFLFLUMXNYQZSZVYWXXUXFYF',\r\n  2522: ' 14H\\\\JFR[ RJFKFRX RZFYFRX RZFR[',\r\n  2523: ' 26E_GFM[ RGFHFMX RRFMX RRIM[ RRIW[ RRFWX R]F\\\\FWX R]FW[',\r\n  2524: ' 16H\\\\KFX[Y[ RKFLFY[ RYFXFK[ RYFL[K[',\r\n  2525: ' 17I\\\\KFRPR[S[ RKFLFSP RZFYFRP RZFSPS[',\r\n  2526: ' 20H\\\\XFK[ RYFL[ RKFYF RKFKGXG RLZYZY[ RK[Y[',\r\n  2551: ' 38E\\\\XFVHTKQPOSLWIZG[E[DZDXEWFXEY RXFWJUTT[ RXFU[ RT[TYSVRTPRNQLQKRKTLWOZR[V[XZ',\r\n  2552: ' 70F^UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWIXHY ROLNNMOKOJNJLKJMHOGRFXFZG[I[KZMXNTORO RXFYGZIZKYMXN RTOWPXQYSYVXYWZU[S[RZRXSU RTOVPWQXSXVWYU[',\r\n  2553: ' 41H]KHJJJLKNNOQOUNWMYKZIZGYFWFTGQJOMMQLULXMZP[R[UZWXXVXTWRURSSRU RWFUGRJPMNQMUMXNZP[',\r\n  2554: ' 43F]UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWJWLXNZP[S[UZWXYTZOZLYIWGUFPFMGKIJKJMKNMNNMOK',\r\n  2555: ' 49I\\\\WIVJVLWMYMZKZIYGWFTFRGQHPJPLQNSO RTFRHQJQMSO RSOQONPLRKTKWLYMZO[R[UZWXXVXTWRURSSRU RQOOPMRLTLXMZ',\r\n  2556: ' 46G\\\\WHVJTORUQWOZM[ RQLPNNOLOKMKKLINGQF[FXGWHVKTSSVRXPZM[K[IZHYHXIWJXIY RSFWGXG ROSPRRQVQXPZMXT',\r\n  2557: ' 53G]JIIKIMJOLPOPROTNWKXHXGWFVFTGRIQKPNPQQSSTUTWSYQZO RWFUGSIRKQNQRST RZOYSWWUYSZO[L[JZIXIWJVKWJX RYSWVUXRZO[',\r\n  2558: ' 55F^LLKKKILGOFRFOQMWLYKZI[G[FZFXGWHXGY RRFOONRLWKYI[ RJTKSMRVOXN[L]J^H^G]F\\\\FZGXJWLURTVTYV[W[YZ[X R\\\\FZHXLVRUVUYV[',\r\n  2559: ' 33IYWHUKSPQUPWNZL[ RYLWNTOQOONNLNJOHQGUFYFWHVJTPRVQXOZL[J[IZIXJWKXJY',\r\n  2560: ' 34IZYFWHUKSPPYN] RYMWOTPQPOONMNKOIQGUFYFWIVKSTQXPZN]M^K_J^J\\\\KZMXOWRVVU',\r\n  2561: ' 59F^LLKKKIMGPFRFOQMWLYKZI[G[FZFXGWHXGY RRFOONRLWKYI[ RZGWKUMSNPO R]G\\\\H]I^H^G]F\\\\FZGWLVMTNPO RPOSPTRUYV[ RPORPSRTYV[W[YZ[X',\r\n  2562: ' 40I[MILKLMMOOPRPUOWNZK[H[GZFYFWGVHTKPUOWMZK[ RVHTLRSQVPXNZK[I[HZHXIWKWMXPZR[U[WZYX',\r\n  2563: ' 49D`RFNOKUIXGZE[C[BZBXCWDXCY RRFPMOQNVNZP[ RRFQJPOOVOZP[ R[FWORXP[ R[FYMXQWVWZY[Z[\\\\Z^X R[FZJYOXVXZY[',\r\n  2564: ' 38G^RFQJOPMULWJZH[F[EZEXFWGXFY RRFRKSVT[ RRFSKTVT[ R`G_H`IaHaG`F^F\\\\GZJYLWQUWT[',\r\n  2565: ' 34H]SFQGOIMLLNKRKVLYMZO[Q[TZVXXUYSZOZKYHXGWGUHSJQNPSPV RQGOJMNLRLVMYO[',\r\n  2566: ' 53F]UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWIXHY ROLNNMOKOJNJLKJMHOGRFVFYGZH[J[MZOYPVQTQRP RVFXGYHZJZMYOXPVQ',\r\n  2567: ' 43H]UJULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWSSWPYNZK[I[HZHXIWKWMXPZS[V[XZZX RWFXGYIYMXPVSSVOYK[',\r\n  2568: ' 65F^UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWIXHY ROLNNMOKOJNJLKJMHOGRFWFZG[I[KZMYNVORO RWFYGZIZKYMXNVO RROUPVRWYX[ RROTPURVYX[Y[[Z]X',\r\n  2569: ' 36H\\\\NIMKMMNOPPSPVOXN[K\\\\H\\\\G[FZFXGWHVJUMSTRWPZN[ RVJUNTUSXQZN[K[IZHXHWIVJWIX',\r\n  2570: ' 38I[YHXJVOTUSWQZO[ RSLRNPONOMMMKNIPGSF\\\\FZGYHXKVSUVTXRZO[M[KZJYJXKWLXKY RUFYGZG',\r\n  2571: ' 39G]HJJGLFMFOHOKNNKVKYL[ RMFNHNKKSJVJYL[N[PZSWUTVR RZFVRUVUYW[X[ZZ\\\\X R[FWRVVVYW[',\r\n  2572: ' 36G\\\\HJJGLFMFOHOKNOLVLYM[ RMFNHNKLRKVKYM[N[QZTWVTXPYMZIZGYFXFWGVIVLWNYP[Q]Q',\r\n  2573: ' 41F]ILHLGKGIHGJFNFMHLLKUJ[ RLLLUK[ RVFTHRLOUMYK[ RVFUHTLSUR[ RTLTUS[ R`F^G\\\\IZLWUUYS[',\r\n  2574: ' 52H\\\\PKOLMLLKLIMGOFQFSGTITLSPQUOXMZJ[H[GZGXHWIXHY RQFRGSISLRPPUNXLZJ[ R]G\\\\H]I^H^G]F[FYGWIULSPRURXSZT[U[WZYX',\r\n  2575: ' 42G]JJLGNFOFQGQIOOORPT ROFPGPINONRPTRTUSWQYNZL R\\\\FZLWTUX R]F[LYQWUUXSZP[L[JZIXIWJVKWJX',\r\n  2576: ' 44G\\\\ZHYJWOVRUTSWQYOZL[ RSLRNPONOMMMKNIPGSF]F[GZHYKXOVUTXQZL[H[GZGXHWJWLXOZQ[T[WZYX RVFZG[G',\r\n  2601: ' 36H\\\\WMW[X[ RWMXMX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2602: ' 36H\\\\LFL[M[ RLFMFM[ RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX',\r\n  2603: ' 32I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX RXPWQVOTNQNOONPMSMUNXOYQZTZVYWWXX',\r\n  2604: ' 36H\\\\WFW[X[ RWFXFX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2605: ' 36I[MTXTXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX RMSWSWQVOTNQNOONPMSMUNXOYQZTZVYWWXX',\r\n  2606: ' 24LZWFUFSGRJR[S[ RWFWGUGSH RTGSJS[ ROMVMVN ROMONVN',\r\n  2607: ' 48H\\\\XMWMW\\\\V_U`SaQaO`N_L_ RXMX\\\\W_UaSbPbNaL_ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2608: ' 25H\\\\LFL[M[ RLFMFM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[',\r\n  2609: ' 24NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMR[S[ RRMSMS[',\r\n  2610: ' 24NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMRbSb RRMSMSb',\r\n  2611: ' 22H[LFL[M[ RLFMFM[ RXMWMMW RXMMX RPTV[X[ RQSX[',\r\n  2612: '  8NWRFR[S[ RRFSFS[',\r\n  2613: ' 42CbGMG[H[ RGMHMH[ RHQKNMMPMRNSQS[ RHQKOMNONQORQR[S[ RSQVNXM[M]N^Q^[ RSQVOXNZN\\\\O]Q][^[',\r\n  2614: ' 25H\\\\LML[M[ RLMMMM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[',\r\n  2615: ' 36I\\\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM RQNOONPMSMUNXOYQZTZVYWXXUXSWPVOTNQN',\r\n  2616: ' 36H\\\\LMLbMb RLMMMMb RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX',\r\n  2617: ' 36H\\\\WMWbXb RWMXMXb RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2618: ' 21KYOMO[P[ ROMPMP[ RPSQPSNUMXM RPSQQSOUNXNXM',\r\n  2619: ' 50J[XPWNTMQMNNMPNRPSUUWV RVUWWWXVZ RWYTZQZNY ROZNXMX RXPWPVN RWOTNQNNO RONNPOR RNQPRUTWUXWXXWZT[Q[NZMX',\r\n  2620: ' 16MXRFR[S[ RRFSFS[ ROMVMVN ROMONVN',\r\n  2621: ' 25H\\\\LMLWMZO[R[TZWW RLMMMMWNYPZRZTYWW RWMW[X[ RWMXMX[',\r\n  2622: ' 14JZLMR[ RLMMMRY RXMWMRY RXMR[',\r\n  2623: ' 26F^IMN[ RIMJMNX RRMNX RRPN[ RRPV[ RRMVX R[MZMVX R[MV[',\r\n  2624: ' 16I[LMW[X[ RLMMMX[ RXMWML[ RXMM[L[',\r\n  2625: ' 17JZLMR[ RLMMMRY RXMWMRYNb RXMR[ObNb',\r\n  2626: ' 20I[VNL[ RXMNZ RLMXM RLMLNVN RNZXZX[ RL[X[',\r\n  2651: ' 33K[UUTSRRPRNSMTLVLXMZO[Q[SZTX RPRNTMVMYO[ RVRTXTZV[XZYY[V RWRUXUZV[',\r\n  2652: ' 23LZLVNSPO RSFMXMZO[P[RZTXUUURVVWWXWZV RTFNXNZO[',\r\n  2653: ' 22LXTSSTTTTSSRQROSNTMVMXNZP[S[VYXV RQROTNVNYP[',\r\n  2654: ' 33K[UUTSRRPRNSMTLVLXMZO[Q[SZTX RPRNTMVMYO[ RZFTXTZV[XZYY[V R[FUXUZV[',\r\n  2655: ' 23LXOYQXRWSUSSRRQROSNTMVMXNZP[S[VYXV RQROTNVNYP[',\r\n  2656: ' 27OXRRUOWLXIXGWFUGTIKdKfLgNfOcPZQ[S[UZVYXV RTISNRRO[M`Kd',\r\n  2657: ' 38K[UUTSRRPRNSMTLVLXMZO[Q[SZTX RPRNTMVMYO[ RVRPd RWRT[R`PdOfMgLfLdMaO_R]V[YY[V',\r\n  2658: ' 30L[LVNSPO RSFL[ RTFM[ ROUQSSRTRVSVUUXUZV[ RTRUSUUTXTZV[XZYY[V',\r\n  2659: ' 19NVSLRMSNTMSL RQROXOZQ[SZTYVV RRRPXPZQ[',\r\n  2660: ' 24NVSLRMSNTMSL RQRKd RRRO[M`KdJfHgGfGdHaJ_M]Q[TYVV',\r\n  2661: ' 31LZLVNSPO RSFL[ RTFM[ RURUSVSURTRRTOU ROURVSZT[ ROUQVRZT[U[XYZV',\r\n  2662: ' 17NVNVPSRO RUFOXOZQ[SZTYVV RVFPXPZQ[',\r\n  2663: ' 45E^EVGSIRKSKUI[ RIRJSJUH[ RKUMSORPRRSRUP[ RPRQSQUO[ RRUTSVRWRYSYUXXXZY[ RWRXSXUWXWZY[[Z\\\\Y^V',\r\n  2664: ' 32I[IVKSMROSOUM[ RMRNSNUL[ ROUQSSRTRVSVUUXUZV[ RTRUSUUTXTZV[XZYY[V',\r\n  2665: ' 29KYRRPRNSMTLVLXMZO[Q[SZTYUWUUTSRRQSQURWTXVXXWYV RPRNTMVMYO[',\r\n  2666: ' 30L[LVNSPO RQLHg RRLIg ROUQSSRTRVSVUUXUZV[ RTRUSUUTXTZV[XZYY[V',\r\n  2667: ' 35K[UUTSRRPRNSMTLVLXMZO[Q[SZ RPRNTMVMYO[ RVRPdPfQgSfTcT[V[YY[V RWRT[R`Pd',\r\n  2668: ' 24LZLVNSPRRSRUP[ RPRQSQUO[ RRUTSVRWRVU RVRVUWWXWZV',\r\n  2669: ' 22NZNVPSQQQSTUUWUYTZR[ RQSSUTWTYR[ RNZP[U[XYZV',\r\n  2670: ' 20NVNVPSRO RUFOXOZQ[SZTYVV RVFPXPZQ[ RPNVN',\r\n  2671: ' 27K[NRLXLZN[O[QZSXUU RORMXMZN[ RVRTXTZV[XZYY[V RWRUXUZV[',\r\n  2672: ' 23KZNRMTLWLZN[O[RZTXUUUR RORNTMWMZN[ RURVVWWXWZV',\r\n  2673: ' 36H]LRJTIWIZK[L[NZPX RMRKTJWJZK[ RRRPXPZR[S[UZWXXUXR RSRQXQZR[ RXRYVZW[W]V',\r\n  2674: ' 42JZJVLSNRPRQSQUPXOZM[L[KZKYLYKZ RWSVTWTWSVRURSSRUQXQZR[U[XYZV RQSRU RSSQU RPXQZ RQXOZ',\r\n  2675: ' 32K[NRLXLZN[O[QZSXUU RORMXMZN[ RVRPd RWRT[R`PdOfMgLfLdMaO_R]V[YY[V',\r\n  2676: ' 38LYLVNSPRRRTSTVSXPZN[ RRRSSSVRXPZ RN[P\\\\Q^QaPdNfLgKfKdLaO^R\\\\VYYV RN[O\\\\P^PaOdNf',\r\n  2700: ' 42H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF ROGMJLOLRMWOZ RNYQZSZVY RUZWWXRXOWJUG RVHSGQGNH',\r\n  2701: ' 12H\\\\NJPISFS[ RNJNKPJRHR[S[',\r\n  2702: ' 34H\\\\LKLJMHNGPFTFVGWHXJXLWNUQL[ RLKMKMJNHPGTGVHWJWLVNTQK[ RLZYZY[ RK[Y[',\r\n  2703: ' 48H\\\\MFXFQO RMFMGWG RWFPO RQNSNVOXQYTYUXXVZS[P[MZLYKWLW RPOSOVPXS RTOWQXTXUWXTZ RXVVYSZPZMYLW ROZLX',\r\n  2704: ' 18H\\\\UIU[V[ RVFV[ RVFKVZV RUILV RLUZUZV',\r\n  2705: ' 53H\\\\MFLO RNGMN RMFWFWG RNGWG RMNPMSMVNXPYSYUXXVZS[P[MZLYKWLW RLOMOONSNVOXR RTNWPXSXUWXTZ RXVVYSZPZMYLW ROZLX',\r\n  2706: ' 62H\\\\VGWIXIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQ RWHTGRGOH RPGNJMOMTNXQZ RMVOYRZSZVYXV RTZWXXUXTWQTO RXSVPSOROOPMS RQONQMT',\r\n  2707: ' 12H\\\\KFYFO[ RKFKGXG RXFN[O[',\r\n  2708: ' 68H\\\\PFMGLILKMMNNPOTPVQWRXTXWWYTZPZMYLWLTMRNQPPTOVNWMXKXIWGTFPF RNGMIMKNMPNTOVPXRYTYWXYWZT[P[MZLYKWKTLRNPPOTNVMWKWIVG RWHTGPGMH RLXOZ RUZXX',\r\n  2709: ' 62H\\\\WPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLXMXNZ RWMVPSR RWNUQRRQRNQLN RPRMPLMLLMIPG RLKNHQGRGUHWK RSGVIWMWRVWTZ RUYRZPZMY',\r\n  2710: ' 16MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2711: ' 24MXTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  2712: ' 32MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2713: ' 40MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  2714: ' 24MXRFRTST RRFSFST RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2715: ' 58I\\\\LKLJMHNGQFTFWGXHYJYLXNWOUPRQ RLKMKMJNHQGTGWHXJXLWNUORP RMIPG RUGXI RXMTP RRPRTSTSP RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2716: ' 24MXTFRGQIQLRMSMTLTKSJRJQK RRKRLSLSKRK RRGQK RQIRJ',\r\n  2717: ' 24MXTHSIRIQHQGRFSFTGTJSLQM RRGRHSHSGRG RSITJ RTHSL',\r\n  2718: ' 71F_\\\\MZMXNWPUVTXSYQZMZKYJWJUKSLRQOSMTKTISGQFPFNGMIMKNNPQUWXZZ[\\\\[ R\\\\M\\\\NZNXO RYNXPVVUXSZQ[M[KZJYIWIUJSLQQNRMSKSIRG RSHQGPGNH ROGNINKONQQVWXYZZ\\\\Z\\\\[',\r\n  2719: ' 51I\\\\RBR_S_ RRBSBS_ RWIYIWGTFQFNGLILKMMNNVRWSXUXWWYTZQZOYNX RWIVHTGQGNHMIMKNMVQXSYUYWXYWZT[Q[NZLXNX RXXUZ',\r\n  2720: '  8G^[BIbJb R[B\\\\BJb',\r\n  2721: ' 24KYUBSDQGOKNPNTOYQ]S`UbVb RUBVBTDRGPKOPOTPYR]T`Vb',\r\n  2722: ' 24KYNBPDRGTKUPUTTYR]P`NbOb RNBOBQDSGUKVPVTUYS]Q`Ob',\r\n  2723: ' 39JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO',\r\n  2724: '  8F_JQ[Q[R RJQJR[R',\r\n  2725: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  2726: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  2727: ' 11NWSFRGRM RSGRM RSFTGRM',\r\n  2728: ' 22I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM',\r\n  2729: ' 30KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF',\r\n  2750: ' 42H]TFQGOIMLLOKSKVLYMZO[Q[TZVXXUYRZNZKYHXGVFTF RTFRGPINLMOLSLVMYO[ RQ[SZUXWUXRYNYKXHVF',\r\n  2751: ' 15H]TJO[ RVFP[ RVFSIPKNL RUIQKNL',\r\n  2752: ' 42H]OJPKOLNKNJOHPGSFVFYGZIZKYMWOTQPSMUKWI[ RVFXGYIYKXMVOPS RJYKXMXRZUZWYXW RMXR[U[WZXW',\r\n  2753: ' 50H]OJPKOLNKNJOHPGSFVFYGZIZKYMVOSP RVFXGYIYKXMVO RQPSPVQWRXTXWWYVZS[O[LZKYJWJVKULVKW RSPUQVRWTWWVYUZS[',\r\n  2754: ' 10H]XGR[ RYFS[ RYFJUZU',\r\n  2755: ' 39H]QFLP RQF[F RQGVG[F RLPMOPNSNVOWPXRXUWXUZR[O[LZKYJWJVKULVKW RSNUOVPWRWUVXTZR[',\r\n  2756: ' 46H]YIXJYKZJZIYGWFTFQGOIMLLOKSKWLYMZO[R[UZWXXVXSWQVPTOQOOPMRLT RTFRGPINLMOLSLXMZ RR[TZVXWVWRVP',\r\n  2757: ' 30H]NFLL R[FZIXLSRQUPWO[ RXLRRPUOWN[ RMIPFRFWI RNHPGRGWIYIZH[F',\r\n  2758: ' 63H]SFPGOHNJNMOOQPTPXOYNZLZIYGVFSF RSFQGPHOJOMPOQP RTPWOXNYLYIXGVF RQPMQKSJUJXKZN[R[VZWYXWXTWRVQTP RQPNQLSKUKXLZN[ RR[UZVYWWWSVQ',\r\n  2759: ' 46H]YMXOVQTRQROQNPMNMKNIPGSFVFXGYHZJZNYRXUVXTZQ[N[LZKXKWLVMWLX ROQNONKOIQGSF RXGYIYNXRWUUXSZQ[',\r\n  2760: '  6MXPYOZP[QZPY',\r\n  2761: '  8MXP[OZPYQZQ[P]N_',\r\n  2762: ' 11MXSMRNSOTNSM RPYOZP[QZ',\r\n  2763: ' 14MXSMRNSOTNSM RP[OZPYQZQ[P]N_',\r\n  2764: ' 17MXUFTGRS RUGRS RUFVGRS RPYOZP[QZPY',\r\n  2765: ' 34H]OJPKOLNKNJOHPGSFWFZG[I[KZMYNSPQQQSRTTT RWFYGZIZKYMXNVO RPYOZP[QZPY',\r\n  2766: '  8MXVFTHSJSKTLUKTJ',\r\n  2767: '  8MXUHTGUFVGVHUJSL',\r\n  2768: ' 55E_\\\\N[O\\\\P]O]N\\\\M[MYNWPRXPZN[K[HZGXGVHTISKRPPROTMUKUITGRFPGOIOLPRQUSXUZW[Y[ZYZX RK[IZHXHVITJSPP ROLPQQTSWUYWZYZZY',\r\n  2769: ' 41H]TBL_ RYBQ_ RZJYKZL[K[JZHYGVFRFOGMIMKNMONVRXT RMKOMVQWRXTXWWYVZS[O[LZKYJWJVKULVKW',\r\n  2770: '  3G]_BEb',\r\n  2771: ' 20KZZBVESHQKOONTNXO]P`Qb RVESIQMPPOUOZP_Qb',\r\n  2772: ' 20JYSBTDUGVLVPUUSYQ\\\\N_Jb RSBTEUJUOTTSWQ[N_',\r\n  2773: '  9J[TFTR ROIYO RYIOO',\r\n  2774: '  3E_IR[R',\r\n  2775: '  6E_RIR[ RIR[R',\r\n  2776: '  6E_IO[O RIU[U',\r\n  2777: '  6NWUFSM RVFSM',\r\n  2778: ' 12I[PFNM RQFNM RYFWM RZFWM',\r\n  2779: ' 14KZSFQGPIPKQMSNUNWMXKXIWGUFSF',\r\n  2801: ' 18H\\\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[',\r\n  2802: ' 31G]LFL[ RMFM[ RIFYFYLXF RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2803: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2804: ' 14I[NFN[ ROFO[ RKFZFZLYF RK[R[',\r\n  2805: ' 31F^NFNLMTLXKZJ[ RXFX[ RYFY[ RKF\\\\F RG[\\\\[ RG[Gb RH[Gb R[[\\\\b R\\\\[\\\\b',\r\n  2806: ' 22G\\\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[',\r\n  2807: ' 71CbRFR[ RSFS[ ROFVF RGGHHGIFHFGGFHFIGJIKMLONPWPYOZM[I\\\\G]F^F_G_H^I]H^G RNPLQKSJXIZH[ RNPMQLSKXJZI[G[FZEX RWPYQZS[X\\\\Z][ RWPXQYSZX[Z\\\\[^[_Z`X RO[V[',\r\n  2808: ' 45H\\\\LIKFKLLINGPFTFWGXIXLWNTOQO RTFVGWIWLVNTO RTOVPXRYTYWXYWZT[O[MZLYKWKVLUMVLW RWQXTXWWYVZT[',\r\n  2809: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RXHLY RH[O[ RU[\\\\[',\r\n  2810: ' 37F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RXHLY RH[O[ RU[\\\\[ RN@N?M?M@NBPCTCVBW@',\r\n  2811: ' 43F^KFK[ RLFL[ RHFOF RLPSPUOVMWIXGYFZF[G[HZIYHZG RSPUQVSWXXZY[ RSPTQUSVXWZX[Z[[Z\\\\X RH[O[',\r\n  2812: ' 25E^MFMLLTKXJZI[H[GZGYHXIYHZ RXFX[ RYFY[ RJF\\\\F RU[\\\\[',\r\n  2813: ' 30F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][',\r\n  2814: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RLPXP RH[O[ RU[\\\\[',\r\n  2815: ' 44G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF',\r\n  2816: ' 21F^KFK[ RLFL[ RXFX[ RYFY[ RHF\\\\F RH[O[ RU[\\\\[',\r\n  2817: ' 29G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[',\r\n  2818: ' 32G\\\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV RQFOGMILKKNKSLVMXOZQ[',\r\n  2819: ' 16I\\\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[',\r\n  2820: ' 24H]KFRV RLFSV RZFSVQYPZN[M[LZLYMXNYMZ RIFOF RVF\\\\F',\r\n  2821: ' 48F_RFR[ RSFS[ ROFVF RPILJJLIOIRJULWPXUXYW[U\\\\R\\\\O[LYJUIPI RPIMJKLJOJRKUMWPX RUXXWZU[R[OZLXJUI RO[V[',\r\n  2822: ' 21H\\\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[',\r\n  2823: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RH[\\\\[ R[[\\\\b R\\\\[\\\\b',\r\n  2824: ' 28F]KFKQLSOTRTUSWQ RLFLQMSOT RWFW[ RXFX[ RHFOF RTF[F RT[[[',\r\n  2825: ' 30BcGFG[ RHFH[ RRFR[ RSFS[ R]F][ R^F^[ RDFKF ROFVF RZFaF RD[a[',\r\n  2826: ' 36BcGFG[ RHFH[ RRFR[ RSFS[ R]F][ R^F^[ RDFKF ROFVF RZFaF RD[a[ R`[ab Ra[ab',\r\n  2827: ' 31F`PFP[ RQFQ[ RIFHLHFTF RQPXP[Q\\\\R]T]W\\\\Y[ZX[M[ RXPZQ[R\\\\T\\\\W[YZZX[',\r\n  2828: ' 41CaHFH[ RIFI[ REFLF RIPPPSQTRUTUWTYSZP[E[ RPPRQSRTTTWSYRZP[ R[F[[ R\\\\F\\\\[ RXF_F RX[_[',\r\n  2829: ' 29H]MFM[ RNFN[ RJFQF RNPUPXQYRZTZWYYXZU[J[ RUPWQXRYTYWXYWZU[',\r\n  2830: ' 39H]LIKFKLLINGQFSFVGXIYKZNZSYVXXVZS[P[MZLYKWKVLUMVLW RSFUGWIXKYNYSXVWXUZS[ RPPYP',\r\n  2831: ' 59CbHFH[ RIFI[ REFLF RE[L[ RVFSGQIPKOOORPVQXSZV[X[[Z]X^V_R_O^K]I[GXFVF RVFTGRIQKPOPRQVRXTZV[ RX[ZZ\\\\X]V^R^O]K\\\\IZGXF RIPOP',\r\n  2832: ' 45G]WFW[ RXFX[ R[FOFLGKHJJJLKNLOOPWP ROFMGLHKJKLLNMOOP RRPPQORLYKZJZIY RPQOSMZL[J[IYIX RT[[[',\r\n  2901: ' 39I]NONPMPMONNPMTMVNWOXQXXYZZ[ RWOWXXZZ[[[ RWQVRPSMTLVLXMZP[S[UZWX RPSNTMVMXNZP[',\r\n  2902: ' 48H\\\\XFWGQINKLNKQKULXNZQ[S[VZXXYUYSXPVNSMQMNNLPKS RXFWHUIQJNLLN RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM',\r\n  2903: ' 37H\\\\MMM[ RNMN[ RJMUMXNYPYQXSUT RUMWNXPXQWSUT RNTUTXUYWYXXZU[J[ RUTWUXWXXWZU[',\r\n  2904: ' 14HZMMM[ RNMN[ RJMXMXRWM RJ[Q[',\r\n  2905: ' 22F]NMNQMWLZK[ RWMW[ RXMX[ RKM[M RI[H`H[[[[`Z[',\r\n  2906: ' 31H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX RWSWPVN RQMONMPLSLUMXOZQ[',\r\n  2907: ' 59E`RMR[ RSMS[ ROMVM RJNIOHNIMJMKNMRNSPTUTWSXRZN[M\\\\M]N\\\\O[N RPTNUMVKZJ[ RPTNVLZK[I[HZGX RUTWUXVZZ[[ RUTWVYZZ[\\\\[]Z^X RO[V[',\r\n  2908: ' 42I[MOLMLQMONNPMTMWNXPXQWSTT RTMVNWPWQVSTT RQTTTWUXWXXWZT[P[MZLXLWMVNWMX RTTVUWWWXVZT[',\r\n  2909: ' 27G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RI[P[ RT[[[ RWNMZ',\r\n  2910: ' 37G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RI[P[ RT[[[ RWNMZ ROGOFNFNGOIQJSJUIVG',\r\n  2911: ' 38H\\\\MMM[ RNMN[ RJMQM RNTPTSSTRVNWMXMYNXOWN RPTSUTVVZW[ RPTRUSVUZV[X[YZZX RJ[Q[',\r\n  2912: ' 22G]NMNQMWLZK[J[IZJYKZ RWMW[ RXMX[ RKM[M RT[[[',\r\n  2913: ' 30G^LML[ RLMR[ RMMRY RXMR[ RXMX[ RYMY[ RIMMM RXM\\\\M RI[O[ RU[\\\\[',\r\n  2914: ' 27G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RMTWT RI[P[ RT[[[',\r\n  2915: ' 36H\\\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM',\r\n  2916: ' 21G]LML[ RMMM[ RWMW[ RXMX[ RIM[M RI[P[ RT[[[',\r\n  2917: ' 36G\\\\LMLb RMMMb RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIMMM RIbPb',\r\n  2918: ' 28H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX RQMONMPLSLUMXOZQ[',\r\n  2919: ' 16I\\\\RMR[ RSMS[ RMMLRLMYMYRXM RO[V[',\r\n  2920: ' 22I[LMR[ RMMRY RXMR[P_NaLbKbJaK`La RJMPM RTMZM',\r\n  2921: ' 52H]RFRb RSFSb ROFSF RRPQNPMNMLNKQKWLZN[P[QZRX RNMMNLQLWMZN[ RWMXNYQYWXZW[ RSPTNUMWMYNZQZWYZW[U[TZSX RObVb',\r\n  2922: ' 21H\\\\LMW[ RMMX[ RXML[ RJMPM RTMZM RJ[P[ RT[Z[',\r\n  2923: ' 23G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RI[[[[`Z[',\r\n  2924: ' 28G]LMLTMVPWRWUVWT RMMMTNVPW RWMW[ RXMX[ RIMPM RTM[M RT[[[',\r\n  2925: ' 30CbHMH[ RIMI[ RRMR[ RSMS[ R\\\\M\\\\[ R]M][ REMLM ROMVM RYM`M RE[`[',\r\n  2926: ' 32CbHMH[ RIMI[ RRMR[ RSMS[ R\\\\M\\\\[ R]M][ REMLM ROMVM RYM`M RE[`[``_[',\r\n  2927: ' 27H]QMQ[ RRMR[ RLMKRKMUM RRTVTYUZWZXYZV[N[ RVTXUYWYXXZV[',\r\n  2928: ' 37E_JMJ[ RKMK[ RGMNM RKTOTRUSWSXRZO[G[ ROTQURWRXQZO[ RYMY[ RZMZ[ RVM]M RV[][',\r\n  2929: ' 25J[OMO[ RPMP[ RLMSM RPTTTWUXWXXWZT[L[ RTTVUWWWXVZT[',\r\n  2930: ' 34I\\\\MOLMLQMONNPMSMVNXPYSYUXXVZS[P[NZLXLWMVNWMX RSMUNWPXSXUWXUZS[ RRTXT',\r\n  2931: ' 51DaIMI[ RJMJ[ RFMMM RF[M[ RVMSNQPPSPUQXSZV[X[[Z]X^U^S]P[NXMVM RVMTNRPQSQURXTZV[ RX[ZZ\\\\X]U]S\\\\PZNXM RJTPT',\r\n  2932: ' 40G\\\\VMV[ RWMW[ RZMOMLNKPKQLSOTVT ROMMNLPLQMSOT RTTQUPVNZM[ RTTRUQVOZN[L[KZJX RS[Z[',\r\n  3001: ' 36H\\\\RFKZ RQIW[ RRIX[ RRFY[ RMUVU RI[O[ RT[[[ RKZJ[ RKZM[ RWZU[ RWYV[ RXYZ[',\r\n  3002: ' 78G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUP RXHYJYLXN RUFWGXIXMWOUP RNPUPXQYRZTZWYYXZU[I[ RXRYTYWXY RUPWQXSXXWZU[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3003: ' 37G\\\\XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXXYV RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[',\r\n  3004: ' 62G]LFL[ RMGMZ RNFN[ RIFSFVGXIYKZNZSYVXXVZS[I[ RWIXKYNYSXVWX RSFUGWJXNXSWWUZS[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3005: ' 83G\\\\LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Y[YU RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[ RT[YZ RV[YY RW[YX RX[YU',\r\n  3006: ' 70G[LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Q[ RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3007: ' 60G^XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXZY[YS RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[ RXTXY RWSWYVZ RTS\\\\S RUSWT RVSWU RZSYU R[SYT',\r\n  3008: ' 81F^KFK[ RLGLZ RMFM[ RWFW[ RXGXZ RYFY[ RHFPF RTF\\\\F RMPWP RH[P[ RT[\\\\[ RIFKG RJFKH RNFMH ROFMG RUFWG RVFWH RZFYH R[FYG RKZI[ RKYJ[ RMYN[ RMZO[ RWZU[ RWYV[ RYYZ[ RYZ[[',\r\n  3009: ' 39LXQFQ[ RRGRZ RSFS[ RNFVF RN[V[ ROFQG RPFQH RTFSH RUFSG RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3010: ' 45JYSFSWRZQ[ RTGTWSZ RUFUWTZQ[O[MZLXLVMUNUOVOWNXMX RMVMWNWNVMV RPFXF RQFSG RRFSH RVFUH RWFUG',\r\n  3011: ' 69F\\\\KFK[ RLGLZ RMFM[ RXGMR RPPW[ RQPX[ RQNY[ RHFPF RUF[F RH[P[ RT[[[ RIFKG RJFKH RNFMH ROFMG RWFXG RZFXG RKZI[ RKYJ[ RMYN[ RMZO[ RWYU[ RWYZ[',\r\n  3012: ' 52I[NFN[ ROGOZ RPFP[ RKFSF RK[Z[ZU RLFNG RMFNH RQFPH RRFPG RNZL[ RNYM[ RPYQ[ RPZR[ RU[ZZ RW[ZY RX[ZX RY[ZU',\r\n  3013: ' 63E_JFJZ RJFQ[ RKFQX RLFRX RXFQ[ RXFX[ RYGYZ RZFZ[ RGFLF RXF]F RG[M[ RU[][ RHFJG R[FZH R\\\\FZG RJZH[ RJZL[ RXZV[ RXYW[ RZY[[ RZZ\\\\[',\r\n  3014: ' 39F^KFKZ RKFY[ RLFXX RMFYX RYGY[ RHFMF RVF\\\\F RH[N[ RIFKG RWFYG R[FYG RKZI[ RKZM[',\r\n  3015: ' 54G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF',\r\n  3016: ' 59G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZMYOXPUQNQ RXHYJYMXO RUFWGXIXNWPUQ RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3017: ' 77G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF RNXOVQURUTVUXV^W`Y`Z^Z\\\\ RV\\\\W^X_Y_ RUXW]X^Y^Z]',\r\n  3018: ' 80G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUPNP RXHYJYLXN RUFWGXIXMWOUP RRPTQUSWYX[Z[[Y[W RWWXYYZZZ RTQURXXYYZY[X RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3019: ' 44H\\\\XIYFYLXIVGSFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[Q[NZLXKUK[LX',\r\n  3020: ' 57H\\\\JFJL RQFQ[ RRGRZ RSFS[ RZFZL RJFZF RN[V[ RKFJL RLFJI RMFJH ROFJG RUFZG RWFZH RXFZI RYFZL RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3021: ' 45F^KFKULXNZQ[S[VZXXYUYG RLGLVMX RMFMVNYOZQ[ RHFPF RVF\\\\F RIFKG RJFKH RNFMH ROFMG RWFYG R[FYG',\r\n  3022: ' 34H\\\\KFR[ RLFRXR[ RMFSX RYGR[ RIFPF RUF[F RJFLH RNFMH ROFMG RWFYG RZFYG',\r\n  3023: ' 55F^JFN[ RKFNVN[ RLFOV RRFOVN[ RRFV[ RSFVVV[ RTFWV RZGWVV[ RGFOF RRFTF RWF]F RHFKG RIFKH RMFLH RNFLG RXFZG R\\\\FZG',\r\n  3024: ' 54H\\\\KFW[ RLFX[ RMFY[ RXGLZ RIFPF RUF[F RI[O[ RT[[[ RJFMH RNFMH ROFMG RVFXG RZFXG RLZJ[ RLZN[ RWZU[ RWYV[ RWYZ[',\r\n  3025: ' 48G]JFQQQ[ RKFRQRZ RLFSQS[ RYGSQ RHFOF RVF\\\\F RN[V[ RIFKG RNFLG RWFYG R[FYG RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3026: ' 41H\\\\YFKFKL RWFK[ RXFL[ RYFM[ RK[Y[YU RLFKL RMFKI RNFKH RPFKG RT[YZ RV[YY RW[YX RX[YU',\r\n  3051: ' 38H\\\\UFIZ RSJT[ RTHUZ RUFUHVYV[ RLUTU RF[L[ RQ[X[ RIZG[ RIZK[ RTZR[ RTYS[ RVYW[',\r\n  3052: ' 78F^OFI[ RPFJ[ RQFK[ RLFWFZG[I[KZNYOVP RYGZIZKYNXO RWFXGYIYKXNVP RNPVPXQYSYUXXVZR[F[ RWQXSXUWXUZ RVPWRWUVXTZR[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3053: ' 41H]ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[S[UZWXXV RQHOJNLMOLSLWMY RTFRGPJOLNOMSMXNZP[',\r\n  3054: ' 63F]OFI[ RPFJ[ RQFK[ RLFUFXGYHZKZOYSWWUYSZO[F[ RWGXHYKYOXSVWTY RUFWHXKXOWSUWRZO[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3055: ' 80F]OFI[ RPFJ[ RQFK[ RULST RLF[FZL RNPTP RF[U[WV RMFPG RNFOH RRFPH RSFPG RWFZG RXFZH RYFZI RZFZL RULSPST RTNRPSR RTOQPSQ RJZG[ RJYH[ RKYL[ RJZM[ RP[UZ RR[UY RUYWV',\r\n  3056: ' 70F\\\\OFI[ RPFJ[ RQFK[ RULST RLF[FZL RNPTP RF[N[ RMFPG RNFOH RRFPH RSFPG RWFZG RXFZH RYFZI RZFZL RULSPST RTNRPSR RTOQPSQ RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3057: ' 65H^ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[R[UZWXYT RQHOJNLMOLSLWMY RVXWWXT RTFRGPJOLNOMSMXNZP[ RR[TZVWWT RTT\\\\T RUTWU RVTWW RZTXV R[TXU',\r\n  3058: ' 81E_NFH[ ROFI[ RPFJ[ RZFT[ R[FU[ R\\\\FV[ RKFSF RWF_F RLPXP RE[M[ RQ[Y[ RLFOG RMFNH RQFOH RRFOG RXF[G RYFZH R]F[H R^F[G RIZF[ RIYG[ RJYK[ RIZL[ RUZR[ RUYS[ RVYW[ RUZX[',\r\n  3059: ' 39KYTFN[ RUFO[ RVFP[ RQFYF RK[S[ RRFUG RSFTH RWFUH RXFUG ROZL[ ROYM[ RPYQ[ ROZR[',\r\n  3060: ' 47I\\\\WFRWQYO[ RXFTSSVRX RYFUSSXQZO[M[KZJXJVKULUMVMWLXKX RKVKWLWLVKV RTF\\\\F RUFXG RVFWH RZFXH R[FXG',\r\n  3061: ' 72F]OFI[ RPFJ[ RQFK[ R\\\\GMR RQOU[ RROV[ RSNWZ RLFTF RYF_F RF[N[ RR[Y[ RMFPG RNFOH RRFPH RSFPG RZF\\\\G R^F\\\\G RJZG[ RJYH[ RKYL[ RJZM[ RUZS[ RUYT[ RVYX[',\r\n  3062: ' 49H\\\\QFK[ RRFL[ RSFM[ RNFVF RH[W[YU ROFRG RPFQH RTFRH RUFRG RLZI[ RLYJ[ RMYN[ RLZO[ RR[WZ RT[XX RV[YU',\r\n  3063: ' 68D`MFGZ RMGNYN[ RNFOY ROFPX R[FPXN[ R[FU[ R\\\\FV[ R]FW[ RJFOF R[F`F RD[J[ RR[Z[ RKFMG RLFMH R^F\\\\H R_F\\\\G RGZE[ RGZI[ RVZS[ RVYT[ RWYX[ RVZY[',\r\n  3064: ' 43F_OFIZ ROFV[ RPFVX RQFWX R\\\\GWXV[ RLFQF RYF_F RF[L[ RMFPG RNFPH RZF\\\\G R^F\\\\G RIZG[ RIZK[',\r\n  3065: ' 56G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF ROIMLLOKSKWLY RUXWUXRYNYJXH RSFQGOJNLMOLSLXMZN[ RQ[SZUWVUWRXNXIWGVF',\r\n  3066: ' 60F]OFI[ RPFJ[ RQFK[ RLFXF[G\\\\I\\\\K[NYPUQMQ RZG[I[KZNXP RXFYGZIZKYNWPUQ RF[N[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3067: ' 78G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF ROIMLLOKSKWLY RUXWUXRYNYJXH RSFQGOJNLMOLSLXMZN[ RQ[SZUWVUWRXNXIWGVF RLXMVOUPURVSXT]U^V^W] RT^U_V_ RSXS_T`V`W]W\\\\',\r\n  3068: ' 78F^OFI[ RPFJ[ RQFK[ RLFWFZG[I[KZNYOVPNP RYGZIZKYNXO RWFXGYIYKXNVP RRPTQURWXXYYYZX RWYXZYZ RURVZW[Y[ZXZW RF[N[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3069: ' 44G^ZH[H\\\\F[L[JZHYGVFRFOGMIMLNNPPVSWUWXVZ RNLONVRWT ROGNINKOMUPWRXTXWWYVZS[O[LZKYJWJUI[JYKY',\r\n  3070: ' 54G]TFN[ RUFO[ RVFP[ RMFKL R]F\\\\L RMF]F RK[S[ RNFKL RPFLI RRFMG RYF\\\\G RZF\\\\H R[F\\\\I R\\\\F\\\\L ROZL[ ROYM[ RPYQ[ ROZR[',\r\n  3071: ' 48F_NFKQJUJXKZN[R[UZWXXU\\\\G ROFLQKUKYLZ RPFMQLULYN[ RKFSF RYF_F RLFOG RMFNH RQFOH RRFOG RZF\\\\G R^F\\\\G',\r\n  3072: ' 35H\\\\NFNHOYO[ ROGPX RPFQW R[GO[ RLFSF RXF^F RMFNH RQFPH RRFOG RYF[G R]F[G',\r\n  3073: ' 57E_MFMHKYK[ RNGLX ROFMW RUFMWK[ RUFUHSYS[ RVGTX RWFUW R]GUWS[ RJFRF RUFWF RZF`F RKFNG RLFMH RPFNI RQFNG R[F]G R_F]G',\r\n  3074: ' 54G]NFT[ ROFU[ RPFV[ R[GIZ RLFSF RXF^F RF[L[ RQ[X[ RMFOH RQFPH RRFPG RYF[G R]F[G RIZG[ RIZK[ RTZR[ RTYS[ RUYW[',\r\n  3075: ' 51G]MFQPN[ RNFRPO[ ROFSPP[ R\\\\GSP RKFRF RYF_F RK[S[ RLFNG RPFOH RQFNG RZF\\\\G R^F\\\\G ROZL[ ROYM[ RPYQ[ ROZR[',\r\n  3076: ' 35G]ZFH[ R[FI[ R\\\\FJ[ R\\\\FNFLL RH[V[XU ROFLL RPFMI RRFNG RR[VZ RT[WX RU[XU',\r\n  3101: ' 54I]NPNOOOOQMQMONNPMTMVNWOXQXXYZZ[ RVOWQWXXZ RTMUNVPVXWZZ[[[ RVRUSPTMULWLXMZP[S[UZVX RNUMWMXNZ RUSQTOUNWNXOZP[',\r\n  3102: ' 47G\\\\LFL[MZOZ RMGMY RIFNFNZ RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RJFLG RKFLH',\r\n  3103: ' 34H[WQWPVPVRXRXPVNTMQMNNLPKSKULXNZQ[S[VZXX RMPLRLVMX RQMONNOMRMVNYOZQ[',\r\n  3104: ' 52H]VFV[[[ RWGWZ RSFXFX[ RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RTFVG RUFVH RXYY[ RXZZ[',\r\n  3105: ' 41H[MSXSXQWOVNSMQMNNLPKSKULXNZQ[S[VZXX RWRWQVO RMPLRLVMX RVSVPUNSM RQMONNOMRMVNYOZQ[',\r\n  3106: ' 40KYWHWGVGVIXIXGWFTFRGQHPKP[ RRHQKQZ RTFSGRIR[ RMMVM RM[U[ RPZN[ RPYO[ RRYS[ RRZT[',\r\n  3107: ' 89I\\\\XNYOZNYMXMVNUO RQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM ROONQNSOU RUUVSVQUO RQMPNOPOTPVQW RSWTVUTUPTNSM RNUMVLXLYM[N\\\\Q]U]X^Y_ RN[Q\\\\U\\\\X] RLYMZP[U[X\\\\Y^Y_XaUbObLaK_K^L\\\\O[ RObMaL_L^M\\\\O[',\r\n  3108: ' 65G^LFL[ RMGMZ RIFNFN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\\\[ RJFLG RKFLH RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[',\r\n  3109: ' 43LXQFQHSHSFQF RRFRH RQGSG RQMQ[ RRNRZ RNMSMS[ RN[V[ ROMQN RPMQO RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3110: ' 41KXRFRHTHTFRF RSFSH RRGTG RRMR^QaPb RSNS]R` ROMTMT]S`RaPbMbLaL_N_NaMaM` RPMRN RQMRO',\r\n  3111: ' 61G]LFL[ RMGMZ RIFNFN[ RWNNW RRSY[ RRTX[ RQTW[ RTM[M RI[Q[ RT[[[ RJFLG RKFLH RUMWN RZMWN RLZJ[ RLYK[ RNYO[ RNZP[ RWYU[ RVYZ[',\r\n  3112: ' 31LXQFQ[ RRGRZ RNFSFS[ RN[V[ ROFQG RPFQH RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3113: ' 99AcFMF[ RGNGZ RCMHMH[ RHQIOJNLMOMQNROSRS[ RQORRRZ ROMPNQQQ[ RSQTOUNWMZM\\\\N]O^R^[ R\\\\O]R]Z RZM[N\\\\Q\\\\[ RC[K[ RN[V[ RY[a[ RDMFN REMFO RFZD[ RFYE[ RHYI[ RHZJ[ RQZO[ RQYP[ RSYT[ RSZU[ R\\\\ZZ[ R\\\\Y[[ R^Y_[ R^Z`[',\r\n  3114: ' 65G^LML[ RMNMZ RIMNMN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\\\[ RJMLN RKMLO RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[',\r\n  3115: ' 46H\\\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RMPLRLVMX RWXXVXRWP RQMONNOMRMVNYOZQ[ RS[UZVYWVWRVOUNSM',\r\n  3116: ' 60G\\\\LMLb RMNMa RIMNMNb RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RIbQb RJMLN RKMLO RLaJb RL`Kb RN`Ob RNaPb',\r\n  3117: ' 55H\\\\VNVb RWOWa RUNWNXMXb RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RSb[b RVaTb RV`Ub RX`Yb RXaZb',\r\n  3118: ' 43IZNMN[ RONOZ RKMPMP[ RWOWNVNVPXPXNWMUMSNQPPS RK[S[ RLMNN RMMNO RNZL[ RNYM[ RPYQ[ RPZR[',\r\n  3119: ' 43J[WOXMXQWOVNTMPMNNMOMQNSPTUUWVXY RNNMQ RNRPSUTWU RXVWZ RMONQPRUSWTXVXYWZU[Q[OZNYMWM[NY',\r\n  3120: ' 22KZPHPVQYRZT[V[XZYX RQHQWRY RPHRFRWSZT[ RMMVM',\r\n  3121: ' 43G^LMLVMYNZP[S[UZVYWW RMNMWNY RIMNMNWOZP[ RWMW[\\\\[ RXNXZ RTMYMY[ RJMLN RKMLO RYYZ[ RYZ[[',\r\n  3122: ' 31I[LMR[ RMMRY RNMSY RXNSYR[ RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN',\r\n  3123: ' 45F^JMN[ RKMNX RLMOX RRMOXN[ RRMV[ RSMVX RRMTMWX RZNWXV[ RGMOM RWM]M RHMKN RNMLN RXMZN R\\\\MZN',\r\n  3124: ' 48H\\\\LMV[ RMMW[ RNMX[ RWNMZ RJMQM RTMZM RJ[P[ RS[Z[ RKMMN RPMNN RUMWN RYMWN RMZK[ RMZO[ RVZT[ RWZY[',\r\n  3125: ' 40H[LMR[ RMMRY RNMSY RXNSYP_NaLbJbIaI_K_KaJaJ` RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN',\r\n  3126: ' 41I[VML[ RWMM[ RXMN[ RXMLMLQ RL[X[XW RMMLQ RNMLP ROMLO RQMLN RS[XZ RU[XY RV[XX RW[XW',\r\n  3151: ' 50G]WMUTUXVZW[Y[[Y\\\\W RXMVTVZ RWMYMWTVX RUTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT RNNLQKTKWLY RPMNOMQLTLWMZN[',\r\n  3152: ' 52I\\\\PFNMMSMWNYOZQ[S[VZXWYTYRXOWNUMSMQNPOOQNT RQFOMNQNWOZ RVYWWXTXQWO RMFRFPMNT RS[UYVWWTWQVNUM RNFQG ROFPH',\r\n  3153: ' 34I[WQWPVPVRXRXPWNUMRMONMQLTLVMYNZP[R[UZWW ROONQMTMWNY RRMPOOQNTNWOZP[',\r\n  3154: ' 58G]YFVQUUUXVZW[Y[[Y\\\\W RZFWQVUVZ RVF[FWTVX RUTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT RMOLQKTKWLY RPMNOMQLTLWMZN[ RWFZG RXFYH',\r\n  3155: ' 33I[MVQUTTWRXPWNUMRMONMQLTLVMYNZP[R[UZWX ROONQMTMWNY RRMPOOQNTNWOZP[',\r\n  3156: ' 45JZZHZGYGYI[I[GZFXFVGTISKRNQRO[N^M`Kb RTJSMRRP[O^ RXFVHUJTMSRQZP]O_MaKbIbHaH_J_JaIaI` RNMYM',\r\n  3157: ' 57H]XMT[S^QaOb RYMU[S_ RXMZMV[T_RaObLbJaI`I^K^K`J`J_ RVTVQUNSMQMNNLQKTKVLYMZO[Q[SZTYUWVT RNOMQLTLWMY RQMOONQMTMWNZO[',\r\n  3158: ' 41G]OFI[K[ RPFJ[ RLFQFK[ RMTOPQNSMUMWNXPXSVX RWNWRVVVZ RWPUUUXVZW[Y[[Y\\\\W RMFPG RNFOH',\r\n  3159: ' 35KXSFSHUHUFSF RTFTH RSGUG RLQMOOMQMRNSPSSQX RRNRRQVQZ RRPPUPXQZR[T[VYWW',\r\n  3160: ' 45KXUFUHWHWFUF RVFVH RUGWG RMQNOPMRMSNTPTSRZQ]P_NaLbJbIaI_K_KaJaJ` RSNSSQZP]O_ RSPRTP[O^N`Lb',\r\n  3161: ' 49G]OFI[K[ RPFJ[ RLFQFK[ RYOYNXNXPZPZNYMWMUNQROS RMSOSQTRUTYUZWZ RQUSYTZ ROSPTRZS[U[WZYW RMFPG RNFOH',\r\n  3162: ' 26LXTFQQPUPXQZR[T[VYWW RUFRQQUQZ RQFVFRTQX RRFUG RSFTH',\r\n  3163: ' 61@cAQBODMFMGNHPHSF[ RGNGSE[ RGPFTD[F[ RHSJPLNNMPMRNSPSSQ[ RRNRSP[ RRPQTO[Q[ RSSUPWNYM[M]N^P^S\\\\X R]N]R\\\\V\\\\Z R]P[U[X\\\\Z][_[aYbW',\r\n  3164: ' 42F^GQHOJMLMMNNPNSL[ RMNMSK[ RMPLTJ[L[ RNSPPRNTMVMXNYPYSWX RXNXRWVWZ RXPVUVXWZX[Z[\\\\Y]W',\r\n  3165: ' 46H\\\\QMNNLQKTKVLYMZP[S[VZXWYTYRXOWNTMQM RNOMQLTLWMY RVYWWXTXQWO RQMOONQMTMWNZP[ RS[UYVWWTWQVNTM',\r\n  3166: ' 66G]HQIOKMMMNNOPOSNWKb RNNNSMWJb RNPMTIb ROTPQQORNTMVMXNYOZRZTYWWZT[R[PZOWOT RXOYQYTXWWY RVMWNXQXTWWVYT[ RFbNb RJaGb RJ`Hb RK`Lb RJaMb',\r\n  3167: ' 57G\\\\WMQb RXMRb RWMYMSb RUTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT RMOLQKTKWLY RPMNOMQLTLWMZN[ RNbVb RRaOb RR`Pb RS`Tb RRaUb',\r\n  3168: ' 30I[JQKOMMOMPNQPQTO[ RPNPTN[ RPPOTM[O[ RYOYNXNXPZPZNYMWMUNSPQT',\r\n  3169: ' 47J[XPXOWOWQYQYOXNUMRMONNONQOSQTTUVVWX RONNQ RORQSTTVU RWVVZ RNOOQQRTSVTWVWXVZS[P[MZLYLWNWNYMYMX',\r\n  3170: ' 23KYTFQQPUPXQZR[T[VYWW RUFRQQUQZ RTFVFRTQX RNMXM',\r\n  3171: ' 42F^GQHOJMLMMNNPNSLX RMNMRLVLZ RMPKUKXLZN[P[RZTXVU RXMVUVXWZX[Z[\\\\Y]W RYMWUWZ RXMZMXTWX',\r\n  3172: ' 29H\\\\IQJOLMNMONPPPSNX RONORNVNZ ROPMUMXNZP[R[TZVXXUYQYMXMXNYP',\r\n  3173: ' 48CaDQEOGMIMJNKPKSIX RJNJRIVIZ RJPHUHXIZK[M[OZQXRU RTMRURXSZU[W[YZ[X]U^Q^M]M]N^P RUMSUSZ RTMVMTTSX',\r\n  3174: ' 51G]JQLNNMPMRNSPSR RPMQNQRPVOXMZK[I[HZHXJXJZIZIY RRORRQVQY RZOZNYNYP[P[NZMXMVNTPSRRVRZS[ RPVPXQZS[U[WZYW',\r\n  3175: ' 49G]HQIOKMMMNNOPOSMX RNNNRMVMZ RNPLULXMZO[Q[SZUXWT RYMU[T^RaPb RZMV[T_ RYM[MW[U_SaPbMbKaJ`J^L^L`K`K_',\r\n  3176: ' 39H\\\\YMXOVQNWLYK[ RXOOOMPLR RVORNONNO RVORMOMMOLR RLYUYWXXV RNYRZUZVY RNYR[U[WYXV',\r\n  3200: ' 50H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RNHMJLNLSMWNY RVYWWXSXNWJVH RQFOGNIMNMSNXOZQ[ RS[UZVXWSWNVIUGSF',\r\n  3201: ' 28H\\\\QHQ[ RRHRZ RSFS[ RSFPINJ RM[W[ RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3202: ' 62H\\\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RWHXJXLWN RTFVGWJWLVNTPPR RKYLXNXSYWYYX RNXSZWZXY RNXS[W[XZYXYV',\r\n  3203: ' 76H\\\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXIXLWNTO RVGWIWLVN RSFUGVIVLUNSO RQOTOVPXRYTYWXYWZT[P[MZLYKWKVLUMUNVNWMXLX RWRXTXWWY RSOUPVQWTWWVZT[ RLVLWMWMVLV',\r\n  3204: ' 28H\\\\SIS[ RTHTZ RUFU[ RUFJUZU RP[X[ RSZQ[ RSYR[ RUYV[ RUZW[',\r\n  3205: ' 55H\\\\MFKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMUNVNWMXLX RWPXRXVWX RSMUNVOWRWVVYUZS[ RLVLWMWMVLV RMFWF RMGUG RMHQHUGWF',\r\n  3206: ' 69H\\\\VIVJWJWIVI RWHVHUIUJVKWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNQNOONPMR RNIMKLOLUMXNY RWXXVXSWQ RRFPGOHNJMNMUNXOZQ[ RS[UZVYWVWSVPUOSN',\r\n  3207: ' 43H\\\\KFKL RYFYIXLTQSSRWR[ RSRRTQWQ[ RXLSQQTPWP[R[ RKJLHNFPFUIWIXHYF RMHNGPGRH RKJLINHPHUI',\r\n  3208: ' 79H\\\\PFMGLILLMNPOTOWNXLXIWGTFPF RNGMIMLNN RVNWLWIVG RPFOGNINLONPO RTOUNVLVIUGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RMQLSLWMY RWYXWXSWQ RPONPMSMWNZP[ RT[VZWWWSVPTO',\r\n  3209: ' 69H\\\\MWMXNXNWMW RWOVQURSSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNVOWOXNYMY RMPLNLKMI RVHWIXLXRWVVX RQSORNQMNMKNHOGQF RSFUGVIWLWSVWUYTZR[',\r\n  3210: ' 16MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3211: ' 24MXTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  3212: ' 32MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3213: ' 40MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  3214: ' 34MXRFQGQIRQ RRFRTST RRFSFST RSFTGTISQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3215: ' 52I\\\\MKMJNJNLLLLJMHNGPFTFWGXHYJYLXNWOSQ RWHXIXMWN RTFVGWIWMVOUP RRQRTSTSQRQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3216: ' 24MXTFRGQIQLRMSMTLTKSJRJQK RRKRLSLSKRK RRGQK RQIRJ',\r\n  3217: ' 24MXTHSIRIQHQGRFSFTGTJSLQM RRGRHSHSGRG RSITJ RTHSL',\r\n  3218: ' 74E_[O[NZNZP\\\\P\\\\N[MZMYNXPVUTXRZP[L[JZIXIUJSPORMSKSIRGPFNGMIMLNOPRTWWZY[[[\\\\Y\\\\X RKZJXJUKSLR RRMSI RSKRG RNGMK RNNPQTVWYYZ RN[LZKXKULSPO RMINMQQUVXYZZ[Z\\\\Y',\r\n  3219: ' 56H\\\\PBP_ RTBT_ RXKXJWJWLYLYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[P[MZLYKWKUMUMWLWLV',\r\n  3220: '  8G^[BIbJb R[B\\\\BJb',\r\n  3221: ' 27KYUBSDQGOKNPNTOYQ]S`Ub RQHPKOOOUPYQ\\\\ RSDRFQIPOPUQ[R^S`',\r\n  3222: ' 27KYOBQDSGUKVPVTUYS]Q`Ob RSHTKUOUUTYS\\\\ RQDRFSITOTUS[R^Q`',\r\n  3223: ' 39JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO',\r\n  3224: '  8F_JQ[Q[R RJQJR[R',\r\n  3225: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  3226: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  3227: ' 11NWSFRGRM RSGRM RSFTGRM',\r\n  3228: ' 22I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM',\r\n  3229: ' 30KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF',\r\n  3250: ' 58H]TFQGOIMLLOKSKVLYMZO[Q[TZVXXUYRZNZKYHXGVFTF RQHOJNLMOLSLWMY RTYVWWUXRYNYJXH RTFRGPJOLNOMSMXNZO[ RQ[SZUWVUWRXNXIWGVF',\r\n  3251: ' 20H]TJO[Q[ RWFUJP[ RWFQ[ RWFTIQKOL RTJRKOL',\r\n  3252: ' 52H]OKOJPJPLNLNJOHPGSFVFYGZIZKYMWOMUKWI[ RXGYIYKXMVOSQ RVFWGXIXKWMUOMU RJYKXMXRYWYXX RMXRZWZ RMXR[U[WZXXXW',\r\n  3253: ' 64H]OKOJPJPLNLNJOHPGSFVFYGZIZKYMXNVOSP RXGYIYKXMWN RVFWGXIXKWMUOSP RQPSPVQWRXTXWWYUZR[O[LZKYJWJULULWKWKV RVRWTWWVY RSPUQVSVWUYTZR[',\r\n  3254: ' 15H]WJR[T[ RZFXJS[ RZFT[ RZFJUZU',\r\n  3255: ' 49H]QFLP RQF[F RQGYG RPHUHYG[F RLPMOPNSNVOWPXRXUWXUZQ[N[LZKYJWJULULWKWKV RVPWRWUVXTZ RSNUOVQVUUXSZQ[',\r\n  3256: ' 61H]YJYIXIXKZKZIYGWFTFQGOIMLLOKSKVLYMZO[R[UZWXXVXSWQVPTOQOOPNQMS RPINLMOLSLWMY RVXWVWSVQ RTFRGPJOLNOMSMXNZO[ RR[TZUYVVVRUPTO',\r\n  3257: ' 39H]NFLL R[FZIXLTQRTQWP[ RRSPWO[ RXLRRPUOWN[P[ RMIPFRFWI ROGRGWI RMIOHRHWIYIZH[F',\r\n  3258: '104H]SFPGOHNJNMOOQPTPWOYNZLZIYGWFSF RUFPG RPHOJONPO ROORP RSPWO RXNYLYIXG RYGUF RSFQHPJPNQP RTPVOWNXLXHWF RQPMQKSJUJXKZN[R[VZWYXWXTWRVQTP RRPMQ RNQLSKUKXLZ RKZP[VZ RVYWWWTVR RVQSP RQPOQMSLULXMZN[ RR[TZUYVWVSUQTP',\r\n  3259: ' 61H]XNWPVQTRQROQNPMNMKNIPGSFVFXGYHZKZNYRXUVXTZQ[N[LZKXKVMVMXLXLW ROPNNNKOI RXHYJYNXRWUUX RQRPQOOOKPHQGSF RVFWGXIXNWRVUUWSZQ[',\r\n  3260: ' 16MXPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3261: ' 22MXQ[P[OZOYPXQXRYR[Q]P^N_ RPYPZQZQYPY RQ[Q\\\\P^',\r\n  3262: ' 32MXSMRNROSPTPUOUNTMSM RSNSOTOTNSN RPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3263: ' 38MXSMRNROSPTPUOUNTMSM RSNSOTOTNSN RQ[P[OZOYPXQXRYR[Q]P^N_ RPYPZQZQYPY RQ[Q\\\\P^',\r\n  3264: ' 34MXVFUFTGRT RVGUGRT RVGVHRT RVFWGWHRT RPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3265: ' 59H]OKOJPJPLNLNJOHPGSFWFZG[I[KZMYNWOSPQQQSSTTT RUFZG RYGZIZKYMXNVO RWFXGYIYKXMWNSPRQRSST RPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3266: ' 22MXWFUGTHSJSLTMUMVLVKUJTJ RUGTITJ RTKTLULUKTK',\r\n  3267: ' 22MXVIUITHTGUFVFWGWIVKULSM RUGUHVHVGUG RVIVJUL',\r\n  3268: ' 72E_\\\\O\\\\N[N[P]P]N\\\\M[MYNWPRXPZN[K[HZGXGVHTISKRPPROTMUKUITGRFPGOIOLPRQURWTZV[X[YYYX RL[HZ RIZHXHVITJSLR RPPQSTYVZ RK[JZIXIVJTKSMRRO ROLPOQRSVUYWZXZYY',\r\n  3269: ' 52H]TBL_ RYBQ_ RZKZJYJYL[L[JZHYGVFRFOGMIMLNNPPVSWUWXVZ RNLONVRWT ROGNINKOMUPWRXTXWWYVZS[O[LZKYJWJULULWKWKV',\r\n  3270: '  8G^_BEbFb R_B`BFb',\r\n  3271: ' 32JZZBXCUERHPKNOMSMXN\\\\O_Qb RSHQKOONTN\\\\ RZBWDTGRJQLPOOSN\\\\ RNTO]P`Qb',\r\n  3272: ' 32JZSBUEVHWLWQVUTYR\\\\O_LaJb RVHVPUUSYQ\\\\ RSBTDUGVP RVHUQTUSXRZP]M`Jb',\r\n  3273: ' 39J[TFSGUQTR RTFTR RTFUGSQTR ROIPIXOYO ROIYO ROIOJYNYO RYIXIPOOO RYIOO RYIYJONOO',\r\n  3274: '  8F_JQ[Q[R RJQJR[R',\r\n  3275: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  3276: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  3277: ' 11MWUFTGRM RUGRM RUFVGRM',\r\n  3278: ' 22H\\\\PFOGMM RPGMM RPFQGMM RZFYGWM RZGWM RZF[GWM',\r\n  3279: ' 30KZSFQGPIPKQMSNUNWMXKXIWGUFSF RSFPIQMUNXKWGSF RUFQGPKSNWMXIUF',\r\n  3301: ' 62F^IHJIIJHIIGKFMFOGPHQKQOPRNTLUIV ROHPKPPOR RMFNGOJOPNSLU RLVOY RKVOZ RIVN[UV R\\\\G[H\\\\H\\\\G[FYFWGVHUJUYW[[W RWHVJVXXZ RYFXGWJWWYY',\r\n  3302: '101E_GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGQHRJRRQUOW RPHQJQT RNFOGPJPUOW RRISGUFWFYGZH[J\\\\K RYHZJ RWFXGYJZK\\\\K R\\\\KRP RYM[O\\\\R\\\\U[XYZV[S[PZJWIWHX RXNYN[P RVNYO[Q\\\\S RTZRZLWKW RZYXZUZRYNWKVIVHXHZI[JZIY',\r\n  3303: ' 79F^RHPFNFLGJJINIRJVLYNZQ[T[WZYY[W RLHKJJMJRKVMYPZ RNFMGLIKMKQLUMWOYRZUZXY[W RUFRHQIPKPLQNTPURUT RQKQLUPUQ RQIQJRLUNVPVRUTSURUPTOR RUFVGXHZH RUGVHWH RTGVIXIZH[G',\r\n  3304: ' 79E_HLHKIIKGNFRFUGWHYJ[M\\\\Q\\\\U[XYZV[S[PZJWIWHX RKHMGRGUHWIYK[N RTZRZLWKW RHKJIMHRHUIWJYL[O\\\\R RZYXZUZRYNWKVIVHXHZI[JZIY RPHMKLMLONSNU RMNMONQNR RMKMMOQOSNUMVKVJUJT',\r\n  3305: ' 95F^RHPFNFLGJJINIRJVLYNZQ[T[WZYY[W RLHKJJMJRKVMYPZ RNFMGLIKMKQLUMWOYRZUZXY[W RUFRHQIPKPLQNTPURUT RQKQLUPUQ RQIQJRLUNVPVRUTSURUPTOR RUFVGXHZH RUGVHWH RTGVIXIZH[G RUNYK RYKZL\\\\L RXLYMZM RWMXNZN\\\\L',\r\n  3306: ' 94F^MNKMJKJIKGNFQFTGXI RKHMGRGUH RJKKIMHRHXIZI[H[GZFYF RSHRIQKQMROVSWVWYV\\\\U]S^ RTPWSXVXYW[ RQMSOVQXSYVYYX[V]S^O^L]K\\\\JZJWLTLRKQ RL\\\\K[KWLU RO^M]L[LWMTMRLQJQIRIS RUPYL RYLZM\\\\M RXMYNZN RWNXOZO\\\\M',\r\n  3307: ' 99E_UJTHSGQFNFKGIJHNHRIUJWLYNZQ[T[WZYY[W\\\\T\\\\Q[NYL RKHJJIMIRJUKW RZW[U[QZNYM RNFLGKIJMJRKVLXNZ RWZYXZUZQYOWM RUFRHPJOLOMPOSQTSTU RPLPMTQTR RPJPKQMTOUQUSTURVQVOUNS RTOYLZJ R\\\\FZJ RYG]I R\\\\F[GYGZHZJ[I]I\\\\H\\\\F',\r\n  3308: ' 92F_RFPGNIMKMMNOPQQSQU RNLNMQQQR RNINKOMQORQRSQUPVNWLWJVIUHSHQIPJQIR RRFTHVHXG RQGSH RPGQHSIUIXG RRPYK RYK[N\\\\Q\\\\T[WYYVZR[ RXLZN[Q[UZW RVMWMYOZRZVYXXYVZ RVZTZRYPYNZM\\\\N^P_R_T^ RSZQZ RR[PZNZ',\r\n  3309: ' 83F_PPNPLOKNJLJJKHLGOFQFTGWJYK RLHNGRGTHUI RJJKIMHQHTIVJYK[K\\\\J\\\\H[GYG RJXKYJZIYIWJVLVNWPYR\\\\T^ RNXOYQ\\\\R] RLVMWNYP\\\\Q]S^V^X]Y\\\\ZZZWYUWRVPVO RYXYWVRVQ RX]Y[YYXWVTURUPWNYNZOZP',\r\n  3310: ' 83F_PPNPLOKNJLJJKHLGOFQFTGWJYK RLHNGRGTHUI RJJKIMHQHTIVJYK[K\\\\J\\\\H[GYG RJXKYJZIYIWJVLVNWPYR\\\\T^ RNXOYQ\\\\R] RLVMWNYP\\\\Q]S^V^X]Y\\\\ZZZWYUWRVPVO RYXYWVRVQ RX]Y[YYXWVTURUPWNYNZOZP',\r\n  3311: ' 81E_[KZIXGUFRFOGMILKLNMQPWPYN[ RMNMOPUPV RNHMJMMNOPSQVQXPZN[L[JZ RHVJZ RGYKW RHVHXGYIYJZJXKWIWHV RNONMOKQJTJVKXMYM RUKWM RRJTKULVN RYMPQ RUOYXZY[Y RTPXXZZ RSPWYY[\\\\X',\r\n  3312: ' 73G^ZSYTVTUSUQVOXLYJYH RVQVPYLYK RWTVSVRWPYNZLZJYHXGUFPFMGLHKJKLLNNQOSOTNV RLKLLOQOR RLHLJMLOOPQPSOUMWJY RMWOWRYUZXZZY RNXOXSZTZ RJYLXMXQZT[V[YZZY[W',\r\n  3313: '128BbEQERFSHSJRJOIMGJGHIF RIOGK RHSIRIPGMFKFIGGIFKFMGOIPLPROUNWLYI[HZGZ RNIOLORNUMW RJZIYHY RKFMHNKNRMVLXKYJXIXF[ RNGPFRFTGVIWLWRVUUWSYQ[PZOZ RUIVLVRUV RRZQYPY RRFTHUKUSTWSYRXQXN[ RUHVGXFZF\\\\G]H^J_K R\\\\H]J RZF[G\\\\J]K_K R_K\\\\M[NZQZT[X][`X R\\\\N[P[T\\\\W^Z R_K]M\\\\O\\\\S]W_Y',\r\n  3314: ' 96D`GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGRISLSRRUQWOYL[KZIZG[ RQIRKRRQUPWOX RMZKYIY RNFPHQKQRPVNYLXJXG[ RRHSGUFWFYGZH[J\\\\K RYHZJ RWFXGYJZK\\\\K R\\\\KYMXNWQWTXXZ[]X RYNXPXTYW[Z R\\\\KZMYOYSZW\\\\Y',\r\n  3315: ' 72D`PFNGLIKKKMMQMS RLLLMMOMP RLILKNONQMSLTJTISIR RPFQGWIZK[M\\\\P\\\\S[VZXXZU[R[OZIWHWGX RPGQHWJYKZL RPFPHQIWKYL[N\\\\P RSZQZKWJW RYYWZTZQYMWJVHVGXGZH[IZHY',\r\n  3316: '100E`HQHRISKSMRMOLMJJJHLF RLOJK RKSLRLPJMIKIIJGLFOFQGRHSJSU RSWS\\\\R^P_M_L^L\\\\M[N\\\\M] RQHRJR\\\\Q^ ROFPGQJQU RQWQ\\\\P^O_ RSJXF RXFZI[K\\\\O\\\\R[UYXV[ RWGZK[N[O RVHXJZM[P[SZVYX RWYUVSU RQUOVMX RWZUWSVPV RV[TXSW RQWOWMX',\r\n  3317: ' 88D`PFNGLIKKKMMQMS RLLLMMOMP RLILKNONQMSLTJTISIR RPFQGWIZK[M\\\\P\\\\S[VZX RXZU[R[OZIWHWGX RPGQHWJYKZL RPFPHQIWKYL[N\\\\P RSZQZKWJW RXZTZQYMWJVHVGXGZH[IZHY RTXVVXV\\\\Z]Z RWWXW[Z RUWVWZ[\\\\[^Y',\r\n  3318: ' 96D`GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGQHRJRVQXOZM[K[IZ RPHQJQVPX RNFOGPJPVOYM[ RGVIZ RFYJW RGVGXFYHYIZIXJWHWGV RRISGUFWFYGZH[J\\\\K RYHZJ RWFXGYJZK\\\\K R\\\\KRP RTOXYZ[]X RUOYX[Z RVNZX[Y\\\\Y',\r\n  3319: ' 83E`\\\\H[G\\\\F]G]I\\\\KZKVISHOHKIIK RYJVHSGOGLH R]I\\\\JZJVGSFOFLGJIIKHNHRIUJWLYNZQ[U[XZZY\\\\W]T]Q\\\\OZNWNUOSRQSOS RLXNYQZUZYY RIUKWMXPYUYYX[W\\\\V]T RXOWOSSRS R]Q[OYOWPUSSTQTOSNQNOOMQL',\r\n  3320: ' 81F_LNJMIKIIJGMFRFUGYJ[J\\\\I RJHLGRGUHXJ RIKJILHRHUIYK[K\\\\I\\\\G[FZG[H RUIRLQNQPSTSV RRORPSRSS RRLRNTRTTSVRWPWOVOT RJYKZJ[IZIXJVLVOWSYVZYZ[Y RLWMWSZUZ RIXJWKWMXQZT[W[ZZ\\\\X',\r\n  3321: ' 45G]JHKHLILWJX RKGMHMXPZ RIILFNHNWPYRY RJXKXMYO[RYVV RTHUHVIVYX[[X RUGWHWYYZ RSIVFYHXIXXYYZY',\r\n  3322: '100D`GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGQHRJRRQUOW RPHQJQT RNFOGPJPUOW RRISGUFWFYG[J\\\\K RYHZJ RWFXGYJZK\\\\K RZKXKWLWNXP[R\\\\T RXO[Q RWMXN[P\\\\R\\\\V[XYZW[S[PZJWIWHX RTZRZLWKW RZYXZUZRYNWKVIVHXHZI[JZIY',\r\n  3323: '143BcEQERFSHSJRJOIMGJGHIF RIOGK RHSIRIPGMFKFIGGIFLFNGOHPJPNOQMTKV RNHOJOONR RLFMGNJNOMSKV RNGPFSFUG RWFTGSISMTPVSWUWWVY RTMTNWSWT RWFUGTITLUNWQXTXVWXUZS[O[MZKXIWGWFX RNZKWJW RQ[OZLWJVGVFXFZG[HZGY RWFZF\\\\G^J_K R\\\\H]J RZF[G\\\\J]K_K R]K[KZLZN[P^R_T R[O^Q RZM[N^P_R_W^Y]Z[[X[UZ RYZXZVY R^Y\\\\ZZZXYWX',\r\n  3324: ' 86F^KHMHOIPJQMQO RQQQUPXM[KZI[ RNZLYKY ROYNYLXI[ RMGPHQIRLRUSWUYWZ RIINFPGRISLSO RSQSTTWUXWYYY RQURXTZV[[X RSLTIWFYG[F RVGXHYH RUHVHXI[F RKSMOQO RSOWOYM RMPWP RKSMQQQ RSQWQYM',\r\n  3325: ' 74E_HQHRISKSMRMOLMJJJHLF RLOJK RKSLRLPJMIKIIJGLFOFQGRHSJSORRQTQUSWTW RQHRJRPQSPUSX ROFPGQJQPPTOVRYUV RSJ[F RYGYZX] RZGZXY[ R[F[VZZY\\\\W^T_P_M^K\\\\JZKYLZK[',\r\n  3326: ' 74F^NIOGQFTFVGWHXJXMWOVPTQ RQQOPNN RVHWIWNVO RTFUGVIVNUPTQ RMUNSORQQTQWRYTZVZZY\\\\W^T_P_N^KZJY RXTYVYZX\\\\ RTQWSXUX[W]V^T_ RO^N]LZKY RR_P^O]MZLYIYHZH\\\\I]J]',\r\n  3401: ' 46J[TMQNOONPMSMVNYO[UX RNVOYPZ RQNOPNSNUOXQZ RRNSOUPUYW[ZX RSNVPVXXZ RTMUNWOXO RWPXO RWPWXXYYY',\r\n  3402: ' 50J[LHMINK RTFQGOINKNXMY RPIOKOXRZ RTFRGQHPKPXRYSZ RMYNYPZQ[TZ RPPVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3403: ' 27KXRNTPVOTMRNOPNRNWOYQ[UY RSNUO RPPOROWPYQZ RQOPQPVQXSZ',\r\n  3404: ' 47J[QFNINKOLSNVPWRWUVXTZ ROJOKSMVOWP ROHOIPJUMWOXRXUWXTZQ[ RRNNPNXMY ROPOXRZ RPOPXRYSZ RMYNYPZQ[',\r\n  3405: ' 27KXPUVQSMOPNRNWOYQ[UY RUQRN RPPOROWPYQZ RTRROQOPQPVQXSZ',\r\n  3406: ' 49LYXFWGUGSFQFPHPMOONP RVHTHRGQG RXFWHVITIRHQHPI RPKQMRNTOVOVP RNPPP RRPVP RPPPTQ` RSOPOQNQ[ RRPRTQ`',\r\n  3407: ' 53J[TMQNOONPMSMVNYO[UX RNWOYPZ RQNOPNSNUOXQZ RRNSOUPUXV[V]U_ RSNVPVZ RTMUNWOXO RWPXO RWPW\\\\V^U_S`P`N_M^M]N]N^',\r\n  3408: ' 50J[LHMINK RTFQGOINKNXMY RPIOKOYPZ RTFRGQHPKPXQYRY RMYOZP[SX RPPVMWOXSXWWZV\\\\T^Q` RUNVOWR RTNVQWTWWV[T^',\r\n  3409: ' 39MWRFQGQHRISHSGRF RQGSH RQHSG ROOPOQPQYS[VX RPNRORXTZ RNPQMRNTO RSPTO RSPSXTYUY',\r\n  3410: ' 45MWRFQGQHRISHSGRF RQGSH RQHSG ROOPOQPQ[P^O_M` RPNROR[Q] RNPQMRNTO RSPTO RSPS[R]P_M` RS[T]U^',\r\n  3411: ' 63KYNHOIPK RUFSGQIPKPMOONP RPPPXOY RRIQKQM RQOPOQMQXSZ RUFSHRKRO RRPRXSYTY ROYQZR[UX RRLVIWJWLUNSO RUJVKVLUN RROWOWP RNPPP RRPWP',\r\n  3412: ' 29MWOHPIQK RWFTGRIQKQXPY RSIRKRYTZ RWFUGTHSKSXTYUY RPYRZS[VX',\r\n  3413: ' 74E_GOHOIPIXHYJ[ RHNJPJXIYJZKYJX RFPIMKOKXLYJ[ RNNPOQQQXPYR[ RPNQORQRXQYRZSYRX RKPNNPMRNSPSXTYR[ RVNWOYPYY[[^X RWNZPZX\\\\Z RSPVNXMYN[O\\\\O R[P\\\\O R[P[X\\\\Y]Y',\r\n  3414: ' 49I[KOLOMPMXLYN[ RLNNPNXMYNZOYNX RJPMMOOOXPYN[ RRNSOUPUYW[ZX RSNVPVXXZ ROPRNTMUNWOXO RWPXO RWPWXXYYY',\r\n  3415: ' 41J[NPNXMY ROPOXRZ RQOPPPXRYSZ RMYNYPZQ[TZ RNPQOVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3416: ' 57J[OJMLMNNQNXLZ RNYO` RNMNNOQO[ RNKNLONPQPXQXSYTZ RPYO` RSZQY RTZR[PY RNYLZ RPPVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3417: ' 43J[TMQNOONPMSMVNYO[UX RNWOYPZ RQNOPNSNUOXQZ RRNSOUPUXV` RSNVPV[ RTMUNWOXO RWPXO RWPWXV`',\r\n  3418: ' 32KYNOOOPPPXOY RONQPQYSZ RMPPMRORXSYTY ROYQZR[UX RTNUPWOVMRO RUNVO',\r\n  3419: ' 42LWXFWGUGSFQFPHPMOONP RVHTHRGQG RXFWHVITIRHQHPI RPKRP RPPPTQ` RQOPOQNQ[ RRPRTQ` RNPPP',\r\n  3420: ' 37LXSIRLQNPONP RSISOVOVP RNPQP RSPVP RQPQXPY RROQORMRXTZ RSPSXTYUY RPYRZS[VX',\r\n  3421: ' 47I[KOLOMPMXLY RLNNPNXPZ RJPMMOOOXQYRZ RLYMYOZP[RZUX RVMTOUPUYW[ZX RVPWOVNUOVPVXXZ RVMXOWPWXXYYY',\r\n  3422: ' 47J[OKMMMONRNXMY RNNNOOROXRZ RNLNMOOPRPXRYSZ RMYNYPZQ[TZ RPPVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3423: ' 72F_KKIMIOJRJXIYK[ RJNJOKRKXJYKZLYKX RJLJMKOLRLXMYK[ RONQORQRXQY RQNROSQSXVZ RLPONQMSNTPTXVYWZ RQYRYTZU[XZ RTPZM[O\\\\R\\\\T[XZYXZ RYNZO[Q RXNZP[S[UZXXZ',\r\n  3424: ' 44KZOOPOQPQXPXNYM[M]N_P`S`V_V^U^U_ RPNRPRXUZ RNPQMSOSXUYVZ RXYT[SZQYOYM[ RUNVPXOWMSO RVNWO',\r\n  3425: ' 47J[OKMMMONRNXMY RNNNOOROYQZ RNLNMOOPRPXQYRY RMYOZP[SX RPPVMWOXSXWWZV\\\\T^Q` RUNVOWR RTNVQWTWWV[T^',\r\n  3426: ' 43KYNPSMUNVPVRUTQV RSNUO RRNTOUQURTTSU RSUUWVYV]U_S`Q`O_N]N[OYQXWV RRVTWUY RQVTXUZU]T_S`',\r\n  3427: ' 61JZRMPNMPMRNU RNPNROT RPNOOORPT RPNROTOVNWMWKVJTJ RQNSN RRMTNVN RNUVRWUWWVYR[ RUSVUVXUY RTSUUUXTZ RTZRYOYL[ RSZQZ RR[PZNZL[',\r\n  3428: ' 78J[VFUGSGQFOFNHNMMOLP RTHRHPGOG RVFUHTIRIPHOHNI RNKPP RNPNTO` ROONOONO[ RPPPTO` RLPNP RPPUMWNXPXRWTSV RUNWO RTNVOWQWRVTUU RUUWVXXX[W]U_R` RUVWW RSVTVVWWYW\\\\V^',\r\n  3429: ' 62J[PIOLNNMOKP RPIPXQYO[ ROONOONOXNYOZPYOX RKPNPNXMYO[ RPPUMWNXPXRWTSV RUNWO RTNVOWQWRVTUU RUUWVXXX[W]U_R` RUVWW RSVTVVWWYW\\\\V^',\r\n  3501: ' 60G]LINGPFRFSGZW[X]X RQGRHYXZZ[YYX RNGPGQHXXYZZ[[[]X RLMMLOKPKQL RPLPM RMLOLPN RG[IYKXNXPY RJYNYOZ RG[JZMZN[PY RRJLX RNSVS',\r\n  3502: '110F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RRIQJPLPU RQKQS RRIRRQTPU RRIXFZG[I[KYMUO RXGZIZK RVGXHYIYLWN RWNZP[R[X RYPZRZW RWNXOYQYX RJ[MYPXTXWY RLZOYTYVZ RJ[NZSZU[WYYX[X RUOUX RURYR RUUYU',\r\n  3503: ' 69E]NGLHJJILHOHSIVJXMZP[S[VZXYZW[U RJKINISKWNYQZTZWY RNGLIKKJNJRKUNXQYTYWXYW[U RPJPV RQJQT RRIRSQUPV RPJRIUFWGYGZF RTGVHXH RSHUIWIYHZF RWIWX',\r\n  3504: ' 72G^IFWFYGZIZX RKGWGYIYW RIFJGLHWHXIXX ROKNLMNMOKOJPJRKQMQMV RNMNT RKPNP ROKOSNUMV RI[LYOXSXVY RKZNYSYUZ RI[MZRZT[VYXXZX RRHRX RRMTNVNXM RRSTRVRXS',\r\n  3505: ' 94G]IHKFMFOGQF RLGNG RIHKGMHOHQF RNKMLLNLOJOIPIRJQLQLW RMMMU RJPMP RNKNTMVLW RQMRJSHTGVFXF[G RTHVGXGZH RRJSIUHWHYI[G RQURRSPTOVOXP RTPVPWQ RRRSQUQVRXP RK[NYRXWX[Y RMZPYWYZZ RK[OZVZY[[Y RQMQX',\r\n  3506: ' 91F]JHLFOFQGSF RMGPG RJHLGNHQHSF RPKOLNNNOLOKPKRLQNQNV ROMOT RLPOP RPKPSOUNV RSJSYRZQZMXKXIYG[ RTJTX RTPXP RPZOZMYJY RUIUOXO RXQUQUWTYP[N[LZJZG[ RSJUIXFZG\\\\G]F RWGYH[H RVHXIZI\\\\H]F RXIXW',\r\n  3507: ' 87E^NGLHJJILHOHRIUJWLYNZQ[U[XZZX[V[SZQYPWOUO RJKINISJV RNGLIKKJNJSKVLXNZ RYXZWZSYQ RU[WZXYYWYSXQWPUO RPJPW RQJQU RRIRTQVPW RPJRIUFWGYGZF RTGVHXH RSHUIWIYHZF RYHUOU[ RUSYS RUVYV',\r\n  3508: '112F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RJ[MYPXSXUY RLZOYRYTZ RJ[NZQZS[UY RRIQJPLPU RQKQS RRIRRQTPU RRITGVFXFZG RWGXGYH RTGVGXIZG RUOWNYLZM[P[TZXX[ RXMYNZPZUYX RWNXNYPYUX[ RUOUY RURYR RUUYU',\r\n  3509: ' 67I\\\\LHNFQFTGVF ROGSG RLHNGQHTHVF RSKRLQNQOOONPNROQQQQV RRMRT ROPRP RSKSSRUQV RYHWJVMVXUZSZOXMXKYI[ RWKWW RRZQZOYLY RYHXJXVWXUZS[P[NZKZI[',\r\n  3510: ' 65H\\\\LHNFQFTGVF ROGSG RLHNGQHTHVF RSKRLQNQOOONPNROQQQQV RRMRT ROPRP RSKSSRUQV RYHWJVMVXUZ RWKWW RYHXJXVWXUZR[O[LZJXJVKULUMVLWKW RJVMV',\r\n  3511: '115F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RJ[MYPXSXUY RLZNYRYTZ RJ[NZQZS[UY RRIQJPLPU RQKQS RRIRRQTPU RRITGVFXFZG RWGXGYH RTGVGXIZG RUOXLYM[N RWMYN[N R[NYQWSUU RWSYTZX[Z\\\\Z RYVZZ RWSXTYZZ[[[\\\\Z RUOUY',\r\n  3512: ' 85G]IHKFNFPGRF RLGOG RIHKGMHPHRF RNKMLLNLOJOIPIRJQLQLW RMMMU RJPMP RNKNTMVLW RK[NYRXWX[Y RMZPYWYZZ RK[OZVZY[[Y RSIRJQLQU RRKRS RSISRRTQU RSIUGWFYF[G RXGYGZH RUGWGYI[G RWGWX',\r\n  3513: '107D`LJKKJMJOHOGPGRHQJQJU RKLKS RHPKP RLJLRKTJU RE[GYIXKXMYNYOX RHYKYMZ RE[GZJZL[M[NZOX RLJPFTJTWUYVY RPGSJSXRYSZTYSX RPPSP RNHOHRKROOO ROQRQRXQYS[VYWX RTJXF\\\\J\\\\W]Y^Y RXG[J[X]Z RXP[P RVHWHZKZOWO RWQZQZY\\\\[^Y ROHOX RWHWX',\r\n  3514: ' 84E^GIIGKFMFOGQJVUXXYY RMGOIPKVWYZ RIGKGMHOKTVVYWZY[ RVHXIZI\\\\H]F RWGYH[H RVHXFZG\\\\G]F RKOIOHPHRIQKQ RIPKP RG[IYKXNXPY RJYMYOZ RG[JZMZN[PY RKGKX RYIY[ RRLSMUNWNYM RKTMSQSST',\r\n  3515: ' 79E_NFLGJIIKHNHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\N[KZIXGVFUGRIOJ RJJIMISJV RNFLHKJJMJSKVLXNZ RZV[S[MYIXH RVZXXYVZSZMYKWHUG ROJOW RPJPU RQJQTPVOW RUGUZ RUMWNXNZM RUSWRXRZS',\r\n  3516: ' 70H^KFLGMIMOKOJPJRKQMQMYJ[MZMbO` RMHNJN` RKPNP RKFMGNHOJO` ROKRIVFZJZX RVGYJYX RTHUHXKXY RRXUXXY RSYUYWZ RRZTZV[XYZX RRIR_ RRMTNVNXM RRSTRVRXS',\r\n  3517: ' 99E_NFLGJIIKHNHRIUJWLYNZP[T[VZXYZW[U\\\\R\\\\N[KZIXGVFUGRIOJ RJJIMISJV RNFLHKJJMJSKVLXNZ RZV[S[MYIXH RVZXXYVZSZMYKWHUG ROJOW RPJPU RQJQTPVOW RUGUZ RUMWNXNZM RUSWRXRZS RP[QZRZT[X`Za[a RT\\\\V_XaYa RRZS[VaXbZb[a',\r\n  3518: '108F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RJ[MYPXRXUY RLZNYRYTZ RJ[NZQZS[UY RRIQJPLPU RQKQS RRIRRQTPU RRIUGWFYGZIZLYNXOTQRR RWGXGYIYMXN RUGWHXJXMWOTQ RTQVRWSZX[Y\\\\Y RWTYX[Z RTQVSXYZ[\\\\Y',\r\n  3519: ' 94G^UITHRGOF RVHTG RWGSFOFLGKHJJKLLMONWNYOZPZRYU RKKLLOMXMZN[O[QZS RKHKJLKOLYL[M\\\\O\\\\QYUU[ RIOJPLQUQVRVSUU RJQLRTRUS RIOIPJRLSSSUTUU RI[LYPXSXVY RKZNYRYUZ RI[MZRZU[ RWGUISL RRNPQ ROSMUKVJVJUKV',\r\n  3520: ' 71E]JJILHOHSIVKYMZP[S[VZXYZW[U RISJVLXNYQZTZWY RJJIMIQJTLWNXQYTYWXYW[U RHIIGKFOFUGYG[F RPGTHXH RHIIHKGNGTIWIYH[F RSIRJPKPV RQKQT RRJRSQUPV RWIWX',\r\n  3521: ' 89F^HHJFLFOGQF RKGNG RHHJGMHOHQF RKJJLIOISJVKXMZP[S[VZXYZ[\\\\Y RJSKVNYQZTZ RKJJNJQKTLVNXQYUYXX RUIQJPLPV RQKQT RRJRSQUPV RUIWHYFZG\\\\HZIZW[Y\\\\Y RYIZHYGXHYIYX[Z RWHXIXX RUIUY RUNXN RURXR',\r\n  3522: ' 72G^JFKGLILOJOIPIRJQLQLXJY RLHMJMX RJPMP RNYQYSZ RJFLGMHNJNXRXUY RJYMYPZR[UYXXZX RRJUIWHYFZG\\\\HZIZX RYIZHYGXHYIYW RWHXIXX RRJRX RRMTNVNXM RRSTRVRXS',\r\n  3523: ' 95E`HFIGJIJOHOGPGRHQJQJXHY RJHKJKX RHPKP RLYNYPZ RHFJGKHLJLXOXQY RHYKYNZO[QYTXVYW[YY\\\\X ROHRFTHTXWXYY RRGSHSX ROHQHRIRXQY RWYXZ RWHZF\\\\H\\\\X RZG[H[X RWHYHZIZXYY ROHOX RWHWX RONRN RORRR RWNZN RWRZR',\r\n  3524: ' 65G]HIJGLFNFOGWYXZZZ RMGNHVYWZ RJGLGMHUZV[X[ZZ\\\\X RWFYG[G\\\\F RWGXHZH RVHWIYI[H\\\\F RH[IYKXMXNY RJYLYMZ RH[IZKZM[ RWFSO RQRM[ RLPPP RSPXP',\r\n  3525: ' 86G^JFKGLILOJOIPIRJQLQLXJY RLHMJMX RJPMP RNYQYSZ RJFLGMHNJNXRXUY RJYMYPZR[UYXX RRJUIWHYFZG\\\\HZIZ^Y`WbUaQ`L` RYIZHYGXHYIYY RWHXIXXZ[ RXaV`S` RY`V_P_L` RRJRX RRMTNVNXM RRSTRVRXS',\r\n  3526: ' 57H\\\\XGWIROOSMWJ[ RVKNV RZFWJUNRRMXLZ RJHLFOGUGZF RKGOHSHWG RJHNIRIVHXG RLZNYRXVXZY RMZQYUYYZ RJ[OZUZX[ZY RMPQP RTPXP',\r\n  3601: ' 53J[PRNTMVMXNZP[RYUX RMVNXOYQZ RNTNVOXQYRY RNPPPSOUNVMXOWPWXXYYY RONNOQO RTOWOVNVYWZ RMOOMPNROUPUYW[YY RMORT',\r\n  3602: ' 44I[LHMJMXKY RNJMHNGNXQZ RLHOFOXQYRZ RKYMYOZP[RZUYWY ROPROTNUMVNXOYOWPWY RTNVOVX RROSOUPUY',\r\n  3603: ' 35JXNONXLYMYOZP[ ROOOYQZ RPOPXRYSYQZP[ RNORNTMUNWOXO RSNTOVO RPORNTPVPXO',\r\n  3604: ' 41IZRMPNMOMXKY RNONXQZ RRMOOOXQYRZ RKYMYOZP[RZUYWY RMHPFQIWOWY RPINHOGPIVOVX RMHUPUY',\r\n  3605: ' 32JXNONXLYMYOZP[ ROOOYQZ RPOPXRYSYQZP[ RNORNTMWQURPU RSNVQ RPORNUR',\r\n  3606: ' 41JWNHNXLYMYOZP[ ROHOYQZ RPHPXRYSYQZP[ RNHQGSFTGVHWH RRGSHUH RPHQGSIUIWH RKMNM RPMTM',\r\n  3607: ' 56I[MOMXKYLYNZO[PZRYUX RNPNYPZ ROOOXQYRY RMOOORNTMUNWOYOWPW\\\\V_TaRbQaO`M` RSNVPV\\\\ RSaQ`P` RRNSOUPUZV]V_ RTaS`Q_O_M`',\r\n  3608: ' 47I[LHMJMXKYLYNZO[ RNJMHNGNYPZ RLHOFOXQYO[ ROPROTNUMVNXOYOWPWYU[T] RTNVOVYU[ RROSOUPUYT]T`UbVbT`',\r\n  3609: ' 35MWRFPHRITHRF RRGQHSHRG RRMQNOOQPQYS[UY RRPSORNQORPRYSZ RRMSNUOSPSXTYUY',\r\n  3610: ' 39MWRFPHRITHRF RRGQHSHRG RRMQNOOQPQYS[T] RRPSORNQORPRYS[ RRMSNUOSPSYT]T`RbPbPaRb',\r\n  3611: ' 50IZLHMJMXKYLYNZO[ RNJMHNGNYPZ RLHOFOXQYO[ ROPRNTMVPSROU RSNUP RRNTQ RSRTSVXWYXY RSSTTUYVZ RRSSTTYV[XY',\r\n  3612: ' 22MWPHQJQXOYPYRZS[ RRJQHRGRYTZ RPHSFSXUYVYTZS[',\r\n  3613: ' 67E_GOHOIPIXGYHYJZK[ RINJOJYLZ RGOIMKOKXMYK[ RKPNOPNQMSOSXUYS[ RPNRORYTZ RNOOOQPQXPYRZS[ RSPVOXNYMZN\\\\O]O[P[X\\\\Y]Y RXNZOZY[Z RVOWOYPYY[[]Y',\r\n  3614: ' 45I[KOLOMPMXKYLYNZO[ RMNNONYPZ RKOMMOOOXQYO[ ROPROTNUMVNXOYOWPWXXYYY RTNVOVYWZ RROSOUPUYW[YY',\r\n  3615: ' 40I[MOMXKY RNPNXQZ ROOOXQYRZ RKYMYOZP[RZUYWY RMOOORNTMUNWOYOWPWY RSNVPVX RRNSOUPUY',\r\n  3616: ' 54I[LMMOMXKYMYMb RMNNONaO`N^ RNYOYQZ RLMNNOOOXQYRZ ROZP[RZUYWY ROZO^P`Mb ROPROTNUMVNXOYOWPWY RTNVOVX RROSOUPUY',\r\n  3617: ' 44I[MOMXKY RNPNYPZ ROOOXQYRY RKYLYNZO[PZRYUX RMOOORNTMUNWOYOWPWb RSNVPVaU`V^ RRNSOUPU^T`Wb',\r\n  3618: ' 38JXLOMONPNXLYMYOZP[ RMNOOOYQZ RLONMPOPXRYSYQZP[ RPOTMUNWOXO RSNTOVO RRNTPVPXO',\r\n  3619: ' 59JZMOMSOTUTWUWY RNONS RVUVY RPNOOOSQT RSTUUUYTZ RMOPNRMTNVNWM RQNSN RPNROTOVN RWYTZR[PZNZL[ RSZQZ RTZRYOYL[ RWMVOTROWL[',\r\n  3620: ' 28MWPHQJQXOYPYRZS[ RRJQHRGRYTZ RPHSFSXUYVYTZS[ RNMQM RSMVM',\r\n  3621: ' 47I[KOLOMPMXKY RLNNONYPZ RKOMMOOOXQYRY RKYLYNZO[PZRYUX RUMVNXOYOWPWXXYYY RTNVOVYWZ RUMSOUPUYW[YY',\r\n  3622: ' 36I[LMMOMXP[RYUXWX RMNNONXQZ RLMNNOOOWPXRY RUMVNXOYOWPWX RTNVOVW RUMSOUPUX',\r\n  3623: ' 57E_HMIOIXL[NYQX RINJOJXMZ RHMJNKOKWLXNY RQMOOQPQXT[VYYX[X RPNRORXUZ RQMRNTOSPSWTXVY RYMZN\\\\O]O[P[X RXNZOZW RYMWOYPYX',\r\n  3624: ' 59H[KOLONPOQSYTZV[XY RMNOOTYVZ RKOMMONPOTWUXWYXY RRSUMVNXNYM RUNVOWO RTOVPXOYM RQUN[MZKZJ[ RNZMYLY ROYMXKYJ[ RMTPT RSTVT',\r\n  3625: ' 60I[KOLOMPMXKY RLNNONYPZ RKOMMOOOXQYRY RKYLYNZO[PZRYUX RUMVNXOYOWPW\\\\V_TaRbQaO`M` RTNVOV\\\\ RSaQ`P` RUMSOUPUZV]V_ RTaS`Q_O_M`',\r\n  3626: ' 38I[XML[ RLONPQPTOXM RMNOOSO RLONMPNTNXM RL[PYSXVXXY RQYUYWZ RL[PZTZV[XY RNTVT',\r\n  3700: ' 42H\\\\LHLXJY RMIMXPZ RNHNXPYQZ RLHNHSGUF RSGTHVIVY RTGWIWX RUFVGXHZHXIXY RJYLYNZO[QZVYXY',\r\n  3701: ' 27H\\\\OHPIQKQXOY RQIPHQGRIRYTZ ROHRFSHSXUYVY ROYPYRZS[TZVY',\r\n  3702: ' 48H\\\\LHNHPGQFSGVHXH RPHRG RLHNIPIRHSG RVHVP RWIWO RXHXPQPNQLSKVK[ RK[OYSXVXZY RNZQYVYYZ RK[PZUZX[ZY',\r\n  3703: ' 57H\\\\LHMHOGPFRGVHXH ROHQG RLHNIPIRG RVHVO RWIWN RXHXOVOSPQQ RQPSQVRXRXY RWSWX RVRVY RKYMXOXQYRZ ROYQZ RKYMYOZP[RZVYXY',\r\n  3704: ' 41H\\\\UFKPKUTU RVUZU[V[TZU RLPLT RMNMU RTGTXRY RUJVHUGUYWZ RUFWHVJVXXYYY RRYSYUZV[WZYY',\r\n  3705: ' 53H\\\\LFLO RLFXF RMGVG RLHUHWGXF RVLUMSNOOLO RSNTNVOVY RUMWNWX RVLWMYNZNXOXY RKYMXOXQYRZ ROYQZ RKYMYOZP[RZVYXY',\r\n  3706: ' 59H\\\\LHLXJY RMIMXPZ RNHNXPYQZ RLHNHRGTFUGWHXH RSGUH RRGTIVIXH RNPOPSOUNVM RSOTOVPVY RUNWPWX RVMWNYOZOXPXY RJYLYNZO[QZVYXY',\r\n  3707: ' 38H\\\\KHMFPGUGZF RLGOHTHWG RKHOIRIVHZF RZFYHWKSOQRPUPXQ[ RRQQTQWRZ RUMSPRSRVSYQ[',\r\n  3708: ' 71H\\\\LILO RMJMN RNINO RLINISHUGVF RSHTHVIVO RUGWHWN RVFWGYHZHXIXO RLONOVRXR RXOVONRLR RLRLXJY RMSMXPZ RNRNXPYQZ RVRVY RWSWX RXRXY RJYLYNZO[QZVYXY',\r\n  3709: ' 60H\\\\LHLQJR RMIMROS RNHNQPRQR RLHNHSGUF RSGTHVIVY RTGWIWX RUFVGXHZHXIXY RJRKRMSNTOSQRUQVQ RKYMXOXQYRZ ROYQZ RKYMYOZP[RZVYXY',\r\n  3710: ' 11LXRXPZR[TZRX RRYQZSZRY',\r\n  3711: ' 14LXR^R\\\\PZRXSZS\\\\R^P_ RRYQZR[RY',\r\n  3712: ' 22LXRMPORPTORM RRNQOSORN RRXPZR[TZRX RRYQZSZRY',\r\n  3713: ' 25LXRMPORPTORM RRNQOSORN RR^R\\\\PZRXSZS\\\\R^P_ RRYQZR[RY',\r\n  3714: ' 30LXRFQGOHQIRT RRISHRGQHRIRT RRFSGUHSIRT RRXPZR[TZRX RRYQZSZRY',\r\n  3715: ' 51I[LJMHNGQFSFVGWHXJXLWNUPSQ RMJNH RVHWIWMVN RLJNKNIOGQF RSFUGVIVMUOSQ RRQRTSQQQRT RRXPZR[TZRX RRYQZSZRY',\r\n  3716: ' 14LXTFRGQIQKRMTKRIRG RRJRLSKRJ',\r\n  3717: ' 14LXRLRJPHRFSHSJRLPM RRGQHRIRG',\r\n  3718: ' 62E_YNZO[O\\\\N RXOYP[P RXPYQZQ[P\\\\N RYNST RRUL[HVNP ROOSKOFJLPRTXVZX[Z[[Z\\\\X RLZIV RRKOG RKLPQTWVYXZ[Z RMZIU RRLNG RKKQQUWVXXY[Y\\\\X',\r\n  3719: ' 60H\\\\PBP_ RTBT_ RTFVGWIWKYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ RXJWH RLLMNOOUQWRXT RMYLW RMGLILKMMONUPXRYTYWXYWZT[P[MZLYKWMVMXNZP[',\r\n  3720: '  8G^[BIbJb R[B\\\\BJb',\r\n  3721: ' 27KYUBSDQGOKNPNTOYQ]S`Ub RQHPKOOOUPYQ\\\\ RSDRFQIPOPUQ[R^S`',\r\n  3722: ' 27KYOBQDSGUKVPVTUYS]Q`Ob RSHTKUOUUTYS\\\\ RQDRFSITOTUS[R^Q`',\r\n  3723: ' 39JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO',\r\n  3724: '  8F_JQ[Q[R RJQJR[R',\r\n  3725: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  3726: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  3727: ' 11NWSFRGRM RSGRM RSFTGRM',\r\n  3728: ' 22I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM',\r\n  3729: ' 30KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF',\r\n  3801: ' 52E_NHLIJKIMHPHSIUKV RJLIOISJU RNHLJKLJOJRKVKXJZH[ RVHXHXYVY RYHYY RZGZZ RHFKGQHVHZG\\\\F RJPXP RH[KZQYVYZZ\\\\[',\r\n  3802: ' 65E_LGLZ RMGMZ RPFNGNZP[ RHJJHLGPFUFXGZIZKYM RXHYIYKXM RUFWGXIXKWL RQUOTNRNPONPMSLVLYM[O\\\\Q\\\\T[WYYWZT[P[LZJYHW RZO[Q[UZW RVLYNZQZUYXWZ',\r\n  3803: ' 60E_\\\\F[HZJXHVGSFQFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[Y\\\\[ R[HZMZT[Y RZKYJ RZNYKXIVG RJKINISJV RNGLIKKJNJSKVLXNZ RYWZV RVZXXYVZS',\r\n  3804: ' 46E_KGKZ RLGLZ RNFMGMZN[ RHKIIKGNFSFVGXHZJ[L\\\\O\\\\R[UZWXYVZS[N[KZIXHV RZK[N[SZV RVGXIYKZNZSYVXXVZ',\r\n  3805: ' 86E_\\\\F[HZJXHVGSFQFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[Y\\\\[ R[HZMZT[Y RZKYJ RZMXIVG RJKINISJV RNGLIKKJNJSKVLXNZ RYWZV RVZXXYVZS RJPKONOUQXQZP RPPRQURWRYQ RMORRUSWSYRZP RZMYLXLWMXNYM',\r\n  3806: ' 69E_JHJZ RMGKHKY ROFMGLILYNY RHJJHLGOFSFVGXHYI\\\\F R\\\\F[HZLZO[S\\\\U RZIYK RVGXIYLZO RLPMOOOTPWPYO RQPTQVQXP RNOTRVRXQYOYLXKWKVLWMXL RH[JZNYSYYZ\\\\[',\r\n  3807: ' 90E_\\\\F[HZJXHVGSFQFNGLHJJILHOHRIUJWLYNZQ[T[VZXYYXZV[Y\\\\[ R[HZMZT[Y RZKYJ RZNYKXIVG RJKINISJV RNGLIKKJNJSKVLXNZ RXXYVYR RVZWYXVXQ RKSLRMSLTKTJS RJPKNMMOMRNUPWQ RKOMNONROTP RJPLOOOUQYQZP',\r\n  3808: ' 50E_JGJZH[ RKHKZ RNHLHLZ RHFJGNHSHYG\\\\F RLPMNOLRKVKYL[N\\\\Q\\\\T[UYV RZN[P[SZU RVKXLYMZOZSYVYXZZ\\\\[ RH[LZPZU[',\r\n  3809: ' 23E_QIQY RRJRX RSISY RHFLHPITIXH\\\\F RH[KZOYUYYZ\\\\[',\r\n  3810: ' 42E_TIVIVXUZS[ RWIWXVY RXHXY RHFLHPITIXH\\\\F RIOHQHUIXKZN[S[VZXYZW\\\\T RIUJXKY RHSJUKXLZN[',\r\n  3811: ' 70E_JGJZH[ RKHKZ RNHLHLZ RHFJGNHSHYG\\\\F RLPMNOLRKUKXLYMYOXPSRQSPTPUQVRUQT RWLXMXOWP RUKWMWOVPSR RSRVRYSZUZWYX RWSYUYW RSRVSXUYXZZ[[\\\\[ RH[LZPZU[',\r\n  3812: ' 45E_JGJZ RKHKY RNHLHLYNY R\\\\KZNYPXSXUYW[X RZOYRYUZW R\\\\K[MZQZT[X\\\\[ RHFJGNHSHYG\\\\F RH[JZNYSYYZ\\\\[',\r\n  3813: ' 68E_QIQY RRJRX RSISY RNYLWJVIUHRHMIJKHMGPFTFWGYH[J\\\\M\\\\R[UZVXWVY RJUIRIMJJ RLWKUJRJLKIMG RZJ[M[RZU RWGYIZLZRYUXW RHFLHPITIXH\\\\F RH[KZOYUYYZ\\\\[',\r\n  3814: ' 48E_JHJZH[ RLHKIKZ ROFMGLILZ RHJJHLGOFSFVGXHZJ[L\\\\O\\\\S[UYV RZK[N[RZU RVGXIYKZNZRYVYXZZ[[\\\\[ RH[LZPZU[',\r\n  3815: ' 54E_QFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\O[LZJXHVGSFQF RJKINISJV RNGLIKKJNJSKVLXNZ RZV[S[NZK RVZXXYVZSZNYKXIVG',\r\n  3816: ' 51E_JIJZ RMHKJKY RQFOGMILKLYNY RHKJINGQFTFWGYH[J\\\\M\\\\O[RYTVURUOTMRLO RZJ[L[PZR RWGYIZLZPYSVU RH[JZNYSYYZ\\\\[',\r\n  3817: ' 74E_QFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\O[LZJXHVGSFQF RJKINISJV RNGLIKKJNJSKVLXNZ RZV[S[NZK RVZXXYVZSZNYKXIVG RJSKUNVTW[W\\\\X\\\\Z[[[Z\\\\Y RPWRW RKUNWQXSXTW',\r\n  3818: ' 69E_JIJZH[ RKIKZ RLHLZ RHKJILHNGQFUFYG[I\\\\K\\\\N[PZQ RYHZI[K[NZP RUFWGYIZKZOYQ RXRUSRSPRPPROUOXPZR\\\\U\\\\W[XZX RXQYR[V[WZT RTOVPXRYTZX[Z\\\\[ RH[LZPZU[',\r\n  3819: ' 94E_TFZG\\\\F[H[JYHWGTFPFMGJJIMIOJRLTOURUTTUSVQVP R[GZH[J RJPKRLSOTRTTS RKIJKJNKPMRPSRSTRVPWOXO RLQMQNPPNRMUMWNYPZRZUYXWZ RPMRLULXMZO[R[UZW RIWJYIZ RNPNOOMPLRKUKXL[O\\\\R\\\\T[WYYWZT[P[MZKYIWIYH[JZP[',\r\n  3820: ' 66E_QHMHKIJJILHOHSIVJXKYMZP[S[VZXYZW[U\\\\R\\\\N[KYIWH RUHTITKULVKUJ RISJVLXNYQZTZWY RJJINIQJTLWNXQYTYWXYW[T\\\\R RHFKI RKHLG RIGJGKFMGQHWHZG\\\\F',\r\n  3821: ' 51E_LHJJILHOHRIUJWLYNZQ[U[XZZY RKJJLIOISJV RKILJLKKMJPJSKVLXNZ RVHXHXXWZU[ RYHYXXY RZGZY\\\\[ RHFKGQHVHZG\\\\F',\r\n  3822: ' 31E_HFR[ RIGJHQWRY RJGKHRWSX R\\\\FR[ RWNUS RYLUQTTTV RHFJGOHUHZG\\\\F',\r\n  3823: ' 67E_LHJJILHOHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\O[LZJXH RJLIOIRJUKW RJJKKKLJOJRKVLXNZ RYWZU[R[OZL RVZXXYVZRZOYLYKZJ RQIQ[ RRJRZ RSIS[ RHFLHPITIXH\\\\F',\r\n  3824: ' 41E_HFXYYZ RIGKHZZ RLH\\\\[ R\\\\FSP RQRJZ RPSMULW RQRMTLUKWKY RHFLHPITIXH\\\\F RH[JZNYSYYZ\\\\[',\r\n  3825: ' 47E_XHXZ RYHYY RZGZY RKHIJHMHPISKUMVPWSWVVXU RLUOVUV RHPIRKTNUTUVV RHFLHPITIXH\\\\F RHWJYLZP[T[XZ\\\\X',\r\n  3826: ' 73E_HFIGKHNHSFVFYGZIZKYM RXGYIYKXM RVFWGXIXL RXNTOROPNPLRKTKXL RTKVLWMVNTO RYM[O\\\\R\\\\T[WYYWZT[P[MZKYIWHTHRIOJNLMNMPNPPOQNPOO RXMZO[Q[UZW RXNYOZQZUYXWZ',\r\n  3901: ' 42J[PQMTMXP[TY RNTNXPZ ROROWRZ RRSMNNMONNO RONSNUMWOWXXY RUNVOVXUYVZWYVX RSNUPUXTYV[XY',\r\n  3902: ' 31IZNHLFMJMXP[UYWX RNHNXPZ RNHPFOJOWRZ ROOTMWPWX RTNVPVX RRNUQUY',\r\n  3903: ' 23KWNPNYP[RY ROPOYPZ RPOPXQYRY RNPTMVOTPRN RSNUO',\r\n  3904: ' 32JZRMMPMXP[RZUYWY RNPNXPZ ROOOWRZ RPIPFQIWPWY RPIVPVX RPIMIPJUPUY',\r\n  3905: ' 25KXNPNYP[RY ROPOYPZ RPOPXQYRY RNPTMWQPU RSNVQ RRNUR',\r\n  3906: ' 32KWOIOXNYP[ RPIPXOYPZQYPX RQHQXRYP[ ROIUFWHUISG RTGVH RLMOM RQMUM',\r\n  3907: ' 41J[MPMXP[UY RNPNXPZ ROOOWRZ RMPOOTMWPW]V_U`SaQaO`MaObQa RTNVPV]U_ RPaNa RRNUQU^T`Sa',\r\n  3908: ' 42I[NHLFMJMXLYN[ RNHNXMYNZOYNX RNHPFOJOXPYN[ ROORNTMWPWYT]T`UbVbT` RTNVPVYU[ RRNUQUZT]',\r\n  3909: ' 37MWRFPHRJTHRF RRGQHRISHRG RRMPOQPQXPYR[ RRPSORNQORPRXQYRZSYRX RRMTOSPSXTYR[',\r\n  3910: ' 37MWRFPHRJTHRF RRGQHRISHRG RRMPOQPQYT] RRPSORNQORPRYS[ RRMTOSPSZT]T`RbPaPbRb',\r\n  3911: ' 51IZNHLFMJMXLYN[ RNHNXMYNZOYNX RNHPFOJOXPYN[ ROPRNTMVPSROU RSNUP RRNTQ RRSSTTYV[XY RSSTUUYVZ RSRTSVXWYXY',\r\n  3912: ' 21MWRHPFQJQXPYR[ RRHRXQYRZSYRX RRHTFSJSXTYR[',\r\n  3913: ' 66E_GOHOIPIXHYJ[ RINJOJXIYJZKYJX RGOIMKOKXLYJ[ RKONNPMSOSXTYR[ RPNRORXQYRZSYRX RNNQPQXPYR[ RSOVNXM[O[X\\\\YZ[ RXNZOZXYYZZ[YZX RVNYPYXXYZ[',\r\n  3914: ' 44I[KOLOMPMXLYN[ RMNNONXMYNZOYNX RKOMMOOOXPYN[ ROORNTMWOWXXYV[ RTNVOVXUYVZWYVX RRNUPUXTYV[',\r\n  3915: ' 28JZMPMXP[UYWX RNPNXPZ ROOOWRZ RMPOOTMWPWX RTNVPVX RRNUQUY',\r\n  3916: ' 47IZLMMOMXKYMYM_LbN` RNON` RLMNNOOOXQYRZ RNYOYQZ ROZP[UYWX ROZO_PbN` ROORNTMWPWX RTNVPVX RRNUQUY',\r\n  3917: ' 31J[MPMXP[UY RNPNXPZ ROOOWRZ RMPOOTMWPW_XbV` RTNVPV` RRNUQU_TbV`',\r\n  3918: ' 31KXMONOOPOXNYP[ RONPOPXOYPZQYPX RMOOMQOQXRYP[ RQOUMWOUPSN RTNVO',\r\n  3919: ' 41JZMPMSOUURWTWX RNPNSOT ROOOSPT RUSVTVX RTSUTUY RMPSMVNTOQN RRNUN RWXQ[MYOXSZ ROYQZ',\r\n  3920: ' 27MWRHPFQJQXPYR[ RRHRXQYRZSYRX RRHTFSJSXTYR[ RNMQM RSMVM',\r\n  3921: ' 40I[KOLOMPMYP[UY RMNNONYPZ RKOMMOOOXRZ RVMXOWPWXXYYY RVPWOVNUOVPVYWZ RVMTOUPUYW[YY',\r\n  3922: ' 36I[LMMOMXQ[SYWW RMNNONXQZ RLMNNOOOWRYSY RVMXOWPWW RVPWOVNUOVPVW RVMTOUPUX',\r\n  3923: ' 59E_HMIOIXM[OYQX RINJOJXMZ RHMJNKOKWNYOY RRMPOQPQXU[WY[W RRPSORNQORPRXUZ RRMTOSPSWVYWY RZM\\\\O[P[W RZP[OZNYOZPZW RZMXOYPYX',\r\n  3924: ' 39I[LONPUZV[XY RMNOOUYWZ RLONMONVXXY RXMVMVOXOXMVOSS RQUNYL[N[NYLYL[ RNTQT RSTVT',\r\n  3925: ' 49I[KOLOMPMYP[UY RMNNONYPZ RKOMMOOOXRZ RVMXOWPW]V_U`SaQaO`MaObQa RVPWOVNUOVPV^U_ RPaNa RVMTOUPU^T`Sa',\r\n  3926: ' 43L[RNOPOORNTMWOWSRU RTNVOVS RRNUPUSTT RRUWWW]V_U`SaQaO`MaObQa RVWV^U_ RPaNa RTVUWU^T`Sa'\r\n}\r\n","/*\r\nhttps://oeis.org/wiki/List_of_LaTeX_mathematical_symbols\r\nhttps://en.wikibooks.org/wiki/LaTeX/Mathematics\r\n*/\r\n\r\n/** LaTeX 符号描述接口 */\r\nexport interface Symb {\r\n  /** Hershey 字形索引 */\r\n  glyph: number\r\n  /** 参数元数 */\r\n  arity?: number\r\n  /** 符号标志位集合 */\r\n  flags: Record<string, boolean>\r\n}\r\n\r\n/** LaTeX 符号表，记录每个命令的字形、参数与标志 */\r\nconst SYMB: Record<string, Symb> = {\r\n  '\\\\frac': { glyph: 0, arity: 2, flags: {} },\r\n  '\\\\binom': { glyph: 0, arity: 2, flags: {} },\r\n  '\\\\sqrt': {\r\n    glyph: 2267,\r\n    arity: 1,\r\n    flags: { opt: true, xfl: true, yfl: true }\r\n  },\r\n  '^': { glyph: 0, arity: 1, flags: {} },\r\n  _: { glyph: 0, arity: 1, flags: {} },\r\n  '(': { glyph: 2221, arity: 0, flags: { yfl: true } },\r\n  ')': { glyph: 2222, arity: 0, flags: { yfl: true } },\r\n  '[': { glyph: 2223, arity: 0, flags: { yfl: true } },\r\n  ']': { glyph: 2224, arity: 0, flags: { yfl: true } },\r\n  '\\\\langle': { glyph: 2227, arity: 0, flags: { yfl: true } },\r\n  '\\\\rangle': { glyph: 2228, arity: 0, flags: { yfl: true } },\r\n  '|': { glyph: 2229, arity: 0, flags: { yfl: true } },\r\n\r\n  '\\\\|': { glyph: 2230, arity: 0, flags: { yfl: true } },\r\n  '\\\\{': { glyph: 2225, arity: 0, flags: { yfl: true } },\r\n  '\\\\}': { glyph: 2226, arity: 0, flags: { yfl: true } },\r\n\r\n  '\\\\#': { glyph: 2275, arity: 0, flags: {} },\r\n  '\\\\$': { glyph: 2274, arity: 0, flags: {} },\r\n  '\\\\&': { glyph: 2273, arity: 0, flags: {} },\r\n  '\\\\%': { glyph: 2271, arity: 0, flags: {} },\r\n\r\n  /*semantics*/\r\n  '\\\\begin': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\end': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\left': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\right': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\middle': { glyph: 0, arity: 1, flags: {} },\r\n\r\n  /*operators*/\r\n  '\\\\cdot': { glyph: 2236, arity: 0, flags: {} },\r\n  '\\\\pm': { glyph: 2233, arity: 0, flags: {} },\r\n  '\\\\mp': { glyph: 2234, arity: 0, flags: {} },\r\n  '\\\\times': { glyph: 2235, arity: 0, flags: {} },\r\n  '\\\\div': { glyph: 2237, arity: 0, flags: {} },\r\n  '\\\\leqq': { glyph: 2243, arity: 0, flags: {} },\r\n  '\\\\geqq': { glyph: 2244, arity: 0, flags: {} },\r\n  '\\\\leq': { glyph: 2243, arity: 0, flags: {} },\r\n  '\\\\geq': { glyph: 2244, arity: 0, flags: {} },\r\n  '\\\\propto': { glyph: 2245, arity: 0, flags: {} },\r\n  '\\\\sim': { glyph: 2246, arity: 0, flags: {} },\r\n  '\\\\equiv': { glyph: 2240, arity: 0, flags: {} },\r\n  '\\\\dagger': { glyph: 2277, arity: 0, flags: {} },\r\n  '\\\\ddagger': { glyph: 2278, arity: 0, flags: {} },\r\n  '\\\\ell': { glyph: 662, arity: 0, flags: {} },\r\n\r\n  /*accents*/\r\n  '\\\\vec': {\r\n    glyph: 2261,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\overrightarrow': {\r\n    glyph: 2261,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\overleftarrow': {\r\n    glyph: 2263,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\bar': { glyph: 2231, arity: 1, flags: { hat: true, xfl: true } },\r\n  '\\\\overline': { glyph: 2231, arity: 1, flags: { hat: true, xfl: true } },\r\n  '\\\\widehat': {\r\n    glyph: 2247,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\hat': { glyph: 2247, arity: 1, flags: { hat: true } },\r\n  '\\\\acute': { glyph: 2248, arity: 1, flags: { hat: true } },\r\n  '\\\\grave': { glyph: 2249, arity: 1, flags: { hat: true } },\r\n  '\\\\breve': { glyph: 2250, arity: 1, flags: { hat: true } },\r\n  '\\\\tilde': { glyph: 2246, arity: 1, flags: { hat: true } },\r\n  '\\\\underline': { glyph: 2231, arity: 1, flags: { mat: true, xfl: true } },\r\n\r\n  '\\\\not': { glyph: 2220, arity: 1, flags: {} },\r\n\r\n  '\\\\neq': { glyph: 2239, arity: 1, flags: {} },\r\n  '\\\\ne': { glyph: 2239, arity: 1, flags: {} },\r\n  '\\\\exists': { glyph: 2279, arity: 0, flags: {} },\r\n  '\\\\in': { glyph: 2260, arity: 0, flags: {} },\r\n  '\\\\subset': { glyph: 2256, arity: 0, flags: {} },\r\n  '\\\\supset': { glyph: 2258, arity: 0, flags: {} },\r\n  '\\\\cup': { glyph: 2257, arity: 0, flags: {} },\r\n  '\\\\cap': { glyph: 2259, arity: 0, flags: {} },\r\n  '\\\\infty': { glyph: 2270, arity: 0, flags: {} },\r\n  '\\\\partial': { glyph: 2265, arity: 0, flags: {} },\r\n  '\\\\nabla': { glyph: 2266, arity: 0, flags: {} },\r\n  '\\\\aleph': { glyph: 2077, arity: 0, flags: {} },\r\n  '\\\\wp': { glyph: 2190, arity: 0, flags: {} },\r\n  '\\\\therefore': { glyph: 740, arity: 0, flags: {} },\r\n  '\\\\mid': { glyph: 2229, arity: 0, flags: {} },\r\n\r\n  '\\\\sum': { glyph: 2402, arity: 0, flags: { big: true } },\r\n  '\\\\prod': { glyph: 2401, arity: 0, flags: { big: true } },\r\n  '\\\\bigoplus': { glyph: 2284, arity: 0, flags: { big: true } },\r\n  '\\\\bigodot': { glyph: 2281, arity: 0, flags: { big: true } },\r\n  '\\\\int': { glyph: 2412, arity: 0, flags: { yfl: true } },\r\n  '\\\\oint': { glyph: 2269, arity: 0, flags: { yfl: true } },\r\n  '\\\\oplus': { glyph: 1284, arity: 0, flags: {} },\r\n  '\\\\odot': { glyph: 1281, arity: 0, flags: {} },\r\n  '\\\\perp': { glyph: 738, arity: 0, flags: {} },\r\n  '\\\\angle': { glyph: 739, arity: 0, flags: {} },\r\n  '\\\\triangle': { glyph: 842, arity: 0, flags: {} },\r\n  '\\\\Box': { glyph: 841, arity: 0, flags: {} },\r\n\r\n  '\\\\rightarrow': { glyph: 2261, arity: 0, flags: {} },\r\n  '\\\\to': { glyph: 2261, arity: 0, flags: {} },\r\n  '\\\\leftarrow': { glyph: 2263, arity: 0, flags: {} },\r\n  '\\\\gets': { glyph: 2263, arity: 0, flags: {} },\r\n  '\\\\circ': { glyph: 902, arity: 0, flags: {} },\r\n  '\\\\bigcirc': { glyph: 904, arity: 0, flags: {} },\r\n  '\\\\bullet': { glyph: 828, arity: 0, flags: {} },\r\n  '\\\\star': { glyph: 856, arity: 0, flags: {} },\r\n  '\\\\diamond': { glyph: 743, arity: 0, flags: {} },\r\n  '\\\\ast': { glyph: 728, arity: 0, flags: {} },\r\n\r\n  /*verbatim symbols*/\r\n  '\\\\log': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\ln': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\exp': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\mod': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\lim': { glyph: 0, arity: 0, flags: { txt: true, big: true } },\r\n\r\n  '\\\\sin': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\cos': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\tan': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\csc': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\sec': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\cot': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\sinh': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\cosh': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\tanh': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\csch': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\sech': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\coth': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arcsin': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arccos': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arctan': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arccsc': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arcsec': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arccot': { glyph: 0, arity: 0, flags: { txt: true } },\r\n\r\n  /*font modes*/\r\n  '\\\\text': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathnormal': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathrm': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathit': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathbf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathsf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathtt': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathfrak': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathcal': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathbb': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathscr': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\rm': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\it': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\bf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\sf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\tt': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\frak': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\cal': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\bb': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\scr': { glyph: 0, arity: 1, flags: {} },\r\n\r\n  '\\\\quad': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\,': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\.': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\;': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\!': { glyph: 0, arity: 0, flags: {} },\r\n\r\n  /*greek letters*/\r\n  '\\\\alpha': { glyph: 2127, flags: {} },\r\n  '\\\\beta': { glyph: 2128, flags: {} },\r\n  '\\\\gamma': { glyph: 2129, flags: {} },\r\n  '\\\\delta': { glyph: 2130, flags: {} },\r\n  '\\\\varepsilon': { glyph: 2131, flags: {} },\r\n  '\\\\zeta': { glyph: 2132, flags: {} },\r\n  '\\\\eta': { glyph: 2133, flags: {} },\r\n  '\\\\vartheta': { glyph: 2134, flags: {} },\r\n  '\\\\iota': { glyph: 2135, flags: {} },\r\n  '\\\\kappa': { glyph: 2136, flags: {} },\r\n  '\\\\lambda': { glyph: 2137, flags: {} },\r\n  '\\\\mu': { glyph: 2138, flags: {} },\r\n  '\\\\nu': { glyph: 2139, flags: {} },\r\n  '\\\\xi': { glyph: 2140, flags: {} },\r\n  '\\\\omicron': { glyph: 2141, flags: {} },\r\n  '\\\\pi': { glyph: 2142, flags: {} },\r\n  '\\\\rho': { glyph: 2143, flags: {} },\r\n  '\\\\sigma': { glyph: 2144, flags: {} },\r\n  '\\\\tau': { glyph: 2145, flags: {} },\r\n  '\\\\upsilon': { glyph: 2146, flags: {} },\r\n  '\\\\varphi': { glyph: 2147, flags: {} },\r\n  '\\\\chi': { glyph: 2148, flags: {} },\r\n  '\\\\psi': { glyph: 2149, flags: {} },\r\n  '\\\\omega': { glyph: 2150, flags: {} },\r\n\r\n  '\\\\epsilon': { glyph: 2184, flags: {} },\r\n  '\\\\theta': { glyph: 2185, flags: {} },\r\n  '\\\\phi': { glyph: 2186, flags: {} },\r\n  '\\\\varsigma': { glyph: 2187, flags: {} },\r\n\r\n  '\\\\Alpha': { glyph: 2027, flags: {} },\r\n  '\\\\Beta': { glyph: 2028, flags: {} },\r\n  '\\\\Gamma': { glyph: 2029, flags: {} },\r\n  '\\\\Delta': { glyph: 2030, flags: {} },\r\n  '\\\\Epsilon': { glyph: 2031, flags: {} },\r\n  '\\\\Zeta': { glyph: 2032, flags: {} },\r\n  '\\\\Eta': { glyph: 2033, flags: {} },\r\n  '\\\\Theta': { glyph: 2034, flags: {} },\r\n  '\\\\Iota': { glyph: 2035, flags: {} },\r\n  '\\\\Kappa': { glyph: 2036, flags: {} },\r\n  '\\\\Lambda': { glyph: 2037, flags: {} },\r\n  '\\\\Mu': { glyph: 2038, flags: {} },\r\n  '\\\\Nu': { glyph: 2039, flags: {} },\r\n  '\\\\Xi': { glyph: 2040, flags: {} },\r\n  '\\\\Omicron': { glyph: 2041, flags: {} },\r\n  '\\\\Pi': { glyph: 2042, flags: {} },\r\n  '\\\\Rho': { glyph: 2043, flags: {} },\r\n  '\\\\Sigma': { glyph: 2044, flags: {} },\r\n  '\\\\Tau': { glyph: 2045, flags: {} },\r\n  '\\\\Upsilon': { glyph: 2046, flags: {} },\r\n  '\\\\Phi': { glyph: 2047, flags: {} },\r\n  '\\\\Chi': { glyph: 2048, flags: {} },\r\n  '\\\\Psi': { glyph: 2049, flags: {} },\r\n  '\\\\Omega': { glyph: 2050, flags: {} }\r\n}\r\n\r\nexport { SYMB }\r\n\r\n/**\r\n * 将 ASCII 字符按指定模式映射到 Hershey 字形索引\r\n * @param x 字符\r\n * @param mode 排版模式，默认 math\r\n * @returns Hershey 字形索引\r\n */\r\nexport function asciiMap(x: string, mode = 'math'): number {\r\n  const c = x.charCodeAt(0)\r\n  if (65 <= c && c <= 90) {\r\n    const d = c - 65\r\n    if (mode == 'text' || mode == 'rm') {\r\n      return d + 2001\r\n    } else if (mode == 'tt') {\r\n      return d + 501\r\n    } else if (mode == 'bf' || mode == 'bb') {\r\n      return d + 3001\r\n    } else if (mode == 'sf') {\r\n      return d + 2501\r\n    } else if (mode == 'frak') {\r\n      return d + 3301\r\n    } else if (mode == 'scr' || mode == 'cal') {\r\n      return d + 2551\r\n    } else {\r\n      return d + 2051\r\n    }\r\n  }\r\n  if (97 <= c && c <= 122) {\r\n    const d = c - 97\r\n    if (mode == 'text' || mode == 'rm') {\r\n      return d + 2101\r\n    } else if (mode == 'tt') {\r\n      return d + 601\r\n    } else if (mode == 'bf' || mode == 'bb') {\r\n      return d + 3101\r\n    } else if (mode == 'sf') {\r\n      return d + 2601\r\n    } else if (mode == 'frak') {\r\n      return d + 3401\r\n    } else if (mode == 'scr' || mode == 'cal') {\r\n      return d + 2651\r\n    } else {\r\n      return d + 2151\r\n    }\r\n  }\r\n  if (48 <= c && c <= 57) {\r\n    const d = c - 48\r\n    if (mode == 'it') {\r\n      return d + 2750\r\n    } else if (mode == 'bf') {\r\n      return d + 3200\r\n    } else if (mode == 'tt') {\r\n      return d + 700\r\n    } else {\r\n      return d + 2200\r\n    }\r\n  }\r\n\r\n  return <number>{\r\n    '.': 2210,\r\n    ',': 2211,\r\n    ':': 2212,\r\n    ';': 2213,\r\n    '!': 2214,\r\n    '?': 2215,\r\n    '\\'': 2216,\r\n    '\"': 2217,\r\n    '*': 2219,\r\n    '/': 2220,\r\n    '-': 2231,\r\n    '+': 2232,\r\n    '=': 2238,\r\n    '<': 2241,\r\n    '>': 2242,\r\n    '~': 2246,\r\n    '@': 2273,\r\n    '\\\\': 804\r\n  }[x]\r\n}\r\n","import { HERSHEY } from './latex-hershey'\r\nimport { SYMB, Symb, asciiMap } from './latex-symbols'\r\n\r\n/** LaTeX 排版配置常量 */\r\nconst CONFIG: Record<string, number> = {\r\n  /** 上下标缩放比例 */\r\n  SUB_SUP_SCALE: 0.5,\r\n  /** 根号额外项缩放比例 */\r\n  SQRT_MAG_SCALE: 0.5,\r\n  /** 分式缩放比例 */\r\n  FRAC_SCALE: 0.85,\r\n  /** 行间距 */\r\n  LINE_SPACING: 0.5,\r\n  /** 分式上下间距 */\r\n  FRAC_SPACING: 0.4\r\n}\r\n\r\n/**\r\n * 将 LaTeX 字符串切分为 token 数组\r\n * @param str LaTeX 字符串\r\n * @returns token 数组\r\n */\r\nfunction tokenize(str: string): string[] {\r\n  str = str.replace(/\\n/g, ' ')\r\n  let i = 0\r\n  const tokens: string[] = []\r\n  let curr = ''\r\n  while (i < str.length) {\r\n    if (str[i] == ' ') {\r\n      if (curr.length) {\r\n        tokens.push(curr)\r\n        curr = ''\r\n      }\r\n    } else if (str[i] == '\\\\') {\r\n      if (curr.length == 1 && curr[0] == '\\\\') {\r\n        curr += str[i]\r\n        tokens.push(curr)\r\n        curr = ''\r\n      } else {\r\n        if (curr.length) {\r\n          tokens.push(curr)\r\n        }\r\n        curr = str[i]\r\n      }\r\n    } else if (/[A-Za-z0-9\\.]/.test(str[i])) {\r\n      curr += str[i]\r\n    } else {\r\n      if (curr.length && curr != '\\\\') {\r\n        tokens.push(curr)\r\n        curr = ''\r\n      }\r\n      curr += str[i]\r\n      tokens.push(curr)\r\n      curr = ''\r\n    }\r\n    i++\r\n  }\r\n  if (curr.length) tokens.push(curr)\r\n  return tokens\r\n}\r\n\r\n/** 包围盒信息 */\r\ninterface Bbox {\r\n  /** 左上角 X 坐标 */\r\n  x: number\r\n  /** 左上角 Y 坐标 */\r\n  y: number\r\n  /** 宽度 */\r\n  w: number\r\n  /** 高度 */\r\n  h: number\r\n}\r\n\r\n/** LaTeX 表达式节点 */\r\ninterface Expr {\r\n  /** 节点类型 */\r\n  type: string\r\n  /** 节点文本 */\r\n  text: string\r\n  /** 排版模式 */\r\n  mode: string\r\n  /** 子节点 */\r\n  chld: Expr[]\r\n  /** 包围盒 */\r\n  bbox: Bbox\r\n}\r\n\r\n/**\r\n * 将单个 token 解析为原子表达式\r\n * @param x token 字符串\r\n * @returns 原子表达式\r\n */\r\nfunction parseAtom(x: string): Expr {\r\n  return {\r\n    type: SYMB[x] ? 'symb' : 'char',\r\n    mode: 'math',\r\n    text: x,\r\n    chld: [],\r\n    // @ts-ignore\r\n    bbox: null\r\n  }\r\n}\r\n\r\n/**\r\n * 将 token 数组解析为表达式树\r\n * @param tokens token 数组\r\n * @returns 表达式树\r\n */\r\nfunction parse(tokens: string[]): Expr {\r\n  let i = 0\r\n  let expr: Expr = {\r\n    type: 'node',\r\n    text: '',\r\n    mode: 'math',\r\n    chld: [],\r\n    // @ts-ignore\r\n    bbox: null\r\n  }\r\n\r\n  /** 取可选参数（方括号包裹部分） */\r\n  function takeOpt(): Expr | null {\r\n    if (tokens[i] != '[') {\r\n      return null\r\n    }\r\n    let lvl = 0\r\n    let j = i\r\n    while (j < tokens.length) {\r\n      if (tokens[j] == '[') {\r\n        lvl++\r\n      } else if (tokens[j] == ']') {\r\n        lvl--\r\n        if (!lvl) {\r\n          break\r\n        }\r\n      }\r\n      j++\r\n    }\r\n    const ret: Expr = parse(tokens.slice(i + 1, j))\r\n    i = j\r\n    return ret\r\n  }\r\n\r\n  /**\r\n   * 顺序取 n 个参数（花括号包裹或单个 token）\r\n   * @param n 参数个数\r\n   * @returns 参数表达式数组\r\n   */\r\n  function takeN(n: number): Expr[] {\r\n    let j: number = i\r\n    let j0: number = j\r\n    let lvl = 0\r\n    let cnt = 0\r\n    const ret: Expr[] = []\r\n    while (j < tokens.length) {\r\n      if (tokens[j] == '{') {\r\n        if (!lvl) {\r\n          j0 = j\r\n        }\r\n        lvl++\r\n      } else if (tokens[j] == '}') {\r\n        lvl--\r\n        if (!lvl) {\r\n          ret.push(parse(tokens.slice(j0 + 1, j)))\r\n          cnt++\r\n          if (cnt == n) {\r\n            break\r\n          }\r\n        }\r\n      } else {\r\n        if (lvl == 0) {\r\n          ret.push(parseAtom(tokens[j]))\r\n          cnt++\r\n          if (cnt == n) {\r\n            break\r\n          }\r\n        }\r\n      }\r\n      j++\r\n    }\r\n    i = j\r\n    return ret\r\n  }\r\n\r\n  for (i = 0; i < tokens.length; i++) {\r\n    const s: Symb = SYMB[tokens[i]]\r\n    const e: Expr = {\r\n      type: '',\r\n      text: tokens[i],\r\n      mode: 'math',\r\n      chld: [],\r\n      // @ts-ignore\r\n      bbox: null\r\n    }\r\n    if (s) {\r\n      if (s.arity) {\r\n        i++\r\n        e.type = 'func'\r\n        let opt: Expr | null = null\r\n        if (s.flags.opt) {\r\n          opt = takeOpt()\r\n          if (opt) i++\r\n        }\r\n        const chld: Expr[] = takeN(s.arity)\r\n        e.chld = chld\r\n        if (opt) {\r\n          e.chld.push(opt)\r\n        }\r\n      } else {\r\n        e.type = 'symb'\r\n      }\r\n    } else {\r\n      if (tokens[i] == '{') {\r\n        e.type = 'node'\r\n        e.text = ''\r\n        e.chld = takeN(1)\r\n      } else {\r\n        e.type = 'char'\r\n      }\r\n    }\r\n    expr.chld.push(e)\r\n  }\r\n  if (expr.chld.length == 1) {\r\n    expr = expr.chld[0]\r\n  }\r\n  return expr\r\n}\r\n\r\n/**\r\n * 处理 \\begin/\\end 环境结构，将环境内容收纳为子节点\r\n * @param exprs 表达式数组\r\n */\r\nfunction environments(exprs: Expr[]) {\r\n  let i = 0\r\n  while (i < exprs.length) {\r\n    if (exprs[i].text == '\\\\begin') {\r\n      let j: number\r\n      for (j = i; j < exprs.length; j++) {\r\n        if (exprs[j].text == '\\\\end') {\r\n          break\r\n        }\r\n      }\r\n      const es: Expr[] = exprs.splice(i + 1, j - (i + 1))\r\n      environments(es)\r\n      exprs[i].text = exprs[i].chld[0].text\r\n      exprs[i].chld = es\r\n      exprs.splice(i + 1, 1)\r\n    }\r\n    i++\r\n  }\r\n}\r\n\r\n/**\r\n * 对表达式及其子树进行缩放与平移变换\r\n * @param expr 表达式\r\n * @param sclx X 缩放\r\n * @param scly Y 缩放\r\n * @param x X 平移\r\n * @param y Y 平移\r\n * @param notFirst 是否非首层（首层不缩放坐标）\r\n */\r\nfunction transform(\r\n  expr: Expr,\r\n  sclx: number,\r\n  scly: number,\r\n  x: number,\r\n  y: number,\r\n  notFirst?: boolean\r\n) {\r\n  if (scly == null) {\r\n    scly = sclx\r\n  }\r\n  if (!expr.bbox) return\r\n  if (notFirst) {\r\n    expr.bbox.x *= sclx\r\n    expr.bbox.y *= scly\r\n  }\r\n  expr.bbox.w *= sclx\r\n  expr.bbox.h *= scly\r\n  for (let i = 0; i < expr.chld.length; i++) {\r\n    transform(expr.chld[i], sclx, scly, 0, 0, true)\r\n  }\r\n  expr.bbox.x += x\r\n  expr.bbox.y += y\r\n}\r\n\r\n/**\r\n * 计算表达式数组的合并包围盒\r\n * @param exprs 表达式数组\r\n * @returns 合并包围盒\r\n */\r\nfunction computeBbox(exprs: Expr[]): Bbox {\r\n  let xmin = Infinity\r\n  let xmax = -Infinity\r\n  let ymin = Infinity\r\n  let ymax = -Infinity\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (!exprs[i].bbox) {\r\n      continue\r\n    }\r\n    xmin = Math.min(xmin, exprs[i].bbox.x)\r\n    ymin = Math.min(ymin, exprs[i].bbox.y)\r\n    xmax = Math.max(xmax, exprs[i].bbox.x + exprs[i].bbox.w)\r\n    ymax = Math.max(ymax, exprs[i].bbox.y + exprs[i].bbox.h)\r\n  }\r\n  return { x: xmin, y: ymin, w: xmax - xmin, h: ymax - ymin }\r\n}\r\n\r\n/**\r\n * 将表达式数组打包为单个节点，并归零子节点坐标\r\n * @param exprs 表达式数组\r\n * @returns 打包后的表达式\r\n */\r\nfunction group(exprs: Expr[]): Expr {\r\n  if (!exprs.length) {\r\n    // @ts-ignore\r\n    return null\r\n  }\r\n  const bbox: Bbox = computeBbox(exprs)\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (!exprs[i].bbox) {\r\n      continue\r\n    }\r\n    exprs[i].bbox.x -= bbox.x\r\n    exprs[i].bbox.y -= bbox.y\r\n  }\r\n  const expr: Expr = {\r\n    type: 'node',\r\n    text: '',\r\n    mode: 'math',\r\n    chld: exprs,\r\n    bbox\r\n  }\r\n  return expr\r\n}\r\n\r\n/**\r\n * 对表达式数组进行上下标、左右定界符与矩阵/方程组对齐处理\r\n * @param exprs 表达式数组\r\n * @param alignment 对齐方式\r\n */\r\nfunction align(exprs: Expr[], alignment = 'center'): void {\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (exprs[i].text == '^' || exprs[i].text == '\\'') {\r\n      let h = 0\r\n      let j = i\r\n      while (\r\n        j > 0 &&\r\n        (exprs[j].text == '^' || exprs[j].text == '_' || exprs[j].text == '\\'')\r\n      ) {\r\n        j--\r\n      }\r\n      h = exprs[j].bbox.y\r\n      if (exprs[i].text == '\\'') {\r\n        exprs[i].bbox.y = h\r\n      } else {\r\n        // @ts-ignore\r\n        transform(exprs[i], CONFIG.SUB_SUP_SCALE, null, 0, 0)\r\n        if (SYMB[exprs[j].text] && SYMB[exprs[j].text].flags.big) {\r\n          exprs[i].bbox.y = h - exprs[i].bbox.h\r\n        } else if (exprs[j].text == '\\\\int') {\r\n          exprs[i].bbox.y = h\r\n        } else {\r\n          exprs[i].bbox.y = h - exprs[i].bbox.h / 2\r\n        }\r\n      }\r\n    } else if (exprs[i].text == '_') {\r\n      let h = 1\r\n      let j = i\r\n      while (\r\n        j > 0 &&\r\n        (exprs[j].text == '^' || exprs[j].text == '_' || exprs[j].text == '\\'')\r\n      ) {\r\n        j--\r\n      }\r\n      h = exprs[j].bbox.y + exprs[j].bbox.h\r\n      // @ts-ignore\r\n      transform(exprs[i], CONFIG.SUB_SUP_SCALE, null, 0, 0)\r\n      if (SYMB[exprs[j].text] && SYMB[exprs[j].text].flags.big) {\r\n        exprs[i].bbox.y = h\r\n      } else if (exprs[j].text == '\\\\int') {\r\n        exprs[i].bbox.y = h - exprs[i].bbox.h\r\n      } else {\r\n        exprs[i].bbox.y = h - exprs[i].bbox.h / 2\r\n      }\r\n    }\r\n  }\r\n  /**\r\n   * 在指定方向上搜索定界符包围的纵向范围\r\n   * @param i 起始索引\r\n   * @param l 左定界符\r\n   * @param r 右定界符\r\n   * @param dir 搜索方向\r\n   * @param lvl0 初始层级\r\n   * @returns [ymin, ymax]\r\n   */\r\n  function searchHigh(\r\n    i: number,\r\n    l: string,\r\n    r: string,\r\n    dir: number,\r\n    lvl0: number\r\n  ): number[] {\r\n    let j = i\r\n    let lvl = lvl0\r\n    let ymin = Infinity\r\n    let ymax = -Infinity\r\n    while (dir > 0 ? j < exprs.length : j >= 0) {\r\n      if (exprs[j].text == l) {\r\n        lvl++\r\n      } else if (exprs[j].text == r) {\r\n        lvl--\r\n        if (lvl == 0) {\r\n          break\r\n        }\r\n      } else if (exprs[j].text == '^' || exprs[j].text == '_') {\r\n        //skip\r\n      } else if (exprs[j].bbox) {\r\n        ymin = Math.min(ymin, exprs[j].bbox.y)\r\n        ymax = Math.max(ymax, exprs[j].bbox.y + exprs[j].bbox.h)\r\n      }\r\n      j += dir\r\n    }\r\n    return [ymin, ymax]\r\n  }\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (exprs[i].text == '\\\\left') {\r\n      const [ymin, ymax] = searchHigh(i, '\\\\left', '\\\\right', 1, 0)\r\n      if (ymin != Infinity && ymax != -Infinity) {\r\n        exprs[i].bbox.y = ymin\r\n        transform(exprs[i], 1, (ymax - ymin) / exprs[i].bbox.h, 0, 0)\r\n      }\r\n    } else if (exprs[i].text == '\\\\right') {\r\n      const [ymin, ymax] = searchHigh(i, '\\\\right', '\\\\left', -1, 0)\r\n      if (ymin != Infinity && ymax != -Infinity) {\r\n        exprs[i].bbox.y = ymin\r\n        transform(exprs[i], 1, (ymax - ymin) / exprs[i].bbox.h, 0, 0)\r\n      }\r\n    } else if (exprs[i].text == '\\\\middle') {\r\n      const [lmin, lmax] = searchHigh(i, '\\\\right', '\\\\left', -1, 1)\r\n      const [rmin, rmax] = searchHigh(i, '\\\\left', '\\\\right', 1, 1)\r\n      const ymin = Math.min(lmin, rmin)\r\n      const ymax = Math.max(lmax, rmax)\r\n      if (ymin != Infinity && ymax != -Infinity) {\r\n        exprs[i].bbox.y = ymin\r\n        transform(exprs[i], 1, (ymax - ymin) / exprs[i].bbox.h, 0, 0)\r\n      }\r\n    }\r\n  }\r\n\r\n  if (!exprs.some(x => x.text == '&' || x.text == '\\\\\\\\')) {\r\n    return\r\n  }\r\n\r\n  const rows: Expr[][][] = []\r\n  let row: Expr[][] = []\r\n  let cell: Expr[] = []\r\n\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (exprs[i].text == '&') {\r\n      row.push(cell)\r\n      cell = []\r\n    } else if (exprs[i].text == '\\\\\\\\') {\r\n      if (cell.length) {\r\n        row.push(cell)\r\n        cell = []\r\n      }\r\n      rows.push(row)\r\n      row = []\r\n    } else {\r\n      cell.push(exprs[i])\r\n    }\r\n  }\r\n  if (cell.length) {\r\n    row.push(cell)\r\n  }\r\n  if (row.length) {\r\n    rows.push(row)\r\n  }\r\n  const colws: number[] = []\r\n  const erows: Expr[][] = []\r\n  for (let i = 0; i < rows.length; i++) {\r\n    const erow: Expr[] = []\r\n    for (let j = 0; j < rows[i].length; j++) {\r\n      const e: Expr = group(rows[i][j])\r\n      if (e) {\r\n        colws[j] = colws[j] || 0\r\n        colws[j] = Math.max(e.bbox.w + 1, colws[j])\r\n      }\r\n      erow[j] = e\r\n    }\r\n    erows.push(erow)\r\n  }\r\n\r\n  const ybds: number[][] = []\r\n  for (let i = 0; i < erows.length; i++) {\r\n    let ymin = Infinity\r\n    let ymax = -Infinity\r\n    for (let j = 0; j < erows[i].length; j++) {\r\n      if (!erows[i][j]) {\r\n        continue\r\n      }\r\n      ymin = Math.min(ymin, erows[i][j].bbox.y)\r\n      ymax = Math.max(ymax, erows[i][j].bbox.y + erows[i][j].bbox.h)\r\n    }\r\n    ybds.push([ymin, ymax])\r\n  }\r\n\r\n  for (let i = 0; i < ybds.length; i++) {\r\n    if (ybds[i][0] == Infinity || ybds[i][1] == Infinity) {\r\n      ybds[i][0] = i == 0 ? 0 : ybds[i - 1][1]\r\n      ybds[i][1] = ybds[i][0] + 2\r\n    }\r\n  }\r\n\r\n  for (let i = 1; i < erows.length; i++) {\r\n    const shft = ybds[i - 1][1] - ybds[i][0] + CONFIG.LINE_SPACING\r\n    for (let j = 0; j < erows[i].length; j++) {\r\n      if (erows[i][j]) {\r\n        erows[i][j].bbox.y += shft\r\n      }\r\n    }\r\n    ybds[i][0] += shft\r\n    ybds[i][1] += shft\r\n  }\r\n\r\n  exprs.splice(0, exprs.length)\r\n  for (let i = 0; i < erows.length; i++) {\r\n    let dx = 0\r\n    for (let j = 0; j < erows[i].length; j++) {\r\n      const e: Expr = erows[i][j]\r\n      if (!e) {\r\n        dx += colws[j]\r\n        continue\r\n      }\r\n      e.bbox.x += dx\r\n      dx += colws[j] - e.bbox.w\r\n      // e.bbox.w = colws[j];\r\n      if (alignment == 'center') {\r\n        e.bbox.x += (colws[j] - e.bbox.w) / 2\r\n      } else if (alignment == 'left') {\r\n        //ok\r\n      } else if (alignment == 'right') {\r\n        e.bbox.x += colws[j] - e.bbox.w\r\n      } else if (alignment == 'equation') {\r\n        if (j != erows[i].length - 1) {\r\n          e.bbox.x += colws[j] - e.bbox.w\r\n        }\r\n      }\r\n      exprs.push(e)\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 排版表达式：递归计算各节点包围盒\r\n * @param expr 表达式\r\n * @param mode 当前排版模式\r\n */\r\nfunction plan(expr: Expr, mode = 'math'): void {\r\n  const tmd: string =\r\n    {\r\n      '\\\\text': 'text',\r\n      '\\\\mathnormal': 'math',\r\n      '\\\\mathrm': 'rm',\r\n      '\\\\mathit': 'it',\r\n      '\\\\mathbf': 'bf',\r\n      '\\\\mathsf': 'sf',\r\n      '\\\\mathtt': 'tt',\r\n      '\\\\mathfrak': 'frak',\r\n      '\\\\mathcal': 'cal',\r\n      '\\\\mathbb': 'bb',\r\n      '\\\\mathscr': 'scr',\r\n      '\\\\rm': 'rm',\r\n      '\\\\it': 'it',\r\n      '\\\\bf': 'bf',\r\n      '\\\\sf': 'tt',\r\n      '\\\\tt': 'tt',\r\n      '\\\\frak': 'frak',\r\n      '\\\\cal': 'cal',\r\n      '\\\\bb': 'bb',\r\n      '\\\\scr': 'scr'\r\n    }[expr.text] ?? mode\r\n  if (!expr.chld.length) {\r\n    if (SYMB[expr.text]) {\r\n      if (SYMB[expr.text].flags.big) {\r\n        if (expr.text == '\\\\lim') {\r\n          expr.bbox = { x: 0, y: 0, w: 3.5, h: 2 }\r\n        } else {\r\n          expr.bbox = { x: 0, y: -0.5, w: 3, h: 3 }\r\n        }\r\n      } else if (SYMB[expr.text].flags.txt) {\r\n        let w = 0\r\n        for (let i = 1; i < expr.text.length; i++) {\r\n          w += HERSHEY(asciiMap(expr.text[i], 'text')).w\r\n        }\r\n        w /= 16\r\n        expr.bbox = { x: 0, y: 0, w: w, h: 2 }\r\n      } else if (SYMB[expr.text].glyph) {\r\n        let w = HERSHEY(SYMB[expr.text].glyph).w\r\n        w /= 16\r\n        if (expr.text == '\\\\int' || expr.text == '\\\\oint') {\r\n          expr.bbox = { x: 0, y: -1.5, w: w, h: 5 }\r\n        } else {\r\n          expr.bbox = { x: 0, y: 0, w: w, h: 2 }\r\n        }\r\n      } else {\r\n        expr.bbox = { x: 0, y: 0, w: 1, h: 2 }\r\n      }\r\n    } else {\r\n      let w = 0\r\n      for (let i = 0; i < expr.text.length; i++) {\r\n        if (!HERSHEY(asciiMap(expr.text[i], tmd))) {\r\n          continue\r\n        }\r\n        if (tmd == 'tt') {\r\n          w += 16\r\n        } else {\r\n          w += HERSHEY(asciiMap(expr.text[i], tmd)).w\r\n        }\r\n      }\r\n      w /= 16\r\n      expr.bbox = { x: 0, y: 0, w: w, h: 2 }\r\n    }\r\n    expr.mode = tmd\r\n    return\r\n  }\r\n  if (expr.text == '\\\\frac') {\r\n    const a: Expr = expr.chld[0]\r\n    const b: Expr = expr.chld[1]\r\n    const s: number = CONFIG.FRAC_SCALE\r\n    plan(a)\r\n    plan(b)\r\n    a.bbox.x = 0\r\n    a.bbox.y = 0\r\n    b.bbox.x = 0\r\n    b.bbox.y = 0\r\n    const mw: number = Math.max(a.bbox.w, b.bbox.w) * s\r\n    // @ts-ignore\r\n    transform(a, s, null, (mw - a.bbox.w * s) / 2, 0)\r\n    transform(\r\n      b,\r\n      s,\r\n      // @ts-ignore\r\n      null,\r\n      (mw - b.bbox.w * s) / 2,\r\n      a.bbox.h + CONFIG.FRAC_SPACING\r\n    )\r\n    expr.bbox = {\r\n      x: 0,\r\n      y: -a.bbox.h + 1 - CONFIG.FRAC_SPACING / 2,\r\n      w: mw,\r\n      h: a.bbox.h + b.bbox.h + CONFIG.FRAC_SPACING\r\n    }\r\n  } else if (expr.text == '\\\\binom') {\r\n    const a: Expr = expr.chld[0]\r\n    const b: Expr = expr.chld[1]\r\n    plan(a)\r\n    plan(b)\r\n    a.bbox.x = 0\r\n    a.bbox.y = 0\r\n    b.bbox.x = 0\r\n    b.bbox.y = 0\r\n    const mw: number = Math.max(a.bbox.w, b.bbox.w)\r\n    // @ts-ignore\r\n    transform(a, 1, null, (mw - a.bbox.w) / 2 + 1, 0)\r\n    // @ts-ignore\r\n    transform(b, 1, null, (mw - b.bbox.w) / 2 + 1, a.bbox.h)\r\n    expr.bbox = { x: 0, y: -a.bbox.h + 1, w: mw + 2, h: a.bbox.h + b.bbox.h }\r\n  } else if (expr.text == '\\\\sqrt') {\r\n    const e: Expr = expr.chld[0]\r\n    plan(e)\r\n    const f: Expr = expr.chld[1]\r\n    let pl = 0\r\n    if (f) {\r\n      plan(f)\r\n      pl = Math.max(f.bbox.w * CONFIG.SQRT_MAG_SCALE - 0.5, 0)\r\n      // @ts-ignore\r\n      transform(f, CONFIG.SQRT_MAG_SCALE, null, 0, 0.5)\r\n    }\r\n    // @ts-ignore\r\n    transform(e, 1, null, 1 + pl, 0.5)\r\n    expr.bbox = {\r\n      x: 0,\r\n      y: 2 - e.bbox.h - 0.5,\r\n      w: e.bbox.w + 1 + pl,\r\n      h: e.bbox.h + 0.5\r\n    }\r\n  } else if (SYMB[expr.text] && SYMB[expr.text].flags.hat) {\r\n    const e: Expr = expr.chld[0]\r\n    plan(e)\r\n    const y0 = e.bbox.y - 0.5\r\n    e.bbox.y = 0.5\r\n    expr.bbox = { x: 0, y: y0, w: e.bbox.w, h: e.bbox.h + 0.5 }\r\n  } else if (SYMB[expr.text] && SYMB[expr.text].flags.mat) {\r\n    const e: Expr = expr.chld[0]\r\n    plan(e)\r\n    expr.bbox = { x: 0, y: 0, w: e.bbox.w, h: e.bbox.h + 0.5 }\r\n  } else {\r\n    let dx = 0\r\n    let dy = 0\r\n    let mh = 1\r\n    for (let i = 0; i < expr.chld.length; i++) {\r\n      const c: Expr = expr.chld[i]\r\n      // @ts-ignore\r\n      const spac: number =\r\n        {\r\n          '\\\\quad': 2,\r\n          '\\\\,': (2 * 3) / 18,\r\n          '\\\\:': (2 * 4) / 18,\r\n          '\\\\;': (2 * 5) / 18,\r\n          '\\\\!': (2 * -3) / 18\r\n        }[c.text] ?? null\r\n\r\n      if (c.text == '\\\\\\\\') {\r\n        dy += mh\r\n        dx = 0\r\n        mh = 1\r\n        continue\r\n      } else if (c.text == '&') {\r\n        continue\r\n      } else if (spac != null) {\r\n        dx += spac\r\n        continue\r\n      } else {\r\n        plan(c, tmd)\r\n        // @ts-ignore\r\n        transform(c, 1, null, dx, dy)\r\n        if (c.text == '^' || c.text == '_' || c.text == '\\'') {\r\n          let j: number = i\r\n          while (\r\n            j > 0 &&\r\n            (expr.chld[j].text == '^' ||\r\n              expr.chld[j].text == '_' ||\r\n              expr.chld[j].text == '\\'')\r\n          ) {\r\n            j--\r\n          }\r\n          const wasBig =\r\n            SYMB[expr.chld[j].text] && SYMB[expr.chld[j].text].flags.big\r\n          if (c.text == '\\'') {\r\n            let k = j + 1\r\n            let nth = 0\r\n            while (k < i) {\r\n              if (expr.chld[k].text == '\\'') {\r\n                nth++\r\n              }\r\n              k++\r\n            }\r\n            c.bbox.x =\r\n              expr.chld[j].bbox.x + expr.chld[j].bbox.w + c.bbox.w * nth\r\n            dx = Math.max(dx, c.bbox.x + c.bbox.w)\r\n          } else {\r\n            if (wasBig) {\r\n              const ex =\r\n                expr.chld[j].bbox.x +\r\n                (expr.chld[j].bbox.w - c.bbox.w * CONFIG.SUB_SUP_SCALE) / 2\r\n              c.bbox.x = ex\r\n              dx = Math.max(\r\n                dx,\r\n                expr.chld[j].bbox.x +\r\n                  expr.chld[j].bbox.w +\r\n                  (c.bbox.w * CONFIG.SUB_SUP_SCALE - expr.chld[j].bbox.w) / 2\r\n              )\r\n            } else {\r\n              c.bbox.x = expr.chld[j].bbox.x + expr.chld[j].bbox.w\r\n              dx = Math.max(dx, c.bbox.x + c.bbox.w * CONFIG.SUB_SUP_SCALE)\r\n            }\r\n          }\r\n        } else {\r\n          dx += c.bbox.w\r\n        }\r\n        if (mode == 'text') {\r\n          dx += 1\r\n        }\r\n        mh = Math.max(c.bbox.y + c.bbox.h - dy, mh)\r\n      }\r\n    }\r\n    dy += mh\r\n    const m2s: Record<string, string[]> = {\r\n      bmatrix: ['[', ']'],\r\n      pmatrix: ['(', ')'],\r\n      Bmatrix: ['\\\\{', '\\\\}'],\r\n      cases: ['\\\\{']\r\n    }\r\n    const alt: string =\r\n      {\r\n        bmatrix: 'center',\r\n        pmatrix: 'center',\r\n        Bmatrix: 'center',\r\n        cases: 'left',\r\n        matrix: 'center',\r\n        aligned: 'equation'\r\n      }[expr.text] ?? 'left'\r\n\r\n    const hasLp = !!m2s[expr.text]\r\n    const hasRp = !!m2s[expr.text] && m2s[expr.text].length > 1\r\n\r\n    align(expr.chld, alt)\r\n    const bb = computeBbox(expr.chld)\r\n    if (expr.text == '\\\\text') {\r\n      bb.x -= 1\r\n      bb.w += 2\r\n    }\r\n\r\n    for (let i = 0; i < expr.chld.length; i++) {\r\n      // @ts-ignore\r\n      transform(expr.chld[i], 1, null, -bb.x + (hasLp ? 1.5 : 0), -bb.y)\r\n    }\r\n    expr.bbox = {\r\n      x: 0,\r\n      y: 0,\r\n      w: bb.w + 1.5 * Number(hasLp) + 1.5 * Number(hasRp),\r\n      h: bb.h\r\n    }\r\n\r\n    if (hasLp) {\r\n      expr.chld.unshift({\r\n        type: 'symb',\r\n        text: m2s[expr.text][0],\r\n        mode: expr.mode,\r\n        chld: [],\r\n        bbox: { x: 0, y: 0, w: 1, h: bb.h }\r\n      })\r\n    }\r\n    if (hasRp) {\r\n      expr.chld.push({\r\n        type: 'symb',\r\n        text: m2s[expr.text][1],\r\n        mode: expr.mode,\r\n        chld: [],\r\n        bbox: { x: bb.w + 2, y: 0, w: 1, h: bb.h }\r\n      })\r\n    }\r\n    if (hasLp || hasRp || expr.text == 'matrix') {\r\n      expr.type = 'node'\r\n      expr.text = ''\r\n      expr.bbox.y -= (expr.bbox.h - 2) / 2\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 将表达式树扁平化为符号列表，提取分数线、根号等装饰符号\r\n * @param expr 表达式\r\n */\r\nfunction flatten(expr: Expr) {\r\n  /**\r\n   * 递归扁平化子节点\r\n   * @param expr 当前表达式\r\n   * @param dx X 累计偏移\r\n   * @param dy Y 累计偏移\r\n   * @returns 扁平化后的符号表达式数组\r\n   */\r\n  function flat(expr: Expr, dx: number, dy: number): Expr[] {\r\n    const ff: Expr[] = []\r\n    if (expr.bbox) {\r\n      dx += expr.bbox.x\r\n      dy += expr.bbox.y\r\n      if (expr.text == '\\\\frac') {\r\n        const h: number =\r\n          expr.chld[1].bbox.y - (expr.chld[0].bbox.y + expr.chld[0].bbox.h)\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: '\\\\bar',\r\n          bbox: {\r\n            x: dx,\r\n            y: dy + (expr.chld[1].bbox.y - h / 2) - h / 2,\r\n            w: expr.bbox.w,\r\n            h: h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      } else if (expr.text == '\\\\sqrt') {\r\n        const h: number = expr.chld[0].bbox.y\r\n        const xx: number = Math.max(\r\n          0,\r\n          expr.chld[0].bbox.x - expr.chld[0].bbox.h / 2\r\n        )\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: '\\\\sqrt',\r\n          bbox: {\r\n            x: dx + xx,\r\n            y: dy + h / 2,\r\n            w: expr.chld[0].bbox.x - xx,\r\n            h: expr.bbox.h - h / 2\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n        ff.push({\r\n          type: 'symb',\r\n          text: '\\\\bar',\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx + expr.chld[0].bbox.x,\r\n            y: dy,\r\n            w: expr.bbox.w - expr.chld[0].bbox.x,\r\n            h: h\r\n          },\r\n          chld: []\r\n        })\r\n      } else if (expr.text == '\\\\binom') {\r\n        const w = Math.min(expr.chld[0].bbox.x, expr.chld[1].bbox.x)\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: '(',\r\n          bbox: {\r\n            x: dx,\r\n            y: dy,\r\n            w: w,\r\n            h: expr.bbox.h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n        ff.push({\r\n          type: 'symb',\r\n          text: ')',\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx + expr.bbox.w - w,\r\n            y: dy,\r\n            w: w,\r\n            h: expr.bbox.h\r\n          },\r\n          chld: []\r\n        })\r\n      } else if (SYMB[expr.text] && SYMB[expr.text].flags.hat) {\r\n        const h: number = expr.chld[0].bbox.y\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: expr.text,\r\n          bbox: {\r\n            x: dx,\r\n            y: dy,\r\n            w: expr.bbox.w,\r\n            h: h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      } else if (SYMB[expr.text] && SYMB[expr.text].flags.mat) {\r\n        const h: number = expr.chld[0].bbox.h\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          text: expr.text,\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx,\r\n            y: dy + h,\r\n            w: expr.bbox.w,\r\n            h: expr.bbox.h - h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      } else if (expr.type != 'node' && expr.text != '^' && expr.text != '_') {\r\n        const e: Expr = {\r\n          type: expr.type == 'func' ? 'symb' : expr.type,\r\n          text: expr.text,\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx,\r\n            y: dy,\r\n            w: expr.bbox.w,\r\n            h: expr.bbox.h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      }\r\n    }\r\n    for (let i = 0; i < expr.chld.length; i++) {\r\n      const f = flat(expr.chld[i], dx, dy)\r\n      ff.push(...f)\r\n    }\r\n    return ff\r\n  }\r\n  const f = flat(expr, -expr.bbox.x, -expr.bbox.y)\r\n  expr.type = 'node'\r\n  expr.text = ''\r\n  expr.chld = f\r\n}\r\n\r\n/**\r\n * 将扁平化后的表达式渲染为多段折线（用于 SVG/Canvas/PDF 输出）\r\n * @param expr 表达式\r\n * @returns 折线坐标数组\r\n */\r\nfunction render(expr: Expr): number[][][] {\r\n  const o: number[][][] = []\r\n  for (let i = 0; i < expr.chld.length; i++) {\r\n    const e: Expr = expr.chld[i]\r\n    let s = e.bbox.h / 2\r\n    let isSmallHat = false\r\n    if (\r\n      SYMB[e.text] &&\r\n      SYMB[e.text].flags.hat &&\r\n      !SYMB[e.text].flags.xfl &&\r\n      !SYMB[e.text].flags.yfl\r\n    ) {\r\n      s *= 4\r\n      isSmallHat = true\r\n    }\r\n    if (SYMB[e.text] && SYMB[e.text].glyph) {\r\n      const d = HERSHEY(SYMB[e.text].glyph)\r\n      for (let j = 0; j < d.polylines.length; j++) {\r\n        const l: number[][] = []\r\n\r\n        for (let k = 0; k < d.polylines[j].length; k++) {\r\n          let x = d.polylines[j][k][0]\r\n          let y = d.polylines[j][k][1]\r\n\r\n          if (SYMB[e.text].flags.xfl) {\r\n            x = ((x - d.xmin) / Math.max(d.xmax - d.xmin, 1)) * e.bbox.w\r\n            x += e.bbox.x\r\n          } else if ((d.w / 16) * s > e.bbox.w) {\r\n            x = (x / Math.max(d.w, 1)) * e.bbox.w\r\n            x += e.bbox.x\r\n          } else {\r\n            x = (x / 16) * s\r\n            const p = (e.bbox.w - (d.w / 16) * s) / 2\r\n            x += e.bbox.x + p\r\n          }\r\n          if (SYMB[e.text].flags.yfl) {\r\n            y = ((y - d.ymin) / Math.max(d.ymax - d.ymin, 1)) * e.bbox.h\r\n            y += e.bbox.y\r\n          } else {\r\n            y = (y / 16) * s\r\n            if (isSmallHat) {\r\n              const p = (d.ymax + d.ymin) / 2\r\n              y -= (p / 16) * s\r\n            }\r\n            y += e.bbox.y + e.bbox.h / 2\r\n          }\r\n          l.push([x, y])\r\n        }\r\n        o.push(l)\r\n      }\r\n    } else if ((SYMB[e.text] && SYMB[e.text].flags.txt) || e.type == 'char') {\r\n      let x0 = e.bbox.x\r\n      const isVerb = !!(SYMB[e.text] && SYMB[e.text].flags.txt)\r\n      for (let n = Number(isVerb); n < e.text.length; n++) {\r\n        const d = HERSHEY(asciiMap(e.text[n], isVerb ? 'text' : e.mode))\r\n        if (!d) {\r\n          console.warn('unmapped character: ' + e.text[n])\r\n          continue\r\n        }\r\n        for (let j = 0; j < d.polylines.length; j++) {\r\n          const l: number[][] = []\r\n          for (let k = 0; k < d.polylines[j].length; k++) {\r\n            let x = d.polylines[j][k][0]\r\n            let y = d.polylines[j][k][1]\r\n            x /= 16\r\n            y /= 16\r\n            x *= s\r\n            y *= s\r\n            if (e.mode == 'tt') {\r\n              if (d.w > 16) {\r\n                x *= 16 / d.w\r\n              } else {\r\n                x += (16 - d.w) / 2 / 16\r\n              }\r\n            }\r\n            x += x0\r\n            y += e.bbox.y + e.bbox.h / 2\r\n            l.push([x, y])\r\n          }\r\n          o.push(l)\r\n        }\r\n        if (e.mode == 'tt') {\r\n          x0 += s\r\n        } else {\r\n          x0 += (d.w / 16) * s\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return o\r\n}\r\n\r\n/** LaTeX 导出选项 */\r\ninterface ExportOpt {\r\n  /** 最小字符高度 */\r\n  MIN_CHAR_H?: number\r\n  /** 最大宽度 */\r\n  MAX_W?: number\r\n  /** 最大高度 */\r\n  MAX_H?: number\r\n  /** X 方向边距 */\r\n  MARGIN_X?: number\r\n  /** Y 方向边距 */\r\n  MARGIN_Y?: number\r\n  /** X 缩放 */\r\n  SCALE_X?: number\r\n  /** Y 缩放 */\r\n  SCALE_Y?: number\r\n  /** 描边宽度 */\r\n  STROKE_W?: number\r\n  /** 前景颜色 */\r\n  FG_COLOR?: string\r\n  /** 背景颜色 */\r\n  BG_COLOR?: string\r\n}\r\n\r\n/**\r\n * 将数值保留两位小数\r\n * @param x 待处理数值\r\n * @returns 处理后的数值\r\n */\r\nfunction nf(x: number): number {\r\n  return Math.round(x * 100) / 100\r\n}\r\n\r\n/** LaTeX 转 SVG 结果 */\r\nexport interface LaTexSVG {\r\n  /** SVG data URL */\r\n  svg: string\r\n  /** 宽度 */\r\n  width: number\r\n  /** 高度 */\r\n  height: number\r\n}\r\n\r\n/** LaTeX 工具类，提供从 LaTeX 字符串到 SVG/PDF/折线的转换能力 */\r\nexport class LaTexUtils {\r\n  /** 原始 LaTeX 字符串 */\r\n  _latex: string\r\n  /** 解析后的表达式树 */\r\n  _tree: Expr\r\n  /** token 数组 */\r\n  _tokens: string[]\r\n  /** 渲染后的折线 */\r\n  _polylines: number[][][]\r\n\r\n  /**\r\n   * 创建 LaTeX 工具实例并完成解析与排版\r\n   * @param latex LaTeX 字符串\r\n   */\r\n  constructor(latex: string) {\r\n    this._latex = latex\r\n    this._tokens = tokenize(latex)\r\n    this._tree = parse(this._tokens)\r\n    environments(this._tree.chld)\r\n    plan(this._tree)\r\n    flatten(this._tree)\r\n    this._polylines = render(this._tree)\r\n  }\r\n\r\n  /**\r\n   * 根据导出选项解析缩放与边距\r\n   * @param opt 导出选项\r\n   * @returns [px, py, sclx, scly]\r\n   */\r\n  private resolveScale(opt?: ExportOpt): number[] {\r\n    if (opt == undefined) {\r\n      return [16, 16, 16, 16]\r\n    }\r\n    let sclx: number = opt.SCALE_X ?? 16\r\n    let scly: number = opt.SCALE_Y ?? 16\r\n\r\n    if (opt.MIN_CHAR_H != undefined) {\r\n      let mh = 0\r\n      for (let i = 0; i < this._tree.chld.length; i++) {\r\n        const c: Expr = this._tree.chld[i]\r\n        if (\r\n          c.type == 'char' ||\r\n          (SYMB[c.text] &&\r\n            (SYMB[c.text].flags.txt || !Object.keys(SYMB[c.text].flags).length))\r\n        ) {\r\n          mh = Math.min(c.bbox.h, mh)\r\n        }\r\n      }\r\n      const s: number = Math.max(1, opt.MIN_CHAR_H / mh)\r\n      sclx *= s\r\n      scly *= s\r\n    }\r\n    if (opt.MAX_W != undefined) {\r\n      const s0 = sclx\r\n      sclx = Math.min(sclx, opt.MAX_W / this._tree.bbox.w)\r\n      scly *= sclx / s0\r\n    }\r\n    if (opt.MAX_H != undefined) {\r\n      const s0 = scly\r\n      scly = Math.min(scly, opt.MAX_H / this._tree.bbox.h)\r\n      sclx *= scly / s0\r\n    }\r\n    const px: number = opt.MARGIN_X ?? sclx\r\n    const py: number = opt.MARGIN_Y ?? scly\r\n    return [px, py, sclx, scly]\r\n  }\r\n\r\n  /**\r\n   * 输出折线坐标，应用缩放与边距\r\n   * @param opt 导出选项\r\n   * @returns 折线坐标数组\r\n   */\r\n  polylines(opt?: ExportOpt): number[][][] {\r\n    if (!opt) opt = {}\r\n    const polylines: number[][][] = []\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      polylines.push([])\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        polylines[polylines.length - 1].push([px + x * sclx, py + y * scly])\r\n      }\r\n    }\r\n    return polylines\r\n  }\r\n\r\n  /**\r\n   * 输出 SVG path 的 d 属性字符串\r\n   * @param opt 导出选项\r\n   * @returns path d 字符串\r\n   */\r\n  pathd(opt?: ExportOpt): string {\r\n    if (!opt) opt = {}\r\n    let d = ''\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        d += !j ? 'M' : 'L'\r\n        d += `${nf(px + x * sclx)} ${nf(py + y * scly)}`\r\n      }\r\n    }\r\n    return d\r\n  }\r\n\r\n  /**\r\n   * 生成 SVG data URL\r\n   * @param opt 导出选项\r\n   * @returns SVG 结果\r\n   */\r\n  svg(opt: ExportOpt): LaTexSVG {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    const w = nf(this._tree.bbox.w * sclx + px * 2)\r\n    const h = nf(this._tree.bbox.h * scly + py * 2)\r\n    let o = `<svg\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n      width=\"${w}\" height=\"${h}\"\r\n      fill=\"none\" stroke=\"${opt.FG_COLOR ?? 'black'}\" stroke-width=\"${\r\n      opt.STROKE_W ?? 1\r\n    }\"\r\n      stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n    >`\r\n    if (opt.BG_COLOR) {\r\n      o += `<rect x=\"${0}\" y=\"${0}\" width=\"${w}\" height=\"${h}\" fill=\"${\r\n        opt.BG_COLOR\r\n      }\" stroke=\"none\"></rect>`\r\n    }\r\n    o += `<path d=\"`\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      o += 'M'\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        o += nf(px + x * sclx) + ' ' + nf(py + y * scly) + ' '\r\n      }\r\n    }\r\n    o += `\"/>`\r\n    o += `</svg>`\r\n    return {\r\n      svg: `data:image/svg+xml;base64,${window.btoa(o)}`,\r\n      width: Math.ceil(w),\r\n      height: Math.ceil(h)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 生成 PDF 字符串\r\n   * @param opt 导出选项\r\n   * @returns PDF 字符串\r\n   */\r\n  pdf(opt: ExportOpt): string {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n\r\n    const width = nf(this._tree.bbox.w * sclx + px * 2)\r\n    const height = nf(this._tree.bbox.h * scly + py * 2)\r\n    let head = `%PDF-1.1\\n%%¥±ë\\n1 0 obj\\n<< /Type /Catalog\\n/Pages 2 0 R\\n>>endobj\r\n    2 0 obj\\n<< /Type /Pages\\n/Kids [3 0 R]\\n/Count 1\\n/MediaBox [0 0 ${width} ${height}]\\n>>\\nendobj\r\n    3 0 obj\\n<< /Type /Page\\n/Parent 2 0 R\\n/Resources\\n<< /Font\\n<< /F1\\n<< /Type /Font\r\n    /Subtype /Type1\\n/BaseFont /Times-Roman\\n>>\\n>>\\n>>\\n/Contents [`\r\n    let pdf = ''\r\n    let count = 4\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      pdf += `${count} 0 obj \\n<< /Length 0 >>\\n stream\\n 1 j 1 J ${\r\n        opt.STROKE_W ?? 1\r\n      } w\\n`\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        pdf += `${nf(px + x * sclx)} ${nf(height - (py + y * scly))} ${\r\n          j ? 'l' : 'm'\r\n        } `\r\n      }\r\n      pdf += '\\nS\\nendstream\\nendobj\\n'\r\n      head += `${count} 0 R `\r\n      count++\r\n    }\r\n    head += ']\\n>>\\nendobj\\n'\r\n    pdf += '\\ntrailer\\n<< /Root 1 0 R \\n /Size 0\\n >>startxref\\n\\n%%EOF\\n'\r\n    return head + pdf\r\n  }\r\n\r\n  /**\r\n   * 返回各子节点的包围盒\r\n   * @param opt 导出选项\r\n   * @returns 包围盒数组\r\n   */\r\n  boxes(opt: ExportOpt): Bbox[] {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    const bs: Bbox[] = []\r\n    for (let i = 0; i < this._tree.chld.length; i++) {\r\n      const { x, y, w, h } = this._tree.chld[i].bbox\r\n      bs.push({ x: px + x * sclx, y: py + y * scly, w: w * sclx, h: h * scly })\r\n    }\r\n    return bs\r\n  }\r\n\r\n  /**\r\n   * 返回整体包围盒\r\n   * @param opt 导出选项\r\n   * @returns 包围盒\r\n   */\r\n  box(opt: ExportOpt): Bbox {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    return {\r\n      x: px + this._tree.bbox.x * sclx,\r\n      y: py + this._tree.bbox.y * scly,\r\n      w: this._tree.bbox.w * sclx,\r\n      h: this._tree.bbox.h * scly\r\n    }\r\n  }\r\n}\r\n\r\n/** 内部实现集合，便于外部测试或调试 */\r\nconst _impl: Record<string, Function> = {\r\n  tokenize,\r\n  parse,\r\n  environments,\r\n  plan,\r\n  flatten,\r\n  render\r\n}\r\n\r\nexport { CONFIG, _impl }\r\n","import type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport type { ILatexElement } from './constants'\r\nimport { LaTexSVG, LaTexUtils } from './latex-utils'\r\n\r\n/** 默认缩放比例 */\r\nconst DEFAULT_SCALE = 1\r\n\r\n/** LaTeX 粒子渲染器，将 LaTeX 元素以 SVG 图片形式绘制到 canvas */\r\nexport class LaTexParticle {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 已加载图片缓存，避免重复加载 */\r\n  private imageCache: Map<string, HTMLImageElement> = new Map()\r\n  /** 正在加载的图片 Promise 集合 */\r\n  private pendingImages: Set<Promise<unknown>> = new Set()\r\n\r\n  /**\r\n   * 创建 LaTeX 粒子渲染器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n  }\r\n\r\n  /**\r\n   * 将 LaTeX 字符串转换为 SVG\r\n   * @param laTex LaTeX 字符串\r\n   * @returns SVG 结果\r\n   */\r\n  public static convertLaTextToSVG(laTex: string): LaTexSVG {\r\n    return new LaTexUtils(laTex).svg({\r\n      SCALE_X: 10,\r\n      SCALE_Y: 10,\r\n      MARGIN_X: 0,\r\n      MARGIN_Y: 0\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在 canvas 上渲染 LaTeX 元素\r\n   * @param ctx canvas 上下文\r\n   * @param element 元素\r\n   * @param x X 坐标\r\n   * @param y Y 坐标\r\n   */\r\n  public render(\r\n    ctx: CanvasRenderingContext2D,\r\n    element: IElement,\r\n    x: number,\r\n    y: number\r\n  ): void {\r\n    const { scale = DEFAULT_SCALE } = this.draw.getOptions() as { scale?: number }\r\n    const el = element as unknown as ILatexElement\r\n    const width = el.width * scale\r\n    const height = el.height * scale\r\n    if (this.imageCache.has(element.value)) {\r\n      const img = this.imageCache.get(element.value)!\r\n      ctx.drawImage(img, x, y, width, height)\r\n      return\r\n    }\r\n    const promise = new Promise<void>((resolve, reject) => {\r\n      const img = new Image()\r\n      img.src = el.laTexSVG\r\n      img.onload = () => {\r\n        ctx.drawImage(img, x, y, width, height)\r\n        this.imageCache.set(element.value, img)\r\n        resolve()\r\n      }\r\n      img.onerror = reject\r\n    })\r\n    this.pendingImages.add(promise)\r\n    promise.finally(() => this.pendingImages.delete(promise))\r\n  }\r\n\r\n  /**\r\n   * 等待所有正在加载的 LaTeX 图片完成\r\n   * @returns Promise\r\n   */\r\n  public awaitImages(): Promise<void> {\r\n    return Promise.all(this.pendingImages).then(() => undefined)\r\n  }\r\n\r\n  /** 销毁渲染器，清空缓存 */\r\n  public destroy(): void {\r\n    this.imageCache.clear()\r\n    this.pendingImages.clear()\r\n  }\r\n}\r\n","import type { IElement, IEditorOption, Path, ISearchResult, IReplaceOption, INavigateInfo } from '@vervedoc/docx-editor-schema'\r\nimport { walkTree, getByPath } from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport { TEXTLIKE_ELEMENT_TYPE } from './constants'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 commands 包 API 兼容\r\nexport type { ISearchResult, IReplaceOption, INavigateInfo } from '@vervedoc/docx-editor-schema'\r\n\r\n/**\r\n * 生成简易唯一 ID\r\n * @returns 唯一 ID 字符串\r\n */\r\nfunction getUUID(): string {\r\n  return `s-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`\r\n}\r\n\r\n/**\r\n * 判断值是否为数字\r\n * @param v 待判断值\r\n * @returns 是否为数字\r\n */\r\nfunction isNumber(v: unknown): v is number {\r\n  return typeof v === 'number'\r\n}\r\n\r\n/**\r\n * 文本类元素判定（可参与搜索）\r\n * @param el 元素\r\n * @returns 是否可搜索\r\n */\r\nfunction isSearchable(el: IElement): boolean {\r\n  return TEXTLIKE_ELEMENT_TYPE.has(el.type) && !!el.value\r\n}\r\n\r\n/** 搜索管理器，提供关键字搜索、高亮、导航与替换能力 */\r\nexport class Search {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 编辑器选项 */\r\n  private options: IEditorOption\r\n  /** 选区管理器 */\r\n  private range: RangeManager | null\r\n  /** 当前搜索关键字 */\r\n  private searchKeyword: string | null\r\n  /** 当前导航索引 */\r\n  private searchNavigateIndex: number | null\r\n  /** 匹配结果列表 */\r\n  private searchMatchList: ISearchResult[]\r\n\r\n  /**\r\n   * 创建搜索管理器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n    this.options = draw.getOptions()\r\n    this.range = draw.getRange()\r\n    this.searchNavigateIndex = null\r\n    this.searchKeyword = null\r\n    this.searchMatchList = []\r\n  }\r\n\r\n  /**\r\n   * 获取当前搜索关键字\r\n   * @returns 关键字或 null\r\n   */\r\n  public getSearchKeyword(): string | null {\r\n    return this.searchKeyword\r\n  }\r\n\r\n  /**\r\n   * 设置搜索关键字并重置导航索引\r\n   * @param payload 关键字\r\n   */\r\n  public setSearchKeyword(payload: string | null) {\r\n    this.searchKeyword = payload\r\n    this.searchNavigateIndex = null\r\n  }\r\n\r\n  /**\r\n   * 上一个匹配\r\n   * @returns 当前导航索引或 null\r\n   */\r\n  public searchNavigatePre(): number | null {\r\n    if (!this.searchMatchList.length || !this.searchKeyword) return null\r\n    if (this.searchNavigateIndex === null) {\r\n      this.searchNavigateIndex = 0\r\n    } else {\r\n      this.searchNavigateIndex = Math.max(0, this.searchNavigateIndex - 1)\r\n    }\r\n    this._applyNavigate()\r\n    return this.searchNavigateIndex\r\n  }\r\n\r\n  /**\r\n   * 下一个匹配\r\n   * @returns 当前导航索引或 null\r\n   */\r\n  public searchNavigateNext(): number | null {\r\n    if (!this.searchMatchList.length || !this.searchKeyword) return null\r\n    if (this.searchNavigateIndex === null) {\r\n      this.searchNavigateIndex = 0\r\n    } else {\r\n      this.searchNavigateIndex = Math.min(\r\n        this.searchMatchList.length - 1,\r\n        this.searchNavigateIndex + 1\r\n      )\r\n    }\r\n    this._applyNavigate()\r\n    return this.searchNavigateIndex\r\n  }\r\n\r\n  /**\r\n   * 将当前导航匹配定位到光标\r\n   */\r\n  private _applyNavigate(): void {\r\n    if (this.searchNavigateIndex === null) return\r\n    const match = this.searchMatchList[this.searchNavigateIndex]\r\n    if (!match || !this.range) return\r\n    this.range.setCaret({ path: match.path.slice() as Path, offset: match.offset })\r\n  }\r\n\r\n  /**\r\n   * 获取当前导航索引列表（用于高亮判定）\r\n   * @returns 导航索引数组\r\n   */\r\n  public getSearchNavigateIndexList(): number[] {\r\n    if (this.searchNavigateIndex === null || !this.searchKeyword) return []\r\n    return [this.searchNavigateIndex]\r\n  }\r\n\r\n  /**\r\n   * 获取搜索匹配结果列表\r\n   * @returns 匹配结果数组\r\n   */\r\n  public getSearchMatchList(): ISearchResult[] {\r\n    return this.searchMatchList\r\n  }\r\n\r\n  /**\r\n   * 获取搜索导航信息\r\n   * @returns 导航信息或 null\r\n   */\r\n  public getSearchNavigateInfo(): null | INavigateInfo {\r\n    if (!this.searchKeyword || !this.searchMatchList.length) return null\r\n    const index = this.searchNavigateIndex !== null ? this.searchNavigateIndex + 1 : 0\r\n    return {\r\n      index,\r\n      count: this.searchMatchList.length\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 在元素列表中搜索关键字，返回匹配列表。\r\n   * 基于 walkTree 遍历，在每个文本元素的 value 内进行匹配。\r\n   * @param payload 搜索关键字\r\n   * @param elementList 元素列表\r\n   * @returns 匹配结果数组\r\n   */\r\n  public getSearchMatchListByKeyword(\r\n    payload: string,\r\n    elementList: IElement[]\r\n  ): ISearchResult[] {\r\n    if (!payload) return []\r\n    const keyword = payload.toLocaleLowerCase()\r\n    const matchList: ISearchResult[] = []\r\n\r\n    walkTree(elementList, (node, ctx) => {\r\n      if (!isSearchable(node)) return\r\n      const text = node.value.toLocaleLowerCase()\r\n      let pos = text.indexOf(keyword)\r\n      while (pos !== -1) {\r\n        matchList.push({\r\n          path: ctx.path.slice() as Path,\r\n          offset: pos,\r\n          length: payload.length,\r\n          groupId: getUUID()\r\n        })\r\n        pos = text.indexOf(keyword, pos + keyword.length)\r\n      }\r\n    })\r\n\r\n    return matchList\r\n  }\r\n\r\n  /**\r\n   * 计算并缓存搜索匹配\r\n   * @param payload 搜索关键字\r\n   */\r\n  public computeSearchMatches(payload: string) {\r\n    this.searchMatchList = this.getSearchMatchListByKeyword(\r\n      payload,\r\n      this.draw.getElementList()\r\n    )\r\n  }\r\n\r\n  /**\r\n   * 绘制搜索高亮：从 verve layout 查找匹配元素的 inline 坐标。\r\n   * @param ctx canvas 上下文\r\n   * @param pageIndex 页码\r\n   */\r\n  public renderSearchHighlights(ctx: CanvasRenderingContext2D, pageIndex: number) {\r\n    if (!this.searchMatchList.length || !this.searchKeyword) return\r\n    const layout = (this.draw as any).getLayout?.()\r\n    if (!layout) return\r\n\r\n    const opts = this.options as any\r\n    const alpha = opts.searchMatchAlpha ?? 0.3\r\n    const matchColor = opts.searchMatchColor ?? '#ffe58f'\r\n    const navigateColor = opts.searchNavigateMatchColor ?? '#ff9c6e'\r\n    const navigateIndexList = this.getSearchNavigateIndexList()\r\n\r\n    ctx.save()\r\n    ctx.globalAlpha = alpha\r\n    for (let s = 0; s < this.searchMatchList.length; s++) {\r\n      const match = this.searchMatchList[s]\r\n      const rect = this._findMatchRect(layout, match)\r\n      if (!rect) continue\r\n      if (rect.pageNo !== pageIndex) continue\r\n      ctx.fillStyle = navigateIndexList.includes(s) ? navigateColor : matchColor\r\n      ctx.fillRect(rect.x, rect.y, rect.width, rect.height)\r\n    }\r\n    ctx.restore()\r\n  }\r\n\r\n  /**\r\n   * 在 layout 中查找匹配对应的矩形坐标\r\n   * @param layout 布局对象\r\n   * @param match 匹配结果\r\n   * @returns 矩形坐标或 null\r\n   */\r\n  private _findMatchRect(\r\n    layout: any,\r\n    match: ISearchResult\r\n  ): { x: number; y: number; width: number; height: number; pageNo: number } | null {\r\n    for (let p = 0; p < layout.pages.length; p++) {\r\n      const page = layout.pages[p]\r\n      const found = this._findInBlocks(page.blocks, page.contentRect.x, page.contentRect.y, p, match)\r\n      if (found) return found\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 在指定页块的子块中查找匹配矩形\r\n   * @param blocks 块列表\r\n   * @param originX 起始 X 偏移\r\n   * @param originY 起始 Y 偏移\r\n   * @param pageNo 页码\r\n   * @param match 匹配结果\r\n   * @returns 矩形坐标或 null\r\n   */\r\n  private _findInBlocks(\r\n    blocks: any[],\r\n    originX: number,\r\n    originY: number,\r\n    pageNo: number,\r\n    match: ISearchResult\r\n  ): { x: number; y: number; width: number; height: number; pageNo: number } | null {\r\n    for (const b of blocks) {\r\n      if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          for (const cell of row.cells) {\r\n            const cx = originX + b.rect.x + cell.rect.x + cell.contentPaddingLeft\r\n            const cy = originY + b.rect.y + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n            const found = this._findInBlocks(cell.content, cx, cy, pageNo, match)\r\n            if (found) return found\r\n          }\r\n        }\r\n        continue\r\n      }\r\n      if (b.kind !== 'paragraph') continue\r\n      const bx = originX + b.rect.x\r\n      const by = originY + b.rect.y\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          // 通过 inline 的 path 匹配\r\n          if (this._pathMatchesInline(inl, match)) {\r\n            return {\r\n              x: bx + inl.x,\r\n              y: by + line.y,\r\n              width: inl.width,\r\n              height: line.height,\r\n              pageNo\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 判断 inline 是否属于匹配的元素\r\n   * @param inl inline 对象\r\n   * @param match 匹配结果\r\n   * @returns 是否匹配\r\n   */\r\n  private _pathMatchesInline(inl: any, match: ISearchResult): boolean {\r\n    if (!inl.path) return false\r\n    const p = inl.path as Path\r\n    if (p.length !== match.path.length) return false\r\n    for (let i = 0; i < p.length; i++) {\r\n      if (p[i] !== match.path[i]) return false\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** 滚动到当前导航匹配的可视范围 */\r\n  public searchNavigateScrollIntoView() {\r\n    if (this.searchNavigateIndex === null) return\r\n    const match = this.searchMatchList[this.searchNavigateIndex]\r\n    if (!match) return\r\n    const layout = (this.draw as any).getLayout?.()\r\n    if (!layout) return\r\n    const rect = this._findMatchRect(layout, match)\r\n    if (!rect) return\r\n    const container = this.draw.getContainer()\r\n    const anchor = document.createElement('div')\r\n    anchor.style.position = 'absolute'\r\n    anchor.style.width = `${rect.width + 50}px`\r\n    anchor.style.height = `${rect.height + 50}px`\r\n    anchor.style.left = `${rect.x}px`\r\n    anchor.style.top = `${rect.y}px`\r\n    container.append(anchor)\r\n    anchor.scrollIntoView(false)\r\n    anchor.remove()\r\n  }\r\n\r\n  /**\r\n   * 替换匹配的关键词。\r\n   * 基于 verve 树模型：直接修改元素的 value，再 setDocument 刷新。\r\n   * @param payload 替换文本\r\n   * @param option 替换选项\r\n   */\r\n  public replaceSearchMatch(payload: string, option?: IReplaceOption) {\r\n    const isReadonly = (this.draw as any).isReadonly?.()\r\n    if (isReadonly) return\r\n    if (!payload) return\r\n\r\n    let matchList = this.getSearchMatchList()\r\n    const replaceIndex = option?.index\r\n    if (isNumber(replaceIndex)) {\r\n      matchList = [matchList[replaceIndex]].filter(Boolean)\r\n    }\r\n    if (!matchList.length) return\r\n\r\n    const elementList = this.draw.getElementList()\r\n    const keyword = this.searchKeyword!\r\n    let firstMatch: ISearchResult | null = null\r\n\r\n    for (const match of matchList) {\r\n      const element = getByPath(elementList, match.path)\r\n      if (!element || !element.value) continue\r\n      // 在 value 中替换关键词\r\n      const before = element.value\r\n      element.value = before.slice(0, match.offset) + payload + before.slice(match.offset + keyword.length)\r\n      if (!firstMatch) firstMatch = match\r\n    }\r\n\r\n    if (!firstMatch) return\r\n    // 定位到首个替换位置\r\n    if (this.range) {\r\n      this.range.setCaret({\r\n        path: firstMatch.path.slice() as Path,\r\n        offset: firstMatch.offset + payload.length\r\n      })\r\n    }\r\n    // 重新渲染\r\n    this.draw.setDocument(this.draw.getDocument())\r\n    // 重新计算匹配\r\n    this.computeSearchMatches(keyword)\r\n  }\r\n}\r\n","import type { IBlockElement } from './constants'\r\n\r\n/** 允许作为 iframe src 的协议白名单 */\r\nconst ALLOWED_SRC_PROTOCOLS = ['https:', 'http:']\r\n\r\n/**\r\n * 判断给定 URL 是否使用了允许的协议\r\n * @param url 待校验 URL\r\n * @returns 是否允许加载\r\n */\r\nfunction isAllowedSrc(url: string): boolean {\r\n  try {\r\n    const { protocol } = new URL(url, location.href)\r\n    return ALLOWED_SRC_PROTOCOLS.includes(protocol)\r\n  } catch {\r\n    return false\r\n  }\r\n}\r\n\r\n/** iframe 块组件，用于在文档中嵌入外部页面 */\r\nexport class IFrameBlock {\r\n  /** iframe sandbox 允许的能力，仅允许脚本执行 */\r\n  public static readonly sandbox = ['allow-scripts']\r\n  /** 关联的块元素 */\r\n  private element: IBlockElement\r\n\r\n  /**\r\n   * 创建 iframe 块实例\r\n   * @param element 块元素\r\n   */\r\n  constructor(element: IBlockElement) {\r\n    this.element = element\r\n  }\r\n\r\n  /**\r\n   * 在 iframe 的 window 上定义隔离属性，阻断 parent/top 访问\r\n   * @param iframeWindow iframe 的 contentWindow\r\n   */\r\n  private _defineIframeProperties(iframeWindow: Window) {\r\n    try {\r\n      Object.defineProperties(iframeWindow, {\r\n        parent: { get: () => null },\r\n        top: { get: () => null },\r\n        __POWERED_BY_CANVAS_EDITOR__: { get: () => true }\r\n      })\r\n    } catch {}\r\n  }\r\n\r\n  /**\r\n   * 渲染 iframe 到指定容器\r\n   * @param blockItemContainer 块项容器\r\n   */\r\n  public render(blockItemContainer: HTMLDivElement) {\r\n    const iframeBlock = this.element.block?.iframeBlock\r\n    const iframe = document.createElement('iframe')\r\n    iframe.setAttribute('data-id', this.element.id ?? '')\r\n    iframe.sandbox.add(...IFrameBlock.sandbox)\r\n    iframe.style.border = 'none'\r\n    iframe.style.width = '100%'\r\n    iframe.style.height = '100%'\r\n    if (iframeBlock?.src) {\r\n      if (!isAllowedSrc(iframeBlock.src)) return\r\n      iframe.src = iframeBlock.src\r\n    } else if (iframeBlock?.srcdoc) {\r\n      iframe.srcdoc = iframeBlock.srcdoc\r\n    }\r\n    iframe.addEventListener('load', () => {\r\n      const contentWindow = iframe.contentWindow\r\n      if (contentWindow) {\r\n        this._defineIframeProperties(contentWindow)\r\n      }\r\n    })\r\n    blockItemContainer.append(iframe)\r\n  }\r\n}\r\n","import { EDITOR_PREFIX, BlockType } from './constants'\r\nimport type { IBlockElement } from './constants'\r\nimport type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport { BlockParticle } from './block-particle'\r\nimport { IFrameBlock } from './block-iframe'\r\n\r\n/** 嵌入块基类，根据块类型分发到具体实现（iframe） */\r\nexport class BaseBlock {\r\n  /** 关联的块元素 */\r\n  private element: IElement\r\n  /** 具体块实现实例 */\r\n  private block: IFrameBlock | null\r\n  /** 块容器 */\r\n  private blockContainer: HTMLDivElement\r\n  /** 当前块项 DOM */\r\n  private blockItem: HTMLDivElement\r\n\r\n  constructor(blockParticle: BlockParticle, element: IElement) {\r\n    this.blockContainer = blockParticle.getBlockContainer()\r\n    this.element = element\r\n    this.block = null\r\n    this.blockItem = this._createBlockItem()\r\n    this.blockContainer.append(this.blockItem)\r\n  }\r\n\r\n  public getBlockElement(): IElement {\r\n    return this.element\r\n  }\r\n\r\n  private _createBlockItem(): HTMLDivElement {\r\n    const blockItem = document.createElement('div')\r\n    blockItem.classList.add(`${EDITOR_PREFIX}-block-item`)\r\n    return blockItem\r\n  }\r\n\r\n  public render() {\r\n    const el = this.element as IBlockElement\r\n    const block = el.block\r\n    if (!block) return\r\n    if (block.type === BlockType.IFRAME) {\r\n      this.block = new IFrameBlock(el)\r\n      this.block.render(this.blockItem)\r\n    }\r\n  }\r\n\r\n  public setClientRects(_pageNo: number, x: number, y: number) {\r\n    const metrics = (this.element as IBlockElement).metrics\r\n    if (metrics) {\r\n      this.blockItem.style.width = `${metrics.width}px`\r\n      this.blockItem.style.height = `${metrics.height}px`\r\n    }\r\n    this.blockItem.style.position = 'absolute'\r\n    this.blockItem.style.left = `${x}px`\r\n    this.blockItem.style.top = `${y}px`\r\n  }\r\n\r\n  public remove() {\r\n\r\n    this.blockItem.remove()\r\n  }\r\n}\r\n","import { EDITOR_PREFIX } from './constants'\r\n\r\nimport { walkTree } from '@vervedoc/docx-editor-schema'\r\nimport type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport { BaseBlock } from './block-base'\r\nimport './assets/css/block.css'\r\n\r\n/** 块粒子管理器，负责嵌入块元素的创建、缓存与清理 */\r\nexport class BlockParticle {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 编辑器容器 */\r\n  private container: HTMLDivElement\r\n  /** 块容器 */\r\n  private blockContainer: HTMLDivElement\r\n  /** 块实例缓存，按元素 id 索引 */\r\n  private blockMap: Map<string, BaseBlock>\r\n\r\n  /**\r\n   * 创建块粒子管理器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n    this.container = draw.getContainer()\r\n    this.blockMap = new Map()\r\n    this.blockContainer = this._createBlockContainer()\r\n    this.container.append(this.blockContainer)\r\n  }\r\n\r\n  /** 创建块容器 DOM 并设置基础样式 */\r\n  private _createBlockContainer(): HTMLDivElement {\r\n    const blockContainer = document.createElement('div')\r\n    blockContainer.classList.add(`${EDITOR_PREFIX}-block-container`)\r\n    blockContainer.style.position = 'absolute'\r\n    blockContainer.style.inset = '0'\r\n    blockContainer.style.pointerEvents = 'auto'\r\n    return blockContainer\r\n  }\r\n\r\n  /**\r\n   * 获取编辑器绘制实例\r\n   * @returns 绘制实例\r\n   */\r\n  public getDraw(): Draw {\r\n    return this.draw\r\n  }\r\n\r\n  /**\r\n   * 获取块容器\r\n   * @returns 块容器 DOM\r\n   */\r\n  public getBlockContainer(): HTMLDivElement {\r\n    return this.blockContainer\r\n  }\r\n\r\n  /**\r\n   * 渲染指定页的块元素，复用已存在实例\r\n   * @param pageNo 页码\r\n   * @param element 元素\r\n   * @param x X 坐标\r\n   * @param y Y 坐标\r\n   */\r\n  public render(pageNo: number, element: IElement, x: number, y: number) {\r\n    const id = (element as any).id\r\n    if (!id) return\r\n    const cacheBlock = this.blockMap.get(id)\r\n    if (cacheBlock) {\r\n      cacheBlock.setClientRects(pageNo, x, y)\r\n    } else {\r\n      const newBlock = new BaseBlock(this, element)\r\n      newBlock.render()\r\n      newBlock.setClientRects(pageNo, x, y)\r\n      this.blockMap.set(id, newBlock)\r\n    }\r\n  }\r\n\r\n  /** 清理已从文档中删除的块实例 */\r\n  public clear() {\r\n    if (!this.blockMap.size) return\r\n    const elementList = this.draw.getElementList()\r\n    const blockElementIds: string[] = []\r\n    walkTree(elementList, (node) => {\r\n      if (node.type === 'block') {\r\n        const id = (node as any).id\r\n        if (id) blockElementIds.push(id)\r\n      }\r\n    })\r\n    this.blockMap.forEach(block => {\r\n      const id = (block.getBlockElement() as any).id\r\n      if (id && !blockElementIds.includes(id)) {\r\n        block.remove()\r\n        this.blockMap.delete(id)\r\n      }\r\n    })\r\n  }\r\n\r\n  /** 销毁所有块实例并移除块容器 */\r\n  public destroy() {\r\n    this.blockMap.forEach(block => block.remove())\r\n    this.blockMap.clear()\r\n    this.blockContainer.remove()\r\n  }\r\n}\r\n","import type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport { walkTree } from '@vervedoc/docx-editor-schema'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport { EDITOR_PREFIX } from './constants'\r\n\r\n/**\r\n * 控件组件（checkbox / radio / text / select / date / number）挂载骨架。\r\n *\r\n * verve view 未提供 Control 系列类，此处提供统一挂载框架：\r\n * - install 时获取容器\r\n * - clear 在每帧渲染后清理已从文档中删除的控件 DOM\r\n * - render 在控件元素需要渲染时创建对应 DOM（具体控件 UI 待实现）\r\n */\r\nexport class ControlComponent {\r\n  private draw: Draw | null = null\r\n  private container: HTMLDivElement | null = null\r\n  private controlMap: Map<string, HTMLElement> = new Map()\r\n\r\n  public install(draw: Draw): this {\r\n    this.draw = draw\r\n    this.container = draw.getContainer()\r\n    this._createControlContainer()\r\n    return this\r\n  }\r\n\r\n  private _createControlContainer(): HTMLDivElement {\r\n    const controlContainer = document.createElement('div')\r\n    controlContainer.classList.add(`${EDITOR_PREFIX}-control-container`)\r\n    controlContainer.style.position = 'absolute'\r\n    controlContainer.style.inset = '0'\r\n    controlContainer.style.pointerEvents = 'auto'\r\n    this.container?.append(controlContainer)\r\n    return controlContainer\r\n  }\r\n\r\n  /**\r\n   * 渲染单个控件元素（具体控件 UI 待实现）。\r\n   * 由外部渲染流程在遇到 control 类型元素时调用。\r\n   */\r\n  public render(element: IElement, x: number, y: number): void {\r\n    if (!this.draw) return\r\n    const id = (element as { id?: string }).id\r\n    if (!id) return\r\n    // TODO: 根据 element.type（checkbox/radio/text/select/date/number）创建对应控件 DOM\r\n    void x\r\n    void y\r\n  }\r\n\r\n  /** 每帧渲染后清理已从文档中删除的控件 DOM */\r\n  public clear(): void {\r\n    if (!this.controlMap.size || !this.draw) return\r\n    const elementList = this.draw.getElementList()\r\n    const controlIds: string[] = []\r\n    walkTree(elementList, (node) => {\r\n      if (node.type === 'control') {\r\n        const id = (node as { id?: string }).id\r\n        if (id) controlIds.push(id)\r\n      }\r\n    })\r\n    this.controlMap.forEach((el, id) => {\r\n      if (!controlIds.includes(id)) {\r\n        el.remove()\r\n        this.controlMap.delete(id)\r\n      }\r\n    })\r\n  }\r\n\r\n  public destroy(): void {\r\n    this.controlMap.forEach(el => el.remove())\r\n    this.controlMap.clear()\r\n    this.draw = null\r\n    this.container = null\r\n  }\r\n}\r\n","/**\r\n * VerveDocs History —— HistoryManager\r\n *\r\n * 基于整树快照的撤销/重做管理器。\r\n * 使用 rfdc（经 schema cloneTree）深拷贝文档树，配合 coalescing 合并连续同类编辑。\r\n */\r\n\r\nimport type { IDocxDocumentMeta, IRange, HistorySnapshot } from '@vervedoc/docx-editor-schema'\r\nimport { cloneTree } from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 history 包 API 兼容\r\nexport type { HistorySnapshot } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 默认最大历史记录数 */\r\nconst DEFAULT_MAX_RECORD_COUNT = 50\r\n/** 默认合并时间窗（毫秒） */\r\nconst DEFAULT_COALESCE_MS = 300\r\n\r\n/** 基于整树快照的撤销/重做管理器 */\r\nexport class HistoryManager {\r\n  /** 撤销栈 */\r\n  private _undoStack: HistorySnapshot[] = []\r\n  /** 重做栈 */\r\n  private _redoStack: HistorySnapshot[] = []\r\n  /** 最大记录数 */\r\n  private _maxRecordCount: number\r\n  /** 合并时间窗（毫秒） */\r\n  private _coalesceMs: number\r\n  /** 上次提交时间戳 */\r\n  private _lastPushTime = 0\r\n  /** 上次合并键 */\r\n  private _lastCoalesceKey: string | undefined = undefined\r\n  /** 是否正在执行撤销/重做 */\r\n  private _isExecuting = false\r\n\r\n  /**\r\n   * 构造历史管理器\r\n   * @param options 配置选项，包含最大记录数与合并时间窗\r\n   */\r\n  constructor(options?: { maxRecordCount?: number; coalesceMs?: number }) {\r\n    this._maxRecordCount = options?.maxRecordCount ?? DEFAULT_MAX_RECORD_COUNT\r\n    this._coalesceMs = options?.coalesceMs ?? DEFAULT_COALESCE_MS\r\n  }\r\n\r\n  /**\r\n   * 初始化首快照（编辑器就绪后调用一次）\r\n   * @param snapshot 初始快照\r\n   * @returns 无返回值\r\n   */\r\n  pushInitial(snapshot: HistorySnapshot): void {\r\n    this._undoStack = [snapshot]\r\n    this._redoStack = []\r\n    this._lastPushTime = Date.now()\r\n    this._lastCoalesceKey = undefined\r\n  }\r\n\r\n  /**\r\n   * 提交一次编辑后的快照。\r\n   * coalesceKey 传入时：若与上次相同且在时间窗内，则替换栈顶（合并连续同类编辑）。\r\n   * @param snapshot 编辑后的快照\r\n   * @param coalesceKey 合并键，用于合并连续同类编辑\r\n   * @returns 无返回值\r\n   */\r\n  push(snapshot: HistorySnapshot, coalesceKey?: string): void {\r\n    if (this._isExecuting) return\r\n    const now = Date.now()\r\n    if (\r\n      coalesceKey !== undefined &&\r\n      coalesceKey === this._lastCoalesceKey &&\r\n      now - this._lastPushTime < this._coalesceMs &&\r\n      this._undoStack.length > 0\r\n    ) {\r\n      this._undoStack[this._undoStack.length - 1] = snapshot\r\n      this._redoStack = []\r\n      this._lastPushTime = now\r\n      return\r\n    }\r\n    this._undoStack.push(snapshot)\r\n    this._redoStack = []\r\n    this._lastPushTime = now\r\n    this._lastCoalesceKey = coalesceKey\r\n    while (this._undoStack.length > this._maxRecordCount) {\r\n      this._undoStack.shift()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 撤销：返回要恢复的快照，current 被压入 redo 栈\r\n   * @param current 当前快照\r\n   * @returns 要恢复的快照，无法撤销时返回 null\r\n   */\r\n  undo(current: HistorySnapshot): HistorySnapshot | null {\r\n    if (this._isExecuting) return null\r\n    if (this._undoStack.length <= 1) return null\r\n    this._isExecuting = true\r\n    try {\r\n      this._redoStack.push(current)\r\n      this._undoStack.pop()\r\n      this._lastCoalesceKey = undefined\r\n      return this._undoStack[this._undoStack.length - 1] ?? null\r\n    } finally {\r\n      this._isExecuting = false\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 重做：将恢复的快照压入 undo 栈并返回\r\n   * @param _current 当前快照（保留接口兼容）\r\n   * @returns 要恢复的快照，无法重做时返回 null\r\n   */\r\n  redo(_current: HistorySnapshot): HistorySnapshot | null {\r\n    if (this._isExecuting) return null\r\n    if (this._redoStack.length === 0) return null\r\n    this._isExecuting = true\r\n    try {\r\n      const next = this._redoStack.pop()!\r\n      this._undoStack.push(next)\r\n      this._lastPushTime = Date.now()\r\n      this._lastCoalesceKey = undefined\r\n      return next\r\n    } finally {\r\n      this._isExecuting = false\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 是否可撤销\r\n   * @returns 可撤销时返回 true\r\n   */\r\n  canUndo(): boolean { return this._undoStack.length > 1 }\r\n\r\n  /**\r\n   * 是否可重做\r\n   * @returns 可重做时返回 true\r\n   */\r\n  canRedo(): boolean { return this._redoStack.length > 0 }\r\n\r\n  /**\r\n   * 历史栈是否为空\r\n   * @returns 撤销栈与重做栈均空时返回 true\r\n   */\r\n  isStackEmpty(): boolean { return this._undoStack.length <= 1 && this._redoStack.length === 0 }\r\n\r\n  /**\r\n   * 清空所有历史记录\r\n   * @returns 无返回值\r\n   */\r\n  clear(): void {\r\n    this._undoStack = []\r\n    this._redoStack = []\r\n    this._lastCoalesceKey = undefined\r\n  }\r\n\r\n  /**\r\n   * 销毁管理器，清空历史记录\r\n   * @returns 无返回值\r\n   */\r\n  destroy(): void { this.clear() }\r\n}\r\n\r\n/**\r\n * 工具：从文档 + range 创建快照（深拷贝 doc，浅拷贝 range）\r\n * @param doc 文档元数据\r\n * @param range 选区范围\r\n * @returns 创建的快照\r\n */\r\nexport function createSnapshot(doc: IDocxDocumentMeta, range: IRange | null): HistorySnapshot {\r\n  return {\r\n    doc: cloneTree(doc),\r\n    range: range ? { anchor: range.anchor, focus: range.focus } : null\r\n  }\r\n}\r\n","/**\r\n * VerveDocs History —— HistoryComponent\r\n *\r\n * 轻载器：创建 HistoryManager 实例，由 core 注入 CommandAdapt。\r\n */\r\n\r\nimport { HistoryManager } from './history-manager'\r\n\r\nexport class HistoryComponent {\r\n  /** 历史管理器实例 */\r\n  private _historyManager: HistoryManager | null = null\r\n\r\n  /**\r\n   * 安装历史组件，创建 HistoryManager 实例\r\n   * @param options 配置选项，包含最大记录数与合并时间窗\r\n   * @returns 创建的 HistoryManager 实例\r\n   */\r\n  public install(options?: { maxRecordCount?: number; coalesceMs?: number }): HistoryManager {\r\n    this._historyManager = new HistoryManager(options)\r\n    return this._historyManager\r\n  }\r\n\r\n  /**\r\n   * 获取历史管理器实例\r\n   * @returns 当前的 HistoryManager 实例，未安装时返回 null\r\n   */\r\n  public getHistoryManager(): HistoryManager | null {\r\n    return this._historyManager\r\n  }\r\n\r\n  /**\r\n   * 销毁历史组件，释放资源\r\n   * @returns 无返回值\r\n   */\r\n  public destroy(): void {\r\n    this._historyManager?.destroy()\r\n    this._historyManager = null\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Core —— 快捷键处理\r\n *\r\n * 从 docx-editor.ts 抽离的键盘快捷键逻辑，分四组：\r\n *  - 编辑键：复制/剪切/粘贴/全选/删除/Enter/Tab/Escape\r\n *  - 光标键：方向键/Home/End/PageUp/PageDown（含 Ctrl 词移动/文档首尾）\r\n *  - 格式键：加粗/斜体/下划线/删除线/字号/对齐/列表/标题/清除格式\r\n *  - 历史键：撤销/重做/分页\r\n */\r\n\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport type { Command, CommandAdapt } from '@vervedoc/docx-editor-transform'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport { ROW_FLEX, LIST_TYPE, LIST_STYLE, TITLE_LEVEL } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 快捷键处理器依赖注入接口 */\r\nexport interface ShortcutDeps {\r\n  /** 获取 Draw 视图实例 */\r\n  getDraw: () => Draw\r\n  /** 获取 Command 命令实例 */\r\n  getCommand: () => Command\r\n  dispatchCommand: (command: string, ...args: any[]) => any\r\n  /** 获取 RangeManager 选区管理器 */\r\n  getRange: () => RangeManager\r\n  /** 获取 CommandAdapt 适配器（可能未初始化） */\r\n  getAdapt: () => CommandAdapt | null\r\n}\r\n\r\n/** 键盘快捷键处理器，分编辑/光标/格式/历史四组 */\r\nexport class ShortcutHandler {\r\n  /** 依赖注入 */\r\n  private deps: ShortcutDeps\r\n\r\n  /**\r\n   * 构造快捷键处理器\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(deps: ShortcutDeps) {\r\n    this.deps = deps\r\n  }\r\n\r\n  /**\r\n   * 处理键盘事件，依次尝试编辑/光标/格式/历史四组快捷键\r\n   * @param e 键盘事件\r\n   */\r\n  handle = (e: KeyboardEvent): void => {\r\n    const adapt = this.deps.getAdapt()\r\n    if (!adapt) return\r\n    const draw = this.deps.getDraw()\r\n    const command = this.deps.getCommand()\r\n\r\n    if (this.handleEditKeys(e, adapt, draw)) return\r\n    if (this.handleCursorKeys(e, adapt, draw)) return\r\n    if (this.handleFormatKeys(e, command)) return\r\n    if (this.handleHistoryKeys(e, command)) return\r\n  }\r\n\r\n  /**\r\n   * 处理编辑类快捷键（复制/剪切/粘贴/全选/删除/Enter/Tab/Escape）\r\n   * @param e 键盘事件\r\n   * @param adapt 命令适配器\r\n   * @param draw 视图实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleEditKeys(e: KeyboardEvent, adapt: CommandAdapt, draw: Draw): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n\r\n    const clipboardCommand = { c: 'executeCopy', x: 'executeCut', v: 'executePaste' }[e.key.toLowerCase()]\r\n    if (mod && !e.altKey && !e.shiftKey && clipboardCommand) {\r\n      e.preventDefault()\r\n      this.deps.dispatchCommand(clipboardCommand)\r\n      return true\r\n    }\r\n    if (mod && e.key === 'a') {\r\n      e.preventDefault()\r\n      draw.selectAll()\r\n      return true\r\n    }\r\n    if (e.key === 'Backspace') { e.preventDefault(); adapt.deleteBackward(); return true }\r\n    if (e.key === 'Delete')    { e.preventDefault(); adapt.deleteForward(); return true }\r\n    if (e.key === 'Enter')     { e.preventDefault(); adapt.splitParagraph(); return true }\r\n    if (e.key === 'Tab')       { e.preventDefault(); adapt.insertText('\\t'); return true }\r\n    if (e.key === 'Escape')    { e.preventDefault(); this.deps.getRange().collapseToStart(); return true }\r\n\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理光标移动快捷键（方向键/Home/End/PageUp/PageDown，含 Ctrl 词移动/文档首尾）\r\n   * @param e 键盘事件\r\n   * @param adapt 命令适配器\r\n   * @param draw 视图实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleCursorKeys(e: KeyboardEvent, adapt: CommandAdapt, draw: Draw): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n\r\n    if (e.key === 'ArrowLeft') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretWordLeft()\r\n      else adapt.moveCaretLeft()\r\n      return true\r\n    }\r\n    if (e.key === 'ArrowRight') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretWordRight()\r\n      else adapt.moveCaretRight()\r\n      return true\r\n    }\r\n    if (e.key === 'ArrowUp')   { e.preventDefault(); draw.moveCaretUp(); return true }\r\n    if (e.key === 'ArrowDown') { e.preventDefault(); draw.moveCaretDown(); return true }\r\n    if (e.key === 'Home') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretToDocStart()\r\n      else draw.moveCaretToLineStart()\r\n      return true\r\n    }\r\n    if (e.key === 'End') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretToDocEnd()\r\n      else draw.moveCaretToLineEnd()\r\n      return true\r\n    }\r\n    if (e.key === 'PageUp')   { e.preventDefault(); for (let i = 0; i < 10; i++) draw.moveCaretUp(); return true }\r\n    if (e.key === 'PageDown') { e.preventDefault(); for (let i = 0; i < 10; i++) draw.moveCaretDown(); return true }\r\n\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理格式快捷键（加粗/斜体/下划线/删除线/字号/对齐/列表/标题/清除格式）\r\n   * @param e 键盘事件\r\n   * @param command 命令实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleFormatKeys(e: KeyboardEvent, command: Command): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n    if (!mod) return false\r\n    const k = e.key.toLowerCase()\r\n\r\n    if (!e.shiftKey && !e.altKey) {\r\n      if (k === 'b') { e.preventDefault(); command.executeSetBold(); return true }\r\n      if (k === 'i') { e.preventDefault(); command.executeSetItalic(); return true }\r\n      if (k === 'u') { e.preventDefault(); command.executeSetUnderline(); return true }\r\n      if (k === '\\\\') { e.preventDefault(); command.executeClearFormat(); return true }\r\n      if (k === '[') { e.preventDefault(); command.executeSizeMinus(); return true }\r\n      if (k === ']') { e.preventDefault(); command.executeSizeAdd(); return true }\r\n      if (k === 'l') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.LEFT); return true }\r\n      if (k === 'e') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.CENTER); return true }\r\n      if (k === 'r') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.RIGHT); return true }\r\n      if (k === 'j') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.JUSTIFY); return true }\r\n    }\r\n\r\n    if (e.shiftKey && !e.altKey) {\r\n      if (k === 'x') { e.preventDefault(); command.executeSetStrikeout(); return true }\r\n      if (k === 'j') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.DISTRIBUTE); return true }\r\n      if (k === 'i') { e.preventDefault(); command.executeSetList(LIST_TYPE.UL, LIST_STYLE.DISC); return true }\r\n      if (k === 'u') { e.preventDefault(); command.executeSetList(LIST_TYPE.OL, LIST_STYLE.DECIMAL); return true }\r\n    }\r\n\r\n    if (e.altKey && !e.shiftKey) {\r\n      if (k === '0') { e.preventDefault(); command.executeSetTitle(null); return true }\r\n      if (k === '1') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.FIRST); return true }\r\n      if (k === '2') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.SECOND); return true }\r\n      if (k === '3') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.THIRD); return true }\r\n      if (k === '4') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.FOURTH); return true }\r\n      if (k === '5') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.FIFTH); return true }\r\n      if (k === '6') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.SIXTH); return true }\r\n    }\r\n\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理历史快捷键（撤销/重做/分页）\r\n   * @param e 键盘事件\r\n   * @param command 命令实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleHistoryKeys(e: KeyboardEvent, command: Command): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n    if (!mod) return false\r\n    const k = e.key.toLowerCase()\r\n\r\n    if (!e.shiftKey && k === 'z') { e.preventDefault(); command.executeUndo(); return true }\r\n    if ((e.shiftKey && k === 'z') || (!e.shiftKey && k === 'y')) { e.preventDefault(); command.executeRedo(); return true }\r\n    if (k === 'enter') { e.preventDefault(); command.executePageBreak(); return true }\r\n\r\n    return false\r\n  }\r\n}\r\n","import { walkTree } from '@vervedoc/docx-editor-schema'\r\nimport type { IElement, ITitleElement, ITextElement, PathSegment } from '@vervedoc/docx-editor-schema'\r\n\r\nconst levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\r\n\r\nexport function computeToc(elements: IElement[]) {\r\n  const toc: { id: string; level: number; name: string; number?: string }[] = []\r\n  const counters = new Map<string, number>()\r\n  walkTree(elements, (node, ctx) => {\r\n    if (node.type !== 'title') return\r\n    const t = node as ITitleElement\r\n    const name = (t.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\r\n    const level = levelMap[t.level] ?? 1\r\n    let number: string | undefined\r\n    const num = (t as unknown as { listNumbering?: { numFmt: string; lvlText: string; start: number; numId?: string; abstractNumId?: string; level?: number } }).listNumbering\r\n    if (num && num.numFmt !== 'bullet') {\r\n      const numId = num.numId ?? num.abstractNumId ?? 'default'\r\n      const numLevel = num.level ?? 0\r\n      const key = `${numId}:${numLevel}`\r\n      const prev = counters.get(key)\r\n      const current = (prev == null ? (num.start ?? 1) - 1 : prev) + 1\r\n      counters.set(key, current)\r\n      for (const k of counters.keys()) {\r\n        if (k.startsWith(`${numId}:`) && Number(k.slice(numId.length + 1)) > numLevel) counters.delete(k)\r\n      }\r\n      number = (num.lvlText ?? '%1.').replace(/%([1-9])/g, (_, d: string) => {\r\n        const lvl = Number(d) - 1\r\n        return String(lvl === numLevel ? current : counters.get(`${numId}:${lvl}`) ?? (num.start ?? 1))\r\n      })\r\n    }\r\n    toc.push({ id: JSON.stringify(ctx.path), level, name, number })\r\n  })\r\n  return { toc }\r\n}\r\n\r\nexport function computeSearch(elements: IElement[], keyword: string) {\r\n  const results: { path: PathSegment[]; offset: number; length: number }[] = []\r\n  if (!keyword) return { results, count: 0 }\r\n  const lowerKeyword = keyword.toLowerCase()\r\n  walkTree(elements, (node, ctx) => {\r\n    if (node.type !== 'text') return\r\n    const text = ((node as ITextElement).value || '').toLowerCase()\r\n    let idx = text.indexOf(lowerKeyword)\r\n    while (idx !== -1) {\r\n      results.push({ path: [...ctx.path], offset: idx, length: keyword.length })\r\n      idx = text.indexOf(lowerKeyword, idx + 1)\r\n    }\r\n  })\r\n  return { results, count: results.length }\r\n}\r\n","import type { IElement, PathSegment } from '@vervedoc/docx-editor-schema'\r\nimport { cloneTree } from '@vervedoc/docx-editor-schema'\r\nimport { computeToc, computeSearch } from './compute'\r\n\r\nexport interface TocResult {\r\n  toc: { id: string; level: number; name: string; number?: string }[]\r\n}\r\nexport interface SearchResult {\r\n  results: { path: PathSegment[]; offset: number; length: number }[]\r\n  count: number\r\n}\r\ntype TocListener = (result: TocResult) => void\r\ntype SearchListener = (result: SearchResult) => void\r\ntype CloneListener = (data: unknown) => void\r\ntype ErrorListener = (message: string) => void\r\n\r\nexport class WorkerManager {\r\n  private worker: Worker | null = null\r\n  private failed = false\r\n  private destroyed = false\r\n  private pending = false\r\n  private elements: IElement[] = []\r\n  private tocListeners = new Set<TocListener>()\r\n  private searchListeners = new Set<SearchListener>()\r\n  private cloneListeners = new Set<CloneListener>()\r\n  private errorListeners = new Set<ErrorListener>()\r\n\r\n  init(): void {\r\n    if (this.worker || this.failed || this.destroyed) return\r\n    try {\r\n      this.worker = new Worker(new URL('./editor-worker.ts', import.meta.url), { type: 'module' })\r\n      this.worker.onmessage = (e: MessageEvent) => {\r\n        const msg = e.data\r\n        switch (msg.type) {\r\n          case 'toc-result': this.tocListeners.forEach(fn => fn({ toc: msg.toc })); break\r\n          case 'search-result': this.searchListeners.forEach(fn => fn({ results: msg.results, count: msg.count })); break\r\n          case 'clone-result': this.cloneListeners.forEach(fn => fn(msg.data)); break\r\n          case 'error': this.fallback(msg.message); break\r\n        }\r\n      }\r\n      this.worker.onerror = e => this.fallback(e.message)\r\n      this.worker.onmessageerror = () => this.fallback('Worker message could not be decoded')\r\n    } catch (error) {\r\n      this.failed = true\r\n      this.errorListeners.forEach(fn => fn(String(error)))\r\n    }\r\n  }\r\n\r\n  private fallback(message: string): void {\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    this.failed = true\r\n    this.errorListeners.forEach(fn => fn(message))\r\n    const result = computeToc(this.elements)\r\n    this.tocListeners.forEach(fn => fn(result))\r\n  }\r\n\r\n  updateElements(elements: IElement[]): void {\r\n    if (this.destroyed) return\r\n    this.elements = elements\r\n    if (this.pending) return\r\n    this.pending = true\r\n    queueMicrotask(() => this.flush())\r\n  }\r\n\r\n  private flush(): void {\r\n    if (!this.pending || this.destroyed) return\r\n    this.pending = false\r\n    this.init()\r\n    if (this.worker) {\r\n      try { this.worker.postMessage({ type: 'update', elements: this.elements }) }\r\n      catch (error) { this.fallback(String(error)) }\r\n    } else {\r\n      const result = computeToc(this.elements)\r\n      this.tocListeners.forEach(fn => fn(result))\r\n    }\r\n  }\r\n\r\n  search(keyword: string): void {\r\n    if (this.destroyed) return\r\n    this.flush()\r\n    this.init()\r\n    if (this.worker) {\r\n      try { this.worker.postMessage({ type: 'search', keyword }); return }\r\n      catch (error) { this.fallback(String(error)) }\r\n    }\r\n    const result = computeSearch(this.elements, keyword)\r\n    this.searchListeners.forEach(fn => fn(result))\r\n  }\r\n\r\n  clone(data: unknown): void {\r\n    if (this.destroyed) return\r\n    this.init()\r\n    if (this.worker) {\r\n      try { this.worker.postMessage({ type: 'clone', data }); return }\r\n      catch (error) { this.fallback(String(error)) }\r\n    }\r\n    const result = cloneTree(data)\r\n    this.cloneListeners.forEach(fn => fn(result))\r\n  }\r\n\r\n  onTocResult(listener: TocListener): () => void {\r\n    this.tocListeners.add(listener)\r\n    return () => this.tocListeners.delete(listener)\r\n  }\r\n  onSearchResult(listener: SearchListener): () => void {\r\n    this.searchListeners.add(listener)\r\n    return () => this.searchListeners.delete(listener)\r\n  }\r\n  onCloneResult(listener: CloneListener): () => void {\r\n    this.cloneListeners.add(listener)\r\n    return () => this.cloneListeners.delete(listener)\r\n  }\r\n  onError(listener: ErrorListener): () => void {\r\n    this.errorListeners.add(listener)\r\n    return () => this.errorListeners.delete(listener)\r\n  }\r\n  destroy(): void {\r\n    this.destroyed = true\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    this.elements = []\r\n    this.tocListeners.clear()\r\n    this.searchListeners.clear()\r\n    this.cloneListeners.clear()\r\n    this.errorListeners.clear()\r\n  }\r\n}\r\n","/** Background composition is isolated from document search/TOC work. */\r\nexport class ThumbnailManager {\r\n  private worker: Worker | null = null\r\n  private epoch = 0\r\n  private sources: string[] = []\r\n  private color = ''\r\n  private scheduled = false\r\n  private sourcesDirty = false\r\n  private disposed = false\r\n  private failed = false\r\n  private invalidated = false\r\n\r\n  constructor(private publish: (images: string[]) => void) {}\r\n\r\n  invalidate(): void {\r\n    this.epoch++\r\n    this.color = ''\r\n    this.invalidated = true\r\n  }\r\n\r\n  update(sources: string[], color: string): void {\r\n    if (this.disposed || this.failed) return\r\n    this.invalidated = false\r\n    const changed = sources.length !== this.sources.length || sources.some((value, i) => value !== this.sources[i])\r\n    if (!changed && color === this.color) return\r\n    this.sources = sources\r\n    this.color = color\r\n    this.sourcesDirty ||= changed\r\n    this.epoch++\r\n    if (this.scheduled) return\r\n    this.scheduled = true\r\n    queueMicrotask(() => this.flush())\r\n  }\r\n\r\n  private flush(): void {\r\n    this.scheduled = false\r\n    if (this.disposed || this.failed || this.invalidated) return\r\n    try {\r\n      if (!this.worker) {\r\n        this.worker = new Worker(new URL('./thumbnail-worker.ts', import.meta.url), { type: 'module' })\r\n        this.worker.onmessage = (event: MessageEvent<{ id: number; images?: string[]; error?: string }>) => {\r\n          if (this.disposed || event.data.id !== this.epoch) return\r\n          if (event.data.error) { this.fail(event.data.error); return }\r\n          if (event.data.images) this.publish(event.data.images)\r\n        }\r\n        this.worker.onerror = event => this.fail(event.message)\r\n        this.worker.onmessageerror = () => this.fail('Thumbnail worker message could not be decoded')\r\n      }\r\n      this.worker.postMessage({\r\n        id: this.epoch, color: this.color,\r\n        ...(this.sourcesDirty ? { sources: this.sources } : {})\r\n      })\r\n      this.sourcesDirty = false\r\n    } catch (error) {\r\n      this.fail(String(error))\r\n    }\r\n  }\r\n\r\n  private fail(message: string): void {\r\n    this.failed = true\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    // Keep existing previews rather than falling back to blocking page rendering.\r\n    console.warn('[VerveDocs] Background thumbnails unavailable:', message)\r\n  }\r\n\r\n  destroy(): void {\r\n    this.disposed = true\r\n    this.epoch++\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    this.sources = []\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Core —— DocxEditor\r\n *\r\n * 全新构造，零兼容：只接受 IDocxDocumentMeta。\r\n */\r\n\r\nimport { createEditorI18n, type EditorI18n, type BuiltinLocale } from '@vervedoc/i18n'\r\nimport type { IDocxDocumentMeta, IEditorOption, EditorPlugin, PluginHost } from '@vervedoc/docx-editor-schema'\r\nimport { cloneTree, formatElementTree, mergeOption } from '@vervedoc/docx-editor-schema'\r\nimport { EventBus, Listener, RangeManager } from '@vervedoc/docx-editor-state'\r\nimport { Draw } from '@vervedoc/docx-editor-view'\r\nimport { CommandChain } from './command-chain'\r\nimport { Command, CommandAdapt } from '@vervedoc/docx-editor-transform'\r\nimport { Search, BlockParticle, DateParticle, LaTexParticle, ControlComponent } from '@vervedoc/docx-editor-commands'\r\nimport { HistoryComponent } from '@vervedoc/docx-editor-history'\r\nimport { ShortcutHandler } from './shortcut'\r\nimport { WorkerManager } from './workers/worker-manager'\r\nimport { ThumbnailManager } from './workers/thumbnail-manager'\r\n\r\n/**\r\n * DocxEditor 文档编辑器主类\r\n *\r\n * 全新构造，零兼容：只接受 IDocxDocumentMeta。\r\n * 组合 Listener / EventBus / RangeManager / Draw / Command / Comment / Revision / Search 等组件。\r\n */\r\nexport class DocxEditor {\r\n  private readonly i18n: EditorI18n\r\n  /** 事件监听器（content/range/page/catalog 等命名空间） */\r\n  public listener: Listener\r\n  /** 全局事件总线（hyperlinkMenuClick / chartClick 等右键菜单事件） */\r\n  public eventBus: EventBus\r\n  /** 选区管理器（anchor/focus 位置与折叠/展开） */\r\n  public range: RangeManager\r\n  /** 视图绘制引擎（布局 + Canvas 渲染 + 交互） */\r\n  public draw: Draw\r\n  /** 命令入口（executeXxx 系列方法） */\r\n  public command: Command\r\n  private adapt: CommandAdapt\r\n  private destroyed = false\r\n  private clipboardEpoch = 0\r\n\r\n  private clipboardGuard(): () => boolean {\r\n    const doc = this.draw.getDocument()\r\n    const epoch = this.clipboardEpoch\r\n    const zone = this.draw.getZone()\r\n    const range = JSON.stringify(this.range.getRange())\r\n    return () => !this.destroyed && epoch === this.clipboardEpoch &&\r\n      doc === this.draw.getDocument() && zone === this.draw.getZone() &&\r\n      range === JSON.stringify(this.range.getRange())\r\n  }\r\n  /** 已注册插件表（按 name 索引） */\r\n  private plugins = new Map<string, EditorPlugin>()\r\n  /** 插件命令注册表（命令名 → 处理函数），责任链中插件命令 handler 查此表分发 */\r\n  private pluginCommands = new Map<string, (...args: any[]) => any>()\r\n  /** 命令分发责任链 */\r\n  private commandChain = new CommandChain()\r\n  /** 插件宿主契约实例，构造完成后赋值，use(plugin) 时注入给插件 */\r\n  private pluginHost: PluginHost | null = null\r\n  /** 搜索组件 */\r\n  public search: Search\r\n  /** 块级粒子组件（图片/视频/音频/图表等块级元素） */\r\n  public block: BlockParticle\r\n  /** 日期粒子组件 */\r\n  public date: DateParticle\r\n  /** LaTeX 公式粒子组件 */\r\n  public laTex: LaTexParticle\r\n  /** 控件组件（checkbox/radio/dropdown 等） */\r\n  public control: ControlComponent\r\n  /** 历史管理组件（撤销/重做） */\r\n  public history: HistoryComponent\r\n\r\n  /** Worker 管理器（后台计算目录/搜索等） */\r\n  public worker: WorkerManager\r\n  private thumbnailWorker: ThumbnailManager\r\n  private thumbnailSources: string[] = []\r\n\r\n\r\n  /**\r\n   * 构造 DocxEditor 实例\r\n   * @param container 编辑器挂载的 DOM 容器（必须为 HTMLDivElement）\r\n   * @param document 文档元数据（必须包含 elements 数组，不再兼容 IElement[] / IEditorData）\r\n   * @param options 编辑器选项（字体/字号/页边距等，缺省时自动合并默认值）\r\n   * @throws {TypeError} container 非 HTMLDivElement 或 document 非 IDocxDocumentMeta 时抛出\r\n   */\r\n  constructor(\r\n    container: HTMLDivElement,\r\n    document: IDocxDocumentMeta,\r\n    options: IEditorOption = {}\r\n  ) {\r\n    if (!container || !(container instanceof HTMLDivElement)) {\r\n      throw new TypeError('[DocxEditor] container 必须是 HTMLDivElement')\r\n    }\r\n    if (!document || typeof document !== 'object' || !Array.isArray(document.elements)) {\r\n      throw new TypeError(\r\n        '[DocxEditor] document 必须是 IDocxDocumentMeta，且 elements 为数组。不再兼容 IElement[] / IEditorData 形态。'\r\n      )\r\n    }\r\n\r\n\r\n    this.i18n = createEditorI18n(options.locale)\r\n    const editorOptions = mergeOption({ ...options, locale: this.i18n.locale })\r\n    const doc: IDocxDocumentMeta = cloneTree(document)\r\n\r\n    formatElementTree(doc.elements, {\r\n      editorOptions,\r\n      styles: doc.styles,\r\n      numbering: doc.numbering\r\n    })\r\n    if (doc.sections !== undefined && !Array.isArray(doc.sections)) {\r\n      throw new TypeError('旧 sections 内容区必须显式迁移到 contentZones')\r\n    }\r\n    for (const elements of [doc.header, doc.footer, ...Object.values(doc.contentZones ?? {}), ...Object.values(doc.headerFooterParts ?? {})]) {\r\n      if (elements) formatElementTree(elements, { editorOptions, styles: doc.styles, numbering: doc.numbering })\r\n    }\r\n\r\n    this.listener = new Listener()\r\n    this.thumbnailWorker = new ThumbnailManager(images => {\r\n      if (!this.destroyed) this.listener.emit('thumbnailChange', images)\r\n    })\r\n    this.listener.on('thumbnailAppearanceChange', () => this.refreshThumbnailAppearance())\r\n    for (const event of ['contentChange', 'documentSet'] as const) {\r\n      this.listener.on(event, () => this.thumbnailWorker.invalidate())\r\n    }\r\n    this.eventBus = new EventBus()\r\n    this.range = new RangeManager(this.listener)\r\n    for (const event of ['contentChange', 'documentSet', 'rangeChange', 'zoneChange', 'abilityChange'] as const) {\r\n      this.listener.on(event, () => { this.clipboardEpoch++ })\r\n    }\r\n\r\n\r\n    // 渲染后联动通过 after-render 事件订阅，Draw 只 emit 事件不直接耦合各组件\r\n    this.wireAfterRenderHooks()\r\n\r\n    // 先声明适配器占位，以便在 Draw 构造时可以引用（onInput 回调需要 CommandAdapt）\r\n    let adapt: CommandAdapt | null = null\r\n\r\n    const shortcut = new ShortcutHandler({\r\n      getDraw: () => this.draw,\r\n      getCommand: () => this.command,\r\n      dispatchCommand: (command, ...args) => this.dispatchCommand(command, ...args),\r\n      getRange: () => this.range,\r\n      getAdapt: () => adapt\r\n    })\r\n\r\n    this.draw = new Draw(container, editorOptions, {\r\n      document: doc,\r\n      i18n: this.i18n,\r\n      listener: this.listener,\r\n      eventBus: this.eventBus,\r\n\r\n      rangeManager: this.range,\r\n      onInput: (text: string) => {\r\n        adapt?.insertText(text)\r\n      },\r\n      onKeyDown: shortcut.handle,\r\n      afterRender: () => {\r\n        this.listener.emit('afterRender')\r\n      },\r\n      onCommand: (command: string, ...args: any[]) => this.commandChain.dispatch(command, ...args),\r\n      onZoneChange: (zone) => {\r\n        this.listener.emit('zoneChange', zone)\r\n      }\r\n    })\r\n\r\n    adapt = new CommandAdapt(\r\n      {\r\n        getDocument: () => this.draw.getDocument(),\r\n        setDocument: (d: IDocxDocumentMeta) => this.draw.setDocument(d),\r\n        getLayout: () => this.draw.getLayout(),\r\n        getScroller: () => this.draw.getScroller(),\r\n        getActiveDocument: () => this.draw.getActiveDocument(),\r\n        applyActiveDocument: (d: IDocxDocumentMeta) => {\r\n          if (this.draw.getZone() === 'main') this.draw.setDocument(d)\r\n          else this.draw.applyActiveDocument(d)\r\n        },\r\n        setScale: (s: number) => this.draw.setScale(s),\r\n        setPageSize: (w: number, h: number) => this.draw.setPageSize(w, h),\r\n        setRulerVisible: (visible: boolean) => this.draw.setRulerVisible(visible),\r\n        setPaperMargins: (margins: [number, number, number, number]) => this.draw.setPaperMargins(margins),\r\n        getOptions: () => this.draw.getOptions(),\r\n        updateOptions: (patch) => this.draw.updateOptions(patch),\r\n        getZone: () => this.draw.getZone(),\r\n        setZone: (zone) => this.draw.setZone(zone),\r\n        setZoneWithCaret: (zone) => this.draw.setZoneWithCaret(zone),\r\n        print: () => this.draw.print(),\r\n        getPageThumbnails: () => this.draw.getPageThumbnails(),\r\n        scrollPositionIntoView: (pos) => this.draw.scrollPositionIntoView(pos)\r\n      },\r\n      this.range,\r\n      this.listener\r\n    )\r\n    this.adapt = adapt\r\n    this.command = new Command(adapt)\r\n\r\n    // 构建命令分发责任链：事件重定向 → 插件命令 → 剪贴板 → 核心命令兜底\r\n    this.commandChain\r\n      .use((cmd, _args, next) => {\r\n        if (cmd === 'requestInsertImage') { this.listener.emit('requestInsertImage'); return }\r\n        if (cmd === 'requestInsertHyperlink') { this.listener.emit('requestInsertHyperlink'); return }\r\n        if (cmd === 'requestInsertFormula') { this.listener.emit('requestInsertFormula'); return }\r\n        if (cmd === 'executeTableProperty') { this.listener.emit('requestTableProperties'); return }\r\n        return next()\r\n      })\r\n      .use((cmd, args, next) => {\r\n        const pluginCmd = this.pluginCommands.get(cmd)\r\n        if (typeof pluginCmd === 'function') return pluginCmd(...args)\r\n        return next()\r\n      })\r\n      .use((cmd, args, next) => {\r\n        if (cmd === 'executeCopy' || cmd === 'executeCut') {\r\n          if (cmd === 'executeCut' && !this.command.getIsCanInput()) return\r\n          const text = this.command.executeCopy()\r\n          if (!navigator.clipboard) return\r\n          const isCurrent = this.clipboardGuard()\r\n          const fragment = adapt.copyFragment()\r\n          const mime = 'web application/x-vervedocs+json'\r\n          const write = fragment && typeof ClipboardItem !== 'undefined' && ClipboardItem.supports?.(mime)\r\n            ? navigator.clipboard.write([new ClipboardItem({\r\n              'text/plain': new Blob([text], { type: 'text/plain' }),\r\n              [mime]: new Blob([JSON.stringify(fragment)], { type: 'application/x-vervedocs+json' })\r\n            })])\r\n            : navigator.clipboard.writeText(text)\r\n          return write.then(() => {\r\n            if (cmd === 'executeCut' && isCurrent()) this.command.executeCut()\r\n            return text\r\n          }).catch(() => {})\r\n        }\r\n        if (['executePaste', 'executePastePlain', 'executePasteNoFormat'].includes(cmd)) {\r\n          if (!this.command.getIsCanInput()) return\r\n          if (args.length > 0) return next()\r\n          if (!navigator.clipboard) return\r\n          const isCurrent = this.clipboardGuard()\r\n          return (async () => {\r\n            const mime = 'web application/x-vervedocs+json'\r\n            if (cmd === 'executePaste' && navigator.clipboard.read) {\r\n              const items = await navigator.clipboard.read()\r\n              for (const item of items) if (item.types.includes(mime)) {\r\n                const fragment = JSON.parse(await (await item.getType(mime)).text())\r\n                if (isCurrent()) adapt.pasteFragment(fragment)\r\n                return\r\n              }\r\n              for (const item of items) if (item.types.includes('text/plain')) {\r\n                const text = await (await item.getType('text/plain')).text()\r\n                if (isCurrent()) this.command.executePaste(text)\r\n                return\r\n              }\r\n            } else {\r\n              const text = await navigator.clipboard.readText()\r\n              if (isCurrent()) this.command.executePasteNoFormat(text)\r\n            }\r\n          })().catch(() => {})\r\n        }\r\n        return next()\r\n      })\r\n      .use((cmd, args, _next) => {\r\n        if (!this.command) return undefined\r\n        const fn = (this.command as unknown as Record<string, ((...a: any[]) => any) | undefined>)[cmd]\r\n        if (typeof fn === 'function') return fn.call(this.command, ...args)\r\n        return undefined\r\n      })\r\n\r\n    // 历史管理：创建 HistoryManager 注入 CommandAdapt\r\n    this.history = new HistoryComponent()\r\n    const historyManager = this.history.install({\r\n      maxRecordCount: Number(editorOptions.historyMaxRecordCount ?? 50),\r\n      coalesceMs: 300\r\n    })\r\n    adapt.setHistoryManager(historyManager)\r\n    adapt.pushInitialHistory()\r\n\r\n    // commands 组件实例化（基于 verve 树模型）\r\n    this.search = new Search(this.draw)\r\n    this.block = new BlockParticle(this.draw)\r\n    this.date = new DateParticle(this.draw)\r\n    this.laTex = new LaTexParticle(this.draw)\r\n    this.control = new ControlComponent()\r\n    this.control.install(this.draw)\r\n\r\n\r\n    // 构造插件宿主契约（桥接视图与文档查询接口），供 use(plugin) 时注入\r\n    // ⚠️ 该对象是 PluginHost 的唯一合法实现，外部严禁替换。\r\n    const drawRef = this.draw\r\n    this.pluginHost = {\r\n      getI18n: () => this.i18n,\r\n      getContainer: () => drawRef.getScroller(),\r\n      getPositionList: () => null,\r\n      getRevisionAnchor: (revisionId: string) => {\r\n        const anchorMap = drawRef.getRevisionAnchorMap()\r\n        return anchorMap.get(revisionId) || null\r\n      },\r\n      getDrawWidth: () => Number(editorOptions.pageWidth ?? 794),\r\n      getDrawHeight: () => Number(editorOptions.pageHeight ?? 1123),\r\n      getPageGap: () => Number((editorOptions as any).pageGap ?? 24),\r\n      getOptions: () => editorOptions,\r\n      getElementList: () => drawRef.getDocument().elements,\r\n      getDocument: () => drawRef.getDocument(),\r\n      commitTransaction: (action) => this.adapt.commitPluginTransaction(action),\r\n      getGroupContext: (groupId: string) => {\r\n        const anchorMap = drawRef.getGroupAnchorMap()\r\n        const anchor = anchorMap.get(groupId)\r\n        if (!anchor) return null\r\n        return {\r\n          isTable: false,\r\n          index: -1,\r\n          startIndex: -1,\r\n          endIndex: -1,\r\n          _anchor: anchor\r\n        }\r\n      },\r\n      executeSetGroup: (update) => this.adapt.setGroup(update),\r\n      executeDeleteGroup: (groupId: string) => { this.command?.executeDeleteGroup(groupId) },\r\n      executeLocationGroup: (groupId: string) => { this.command?.executeLocationGroup(groupId) },\r\n      executeUpdateOptions: (opts: any) => {\r\n        this.adapt.updateOptions(opts)\r\n      },\r\n      setActiveGroup: (groupId: string | null) => { drawRef.setActiveGroup(groupId) },\r\n      setActiveRevision: (revisionId, color) => { drawRef.setActiveRevision(revisionId, color) },\r\n      getEventBus: () => this.eventBus,\r\n      setChartRenderer: (renderer) => drawRef.setChartRenderer(renderer),\r\n      executeInsertChart: (payload: any) => { this.command?.executeInsertChart(payload) },\r\n      executeUpdateChart: (id: string, patch: Record<string, unknown>) => { this.command?.executeUpdateChart(id, patch) }\r\n    }\r\n\r\n    // 订阅 transform 的文档替换事件，通知插件同步数据（反转原 setCommentHandler 耦合）\r\n    this.listener.on('documentSet', (d: IDocxDocumentMeta) => {\r\n      for (const plugin of this.plugins.values()) {\r\n        plugin.hooks?.onSetDocument?.(d)\r\n      }\r\n    })\r\n\r\n    // 初始化 Worker，推送初始文档数据\r\n    this.worker = new WorkerManager()\r\n    // Worker 计算出目录后，通过 listener 推送给 UI\r\n    this.worker.onTocResult((result) => {\r\n      this.listener.emit('tocChange', result.toc)\r\n    })\r\n    this.listener.on('contentChange', () => {\r\n      this.worker.updateElements(this.draw.getDocument().elements)\r\n    })\r\n    this.worker.updateElements(doc.elements)\r\n\r\n    // 鼠标点击 -> hit + setC8 + focus 隐藏输入框\r\n    // 注意：Draw 内 mousedown 已处理 hit，这里不再重复绑定\r\n  }\r\n\r\n  /**\r\n   * 订阅 after-render 生命周期事件，集中管理渲染后各组件的联动。\r\n   *\r\n   * Draw 只 emit `after-render` 事件，不直接调用插件/block/control/worker，\r\n   * 已注册插件的 `hooks.afterRender` 在此遍历调用，核心组件联动也在此集中订阅。\r\n   */\r\n  private wireAfterRenderHooks(): void {\r\n    this.listener.lifecycle.afterRenderListener(() => {\r\n      for (const plugin of this.plugins.values()) {\r\n        plugin.hooks?.afterRender?.()\r\n      }\r\n      this.renderEmbedBlocks()\r\n      this.block?.clear()\r\n      this.control?.clear()\r\n      if (this.listener.hasListeners('thumbnailChange')) {\r\n        const images = this.draw.getPageThumbnails()\r\n        const sources = this.draw.getThumbnailForegrounds()\r\n        if (sources.length !== this.thumbnailSources.length || sources.some((value, i) => value !== this.thumbnailSources[i])) {\r\n          // Publish new content immediately; background composition follows asynchronously.\r\n          this.listener.emit('thumbnailChange', images)\r\n          this.thumbnailSources = sources\r\n        }\r\n        this.refreshThumbnailAppearance(sources)\r\n      }\r\n    })\r\n  }\r\n\r\n  private refreshThumbnailAppearance(sources?: string[]): void {\r\n    if (this.destroyed || !this.draw || !this.listener.hasListeners('thumbnailChange')) return\r\n    const options = this.draw.getOptions()\r\n    const background = options.background as { color?: string } | undefined\r\n    this.thumbnailWorker.update(sources ?? this.draw.getThumbnailForegrounds(),\r\n      options.eyeCare ? '#C7EDCC' : background?.color || '#ffffff')\r\n  }\r\n\r\n  /**\r\n   * 渲染嵌入块（iframe）：遍历 layout 中 kind === 'block' 的节点，\r\n   * 调 BlockParticle.render 挂载/复用 DOM。chart 已由 canvas drawImage 渲染，不在此处理。\r\n   */\r\n  private renderEmbedBlocks(): void {\r\n    if (!this.block) return\r\n    const layout = this.draw.getLayout()\r\n    if (!layout) return\r\n    for (const page of layout.pages) {\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'block') {\r\n          const x = page.contentRect.x + b.rect.x\r\n          const y = page.contentRect.y + b.rect.y\r\n          this.block.render(page.index, b.block, x, y)\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取当前文档元数据\r\n   * @returns 文档元数据（含 elements/sections/comments 等）\r\n   */\r\n  getDocument(): IDocxDocumentMeta { return this.draw.getDocument() }\r\n\r\n  getLocale(): BuiltinLocale { return this.i18n.locale }\r\n  setLocale(locale: BuiltinLocale): void { this.i18n.setLocale(locale) }\r\n  getI18n(): EditorI18n { return this.i18n }\r\n\r\n  /**\r\n   * 设置文档元数据，重置 zone 到 main 并通知插件同步数据\r\n   * @param doc 文档元数据（必须包含 elements 数组）\r\n   * @throws {TypeError} doc 非 IDocxDocumentMeta 时抛出\r\n   */\r\n  setDocument(doc: IDocxDocumentMeta): void {\r\n    if (!doc || !Array.isArray(doc.elements)) {\r\n      throw new TypeError('[DocxEditor.setDocument] 需要 IDocxDocumentMeta')\r\n    }\r\n    this.adapt.replaceDocument(doc, true)\r\n  }\r\n\r\n  // ============================================================\r\n  //   插件注册 —— 可选功能（批注/修订等）的唯一合法入口\r\n  // ============================================================\r\n\r\n  /**\r\n   * 注册插件。core 在注册时自动注入 PluginHost、登记命令表；\r\n   * 若文档已加载，立即触发 `hooks.onSetDocument` 以同步初始数据。\r\n   *\r\n   * 核心引擎（view/transform）保持内置硬编码，不通过此方法注册。\r\n   *\r\n   * @param plugin 满足 EditorPlugin 契约的插件实例\r\n   */\r\n  use(plugin: EditorPlugin): void {\r\n    if (this.plugins.has(plugin.name)) {\r\n      console.warn(`[DocxEditor] 插件 \"${plugin.name}\" 已注册，忽略重复注册`)\r\n      return\r\n    }\r\n    this.plugins.set(plugin.name, plugin)\r\n    if (this.pluginHost) plugin.install(this.pluginHost)\r\n    if (plugin.commands) {\r\n      for (const [name, fn] of Object.entries(plugin.commands)) {\r\n        this.pluginCommands.set(name, fn)\r\n      }\r\n    }\r\n    // 若文档已加载，通知插件同步初始数据\r\n    if (plugin.hooks?.onSetDocument) {\r\n      plugin.hooks.onSetDocument(this.draw.getDocument())\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取已注册插件实例，供宿主层调用插件特有方法。\r\n   *\r\n   * @param name 插件名称\r\n   * @returns 插件实例，未注册时返回 undefined\r\n   */\r\n  getPlugin<T extends EditorPlugin>(name: string): T | undefined {\r\n    return this.plugins.get(name) as T | undefined\r\n  }\r\n\r\n  /**\r\n   * 分发命令到责任链（供宿主层触发插件命令）\r\n   */\r\n  dispatchCommand(command: string, ...args: any[]): any {\r\n    return this.commandChain.dispatch(command, ...args)\r\n  }\r\n\r\n  /**\r\n   * 销毁编辑器实例，释放所有资源（DOM/事件监听/定时器/组件/插件）\r\n   */\r\n  destroy(): void {\r\n    this.destroyed = true\r\n    for (const plugin of this.plugins.values()) {\r\n      plugin.destroy?.()\r\n    }\r\n    this.block?.destroy()\r\n    this.date?.clearDatePicker()\r\n    this.control?.destroy()\r\n    this.history?.destroy()\r\n    this.draw.destroy()\r\n    this.thumbnailWorker.destroy()\r\n    this.worker.destroy()\r\n    this.listener = new Listener()\r\n    this.eventBus.clear()\r\n    this.range.clear()\r\n  }\r\n}\r\n\r\nexport default DocxEditor\r\n","/**\r\n * VerveDocs Core —— UI 常量与枚举\r\n *\r\n * PaperDirection / TableBorder 已在 schema/constants.ts 定义，通过 export * 透传。\r\n * 字体字号从 schema 已有常量转换，不重复定义数据。\r\n */\r\n\r\nimport { FONT_FAMILY_MAP, FONT_SIZE, FONT_SIZE_LIST } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 编辑器字体选项（从 schema FONT_FAMILY_MAP 转换为 { label, value } 格式） */\r\nexport const EDITOR_FONT_OPTIONS: { label: string; value: string }[] =\r\n  FONT_FAMILY_MAP.map(e => ({ label: e.label, value: e.value }))\r\n\r\n/** 编辑器字号选项（从 schema FONT_SIZE / FONT_SIZE_LIST 转换为 { label, value } 格式） */\r\nexport const EDITOR_SIZE_OPTIONS: { label: string; value: number }[] =\r\n  FONT_SIZE_LIST.map(name => {\r\n    const value = FONT_SIZE[name]\r\n    return { label: name, value: value != null ? value : Number(name) }\r\n  })\r\n\r\n/** 水印字号选项（对齐 Word 标准水印字号） */\r\nexport const WATERMARK_SIZE_OPTIONS: { label: string; value: number }[] = [\r\n  { label: '自动', value: 120 },\r\n  { label: '40', value: 40 },\r\n  { label: '50', value: 50 },\r\n  { label: '60', value: 60 },\r\n  { label: '70', value: 70 },\r\n  { label: '80', value: 80 },\r\n  { label: '90', value: 90 },\r\n  { label: '100', value: 100 },\r\n  { label: '120', value: 120 },\r\n  { label: '140', value: 140 },\r\n  { label: '160', value: 160 },\r\n  { label: '180', value: 180 },\r\n  { label: '200', value: 200 },\r\n]\r\n\r\n","/**\r\n * VerveDocs Core —— 公共入口\r\n */\r\n\r\nimport DocxEditor from './docx-editor'\r\n\r\nexport default DocxEditor\r\nexport { DocxEditor }\r\nexport { DocxEditor as Editor }\r\n\r\n// 树模型 / 工具（全量透传 schema）\r\nexport * from '@vervedoc/docx-editor-schema'\r\nexport type { TitleLevel } from '@vervedoc/docx-editor-schema'\r\n\r\n// UI 常量与枚举\r\nexport * from './constants'\r\n\r\n// Worker 管理器\r\nexport { WorkerManager } from './workers/worker-manager'\r\nexport type { TocResult, SearchResult } from './workers/worker-manager'\r\n\r\n// 状态层\r\nexport { EventBus, Listener, RangeManager } from '@vervedoc/docx-editor-state'\r\nexport type { IRangeStyle, IEditorAbility, ListenerMap, EventHandler } from '@vervedoc/docx-editor-schema'\r\n\r\n// 视图层\r\nexport {\r\n  Draw,\r\n  LayoutEngine,\r\n  CanvasRenderer,\r\n  TextMeasure,\r\n  getSharedMeasure,\r\n  hitTest\r\n} from '@vervedoc/docx-editor-view'\r\nexport type {\r\n  DocumentLayout, PageLayout, BlockNode, ParagraphBlock,\r\n  ImageBlock, PageBreakBlock, TableBlock, TableRowLayout, TableCellLayout,\r\n  LineBox, InlineBox, Rect\r\n} from '@vervedoc/docx-editor-view'\r\n\r\n// 变换层\r\nexport { Command, CommandAdapt } from '@vervedoc/docx-editor-transform'\r\nexport type { IHistoryManager, HistorySnapshot } from '@vervedoc/docx-editor-schema'\r\n\r\n// 命令分发责任链\r\nexport { CommandChain } from './command-chain'\r\nexport type { CommandHandler, CommandNext } from './command-chain'\r\n\r\n// 历史管理\r\nexport { HistoryManager, HistoryComponent, createSnapshot } from '@vervedoc/docx-editor-history'\r\nexport type { HistorySnapshot as HistorySnapshotType } from '@vervedoc/docx-editor-history'\r\n\r\n\r\n// commands 扩展（搜索 / 块级媒体 / 日期 / LaTeX / 小工具）\r\nexport {\r\n  Search,\r\n  BlockParticle,\r\n  DateParticle,\r\n  LaTexParticle,\r\n\r\n  ControlComponent\r\n} from '@vervedoc/docx-editor-commands'\r\nexport type {\r\n  ISearchResult,\r\n  IReplaceOption,\r\n  INavigateInfo,\r\n  IElementPosition\r\n} from '@vervedoc/docx-editor-schema'\r\n\r\n/** VerveDocs Core 版本号 */\r\nexport const version = '4.0.0-tree'\r\n"],"names":["builtinMessages","createEditorI18n","locale","createI18n","lookup","messages","key","value","segment","bundles","initialLocale","fallbackLocale","listeners","params","_","name","nextLocale","listener","SCHEMA_VERSION","DEFAULT_EDITOR_OPTION","PARAGRAPH_ATTR_KEYS","PARAGRAPH_CONTAINER_TYPES","BLOCK_LEVEL_TYPES","LIST_TYPE","LIST_STYLE","ROW_FLEX","TITLE_LEVEL","FONT_FAMILY","FONT_FAMILY_MAP","FONT_FAMILY_LIST","e","FONT_FAMILY_VALUE","FONT_FAMILY_LABEL","a","FONT_FAMILY_CSS","FONT_SIZE","FONT_SIZE_LIST","PaperDirection","TableBorder","DPI","ptToPx","pt","pxToPt","px","PAPER_SIZE_LIST","DEFAULT_PAPER_SIZE","BULLET_STYLES","NUMBER_STYLES","LINE_HEIGHT_OPTIONS","MARGIN_PRESETS","ZOOM_LEVELS","SEPARATOR_STYLES","TITLE_LEVEL_MAP","AUTHOR_COLORS","getAuthorColor","hash","i","FORMAT_KEYS","BOOLEAN_TAGS","snapshotRevisionFormat","element","source","clearRevision","run","extension","decodeXml","escapeXml","readRunProperties","xml","result","tag","_a","attr","underline","fonts","font","scale","color","vertical","getRevisionOldProps","stored","serializeRunProperties","format","parts","add","style","recordFormatRevision","before","meta","after","changed","existing","oldProps","restoreRevisionFormat","target","rfdc_1","rfdc","copyBuffer","cur","opts","rfdcCircles","constructorHandlers","fn","cloneArray","handler","cloneProto","clone","keys","a2","k","o2","refs","refsNew","o","index","_clone","cloneTree","node","isParagraphContainer","el","isTable","walkTree","elements","visitor","parentPath","path","tr","row","td","cell","getByPath","root","current","seg","getParentContainer","replaceAtPath","parent","idx","insertAtPath","removeAtPath","removed","isSamePath","b","comparePath","n","av","bv","comparePosition","c","forEachCell","table","j","getTableColCount","sum","_pathSegAsKey","resolveHeaderFooterPart","doc","zone","sectionIndex","pageIndex","firstPage","section","kind","_c","_b","_e","_d","mergeOption","options","formatElementTree","ctx","stack","ext","normalizeNode","adjustFloatImagePositions","editorOptions","normalizeText","normalizeTitle","normalizeList","normalizeTable","normalizeImage","normalizePageBreak","anyNode","applyParagraphStyleId","inheritParagraphAttrsToChildren","numId","ri","normalizeTr","ci","normalizeTd","applyImageLayout","image","layout","child","wrap","updateImageLayout","changes","geometry","namespace","drawing","transform","styleId","indentationBaseline","axis","container","PARA_KEYS","containerAny","childAny","pairBookmarkMarkers","markers","leaves","indices","isContent","startMap","bookmarks","m","startPath","start","end","first","last","anchor","isParagraphTerminator","v","endsBookmarkParagraph","previous","next","splitParagraphs","out","valueList","segs","splitValueList","runs","startIndex","vi","vStart","toDocxExportDocument","document","contentZones","normalizeHyperlinks","children","normalizeParagraphRuns","group","boundaries","resolvePoint","point","length","addBoundary","position","entries","bookmark","focus","starts","ends","marker","boundary","convert","entry","offset","KeyMap","isApple","isMod","evt","has","prefix","Events","EE","context","once","addListener","emitter","event","clearEvent","EventEmitter","names","events","handlers","l","ee","a1","a3","a4","a5","len","args","module","EventBus","__publicField","Listener","RangeManager","pos","range","ordered","delta","newOffset","LRU","limit","TextMeasure","family","size","bold","italic","ch","hit","w","text","_sharedMeasure","getSharedMeasure","toRoman","num","upper","map","s","toLetter","rem","CN_DIGITS","CN_UNITS","CN_BIG_UNITS","CN_UPPER","toChineseCounting","t","toChineseCountingLarge","segStr","u","digit","toChineseUpper","toIdeographDigital","d","toDecimalZero","formatCounter","numFmt","WINGDINGS_FALLBACK","BULLET_FONT_STACK","BULLET_FONT_STACK_FALLBACK","_hasWingdings","detectWingdings","w1","w2","resolveUnorderedChar","list","bulletFont","isWingdings","trimmed","styleMap","level","fallback","normalizeBulletChar","hasWingdings","resolveBullet","counters","listType","isOrderedStyle","raw","hasWD","fmt","tpl","prev","lvl","val","_blockSeq","nextBlockId","LayoutEngine","measure","headerElements","footerElements","pageGap","sectionFirstPage","pageWidth","pageHeight","mt","mr","mb","ml","contentWidth","contentHeight","setSection","sectionBreaks","sectionColumns","count","gap","width","sectionWidths","columnGroups","columnSection","data","rawBlocks","block","input","columnId","columns","anchorParagraphs","attachedImages","id","placedAnchors","headerBlocks","footerBlocks","headerOffsetY","headerContentHeight","footerOffsetY","pages","cursorY","currentBlocks","activeColumns","activeColumnId","columnIndex","columnTop","columnBottom","columnX","advanceColumn","pushPage","PAGE_FIT_EPSILON","pageOriginY","headerPartId","footerPartId","pageHeaders","pageFooters","footerHeight","height","pageRect","contentRect","headerRect","footerRect","legacyColumnId","sourceColumnId","exclusions","placed","attrs","distance","breakType","nextSection","_f","geometryChanged","_g","margin","origin","lines","line","bh","_h","remaining","frags","fi","frag","floating","_i","_j","horizontal","_k","_l","resolve","ref","isX","leading","align","_m","top","bottom","left","right","_o","_n","_q","_p","lastPage","totalHeight","page","availableWidth","paragraphs","blocks","gi","g","imgEl","issues","issue","feature","reason","reference","hasAnchor","paragraph","supported","item","imgDisplay","imgBlock","runsParentPath","pb","blockEl","anyEl","metrics","h","innerBlock","signature","cached","sameSources","paragraphKind","endIndex","runStartIndex","containerAttrs","collectedRunAttrs","r","ra","rowFlex","firstIndent","indentLeft","indentRight","indentHanging","spacingBefore","spacingAfter","rawLineHeight","lineHeightRule","bulletKind","bulletText","bulletWidth","bulletSize","bulletColor","bulletBold","bulletX","useWordHanging","bulletHanging","hasNumbering","listEl","res","listHanging","listBaseIndent","proposed","cap","fa","rawBulletFont","symbolGap","glyphW","jc","hangingOffset","inner","bulletWidthForLine","usableWidth","currentInlines","currentLineWidth","currentMaxSize","isFirstLine","firstLineOffset","flowY","lineRegion","exclusion","computeLineHeight","leftWidth","rightWidth","currentLineMaxWidth","lh","finalizeLine","isLastLine","region","lineXBase","inl","layoutRuns","rawRun","vl","base","tocEntry","tocPageWidth","runIndex","hyperlinkUrl","anyRun","rawFont","bgColor","strikeout","groupIds","runPath","cursorInRun","maxLineWidth","take","takenWidth","segEnd","segWidth","inline","placeholderRun","placeholderRi","pr","yy","contentRight","applyRowFlex","rect","rotate","occupiedW","occupiedH","x","colWidths","firstTr","inferred","span","per","totalDefined","tableWidth","occupied","rows","rowHeights","rowCells","rowspanPending","colCursor","colspan","rowspan","rr","cc","cellWidth","cellX","sumUp","pl","cellPath","contentPath","content","innerY","cb","required","rp","acc","rowHeight","cellLayouts","cl","cellH","firstFit","fullHeight","totalRows","repeatRows","repeatHeight","firstEnd","startRow","budget","endRow","fit","subAcc","repeatRowsBefore","bodyRows","headerRows","y","spanHeight","from","to","headerOffset","rs","hi","cont","bodyFirst","side","blk","arr","upto","containerWidth","used","free","dx","isJustify","isDistribute","totalChars","gaps","extra","fontOf","addBucket","buckets","cmd","groupHighlightColor","active","paintParagraph","firstLine","bx","by","bgRects","strokes","groupColors","activeColor","hasGroupHighlight","gid","gc","revisionType","inserted","deleted","revisionColor","textColor","my","cx","chartTableSignature","signBlock","_rows","_content","cellAttrs","signParagraph","img","paraKey","runsKey","_path","paint","revision","bulletKey","si","surroundKey","CanvasRenderer","renderer","z","cssWidth","cssHeight","dpr","patch","enabled","quality","pageCount","onForeground","canvas","contentOriginX","contentOriginY","aliveIds","hx","hy","fx","fy","blockIds","ids","collect","revisionId","groupId","bytes","cfg","widget","uppercase","digits","units","tens","ones","hundreds","rest","thousands","ct","scrollY","totalPages","textW","textH","baselineY","relX","relY","rects","pageOffsetX","ov","PADDING","contentTop","contentBottom","fullLineStartX","fullLineEndX","dividerY","viewportHeight","dirtyRect","dy","dw","dh","dTop","dBottom","pageBottom","viewTop","viewBottom","alive","pw","ph","L","sig","corners","p","layer","originX","originY","cache","needRebuild","bitmap","anyBlock","lineType","lineWidth","dashArray","x0","x1","cy","amp","wave","off","grad","sx","sy","mode","url","crop","scaledWidth","scaledHeight","chartBlock","dependency","cacheKey","option","dataUrl","dataSource","chartType","config","subtype","tableEl","tableData","bg","cw","contentX","contentY","edges","edgeKey","y1","x2","y2","b1","b2","drawOnce","bs","bt","showTop","showRight","showBottom","showLeft","slashes","groups","edge","rank","borderRank","borderWeight","brightness","rgb","secondaryBrightness","points","candidates","winner","strokeSide","halfOffset","hitTest","docX","docY","hitBlocks","ox","oy","six","hitParagraph","hitTable","lx","ly","_pb","hitLine","cursor","ls","tbx","tby","ry","contentOX","contentOY","locateCaret","locateInBlocks","locateInParagraph","locateInTable","localX","charOffsetToX","pathStartsWith","offsetInInline","computeSelectionRects","collectSelectionInBlocks","collectSelectionInParagraph","segLeft","segRight","flush","inlStart","inlEnd","clipStartOff","clipEndOff","viewText","viewTranslate","translate","textKeys","translatePanel","preferred","byText","walker","keyedText","PREFIX","SVG","ContextMenu","items","isSub","div","main","icon","label","sc","arrow","inputValue","min","max","unit","colorValue","colorInput","clear","parentEl","vw","vh","positionHandle","handle","viewport","visible","panelHtml$3","TablePropertiesWidget","deps","selection","borders","panelHtml","tab","tabs","button","picker","selectColor","controls","control","invalid","selected","pane","valid","state","type","preview","property","command","BORDER_HOT","TableWidget","tableIndex","matchesTable","part","tableX","tableY","colX","colY","rowX","rowY","clientX","clientY","icons","fire","labels","localize","menu","unitKey","info","screenX","screenY","borderX","borderY","border","newSize","createSelectionLayer","updateSelectionLayer","bounds","positionSelectionToolbar","toolbar","HANDLE_SIZE","HANDLE_OFFSET","HANDLES","ImageWidget","dir","origW","origH","ratio","bar","mkBtn","title","onClick","btn","sp","mkSep","sep","delBtn","delIcon","src","overlay","close","onKey","pageOriginX","sel","bp","hd","ChartWidget","panelHtml$2","PX_PER_CM","ParagraphLayoutWidget","panes","lhType","lhValue","lhUnit","special","specialValue","updateLh","updateSpecial","displayNumber","outline","rule","spAfter","indentPx","alignMap","indent","panelHtml$1","FontLayoutWidget","cjk","sizeKeys","fontValue","fontLabel","fontEntry","styleSel","sizeSel","cnName","doubleStrikeout","hidden","superscript","subscript","styleVal","sizeVal","HyperlinkWidget","onConfirm","onSuccess","textInput","urlInput","error","setError","protocol","ParagraphWidget","onCommand","lastLine","firstInline","lastInline","alignment","addButton","levels","sub","alignments","svg","arrows","savedRange","snapshot","HeaderFooterWidget","make","textEl","f","caret","popup","styleRow","styleLabel","styleSelect","opt","styleKeys","posTitle","posRow","positions","posItems","it","isActive","footer","confirmBtn","hitZone","currentZone","containerRect","dividerScreenY","labelY","pageCenterX","btnWidth","btnHeight","btnRect","popupWidth","popupHeight","RULER_SIZE","BAND_START","BAND_SIZE","BACKGROUND","MARGIN_BACKGROUND","BORDER","MARGINS","INDENTS","RulerWidget","drag","pageX","clamp","movement","margins","createRuler","ruler","isMargin","titles","contentEnd","step","center","firstTick","lastTick","tick","tabStep","aligned","WatermarkWidget","py","fontSize","opacity","repeat","gapX","gapY","stepX","stepY","diag","cols","startX","startY","offsetX","SystemWatermarkWidget","tileW","tileH","escText","encoded","SelectionToolbarWidget","tb","fontSel","colorBtn","hlBtn","sizePt","btns","colorInputs","CaretWidget","nextRenderId","prepareRenderState","dirty","visit","topLevel","bi","old","computeDirtyRect","painted","include","findInlineByPos","findInlineInBlocks","findParagraphByPos","findParagraphInBlocks","findLineByPos","findLineInBlocks","findFirstInline","findFirstInlineInBlocks","findLastInline","findLastInlineInBlocks","onInline","findHyperlinkByPos","collectGroupAnchors","absX","absY","absEndX","absEndY","glyphHeight","absGlyphTop","collectRevisionAnchors","CaretNavigation","localOff","isWord","para","targetY","newPos","ZoneManager","trList","tdList","partId","TEXT_CURSOR","Draw","wasDragging","midY","i18n","assetLoaded","hanging","tableRects","selRects","rowCount","lastRow","lastColIdx","startCol","endCol","paperDirection","frame","images","pageStyles","visualSignature","foreground","bookmarkMarkers","diagnostics","notice","wrapperWidth","scrollLeft","skipAfterRender","pn","wm","CommandChain","HEADING_SIZES","CommandAdapt","draw","mutate","targets","parents","commit","adjusted","backward","hm","resetHistory","action","coalesceKey","tracking","author","insertIndex","startRunIdx","endRunIdx","startRun","endRun","startNode","endNode","toDelete","idxs","pageNo","scroller","wrapper","listPath","childIndex","newPath","flex","cursorIdx","any","toggleKey","collapsed","selectedRuns","allSet","order","depth","forward","shifted","removedPosition","leaf","startOffset","endPath","endOffset","sameRun","second","startParent","startIdx","endIdx","targetPath","fromStart","fromEnd","anchorNode","focusNode","replacements","isTerminator","textFormat","formatRuns","paragraphKeys","restored","candidate","leadingSeparator","bullet","number","colWidth","trIndex","tdIndex","_doc","insertAt","newRow","totalWidth","newColCount","newTd","lastTr","lastTdIdx","lastValue","lastIdx","lastEl","minRow","maxRow","minCol","maxCol","firstTd","allContent","colIndex","rowIndex","imgSrc","imgW","imgH","cells","total","col","containerPath","outer","containerIndex","tail","insertionIndex","payload","file","reader","imageType","response","blob","href","fail","hasRevision","success","selectedText","link","linkIndex","normalized","sepAny","following","catalog","levelMap","blockPath","scrollContainer","empty","all","seen","titleEl","template","direction","keyword","PAD","textNodes","nodeIdx","match","needBefore","niBefore","prevValue","needAfter","niAfter","nextValue","replacement","lastSeg","isVisible","metadata","maxLevel","append","role","pass","isPageStart","pageBreak","ownedBreak","currentOptions","lastNode","cloned","suffix","survivor","sections","fragment","caretIndex","caretNode","defaultStyle","paraEl","titlePath","rowNo","colNo","maxLinesInRow","cellLines","update","sides","rowSpan","external","uniform","values","shown","show","resolved","preset","subPath","topLevelIndex","Command","adapt","EDITOR_PREFIX","BlockType","TEXTLIKE_ELEMENT_TYPE","EDITOR_COMPONENT","EditorComponent","DatePicker","datePickerContainer","dateWrap","datePickerTitle","preYearTitle","preMonthTitle","nowTitle","nextMonthTitle","nextYearTitle","datePickerWeek","sun","mon","tue","wed","thu","fri","sat","week","weekDom","datePickerDay","timeWrap","hourTime","minuteTime","secondTime","li","timeText","ol","isHour","isMinute","time","datePickerMenu","timeMenu","nowMenu","submitMenu","lineHeight","preY","setDate","defaults","weekList","childElement","hourTitle","minuteTitle","secondTitle","localDate","localYear","localMonth","localDay","pickYear","pickMonth","pickDay","year","month","curDay","curWeek","preDay","preStartDay","dayDom","newMonth","nextEndDay","day","isIntoView","hour","minute","hourDom","minuteDom","secondDom","timeDom","dom","pickDom","offsetParents","pointer","curr","viewRectTop","viewRectBottom","pickDateString","date","dateString","dateOption","reg","DateParticle","elementList","ordR","HERSHEY","compile","bound","xmin","xmax","polylines","ymin","ymax","zmin","zmax","SYMB","asciiMap","CONFIG","tokenize","str","tokens","parseAtom","parse","expr","takeOpt","ret","takeN","j0","cnt","chld","environments","exprs","es","sclx","scly","notFirst","computeBbox","bbox","searchHigh","lvl0","lmin","lmax","rmin","rmax","colws","erows","erow","ybds","shft","plan","tmd","mw","y0","mh","spac","wasBig","nth","ex","m2s","alt","hasLp","hasRp","bb","flatten","flat","ff","xx","render","isSmallHat","isVerb","nf","LaTexUtils","latex","s0","head","pdf","DEFAULT_SCALE","LaTexParticle","laTex","promise","reject","getUUID","isNumber","isSearchable","Search","matchList","alpha","matchColor","navigateColor","navigateIndexList","found","replaceIndex","firstMatch","ALLOWED_SRC_PROTOCOLS","isAllowedSrc","_IFrameBlock","iframeWindow","blockItemContainer","iframeBlock","iframe","contentWindow","IFrameBlock","BaseBlock","blockParticle","blockItem","_pageNo","BlockParticle","blockContainer","cacheBlock","newBlock","blockElementIds","ControlComponent","controlContainer","controlIds","DEFAULT_MAX_RECORD_COUNT","DEFAULT_COALESCE_MS","HistoryManager","now","_current","createSnapshot","HistoryComponent","ShortcutHandler","mod","clipboardCommand","computeToc","toc","numLevel","computeSearch","results","lowerKeyword","WorkerManager","_documentCurrentScript","msg","message","ThumbnailManager","publish","sources","DocxEditor","shortcut","_args","pluginCmd","isCurrent","mime","_next","historyManager","drawRef","plugin","epoch","background","EDITOR_FONT_OPTIONS","EDITOR_SIZE_OPTIONS","WATERMARK_SIZE_OPTIONS","version"],"mappings":"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L,IAAK,qCACL,IAAK,uCACL,IAAK,qBACL,IAAK,2CACL,IAAK,uDACL,IAAK,mBACL,IAAK,mEACL,IAAK,uDACL,IAAK,kBACL,IAAK,yBACL,IAAK,8BACL,IAAK,qCACL,IAAK,wBACL,IAAK,gDACL,IAAK,YACL,IAAK,kBACL,IAAK,kCACL,IAAK,6DACL,IAAK,YACL,IAAK,4BACL,IAAK,4BACL,IAAK,YACL,IAAK,YACL,IAAK,kBACL,IAAK,kBACL,IAAK,kBACL,IAAK,wBACL,IAAK,kBACL,IAAK,sBACL,IAAK,sBACL,IAAK,wBACL,IAAK,8BACL,IAAK,gFACL,IAAK,8DACL,IAAK,kBACL,IAAK,kBACL,IAAK,cACL,IAAK,2CACL,IAAK,4EACL,IAAK,4DACL,IAAK,8CACL,IAAK,0GACL,IAAK,sHACL,IAAK,sHACL,IAAK,0CACL,IAAK,sCACL,IAAK,wBACL,IAAK,8DACL,IAAK,0DACL,IAAK,kCACL,IAAK,0BACL,IAAK,4BACL,IAAK,iCACL,IAAK,4BACL,IAAK,oBACL,IAAK,kBACL,IAAK,oBACL,IAAK,oBACL,IAAK,kDACL,IAAK,kDACL,IAAK,sEACL,IAAK,qDACL,IAAK,kEACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,sBACL,IAAK,uBACL,IAAK,wBACL,IAAK,uBACL,IAAK,wBACL,IAAK,wBACL,IAAK,wBACL,IAAK,wBACL,IAAK,gBACL,IAAK,gBACL,IAAK,gBACL,IAAK,gBACL,IAAK,sDACL,IAAK,sDACL,IAAK,oDACL,IAAK,oDACL,IAAK,iDACL,IAAK,6CACL,IAAK,0DACL,IAAK,4BACL,IAAK,wBACL,IAAK,gBACL,IAAK,kBACL,IAAK,wBACL,IAAK,wBACL,IAAK,0CACL,IAAK,kBACL,IAAK,gBACL,IAAK,mBACL,IAAK,8BACL,IAAK,kBACL,IAAK,kBACL,IAAK,wBACL,IAAK,4E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","x_google_ignoreList":[9,15]}