{"version":3,"file":"core.umd.cjs","sources":["../../../plugins/docx-editor-schema/src/constants.ts","../../../plugins/docx-editor-schema/src/author-color.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/export.ts","../../../plugins/docx-editor-schema/src/paragraph.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/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/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":["/**\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 = [\n  '#409EFF', '#67C23A', '#E6A23C', '#F56C6C',\n  '#909399', '#00BCD4', '#9C27B0', '#3F51B5',\n  '#FF9800', '#4CAF50', '#009688', '#795548',\n  '#FF5722', '#C2185B', '#FFC107', '#607D8B'\n]\n\n/** Stable author colors shared by review text, balloons and connectors. */\nexport function getAuthorColor(name: string): string {\n  let hash = 0\n  for (let i = 0; i < name.length; i++) {\n    hash = name.charCodeAt(i) + ((hash << 5) - hash)\n  }\n  return AUTHOR_COLORS[Math.abs(hash) % AUTHOR_COLORS.length]\n}\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\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 配对，start 的 path 作为 range.anchor，end 的 path 作为 range.focus。\r\n */\r\nexport function pairBookmarkMarkers(\r\n  markers: { name: string; position: string; path: Path }[]\r\n): IBookmark[] {\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 {\r\n      const startPath = startMap.get(m.name)\r\n      if (startPath) {\r\n        bookmarks.push({\r\n          name: m.name,\r\n          range: {\r\n            anchor: { path: startPath, offset: 0 },\r\n            focus: { path: m.path, offset: 0 }\r\n          },\r\n          collapsed: false\r\n        })\r\n        startMap.delete(m.name)\r\n      }\r\n    }\r\n  }\r\n  return bookmarks\r\n}\r\n","import type { IDocxDocumentMeta, IElement, IPosition } from './types'\nimport { cloneTree, comparePosition, getByPath, isParagraphContainer, isTable } from './walk'\n\ninterface BookmarkBoundary {\n  offset: number\n  name: string\n  position: 'start' | 'end'\n}\n\n/** Convert editor-only state to the document protocol accepted by DOCX writers. */\nexport function toDocxExportDocument(document: IDocxDocumentMeta): IDocxDocumentMeta {\n  const result = cloneTree(document)\n  const { bookmarks, contentZones } = result\n  delete result.bookmarks\n  delete result.contentZones\n  delete result.meta\n  result.header ??= contentZones?.header\n  result.footer ??= contentZones?.footer\n  if (!bookmarks) return result\n\n  // Resolve all paths before splitting runs so overlapping ranges keep their positions.\n  const boundaries = new Map<IElement, BookmarkBoundary[]>()\n  const addBoundary = (name: string, position: BookmarkBoundary['position'], point: IPosition) => {\n    const node = getByPath(result.elements, point.path)\n    const length = node?.extension?.bookmarkMarker ? 0 : node?.type === 'text' ? node.value.length : 1\n    if (!node || !Number.isInteger(point.offset) || point.offset < 0 || point.offset > length) {\n      throw new Error(`Invalid bookmark position: ${name}`)\n    }\n    const entries = boundaries.get(node) ?? []\n    entries.push({ name, position, offset: point.offset })\n    boundaries.set(node, entries)\n  }\n  for (const bookmark of bookmarks) {\n    const { anchor, focus } = bookmark.range\n    const [start, end] = comparePosition(anchor, focus) <= 0 ? [anchor, focus] : [focus, anchor]\n    addBoundary(bookmark.name, 'start', start)\n    addBoundary(bookmark.name, 'end', end)\n  }\n\n  const marker = (boundary: BookmarkBoundary): IElement => ({\n    type: 'text',\n    value: '',\n    extension: { bookmarkMarker: { name: boundary.name, position: boundary.position } }\n  })\n  const convert = (elements: IElement[]): IElement[] => elements.flatMap(node => {\n    if (isParagraphContainer(node)) {\n      node.valueList = convert(node.valueList)\n    } else if (isTable(node)) {\n      for (const row of node.trList) {\n        for (const cell of row.tdList) cell.value = convert(cell.value)\n      }\n    }\n    const entries = boundaries.get(node)?.sort((a, b) => a.offset - b.offset) ?? []\n    // Runtime ranges are authoritative; replace imported markers instead of duplicating them.\n    if (node.extension?.bookmarkMarker) return entries.map(marker)\n    if (!entries.length) return [node]\n    if (node.type !== 'text') {\n      return [\n        ...entries.filter(entry => entry.offset === 0).map(marker),\n        node,\n        ...entries.filter(entry => entry.offset !== 0).map(marker)\n      ]\n    }\n    const parts: IElement[] = []\n    let offset = 0\n    for (const entry of entries) {\n      if (entry.offset > offset) parts.push({ ...node, value: node.value.slice(offset, entry.offset) })\n      parts.push(marker(entry))\n      offset = entry.offset\n    }\n    if (offset < node.value.length || !node.value.length) {\n      parts.push({ ...node, value: node.value.slice(offset) })\n    }\n    return parts\n  })\n  result.elements = convert(result.elements)\n  return result\n}\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') 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/**\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 (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 (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","/**\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)\n    case 'decimalEnclosedCircle':\n      if (num >= 1 && num <= 20) return String.fromCodePoint(0x2460 + num - 1)\n      if (num >= 21 && num <= 35) return String.fromCodePoint(0x3251 + num - 21)\n      if (num >= 36 && num <= 50) return String.fromCodePoint(0x32B1 + num - 36)\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'\n  private diagnostics: NonNullable<DocumentLayout['diagnostics']> = []\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 sectionWidths = document?.sections?.map((section, index) => {\n      if (section.pageWidth === undefined || section.pageHeight === undefined || !section.margins) throw new TypeError(`Java sections[${index}] 缺少页面尺寸或页边距`)\n      return section.pageWidth - section.margins[1] - section.margins[3]\n    })\n    const columnGroups = new Map<string, { widths: number[]; gap: number }>()\n    let columnSection = 0\n    for (const element of elements) {\n      const data = element as IElement & { columnId?: string; columnCount?: number; columnWidths?: number[]; columnGap?: number }\n      if (data.columnId && data.columnCount) {\n        const gap = data.columnGap ?? 0\n        const width = sectionWidths?.[columnSection] ?? contentWidth\n        columnGroups.set(data.columnId, { gap, widths: data.columnWidths ?? Array(data.columnCount).fill((width - gap * (data.columnCount - 1)) / data.columnCount) })\n      }\n      if (element.type === 'pageBreak' && sectionBreaks.has(element.value)) columnSection++\n    }\n    const rawBlocks = this.layoutBlocks(elements, [], contentWidth, sectionWidths)\n    for (let index = 0; index < rawBlocks.length; index++) {\n      const block = rawBlocks[index]\n      if (block.kind !== 'paragraph') continue\n      const input = this.paragraphInputs.get(block)!\n      const columnId = input.runs.find(run => (run as Record<string, unknown>).columnId)?.columnId as string | undefined\n      const columns = columnId ? columnGroups.get(columnId) : undefined\n      if (columns) rawBlocks[index] = this.layoutParagraph({ ...input, availableWidth: columns.widths[0] })\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[] = []\n    let activeColumns: { widths: number[]; gap: number } | undefined\n    let activeColumnId: string | undefined\n    let columnIndex = 0\n    let columnTop = 0\n    let columnBottom = 0\n    const columnX = () => activeColumns ? activeColumns.widths.slice(0, columnIndex).reduce((sum, width) => sum + width + activeColumns!.gap, 0) : 0\n    const advanceColumn = () => {\n      columnBottom = Math.max(columnBottom, cursorY)\n      if (activeColumns && columnIndex + 1 < activeColumns.widths.length) { columnIndex++; cursorY = columnTop }\n      else { pushPage(); columnIndex = 0; columnTop = 0; columnBottom = 0 }\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]\n      const pageOriginY = previous ? previous.rect.y + previous.rect.height + pageGap : pageGap\n      const section = document?.sections?.[sectionIndex]\n      const headerPartId = document?.sections ? resolveHeaderFooterPart(document, 'header', sectionIndex, pageIndex, pageIndex === sectionFirstPage) : undefined\n      const footerPartId = document?.sections ? resolveHeaderFooterPart(document, 'footer', sectionIndex, pageIndex, pageIndex === sectionFirstPage) : undefined\n      this.layoutZone = `header:${headerPartId ?? ''}`\n      const pageHeaders = document?.sections ? this.layoutBlocks(headerPartId ? document.headerFooterParts?.[headerPartId] ?? [] : [], [], contentWidth) : headerBlocks\n      this.layoutZone = `footer:${footerPartId ?? ''}`\n      const pageFooters = document?.sections ? this.layoutBlocks(footerPartId ? document.headerFooterParts?.[footerPartId] ?? [] : [], [], contentWidth) : footerBlocks\n      this.layoutZone = 'main'\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 sourceColumnId = (source as { columnId?: string } | undefined)?.columnId\r\n      if (sourceColumnId !== activeColumnId) {\r\n        cursorY = Math.max(cursorY, columnBottom)\r\n        activeColumnId = sourceColumnId\r\n        activeColumns = sourceColumnId ? columnGroups.get(sourceColumnId) : undefined\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) => {\n            if (attrs?.[name] === undefined) throw new TypeError(`Java anchored image 缺少 ${name}`)\n            return Number(attrs[name]) / 9525\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        if (breakType !== 'continuous') 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      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')) {\n            const anchor = geometry.anchorParagraphId ? placedAnchors.get(geometry.anchorParagraphId) : undefined\n            if (!anchor) throw new TypeError('Java anchored image 缺少已排版的 anchorParagraphId')\n            origin = isX ? anchor.column.x : anchor.paragraph.rect.y + (anchor.paragraph.lines[0]?.y ?? 0)\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)\n          }\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) 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))\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') {\n      const result = this.computeParagraph(input)\n      this.paragraphInputs.set(result, input)\n      return result\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 } }\n    this.paragraphInputs.set(result, input)\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    for (let ri = 0; ri < runs.length; ri++) {\r\n      const rawRun = runs[ri]\r\n      // 超链接：把 valueList 文本拼成等价 text run，标记 URL，渲染为蓝色下划线\r\n      let hyperlinkUrl: string | undefined\r\n      let run: IElement = 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 => String((r as unknown as { value?: string }).value ?? '')).join('')\r\n        hyperlinkUrl = String((rawRun as unknown as { value?: string }).value ?? '')\r\n        const base = (vl[0] as unknown as Record<string, unknown>) ?? {}\r\n        run = {\r\n          type: 'text', value: text,\r\n          font: base.font, size: base.size, bold: base.bold, italic: base.italic,\r\n          color: '#0563C1', underline: true\r\n        } as unknown as IElement\r\n      } else if (rawRun.type !== 'text') {\r\n        continue\r\n      }\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        // 若当前行已有内容且首个字符放不下 → 先换行再试，避免溢出被裁\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) {\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          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 && 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 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'\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\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})`\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\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) {\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(opts.activeRevision.color, true) })\n      } else if (activeColor && opts.activeGroupId && inl.groupIds?.includes(opts.activeGroupId)) {\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(activeColor, true) })\n      } else if (hasGroupHighlight) {\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\n      const revisionType = run && 'revisionId' in run && run.revisionId && 'revisionType' in run\n        ? run.revisionType : undefined\n      const inserted = revisionType === 'insert'\n      const deleted = revisionType === 'delete'\n      const revisionColor = inserted || deleted\n        ? getAuthorColor(run && 'revisionAuthor' in run ? String(run.revisionAuthor ?? '') : '')\n        : undefined\n      const textColor = revisionColor ?? inl.color\n      const font = fontOf(inl)\r\n      const key = `${font}||${textColor}`\n      addBucket(buckets, key, {\r\n        font, color: textColor,\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.\n      if (inserted || inl.underline) {\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\n        })\r\n      }\r\n      if (deleted || inl.strikeout) {\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\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}\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 * @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: _run, path: _path, ...paint } = inl\r\n      runsKey.push(JSON.stringify([line.x, line.y, line.height, line.baseline, paint]))\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. */\n  private groupBlockIds = new Map<string, Set<number>>()\n  private revisionBlockIds = new Map<string, Set<number>>()\n  private activeRevision: { id: string; color: string } | null = null\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. */\n  setEyeCare(enabled: boolean): void {\n    if (enabled) this.bgLayer.style.setProperty('--vd-eye-care-bg', '#C7EDCC')\n    else this.bgLayer.style.removeProperty('--vd-eye-care-bg')\n  }\n\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 {\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.\n    onForeground?.(canvas.toDataURL('image/png', quality))\n    ctx.globalCompositeOperation = 'destination-over'\n    ctx.fillStyle = this.opts.pageBg\n    ctx.fillRect(0, 0, page.rect.width, page.rect.height)\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()\n    this.revisionBlockIds.clear()\n    const collect = (blocks: BlockNode[]) => {\n      for (const block of blocks) {\n        if (block.kind === 'table') {\n          for (const row of block.rows) {\n            for (const cell of row.cells) collect(cell.content)\n          }\n        } else if (block.kind === 'paragraph') {\n          for (const line of block.lines) {\n            for (const inline of line.inlines) {\n              const revisionId = inline.run && 'revisionId' in inline.run ? inline.run.revisionId : undefined\n              if (typeof revisionId === 'string' && revisionId) {\n                let blockIds = this.revisionBlockIds.get(revisionId)\n                if (!blockIds) this.revisionBlockIds.set(revisionId, blockIds = new Set())\n                blockIds.add(block.id)\n              }\n              for (const groupId of inline.groupIds ?? []) {\n                let blockIds = this.groupBlockIds.get(groupId)\n                if (!blockIds) this.groupBlockIds.set(groupId, blockIds = new Set())\n                blockIds.add(block.id)\n              }\n            }\n          }\n        }\n      }\n    }\n    for (const page of layout.pages) {\n      collect(page.blocks)\n      collect(page.headerBlocks ?? [])\n      collect(page.footerBlocks ?? [])\n    }\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. */\n  setActiveGroup(groupId: string | null): boolean {\n    const previous = this.opts.activeGroupId ?? null\n    if (previous === groupId) return false\n    this.opts.activeGroupId = groupId\n    for (const id of [previous, groupId]) {\n      if (id === null) continue\n      const blocks = this.groupBlockIds.get(id)\n      if (blocks) this.markDirty(blocks)\n    }\n    return true\n  }\n\n  /** Invalidate only the old and new revision's paragraph bitmaps. */\n  setActiveRevision(id: string | null, color = '#e60000'): boolean {\n    const previous = this.activeRevision\n    if ((previous?.id ?? null) === id && (!id || previous?.color === color)) return false\n    this.activeRevision = id === null ? null : { id, color }\n    for (const revisionId of [previous?.id, id]) {\n      if (!revisionId) continue\n      const blocks = this.revisionBlockIds.get(revisionId)\n      if (blocks) this.markDirty(blocks)\n    }\n    return true\n  }\n\n  /** Bound retained bitmap memory with least-recently-used eviction. */\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()\n    this.revisionBlockIds.clear()\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})`\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.rect.width, page.rect.height)\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, pw: number, ph: number): void {\r\n    const [mt, mr, mb, ml] = this.opts.pageMargins\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 })\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 }\n    type Edge = { x1: number; y1: number; x2: number; y2: number; side: BorderSide }\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 }\n    const borderRank = (side: BorderSide) => rank[side.officeType ?? side.style] ?? 1\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)\n          || secondaryBrightness(a.side.color) - secondaryBrightness(b.side.color)\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      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","/**\r\n * VerveDocs View —— 表格右键菜单\r\n *\r\n * 纯 DOM 实现，无框架依赖。支持子菜单、图标、快捷键、分隔线。\r\n */\r\n\r\nimport './assets/css/context-menu.css'\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  /**\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))\n  }\n\n  /** Display custom menu content with the same positioning and dismissal lifecycle. */\n  showContent(x: number, y: number, content: HTMLDivElement): void {\n    this.hide()\r\n    this.menuEl = content\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.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.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 = '无'\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) {\r\n      el.style.left = `${Math.max(4, vw - rect.width - 4)}px`\r\n    }\r\n    if (y + rect.height > vh) {\r\n      el.style.top = `${Math.max(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. */\nexport function positionHandle(\n  handle: HTMLElement,\n  x: number,\n  y: number,\n  size: number,\n  viewport: DOMRect\n): boolean {\n  const left = Math.round(x)\n  const top = Math.round(y)\n  const visible = left >= Math.max(0, viewport.left) &&\n    top >= Math.max(0, viewport.top) &&\n    left + size <= Math.min(window.innerWidth, viewport.right) &&\n    top + size <= Math.min(window.innerHeight, viewport.bottom)\n\n  handle.style.boxSizing = 'border-box'\n  handle.style.left = `${left}px`\n  handle.style.top = `${top}px`\n  handle.style.display = visible ? 'flex' : 'none'\n  return visible\n}\n","export default \"<div class=\\\"pw-panel-mask tp-mask\\\">\\n  <form class=\\\"pw-panel tp-panel\\\" role=\\\"dialog\\\" aria-modal=\\\"true\\\" aria-labelledby=\\\"tp-title\\\" novalidate>\\n    <div class=\\\"pw-panel-title\\\" id=\\\"tp-title\\\">表格属性</div>\\n    <div class=\\\"tp-tabs\\\" role=\\\"tablist\\\" aria-label=\\\"属性类别\\\">\\n      <button type=\\\"button\\\" id=\\\"tp-table-tab\\\" role=\\\"tab\\\" aria-selected=\\\"true\\\" aria-controls=\\\"tp-table-pane\\\" data-tab=\\\"table\\\">表格</button>\\n      <button type=\\\"button\\\" id=\\\"tp-cell-tab\\\" role=\\\"tab\\\" aria-selected=\\\"false\\\" aria-controls=\\\"tp-cell-pane\\\" data-tab=\\\"cell\\\" tabindex=\\\"-1\\\">单元格</button>\\n    </div>\\n    <div class=\\\"tp-body\\\">\\n      <section id=\\\"tp-table-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-table-tab\\\" data-pane=\\\"table\\\">\\n        <p class=\\\"tp-hint\\\">预设替换整个表格的边框组合，未选中的边将清除。</p>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>边框</legend>\\n          <div class=\\\"tp-border-layout\\\">\\n            <div class=\\\"tp-settings\\\">\\n              <label class=\\\"tp-label\\\" for=\\\"tp-type\\\">预设</label>\\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>\\n              <div class=\\\"tp-presets\\\" role=\\\"group\\\" aria-label=\\\"边框预设\\\">\\n                <button type=\\\"button\\\" data-preset=\\\"all\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"all\\\" aria-hidden=\\\"true\\\"></span>全部</button>\\n                <button type=\\\"button\\\" data-preset=\\\"outside\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"outside\\\" aria-hidden=\\\"true\\\"></span>外侧</button>\\n                <button type=\\\"button\\\" data-preset=\\\"none\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"none\\\" aria-hidden=\\\"true\\\"></span>无边框</button>\\n                <button type=\\\"button\\\" data-preset=\\\"inside\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside\\\" aria-hidden=\\\"true\\\"></span>内部</button>\\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>\\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>\\n                <button type=\\\"button\\\" data-preset=\\\"top\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"top\\\" aria-hidden=\\\"true\\\"></span>上边框</button>\\n                <button type=\\\"button\\\" data-preset=\\\"bottom\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"bottom\\\" aria-hidden=\\\"true\\\"></span>下边框</button>\\n                <button type=\\\"button\\\" data-preset=\\\"left\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"left\\\" aria-hidden=\\\"true\\\"></span>左边框</button>\\n                <button type=\\\"button\\\" data-preset=\\\"right\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"right\\\" aria-hidden=\\\"true\\\"></span>右边框</button>\\n              </div>\\n              <label class=\\\"tp-label\\\" for=\\\"tp-color\\\">颜色</label>\\n              <div class=\\\"tp-color-field\\\" data-empty=\\\"true\\\">\\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\\\">\\n                <input type=\\\"color\\\" value=\\\"#000000\\\" data-color-picker=\\\"color\\\" aria-label=\\\"选择边框颜色（当前保持原样）\\\" aria-describedby=\\\"tp-color-help\\\">\\n              </div>\\n              <label class=\\\"tp-label\\\" for=\\\"tp-width\\\">内框宽度</label>\\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>\\n              <label class=\\\"tp-label\\\" for=\\\"tp-external-width\\\">外框宽度</label>\\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>\\n              <p id=\\\"tp-color-help\\\" class=\\\"tp-field-help\\\">颜色格式：#RRGGBB；留空保持原样。</p>\\n            </div>\\n            <div class=\\\"tp-preview-box\\\">\\n              <span class=\\\"tp-label\\\">预览</span>\\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>\\n              <p class=\\\"tp-hint\\\" data-preview-caption aria-live=\\\"polite\\\">边框示意</p>\\n            </div>\\n          </div>\\n        </fieldset>\\n      </section>\\n      <section id=\\\"tp-cell-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-cell-tab\\\" data-pane=\\\"cell\\\" hidden>\\n        <p class=\\\"tp-hint\\\">以下设置仅应用于当前单元格（右键所在格）。</p>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>底色</legend>\\n          <div class=\\\"tp-cell-fill\\\">\\n            <label class=\\\"tp-label\\\" for=\\\"tp-background\\\">颜色</label>\\n            <div class=\\\"tp-color-field\\\" data-empty=\\\"true\\\">\\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\\\">\\n              <input type=\\\"color\\\" value=\\\"#000000\\\" data-color-picker=\\\"backgroundColor\\\" aria-label=\\\"选择单元格底色（当前无底色）\\\" aria-describedby=\\\"tp-background-help\\\">\\n            </div>\\n            <button type=\\\"button\\\" data-clear-background>清除底色</button>\\n          </div>\\n          <p id=\\\"tp-background-help\\\" class=\\\"tp-hint\\\">颜色格式：#RRGGBB；留空表示无底色。</p>\\n        </fieldset>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>垂直对齐</legend>\\n          <div class=\\\"tp-cell-align\\\">\\n            <label class=\\\"tp-label\\\" for=\\\"tp-vertical-align\\\">对齐方式</label>\\n            <select id=\\\"tp-vertical-align\\\" name=\\\"verticalAlign\\\" class=\\\"pw-ctrl\\\"><option value=\\\"top\\\">顶端对齐</option><option value=\\\"middle\\\">居中对齐</option><option value=\\\"bottom\\\">底端对齐</option></select>\\n          </div>\\n        </fieldset>\\n      </section>\\n    </div>\\n    <div class=\\\"tp-actions\\\">\\n      <button type=\\\"submit\\\" class=\\\"tp-primary\\\">确定</button>\\n      <button type=\\\"button\\\" data-cancel>取消</button>\\n    </div>\\n  </form>\\n</div>\\n\"","import '../../assets/css/paragraph-layout-widget.css'\nimport panelHtml from '../../assets/components/table-properties-widget.html?raw'\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\n\ninterface Deps {\n  onCommand: (cmd: string, ...args: any[]) => any\n  focusInput: () => void\n}\n\nexport class TablePropertiesWidget {\n  private root: HTMLElement | null = null\n  private initial: Record<string, string> = {}\n  private target: IPosition | null = null\n\n  constructor(private deps: Deps) {}\n\n  show(target: IPosition): void {\n    this.hide()\n    this.target = { path: [...target.path], offset: target.offset }\n    const cmd = this.deps.onCommand\n    const selection = cmd('getRange')\n    cmd('executeReplaceRange', { anchor: this.target, focus: this.target })\n    const borders = cmd('getTableBorders')\n    const cell = cmd('getCellProperties')\n    cmd('executeReplaceRange', selection)\n    if (!borders || !cell) return\n    const container = document.createElement('div')\n    container.innerHTML = panelHtml\n    this.root = container.firstElementChild as HTMLElement\n    document.body.appendChild(this.root)\n    this.initial = {}\n    for (const [name, value] of Object.entries({ ...borders, ...cell })) {\n      const input = this.root.querySelector<HTMLInputElement | HTMLSelectElement>(`[name=\"${name}\"]`)!\n      input.value = value === undefined ? '' : String(value)\n      if (name === 'color' || name === 'backgroundColor') {\n        input.value = input.value.replace(/^#([\\da-f])([\\da-f])([\\da-f])$/i, '#$1$1$2$2$3$3')\n      }\n      this.initial[name] = input.value\n    }\n    this.root.querySelectorAll<HTMLButtonElement>('[data-tab]').forEach(tab => {\n      tab.addEventListener('click', () => this.selectTab(tab.dataset.tab!))\n      tab.addEventListener('keydown', event => {\n        const tabs = Array.from(this.root!.querySelectorAll<HTMLButtonElement>('[data-tab]'))\n        const index = tabs.indexOf(tab)\n        let next: number\n        if (event.key === 'ArrowRight') next = (index + 1) % tabs.length\n        else if (event.key === 'ArrowLeft') next = (index + tabs.length - 1) % tabs.length\n        else if (event.key === 'Home') next = 0\n        else if (event.key === 'End') next = tabs.length - 1\n        else return\n        event.preventDefault()\n        this.selectTab(tabs[next].dataset.tab!)\n        tabs[next].focus()\n      })\n    })\n    this.root.querySelectorAll<HTMLButtonElement>('[data-preset]').forEach(button => {\n      button.addEventListener('click', () => {\n        this.root!.querySelector<HTMLSelectElement>('[name=\"type\"]')!.value = button.dataset.preset!\n        this.updatePreview()\n      })\n    })\n    this.root.querySelectorAll<HTMLInputElement>('[data-color-picker]').forEach(picker => {\n      const input = this.root!.querySelector<HTMLInputElement>(`[name=\"${picker.dataset.colorPicker}\"]`)!\n      const selectColor = () => {\n        input.value = picker.value\n        this.updatePreview()\n      }\n      picker.addEventListener('input', selectColor)\n      picker.addEventListener('change', selectColor)\n    })\n    this.root.querySelector('[data-clear-background]')!.addEventListener('click', () => {\n      const input = this.root!.querySelector<HTMLInputElement>('[name=\"backgroundColor\"]')!\n      input.value = ''\n      this.updatePreview()\n      input.focus()\n    })\n    this.root.addEventListener('input', () => this.updatePreview())\n    this.root.addEventListener('change', () => this.updatePreview())\n    this.updatePreview()\n    this.root.querySelector('[data-cancel]')!.addEventListener('click', () => this.close())\n    this.root.addEventListener('keydown', event => {\n      if (event.key === 'Escape') { event.preventDefault(); this.close() }\n      if (event.key === 'Tab' && this.root) {\n        const controls = Array.from(this.root.querySelectorAll<HTMLElement>('input, select, button'))\n          .filter(control => control.tabIndex >= 0 && !control.closest('[hidden]'))\n        const first = controls[0]\n        const last = controls[controls.length - 1]\n        if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus() }\n        else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus() }\n      }\n      event.stopPropagation()\n    })\n    this.root.querySelector('form')!.addEventListener('submit', event => {\n      event.preventDefault()\n      const invalid = Array.from(this.root!.querySelectorAll<HTMLInputElement>('input'))\n        .find(input => !input.validity.valid)\n      if (invalid) {\n        this.selectTab(invalid.closest<HTMLElement>('[data-pane]')!.dataset.pane!)\n        invalid.focus()\n        invalid.reportValidity()\n        return\n      }\n      this.apply()\n      this.close()\n    })\n    this.root.querySelector<HTMLElement>('[data-tab=\"table\"]')!.focus()\n  }\n\n  private selectTab(name: string): void {\n    this.root!.querySelectorAll<HTMLElement>('[data-tab]').forEach(tab => {\n      const selected = tab.dataset.tab === name\n      tab.setAttribute('aria-selected', String(selected))\n      tab.tabIndex = selected ? 0 : -1\n    })\n    this.root!.querySelectorAll<HTMLElement>('[data-pane]').forEach(pane => {\n      pane.hidden = pane.dataset.pane !== name\n    })\n  }\n\n  private updatePreview(): void {\n    const value = (name: string) => this.root!.querySelector<HTMLInputElement | HTMLSelectElement>(`[name=\"${name}\"]`)!.value\n    this.root!.querySelectorAll<HTMLInputElement>('[data-color-picker]').forEach(picker => {\n      const color = value(picker.dataset.colorPicker!)\n      const valid = /^#[\\da-f]{6}$/i.test(color)\n      picker.value = valid ? color : '#000000'\n      picker.parentElement!.dataset.empty = String(color === '')\n      const label = picker.dataset.colorPicker === 'color' ? '边框颜色' : '单元格底色'\n      const state = color === '' ? (picker.dataset.colorPicker === 'color' ? '保持原样' : '无底色') : (valid ? color : '颜色格式无效')\n      picker.setAttribute('aria-label', `选择${label}（当前${state}）`)\n    })\n    const type = value('type')\n    this.root!.querySelectorAll<HTMLElement>('[data-preset]').forEach(button => {\n      button.setAttribute('aria-pressed', String(button.dataset.preset === type))\n    })\n    const preview = this.root!.querySelector<HTMLElement>('[data-preview]')!\n    preview.dataset.border = type || 'all'\n    preview.style.setProperty('--tp-line-color', /^#[\\da-f]{6}$/i.test(value('color')) ? value('color') : 'var(--tp-muted)')\n    for (const [name, property] of [['width', '--tp-inner-width'], ['externalWidth', '--tp-outer-width']]) {\n      const width = value(name)\n      preview.style.setProperty(property, `${width === '' ? 1 : Math.min(8, Math.max(0, Number(width)))}px`)\n    }\n    this.root!.querySelector<HTMLElement>('[data-preview-caption]')!.textContent = type\n      ? '边框组合示意；虚线仅标示表格范围。未填写的颜色、宽度保持原样。'\n      : '未选择预设，边框组合保持原样；示意不代表混合样式。'\n  }\n\n  private apply(): void {\n    if (!this.root || !this.target) return\n    const cmd = this.deps.onCommand\n    cmd('executeReplaceRange', { anchor: this.target, focus: this.target })\n    const patch: Record<string, string | number> = {}\n    for (const name of ['type', 'color', 'width', 'externalWidth']) {\n      const value = this.root.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value\n      if (value !== '' && value !== this.initial[name]) {\n        patch[name] = name === 'width' || name === 'externalWidth' ? Number(value) : value\n      }\n    }\n    if (Object.keys(patch).length) cmd('executeSetTableBorders', patch)\n    for (const [name, command] of [['verticalAlign', 'executeSetCellVerticalAlign'], ['backgroundColor', 'executeSetCellBackground']]) {\n      const value = this.root.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value\n      if (value !== this.initial[name]) cmd(command, value)\n    }\n  }\n\n  private close(): void {\n    this.hide()\n    this.deps.focusInput()\n  }\n\n  hide(): void {\n    this.root?.remove()\n    this.root = null\n    this.target = null\n  }\n}\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'\nimport { TablePropertiesWidget } from './layout/table-properties-widget'\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  /** 获取当前文档布局，可能为 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 = new 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\n\n  constructor(private deps: TableWidgetDeps) {\n    this.panel = new TablePropertiesWidget({\n      onCommand: (cmd, ...args) => this.deps.onCommand(cmd, ...args),\n      focusInput: () => this.deps.focusInput()\n    })\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    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      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    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      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    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      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.handle) return\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  /* -------------------- 右键菜单 -------------------- */\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    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[]) => { this.deps.onCommand(cmd, ...args) }\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: () => this.panel.show(pos) },\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\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.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.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'\n\n/** Keep selection chrome clipped to the same viewport as the document canvas. */\nexport function createSelectionLayer(container: HTMLElement, name: string): HTMLDivElement {\n  const layer = document.createElement('div')\n  layer.className = `vervedocs-${name}-selection-layer`\n  layer.style.cssText = 'position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:100;display:none;'\n  container.appendChild(layer)\n  return layer\n}\n\nexport function updateSelectionLayer(\n  layer: HTMLElement,\n  bounds: Rect,\n  viewport: Pick<Rect, 'width' | 'height'>\n): boolean {\n  const visible = bounds.x < viewport.width && bounds.y < viewport.height &&\n    bounds.x + bounds.width > 0 && bounds.y + bounds.height > 0\n  layer.style.display = visible ? 'block' : 'none'\n  return visible\n}\n\n/** Place the toolbar beside the object only when it fits inside the editor. */\nexport function positionSelectionToolbar(toolbar: HTMLElement, bounds: Rect, layer: HTMLElement): void {\n  const padding = 4\n  const gap = 6\n  toolbar.style.display = 'flex'\n  toolbar.style.maxWidth = `${Math.max(0, layer.clientWidth - padding * 2)}px`\n  const width = toolbar.offsetWidth\n  const height = toolbar.offsetHeight\n  const x = Math.max(padding, Math.min(\n    bounds.x + bounds.width / 2 - width / 2,\n    layer.clientWidth - width - padding\n  ))\n  let y = bounds.y - height - gap\n  if (y < padding) y = bounds.y + bounds.height + gap\n  if (y < padding || y + height > layer.clientHeight - padding) {\n    toolbar.style.display = 'none'\n    return\n  }\n  toolbar.style.left = `${Math.round(x)}px`\n  toolbar.style.top = `${Math.round(y)}px`\n}\n","/**\r\n * ImageWidget —— 图片交互 widget\r\n *\r\n * 从 Draw 分离的图片 UI 交互逻辑：\r\n *  - 点击图片选中（高亮边框 + 八方向缩放手柄）\r\n *  - 拖拽手柄缩放图片\r\n *  - 悬浮工具栏（删除、重置大小、对齐方式、替换图片）\n *\r\n * 生命周期：create() → handleMouseDown() / update() → destroy()\n */\r\n\r\nimport type { DocumentLayout, ImageBlock } from '../layout-types'\r\nimport type { Path } from '@vervedoc/docx-editor-schema'\nimport { createSelectionLayer, positionSelectionToolbar, updateSelectionLayer } from './selection-layer'\r\n\r\n\r\n/**\r\n * ImageWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、容器信息以及触发命令等。\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;'\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;`\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\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\n    this.handleEls = []\n    this.toolbar = null\n    this.dragging = null\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'\nimport type { Path } from '@vervedoc/docx-editor-schema'\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;'\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;`\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\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\n    this.handleEls = []\n    this.toolbar = null\n    this.dragging = null\n  }\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask\\\">\\n  <div class=\\\"pw-panel\\\">\\n    <div class=\\\"pw-panel-title\\\">段落</div>\\n\\n    <div class=\\\"pw-tabs\\\">\\n      <div class=\\\"pw-tab pw-tab-active\\\" data-tab=\\\"indent\\\">缩进和间距</div>\\n      <div class=\\\"pw-tab\\\" data-tab=\\\"break\\\">换行和分页</div>\\n      <div class=\\\"pw-tab\\\" data-tab=\\\"cjk\\\">中文版式</div>\\n    </div>\\n\\n    <div class=\\\"pw-panel-body\\\">\\n      <!-- ===== Tab 1：缩进和间距 ===== -->\\n      <div class=\\\"pw-pane pw-pane-active\\\" data-pane=\\\"indent\\\">\\n\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>常规</legend>\\n          <div class=\\\"pw-grid\\\">\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">对齐方式</span>\\n              <select id=\\\"pw-align\\\" class=\\\"pw-ctrl\\\">\\n                <option value=\\\"left\\\">左对齐</option>\\n                <option value=\\\"center\\\">居中对齐</option>\\n                <option value=\\\"right\\\">右对齐</option>\\n                <option value=\\\"justify\\\">两端对齐</option>\\n                <option value=\\\"distribute\\\">分散对齐</option>\\n              </select>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">大纲级别</span>\\n              <select id=\\\"pw-outline\\\" class=\\\"pw-ctrl\\\">\\n                <option value=\\\"\\\">正文文本</option>\\n                <option value=\\\"first\\\">1 级</option>\\n                <option value=\\\"second\\\">2 级</option>\\n                <option value=\\\"third\\\">3 级</option>\\n                <option value=\\\"fourth\\\">4 级</option>\\n                <option value=\\\"fifth\\\">5 级</option>\\n                <option value=\\\"sixth\\\">6 级</option>\\n              </select>\\n            </div>\\n          </div>\\n        </fieldset>\\n\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>缩进</legend>\\n          <div class=\\\"pw-grid\\\">\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">文本之前</span>\\n              <input type=\\\"number\\\" id=\\\"pw-indent-left\\\" class=\\\"pw-ctrl\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.01\\\">\\n              <span class=\\\"pw-unit\\\">厘米</span>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">特殊格式</span>\\n              <select id=\\\"pw-special\\\" class=\\\"pw-ctrl\\\">\\n                <option value=\\\"none\\\">无</option>\\n                <option value=\\\"firstLine\\\">首行缩进</option>\\n                <option value=\\\"hanging\\\">悬挂缩进</option>\\n              </select>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">文本之后</span>\\n              <input type=\\\"number\\\" id=\\\"pw-indent-right\\\" class=\\\"pw-ctrl\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.01\\\">\\n              <span class=\\\"pw-unit\\\">厘米</span>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">度量值</span>\\n              <input type=\\\"number\\\" id=\\\"pw-special-value\\\" class=\\\"pw-ctrl\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.01\\\" disabled>\\n              <span class=\\\"pw-unit\\\">厘米</span>\\n            </div>\\n          </div>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" disabled> 如果定义了文档网格，则自动调整右缩进</label>\\n        </fieldset>\\n\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>间距</legend>\\n          <div class=\\\"pw-grid\\\">\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">段前</span>\\n              <input type=\\\"number\\\" id=\\\"pw-spacing-before\\\" class=\\\"pw-ctrl\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.5\\\">\\n              <span class=\\\"pw-unit\\\">磅</span>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">行距</span>\\n              <select id=\\\"pw-lh-type\\\" class=\\\"pw-ctrl\\\">\\n                <option value=\\\"single\\\">单倍行距</option>\\n                <option value=\\\"1.5\\\">1.5 倍行距</option>\\n                <option value=\\\"double\\\">双倍行距</option>\\n                <option value=\\\"atLeast\\\">最小值</option>\\n                <option value=\\\"exact\\\">固定值</option>\\n                <option value=\\\"multiple\\\">多倍行距</option>\\n              </select>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">段后</span>\\n              <input type=\\\"number\\\" id=\\\"pw-spacing-after\\\" class=\\\"pw-ctrl\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.5\\\">\\n              <span class=\\\"pw-unit\\\">磅</span>\\n            </div>\\n            <div class=\\\"pw-field\\\">\\n              <span class=\\\"pw-field-label\\\">设置值</span>\\n              <input type=\\\"number\\\" id=\\\"pw-lh-value\\\" class=\\\"pw-ctrl\\\" value=\\\"1\\\" min=\\\"0\\\" step=\\\"0.05\\\" disabled>\\n              <span class=\\\"pw-unit\\\" id=\\\"pw-lh-unit\\\">磅</span>\\n            </div>\\n          </div>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" disabled> 如果定义了文档网格，则与网格对齐</label>\\n        </fieldset>\\n\\n        <div class=\\\"pw-preview-box\\\">\\n          <div class=\\\"pw-preview-label\\\">预览</div>\\n          <div class=\\\"pw-preview\\\" id=\\\"pw-preview\\\">段落预览文本</div>\\n        </div>\\n      </div>\\n\\n      <!-- ===== Tab 2：换行和分页 ===== -->\\n      <div class=\\\"pw-pane\\\" data-pane=\\\"break\\\">\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>分页</legend>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-widow\\\" disabled> 孤行控制</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-keep-next\\\" disabled> 与下段同页</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-page-break-before\\\" disabled> 段前分页</label>\\n        </fieldset>\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>换行</legend>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-suppress-line-num\\\" disabled> 取消行号</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-suppress-auto-hyphen\\\" disabled> 取消断字</label>\\n        </fieldset>\\n        <div class=\\\"pw-placeholder\\\">该功能将在后续版本支持</div>\\n      </div>\\n\\n      <!-- ===== Tab 3：中文版式 ===== -->\\n      <div class=\\\"pw-pane\\\" data-pane=\\\"cjk\\\">\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>换行</legend>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-word-wrap\\\" disabled> 按中文习惯换行</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-overflow-punct\\\" disabled> 允许标点溢出边界</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-allow-break-word\\\" disabled> 允许西文在单词中间换行</label>\\n        </fieldset>\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>字符间距</legend>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-compress-punct\\\" disabled> 允许行首标点压缩</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-auto-space-cjk-west\\\" disabled> 自动调整中文与西文的间距</label>\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-auto-space-cjk-num\\\" disabled> 自动调整中文与数字的间距</label>\\n        </fieldset>\\n        <fieldset class=\\\"pw-group\\\">\\n          <legend>文字对齐方式</legend>\\n          <div class=\\\"pw-field\\\">\\n            <span class=\\\"pw-field-label\\\">对齐</span>\\n            <select id=\\\"pw-text-align\\\" class=\\\"pw-ctrl\\\" disabled>\\n              <option value=\\\"auto\\\">自动</option>\\n              <option value=\\\"top\\\">顶端对齐</option>\\n              <option value=\\\"center\\\">居中</option>\\n              <option value=\\\"baseline\\\">基线对齐</option>\\n              <option value=\\\"bottom\\\">底端对齐</option>\\n            </select>\\n          </div>\\n        </fieldset>\\n        <div class=\\\"pw-placeholder\\\">该功能将在后续版本支持</div>\\n      </div>\\n    </div>\\n\\n    <div class=\\\"pw-panel-actions\\\">\\n      <button type=\\\"button\\\" id=\\\"pw-cancel\\\">取消</button>\\n      <button type=\\\"button\\\" id=\\\"pw-ok\\\">确定</button>\\n    </div>\\n  </div>\\n</div>\\n\"","/**\n * ParagraphLayoutWidget —— 段落设置弹出面板（对齐 Word 标准）\n *\n * 结构在 paragraph-layout-widget.html，样式在 paragraph-layout-widget.css，\n * 本模块负责注入资源、填充当前值、绑定事件、应用命令。\n * CSS 由 cssInjectedByJsPlugin 自动注入，HTML 通过 ?raw 导入字符串。\n */\nimport '../../assets/css/paragraph-layout-widget.css'\nimport panelHtml from '../../assets/components/paragraph-layout-widget.html?raw'\n\n/** 每厘米对应的像素数（96 DPI） */\nconst PX_PER_CM = 96 / 2.54\n\n/** 命令调用签名：可返回值（用于 getter） */\ntype CommandFn = (cmd: string, ...args: any[]) => any\n\n/** 段落设置弹出面板依赖 */\nexport interface ParagraphLayoutWidgetDeps {\n  /** 触发编辑器命令 / 读取状态 */\n  onCommand: CommandFn\n}\n\n/**\n * 段落设置弹出面板。\n *\n * show() 显示面板并填充当前段落值，hide() 关闭。\n * 确定按钮应用缩进、行距、对齐、大纲级别等命令。\n */\nexport class ParagraphLayoutWidget {\n  /** 面板根元素（.pw-panel-mask） */\n  private root: HTMLElement | null = null\n  /** 命令回调 */\n  private onCommand: CommandFn | null = null\n\n  /** 注入依赖 */\n  setDeps(deps: ParagraphLayoutWidgetDeps): void {\n    this.onCommand = deps.onCommand\n  }\n\n  /**\n   * 显示段落设置面板。\n   */\n  show(): void {\n    this.hide()\n\n    const container = document.createElement('div')\n    container.innerHTML = panelHtml\n    this.root = container.firstElementChild as HTMLElement\n    document.body.appendChild(this.root)\n\n    this.bindTabs()\n    this.bindIndentSpacing()\n    this.fillValues()\n    this.root.querySelector('#pw-cancel')!.addEventListener('click', () => this.hide())\n    this.root.querySelector('#pw-ok')!.addEventListener('click', () => {\n      this.apply()\n      this.hide()\n    })\n  }\n\n  /**\n   * 关闭面板。\n   */\n  hide(): void {\n    if (this.root) { this.root.remove(); this.root = null }\n  }\n\n  /** 绑定 Tab 切换 */\n  private bindTabs(): void {\n    const tabs = this.root!.querySelectorAll<HTMLElement>('.pw-tab')\n    const panes = this.root!.querySelectorAll<HTMLElement>('.pw-pane')\n    tabs.forEach(tab => {\n      tab.addEventListener('click', () => {\n        const key = tab.dataset.tab\n        tabs.forEach(t => t.classList.toggle('pw-tab-active', t === tab))\n        panes.forEach(p => p.classList.toggle('pw-pane-active', p.dataset.pane === key))\n      })\n    })\n  }\n\n  /** 绑定缩进和间距 Tab 的联动交互 */\n  private bindIndentSpacing(): void {\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\n    const lhUnit = this.root!.querySelector<HTMLElement>('#pw-lh-unit')!\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\n\n    const updateLh = () => {\n      const t = lhType.value\n      const fixed = t === 'single' || t === '1.5' || t === 'double'\n      lhValue.disabled = fixed\n      if (t === 'single') { lhValue.value = '1' }\n      else if (t === '1.5') { lhValue.value = '1.5' }\n      else if (t === 'double') { lhValue.value = '2' }\n      lhUnit.textContent = (t === 'atLeast' || t === 'exact') ? '磅' : '倍'\n      this.updatePreview()\n    }\n\n    const updateSpecial = () => {\n      const s = special.value\n      specialValue.disabled = s === 'none'\n      if (s === 'none') { specialValue.value = '0' }\n      this.updatePreview()\n    }\n\n    lhType.addEventListener('change', updateLh)\n    special.addEventListener('change', updateSpecial)\n    lhValue.addEventListener('input', () => this.updatePreview())\n    specialValue.addEventListener('input', () => this.updatePreview())\n\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!\n    align.addEventListener('change', () => this.updatePreview())\n  }\n\n  /** 从编辑器读取当前段落状态并填充表单 */\n  private fillValues(): void {\n    if (!this.onCommand) return\n    const cmd = this.onCommand\n\n    let style: any = null\n    try { style = cmd('getRangeStyle') } catch { /* noop */ }\n    if (!style) return\n\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!\n    const rowFlex = style.rowFlex === 'alignment' ? 'justify' : (style.rowFlex || 'left')\n    align.value = rowFlex\n\n    const outline = this.root!.querySelector<HTMLSelectElement>('#pw-outline')!\n    outline.value = style.level || ''\n\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\n    const lh = Number(style.lineHeight ?? 1.5)\n    const rule: string = style.lineHeightRule || 'auto'\n    if (rule === 'exact') { lhType.value = 'exact'; lhValue.value = String(Math.round(lh * 72 / 96 * 100) / 100) }\n    else if (rule === 'atLeast') { lhType.value = 'atLeast'; lhValue.value = String(Math.round(lh * 72 / 96 * 100) / 100) }\n    else if (lh === 1) { lhType.value = 'single' }\n    else if (lh === 1.5) { lhType.value = '1.5' }\n    else if (lh === 2) { lhType.value = 'double' }\n    else { lhType.value = 'multiple'; lhValue.value = String(lh) }\n    this.syncLhDisabled()\n\n    const spacingAfter = this.root!.querySelector<HTMLInputElement>('#pw-spacing-after')!\n    let spAfter = 0\n    try { spAfter = Number(cmd('getParagraphSpacingAfter')) || 0 } catch { spAfter = Number(style.rowMargin ?? 0) }\n    spacingAfter.value = String(spAfter)\n\n    const spacingBefore = this.root!.querySelector<HTMLInputElement>('#pw-spacing-before')!\n    try { spacingBefore.value = String(Number(cmd('getParagraphSpacingBefore')) || 0) } catch { /* noop */ }\n\n    const indentLeft = this.root!.querySelector<HTMLInputElement>('#pw-indent-left')!\n    const indentRight = this.root!.querySelector<HTMLInputElement>('#pw-indent-right')!\n    try { indentLeft.value = String((Number(cmd('getParagraphIndentLeft')) || 0) / PX_PER_CM) } catch { /* noop */ }\n    try { indentRight.value = String((Number(cmd('getParagraphIndentRight')) || 0) / PX_PER_CM) } catch { /* noop */ }\n\n    let indentPx = 0\n    try { indentPx = Number(cmd('getFirstLineIndent')) || 0 } catch { /* noop */ }\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\n    if (indentPx === 0) {\n      special.value = 'none'; specialValue.value = '0'\n    } else if (indentPx > 0) {\n      special.value = 'firstLine'; specialValue.value = (Math.round((indentPx / PX_PER_CM) * 100) / 100).toFixed(2)\n    } else {\n      special.value = 'hanging'; specialValue.value = (Math.round((Math.abs(indentPx) / PX_PER_CM) * 100) / 100).toFixed(2)\n    }\n    this.syncSpecialDisabled()\n\n    this.updatePreview()\n  }\n\n  /** 同步行距设置值禁用态 */\n  private syncLhDisabled(): void {\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\n    const lhUnit = this.root!.querySelector<HTMLElement>('#pw-lh-unit')!\n    const t = lhType.value\n    const fixed = t === 'single' || t === '1.5' || t === 'double'\n    lhValue.disabled = fixed\n    lhUnit.textContent = (t === 'atLeast' || t === 'exact') ? '磅' : '倍'\n  }\n\n  /** 同步特殊格式度量值禁用态 */\n  private syncSpecialDisabled(): void {\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\n    specialValue.disabled = special.value === 'none'\n  }\n\n  /** 实时更新预览区 */\n  private updatePreview(): void {\n    const preview = this.root!.querySelector<HTMLElement>('#pw-preview')!\n    if (!preview) return\n\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!.value\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!.value\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!.value\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!.value\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!.value\n\n    const alignMap: Record<string, string> = {\n      left: 'left', center: 'center', right: 'right',\n      justify: 'justify', distribute: 'justify'\n    }\n    preview.style.textAlign = alignMap[align] || 'left'\n\n    let lh = 1.5\n    if (lhType === 'single') lh = 1\n    else if (lhType === '1.5') lh = 1.5\n    else if (lhType === 'double') lh = 2\n    else lh = Number(lhValue) || 1.5\n    if (lhType === 'atLeast' || lhType === 'exact') {\n      preview.style.lineHeight = `${lh * 96 / 72}px`\n    } else {\n      preview.style.lineHeight = String(lh)\n    }\n\n    let indent = 0\n    if (special === 'firstLine') indent = Number(specialValue) || 0\n    else if (special === 'hanging') indent = -(Number(specialValue) || 0)\n    preview.style.textIndent = `${indent * PX_PER_CM}px`\n\n    preview.textContent = '段落预览文本'\n  }\n\n  /** 确定按钮：应用所有设置到编辑器 */\n  private apply(): void {\n    if (!this.onCommand) return\n    const cmd = this.onCommand\n\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!.value\n    cmd('executeSetRowFlex', align)\n\n    const outline = this.root!.querySelector<HTMLSelectElement>('#pw-outline')!.value\n    cmd('executeSetTitle', outline || null)\n\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!.value\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!.value\n    let lh = 1.5\n    let rule: 'auto' | 'exact' | 'atLeast' = 'auto'\n    if (lhType === 'single') { lh = 1; rule = 'auto' }\n    else if (lhType === '1.5') { lh = 1.5; rule = 'auto' }\n    else if (lhType === 'double') { lh = 2; rule = 'auto' }\n    else if (lhType === 'atLeast') { lh = (Number(lhValue) || 1) * 96 / 72; rule = 'atLeast' }\n    else if (lhType === 'exact') { lh = (Number(lhValue) || 1) * 96 / 72; rule = 'exact' }\n    else { lh = Number(lhValue) || 1; rule = 'auto' }\n    cmd('executeSetLineHeight', lh, rule)\n\n    const spacingBefore = this.root!.querySelector<HTMLInputElement>('#pw-spacing-before')!.value\n    cmd('executeSetParagraphSpacingBefore', Number(spacingBefore) || 0)\n\n    const spacingAfter = this.root!.querySelector<HTMLInputElement>('#pw-spacing-after')!.value\n    cmd('executeSetParagraphSpacingAfter', Number(spacingAfter) || 0)\n\n    const indentLeft = this.root!.querySelector<HTMLInputElement>('#pw-indent-left')!.value\n    const indentRight = this.root!.querySelector<HTMLInputElement>('#pw-indent-right')!.value\n    cmd('executeSetParagraphIndentLeft', (Number(indentLeft) || 0) * PX_PER_CM)\n    cmd('executeSetParagraphIndentRight', (Number(indentRight) || 0) * PX_PER_CM)\n\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!.value\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!.value\n    let indentPx = 0\n    if (special === 'firstLine') indentPx = (Number(specialValue) || 0) * PX_PER_CM\n    else if (special === 'hanging') indentPx = -(Number(specialValue) || 0) * PX_PER_CM\n    cmd('executeSetFirstLineIndent', indentPx)\n  }\n}\n","export default \"<div class=\\\"fw-panel-mask\\\">\\n  <div class=\\\"fw-panel\\\">\\n    <div class=\\\"fw-panel-title\\\">字体</div>\\n\\n    <div class=\\\"fw-tabs\\\">\\n      <div class=\\\"fw-tab fw-tab-active\\\" data-tab=\\\"font\\\">字体</div>\\n      <div class=\\\"fw-tab\\\" data-tab=\\\"spacing\\\">字符间距</div>\\n    </div>\\n\\n    <div class=\\\"fw-panel-body\\\">\\n      <!-- ===== Tab 1：字体 ===== -->\\n      <div class=\\\"fw-pane fw-pane-active\\\" data-pane=\\\"font\\\">\\n        <fieldset class=\\\"fw-group\\\">\\n          <legend>字体</legend>\\n          <div class=\\\"fw-row\\\">\\n            <span class=\\\"fw-label\\\">中文字体</span>\\n            <select id=\\\"fw-font-cjk\\\" class=\\\"fw-input\\\"></select>\\n          </div>\\n          <div class=\\\"fw-row\\\">\\n\\n            <span class=\\\"fw-label\\\">字形</span>\\n            <select id=\\\"fw-style\\\" class=\\\"fw-input\\\">\\n              <option value=\\\"regular\\\">常规</option>\\n              <option value=\\\"italic\\\">倾斜</option>\\n              <option value=\\\"bold\\\">加粗</option>\\n              <option value=\\\"bold-italic\\\">加粗倾斜</option>\\n            </select>\\n          </div>\\n          <div class=\\\"fw-row\\\">\\n            <span class=\\\"fw-label\\\">字号</span>\\n            <select id=\\\"fw-size\\\" class=\\\"fw-input\\\"></select>\\n          </div>\\n          <div class=\\\"fw-row\\\">\\n            <span class=\\\"fw-label\\\">颜色</span>\\n            <input type=\\\"color\\\" id=\\\"fw-color\\\" class=\\\"fw-color\\\" value=\\\"#000000\\\">\\n          </div>\\n        </fieldset>\\n\\n        <fieldset class=\\\"fw-group\\\">\\n          <legend>效果</legend>\\n          <div class=\\\"fw-check-grid\\\">\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-strikeout\\\"> 删除线</label>\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-underline\\\"> 下划线</label>\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-superscript\\\"> 上标</label>\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-subscript\\\"> 下标</label>\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-double-strikeout\\\"> 双删除线</label>\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-hidden\\\"> 隐藏</label>\\n          </div>\\n        </fieldset>\\n\\n        <div class=\\\"fw-preview-box\\\">\\n          <div class=\\\"fw-preview-label\\\">预览</div>\\n          <div class=\\\"fw-preview\\\" id=\\\"fw-preview\\\">字体预览文本 ABCabc 123</div>\\n        </div>\\n      </div>\\n\\n      <!-- ===== Tab 2：字符间距 ===== -->\\n      <div class=\\\"fw-pane\\\" data-pane=\\\"spacing\\\">\\n        <fieldset class=\\\"fw-group\\\">\\n          <legend>间距</legend>\\n          <div class=\\\"fw-row\\\">\\n            <span class=\\\"fw-label\\\">缩放</span>\\n            <select id=\\\"fw-scale\\\" class=\\\"fw-input\\\">\\n              <option value=\\\"100\\\">100%</option>\\n              <option value=\\\"90\\\">90%</option>\\n              <option value=\\\"80\\\">80%</option>\\n              <option value=\\\"66\\\">66%</option>\\n              <option value=\\\"50\\\">50%</option>\\n              <option value=\\\"200\\\">200%</option>\\n              <option value=\\\"150\\\">150%</option>\\n            </select>\\n          </div>\\n          <div class=\\\"fw-row\\\">\\n            <span class=\\\"fw-label\\\">间距</span>\\n            <select id=\\\"fw-spacing-type\\\" class=\\\"fw-input\\\">\\n              <option value=\\\"normal\\\">标准</option>\\n              <option value=\\\"expanded\\\">加宽</option>\\n              <option value=\\\"condensed\\\">紧缩</option>\\n            </select>\\n            <input type=\\\"number\\\" id=\\\"fw-spacing-value\\\" class=\\\"fw-input fw-sm\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.1\\\">\\n            <span class=\\\"fw-unit\\\">磅</span>\\n          </div>\\n          <div class=\\\"fw-row\\\">\\n            <span class=\\\"fw-label\\\">位置</span>\\n            <select id=\\\"fw-position-type\\\" class=\\\"fw-input\\\">\\n              <option value=\\\"normal\\\">标准</option>\\n              <option value=\\\"raised\\\">提升</option>\\n              <option value=\\\"lowered\\\">降低</option>\\n            </select>\\n            <input type=\\\"number\\\" id=\\\"fw-position-value\\\" class=\\\"fw-input fw-sm\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.1\\\">\\n            <span class=\\\"fw-unit\\\">磅</span>\\n          </div>\\n        </fieldset>\\n\\n        <div class=\\\"fw-preview-box\\\">\\n          <div class=\\\"fw-preview-label\\\">预览</div>\\n          <div class=\\\"fw-preview\\\" id=\\\"fw-preview-spacing\\\">字符间距预览 ABCabc 123</div>\\n        </div>\\n\\n        <div class=\\\"fw-placeholder\\\">间距与位置功能将在后续版本支持</div>\\n      </div>\\n    </div>\\n\\n    <div class=\\\"fw-panel-actions\\\">\\n      <button type=\\\"button\\\" id=\\\"fw-cancel\\\">取消</button>\\n      <button type=\\\"button\\\" id=\\\"fw-ok\\\">确定</button>\\n    </div>\\n  </div>\\n</div>\\n\"","/**\n * FontLayoutWidget —— 字体设置弹出面板（对齐 Word 标准）\n *\n * 结构在 font-layout-widget.html，样式在 font-layout-widget.css，\n * 本模块负责注入资源、填充当前值、绑定事件、应用命令。\n */\nimport '../../assets/css/font-layout-widget.css'\nimport panelHtml from '../../assets/components/font-layout-widget.html?raw'\nimport {\n  FONT_FAMILY_MAP,\n  FONT_FAMILY_LABEL,\n  FONT_SIZE,\n  FONT_SIZE_LIST\n} from '@vervedoc/docx-editor-schema'\n\n/** 命令调用签名：可返回值（用于 getter） */\ntype CommandFn = (cmd: string, ...args: any[]) => any\n\n/** 字体设置弹出面板依赖 */\nexport interface FontLayoutWidgetDeps {\n  /** 触发编辑器命令 / 读取状态 */\n  onCommand: CommandFn\n}\n\n/**\n * 字体设置弹出面板。\n *\n * show() 显示面板并填充当前字体值，hide() 关闭。\n * 确定按钮应用字体、字号、字形、颜色、效果等命令。\n */\nexport class FontLayoutWidget {\n  /** 面板根元素 */\n  private root: HTMLElement | null = null\n  /** 命令回调 */\n  private onCommand: CommandFn | null = null\n\n  /** 注入依赖 */\n  setDeps(deps: FontLayoutWidgetDeps): void {\n    this.onCommand = deps.onCommand\n  }\n\n  /** 显示字体设置面板 */\n  show(): void {\n    this.hide()\n\n    const container = document.createElement('div')\n    container.innerHTML = panelHtml\n    this.root = container.firstElementChild as HTMLElement\n    document.body.appendChild(this.root)\n\n    this.fillFontOptions()\n    this.fillSizeOptions()\n    this.bindTabs()\n    this.bindPreview()\n    this.fillValues()\n    this.root.querySelector('#fw-cancel')!.addEventListener('click', () => this.hide())\n    this.root.querySelector('#fw-ok')!.addEventListener('click', () => {\n      this.apply()\n      this.hide()\n    })\n  }\n\n  /** 关闭面板 */\n  hide(): void {\n    if (this.root) { this.root.remove(); this.root = null }\n  }\n\n  /** 填充中文字体下拉选项 */\n  private fillFontOptions(): void {\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!\n    const opts = FONT_FAMILY_MAP.map(e => {\n      const o = document.createElement('option')\n      o.value = e.value\n      o.textContent = e.label\n      return o\n    })\n    cjk.append(...opts)\n  }\n\n  /** 填充字号下拉选项 */\n  private fillSizeOptions(): void {\n    const size = this.root!.querySelector<HTMLSelectElement>('#fw-size')!\n    for (const item of FONT_SIZE_LIST) {\n      const o = document.createElement('option')\n      o.value = String(item)\n      o.textContent = String(item)\n      size.appendChild(o)\n    }\n  }\n\n  /** 绑定 Tab 切换 */\n  private bindTabs(): void {\n    const tabs = this.root!.querySelectorAll<HTMLElement>('.fw-tab')\n    const panes = this.root!.querySelectorAll<HTMLElement>('.fw-pane')\n    tabs.forEach(tab => {\n      tab.addEventListener('click', () => {\n        const key = tab.dataset.tab\n        tabs.forEach(t => t.classList.toggle('fw-tab-active', t === tab))\n        panes.forEach(p => p.classList.toggle('fw-pane-active', p.dataset.pane === key))\n      })\n    })\n  }\n\n  /** 绑定实时预览 */\n  private bindPreview(): void {\n    const ids = [\n      '#fw-font-cjk', '#fw-style', '#fw-size', '#fw-color',\n      '#fw-strikeout', '#fw-underline'\n    ]\n    for (const id of ids) {\n      const el = this.root!.querySelector<HTMLElement>(id)!\n      el.addEventListener('input', () => this.updatePreview())\n      el.addEventListener('change', () => this.updatePreview())\n    }\n    const scale = this.root!.querySelector<HTMLElement>('#fw-scale')!\n    scale.addEventListener('change', () => this.updatePreviewSpacing())\n  }\n\n  /** 从编辑器读取当前字体状态并填充表单 */\n  private fillValues(): void {\n    if (!this.onCommand) return\n    let style: any = null\n    try { style = this.onCommand('getRangeStyle') } catch { /* noop */ }\n    if (!style) return\n\n    const fontValue = style.font || 'SimSun'\n    const fontLabel = FONT_FAMILY_LABEL[fontValue] || fontValue\n    const fontEntry = FONT_FAMILY_MAP.find(e => e.label === fontLabel)\n\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!\n    if (fontEntry) {\n      cjk.value = fontEntry.value\n    }\n\n    const styleSel = this.root!.querySelector<HTMLSelectElement>('#fw-style')!\n    const bold = !!style.bold\n    const italic = !!style.italic\n    styleSel.value = bold && italic ? 'bold-italic' : bold ? 'bold' : italic ? 'italic' : 'regular'\n\n    const sizeSel = this.root!.querySelector<HTMLSelectElement>('#fw-size')!\n    const pt = Number(style.size) || 10.5\n    const cnName = Object.keys(FONT_SIZE).find(k => FONT_SIZE[k] === pt)\n    sizeSel.value = cnName ? cnName : String(pt)\n    if (!sizeSel.value) sizeSel.value = '五号'\n\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!\n    color.value = style.color || '#000000'\n\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!\n    strikeout.checked = !!style.strikeout\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!\n    underline.checked = !!style.underline\n\n    const doubleStrikeout = this.root!.querySelector<HTMLInputElement>('#fw-double-strikeout')!\n    doubleStrikeout.checked = !!style.doubleStrikeout\n    const hidden = this.root!.querySelector<HTMLInputElement>('#fw-hidden')!\n    hidden.checked = !!style.hidden\n    const superscript = this.root!.querySelector<HTMLInputElement>('#fw-superscript')!\n    superscript.checked = !!style.superscript\n    const subscript = this.root!.querySelector<HTMLInputElement>('#fw-subscript')!\n    subscript.checked = !!style.subscript\n\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!\n    scale.value = String(style.characterScale || 100)\n\n    this.updatePreview()\n    this.updatePreviewSpacing()\n  }\n\n  /** 实时更新字体预览 */\n  private updatePreview(): void {\n    const preview = this.root!.querySelector<HTMLElement>('#fw-preview')!\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!.value\n    const styleVal = this.root!.querySelector<HTMLSelectElement>('#fw-style')!.value\n    const sizeVal = this.root!.querySelector<HTMLSelectElement>('#fw-size')!.value\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!.value\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!.checked\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!.checked\n\n    const entry = FONT_FAMILY_MAP.find(e => e.value === cjk)\n    preview.style.fontFamily = entry ? entry.css : cjk\n    const pt = FONT_SIZE[sizeVal] ?? Number(sizeVal) ?? 14\n    preview.style.fontSize = `${pt * 1.5}px`\n    preview.style.color = color\n    preview.style.fontWeight = (styleVal === 'bold' || styleVal === 'bold-italic') ? 'bold' : 'normal'\n    preview.style.fontStyle = (styleVal === 'italic' || styleVal === 'bold-italic') ? 'italic' : 'normal'\n    preview.style.textDecoration = [\n      underline ? 'underline' : '',\n      strikeout ? 'line-through' : ''\n    ].filter(Boolean).join(' ') || 'none'\n  }\n\n  /** 实时更新字符间距预览 */\n  private updatePreviewSpacing(): void {\n    const preview = this.root!.querySelector<HTMLElement>('#fw-preview-spacing')!\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!.value\n    preview.style.transform = `scaleX(${Number(scale) / 100})`\n    preview.style.transformOrigin = 'center'\n  }\n\n  /** 确定按钮：应用所有设置到编辑器 */\n  private apply(): void {\n    if (!this.onCommand) return\n    const cmd = this.onCommand\n\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!.value\n    cmd('executeSetFont', cjk)\n\n    const styleVal = this.root!.querySelector<HTMLSelectElement>('#fw-style')!.value\n    const bold = styleVal === 'bold' || styleVal === 'bold-italic'\n    const italic = styleVal === 'italic' || styleVal === 'bold-italic'\n    cmd('executeSetBold', bold)\n    cmd('executeSetItalic', italic)\n\n    const sizeVal = this.root!.querySelector<HTMLSelectElement>('#fw-size')!.value\n    const pt = FONT_SIZE[sizeVal] ?? Number(sizeVal)\n    if (pt) cmd('executeSetSize', pt)\n\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!.value\n    if (color) cmd('executeSetColor', color)\n\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!.checked\n    cmd('executeSetStrikeout', strikeout)\n\n    const doubleStrikeout = this.root!.querySelector<HTMLInputElement>('#fw-double-strikeout')!.checked\n    cmd('executeSetDoubleStrikeout', doubleStrikeout)\n\n    const hidden = this.root!.querySelector<HTMLInputElement>('#fw-hidden')!.checked\n    cmd('executeSetHidden', hidden)\n\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!.checked\n    cmd('executeSetUnderline', underline)\n\n    const superscript = this.root!.querySelector<HTMLInputElement>('#fw-superscript')!.checked\n    if (superscript) cmd('executeSetSuperscript')\n\n    const subscript = this.root!.querySelector<HTMLInputElement>('#fw-subscript')!.checked\n    if (subscript) cmd('executeSetSubscript')\n\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!.value\n    cmd('executeSetCharacterScale', Number(scale))\n  }\n}\n","/**\r\n * ParagraphWidget —— 段落格式悬浮 widget\r\n *\r\n * 光标在段落中或鼠标悬浮在段落上时，在首行左侧显示小图标，\r\n * 点击弹出菜单可修改标题类型、对齐方式。\n */\r\n\r\nimport type { DocumentLayout, ParagraphBlock, BlockNode } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { IPosition, IRangeStyle } from '@vervedoc/docx-editor-schema'\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 { positionHandle } from './handle-position'\r\nimport '../assets/css/paragraph-handle-menu.css'\n\r\n\r\n/**\r\n * ParagraphWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface ParagraphWidgetDeps {\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\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 * 在段落首行左侧显示拖拽手柄，点击后弹出两行格式菜单，可修改标题级别和对齐方式。\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\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[]) => this.deps.onCommand(cmd, ...args)\r\n    this.panel.setDeps({ onCommand })\r\n    this.fontPanel.setDeps({ onCommand })\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    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.handle) return\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    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   * 在手柄下方弹出格式菜单\n   *\r\n   * 第一行为正文和 H1-H4，第二行为五种对齐方式。\n   * 同时绑定滚动隐藏和点击外部关闭逻辑。\r\n   */\r\n  private showMenu(): void {\r\n    this.hideMenu()\r\n    if (!this.handle || !this.currentBlock) return\r\n\r\n    const style: Partial<IRangeStyle> = this.deps.onCommand('getRangeStyle') ?? {}\n    const alignment = style.rowFlex === ROW_FLEX.ALIGNMENT ? ROW_FLEX.JUSTIFY : (style.rowFlex || ROW_FLEX.LEFT)\n    const menu = document.createElement('div')\n    menu.className = 'ce-paragraph-handle-menu'\n    menu.setAttribute('role', 'toolbar')\n    menu.setAttribute('aria-label', '段落格式')\n    menu.addEventListener('mousedown', e => e.preventDefault())\n    menu.addEventListener('keydown', e => {\n      e.stopPropagation()\n      if (e.key === 'Escape') {\n        this.hideMenu()\n        this.deps.focusInput()\n      }\n    })\n\n    const addButton = (label: string, active: boolean, command: string, value: unknown) => {\n      const button = document.createElement('button')\n      button.type = 'button'\n      button.title = label\n      button.setAttribute('aria-label', label)\n      button.setAttribute('aria-pressed', String(active))\n      button.addEventListener('click', () => {\n        this.hideMenu()\n        this.deps.onCommand(command, value)\n        this.deps.focusInput()\n      })\n      menu.appendChild(button)\n      return button\n    }\r\n\r\n    const levels = [null, TITLE_LEVEL.FIRST, TITLE_LEVEL.SECOND, TITLE_LEVEL.THIRD, TITLE_LEVEL.FOURTH]\n    const labels = ['正文', '一级标题', '二级标题', '三级标题', '四级标题']\n    levels.forEach((level, index) => {\n      const button = addButton(labels[index], (style.level ?? null) === level, 'executeTitle', level)\n      button.className = 'ce-paragraph-handle-menu__heading'\n      button.append(index === 0 ? 'T' : 'H')\n      if (index > 0) {\n        const sub = document.createElement('sub')\n        sub.textContent = String(index)\n        button.appendChild(sub)\n      }\r\n    })\n\n    const alignments = [\n      { label: '左对齐', value: ROW_FLEX.LEFT, path: 'M4 5H19M4 12H12M4 19H19' },\n      { label: '居中', value: ROW_FLEX.CENTER, path: 'M4 5H19M8 12H15M4 19H19' },\n      { label: '右对齐', value: ROW_FLEX.RIGHT, path: 'M4 5H19M11 12H19M4 19H19' },\n      { label: '两端对齐', value: ROW_FLEX.JUSTIFY, path: 'M4 5H19M4 12H19M4 19H19' },\n      { label: '分散对齐', value: ROW_FLEX.DISTRIBUTE, path: 'M3 4V20M21 4V20M7 13H17M7 19H17' }\n    ]\r\n    for (const item of alignments) {\n      const button = addButton(item.label, alignment === item.value, 'executeRowFlex', item.value)\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n      svg.setAttribute('viewBox', '0 0 24 24')\n      svg.setAttribute('aria-hidden', 'true')\n      const path = document.createElementNS(svg.namespaceURI, 'path')\n      path.setAttribute('d', item.path)\n      svg.appendChild(path)\n      if (item.value === ROW_FLEX.DISTRIBUTE) {\n        const arrows = document.createElementNS(svg.namespaceURI, 'path')\n        arrows.setAttribute('d', 'M9 4L7 6L9 8M15 4L17 6L15 8')\n        arrows.setAttribute('stroke', '#527bb5')\n        svg.appendChild(arrows)\n      }\n      button.appendChild(svg)\n    }\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)\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    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: string, ...args: any[]) => { this.deps.onCommand(cmd, ...args) }\r\n\r\n    const items: MenuItem[] = [\r\n      { label: '剪切', icon: 'content_cut', shortcut: 'Ctrl+X', onClick: () => fire('executeCut') },\r\n      { label: '复制', icon: 'content_copy', shortcut: 'Ctrl+C', onClick: () => fire('executeCopy') },\r\n      { label: '粘贴', icon: 'content_paste', shortcut: 'Ctrl+V', onClick: () => fire('executePaste') },\r\n      { label: '---' },\r\n      { label: '字体...', icon: 'format_size', onClick: () => this.fontPanel.show() },\r\n      { label: '段落高级设置', icon: 'subject', onClick: () => this.panel.show() },\r\n      { label: '---' },\r\n      { label: '超链接', icon: icons.link, shortcut: 'Ctrl+K', onClick: () => fire('requestInsertHyperlink') },\r\n      { label: '插入批注', 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    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\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  /** 获取当前文档布局 */\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\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  /** 销毁 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('页眉')\r\n    this.headerLabelEl = h.el\r\n    const f = make('页脚')\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    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 = '插入页码'\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.textContent = '样式:'\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    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      opt.textContent = 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.textContent = '位置:'\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: '左侧' },\r\n      { value: 'center', text: '居中' },\r\n      { value: 'right', text: '右侧' },\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.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.textContent = '确定'\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    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 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    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'\n\nconst PX_PER_CM = 96 / 2.54\nconst RULER_SIZE = 27\nconst BAND_START = 3\nconst BAND_SIZE = 17\nconst BACKGROUND = '#e2e2e2'\nconst MARGIN_BACKGROUND = '#d6d6d6'\nconst BORDER = '#bcbcbc'\n\n/** Positions relative to the paragraph's available content area, in document pixels. */\nexport interface RulerIndent {\n  first: number\n  left: number\n  right: number\n}\n\nexport interface RulerWidgetDeps {\n  container: HTMLDivElement\n  getLayout: () => DocumentLayout | null\n  getScrollY: () => number\n  getWrapperWidth: () => number\n  getWrapperHeight: () => number\n  getPageOffsetX: () => number\n  getScale: () => number\n  getPageMargins: () => [number, number, number, number]\n  getParagraphIndent: () => RulerIndent | null\n  onCommand: (cmd: string, ...args: any[]) => void\n}\n\ntype MarginSide = 'left' | 'right' | 'top' | 'bottom'\ntype IndentSide = 'first' | 'hanging' | 'indent' | 'end'\ntype Handle = MarginSide | IndentSide\nconst MARGINS: MarginSide[] = ['left', 'right', 'top', 'bottom']\nconst INDENTS: IndentSide[] = ['first', 'hanging', 'indent', 'end']\n\n/** Compact Word-style rulers. All screen positions use the rendered page geometry. */\nexport class RulerWidget {\n  private hRuler: HTMLDivElement | null = null\n  private vRuler: HTMLDivElement | null = null\n  private hCanvas: HTMLCanvasElement | null = null\n  private vCanvas: HTMLCanvasElement | null = null\n  private corner: HTMLDivElement | null = null\n  private markers = new Map<Handle, HTMLDivElement>()\n  private drag: { side: Handle; start: number; indent: RulerIndent | null; pageIndex: number } | null = null\n  private visible = false\n\n  constructor(private deps: RulerWidgetDeps) {}\n\n  create(): void {\n    const createRuler = (horizontal: boolean): [HTMLDivElement, HTMLCanvasElement] => {\n      const ruler = document.createElement('div')\n      ruler.className = `vervedocs-ruler-${horizontal ? 'horizontal' : 'vertical'}`\n      Object.assign(ruler.style, {\n        position: 'absolute', top: '0', left: '0', zIndex: horizontal ? '6' : '5',\n        background: BACKGROUND, pointerEvents: 'none', overflow: 'hidden',\n        ...(horizontal ? { right: '0', height: `${RULER_SIZE}px` } : { bottom: '0', width: `${RULER_SIZE}px` })\n      })\n      const canvas = document.createElement('canvas')\n      canvas.style.cssText = 'width:100%;height:100%;display:block;'\n      ruler.appendChild(canvas)\n      this.deps.container.appendChild(ruler)\n      return [ruler, canvas]\n    }\n    ;[this.hRuler, this.hCanvas] = createRuler(true)\n    ;[this.vRuler, this.vCanvas] = createRuler(false)\n    this.corner = document.createElement('div')\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;`\n    this.deps.container.appendChild(this.corner)\n\n    for (const side of [...MARGINS, ...INDENTS]) {\n      const marker = this.createMarker(side)\n      this.markers.set(side, marker)\n      this.deps.container.appendChild(marker)\n    }\n    this.applyVisible()\n  }\n\n  private createMarker(side: Handle): HTMLDivElement {\n    const marker = document.createElement('div')\n    const vertical = side === 'top' || side === 'bottom'\n    const isMargin = MARGINS.includes(side as MarginSide)\n    marker.dataset.rulerHandle = side\n    const titles: Record<Handle, string> = {\n      left: '左页边距', right: '右页边距', top: '上页边距', bottom: '下页边距',\n      first: '首行缩进', hanging: '悬挂缩进', indent: '左缩进', end: '右缩进'\n    }\n    marker.title = titles[side]\n    Object.assign(marker.style, {\n      position: 'absolute', zIndex: isMargin ? '6' : '7', pointerEvents: 'auto',\n      cursor: vertical ? 'ns-resize' : 'ew-resize', touchAction: 'none',\n      // Keep a grab area outside the indent handles when they share the margin.\n      width: vertical ? `${BAND_SIZE}px` : isMargin ? '20px' : '12px',\n      height: vertical ? '6px' : isMargin ? `${BAND_SIZE}px` : side === 'indent' ? '6px' : '12px',\n      ...(vertical ? { left: `${BAND_START}px` } : {\n        top: `${isMargin ? BAND_START : side === 'first' ? 0 : side === 'indent' ? 20 : 9}px`\n      })\n    })\n    if (!isMargin) {\n      const canvas = document.createElement('canvas')\n      const height = side === 'indent' ? 6 : 12\n      const dpr = window.devicePixelRatio || 1\n      canvas.width = Math.round(12 * dpr)\n      canvas.height = Math.round(height * dpr)\n      canvas.style.cssText = `display:block;width:12px;height:${height}px;pointer-events:none;`\n      const ctx = canvas.getContext('2d')!\n      ctx.scale(dpr, dpr)\n      ctx.fillStyle = '#fff'\n      ctx.strokeStyle = '#666'\n      ctx.lineWidth = 1\n      ctx.beginPath()\n      if (side === 'indent') {\n        ctx.rect(0.5, 0.5, 11, 5)\n      } else if (side === 'first') {\n        ctx.moveTo(0.5, 0.5)\n        ctx.lineTo(11.5, 0.5)\n        ctx.lineTo(11.5, 4.5)\n        ctx.lineTo(6, 11.5)\n        ctx.lineTo(0.5, 4.5)\n        ctx.closePath()\n      } else {\n        ctx.moveTo(6, 0.5)\n        ctx.lineTo(11.5, 6.5)\n        ctx.lineTo(11.5, 10.5)\n        ctx.lineTo(0.5, 10.5)\n        ctx.lineTo(0.5, 6.5)\n        ctx.closePath()\n      }\n      ctx.fill()\n      ctx.stroke()\n      marker.appendChild(canvas)\n    }\n    marker.addEventListener('mousedown', (event) => {\n      if (event.button !== 0) return\n      event.preventDefault()\n      event.stopPropagation()\n      this.drag = {\n        side, start: event.clientX, indent: this.deps.getParagraphIndent(),\n        pageIndex: this.getVerticalPage()?.index ?? 0\n      }\n      window.addEventListener('mousemove', this.onDragMove)\n      window.addEventListener('mouseup', this.onDragEnd)\n      window.addEventListener('blur', this.onDragEnd)\n    })\n    return marker\n  }\n\n  private getVerticalPage() {\n    const page = this.deps.getLayout()?.pages[0]\n    const scrollY = this.deps.getScrollY()\n    return page && page.rect.y + page.rect.height > scrollY + RULER_SIZE &&\n      page.rect.y - scrollY < this.deps.getWrapperHeight() ? page : undefined\n  }\n\n  private onDragMove = (event: MouseEvent): void => {\n    const drag = this.drag\n    const layout = this.deps.getLayout()\n    if (!drag || !layout) return\n    event.preventDefault()\n    const scale = this.deps.getScale()\n    const rect = this.deps.container.getBoundingClientRect()\n    const pageX = this.deps.getPageOffsetX()\n    const [mt, mr, mb, ml] = this.deps.getPageMargins()\n    const width = layout.pageWidth / scale\n    const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(Math.max(min, max), value))\n    if (INDENTS.includes(drag.side as IndentSide)) {\n      if (!drag.indent) return\n      const next = { ...drag.indent }\n      const contentWidth = width - ml - mr\n      const movement = (event.clientX - drag.start) / scale\n      const limit = contentWidth - next.right - 20\n      if (drag.side === 'first') next.first = clamp(next.first + movement, 0, limit)\n      if (drag.side === 'hanging') next.left = clamp(next.left + movement, 0, limit)\n      if (drag.side === 'end') next.right = clamp(next.right - movement, 0, contentWidth - Math.max(next.first, next.left) - 20)\n      if (drag.side === 'indent') {\n        const delta = clamp(movement,\n          -Math.min(next.first, next.left), limit - Math.max(next.first, next.left))\n        next.first += delta\n        next.left += delta\n      }\n      this.deps.onCommand('executeSetRulerIndent', next.first, next.left, next.right)\n      return\n    }\n    const page = layout.pages[drag.pageIndex]\n    if (!page) return\n    const height = page.rect.height / scale\n    const y = (event.clientY - rect.top + this.deps.getScrollY() - page.rect.y) / scale\n    const x = (event.clientX - rect.left - pageX) / scale\n    const margins: [number, number, number, number] = [mt, mr, mb, ml]\n    if (drag.side === 'left') margins[3] = clamp(x, 0, width - mr - 50)\n    if (drag.side === 'right') margins[1] = clamp(width - x, 0, width - ml - 50)\n    if (drag.side === 'top') margins[0] = clamp(y, 0, height - mb - 50)\n    if (drag.side === 'bottom') margins[2] = clamp(height - y, 0, height - mt - 50)\n    this.deps.onCommand('executeSetPaperMargin', margins)\n  }\n\n  private onDragEnd = (): void => {\n    this.drag = null\n    window.removeEventListener('mousemove', this.onDragMove)\n    window.removeEventListener('mouseup', this.onDragEnd)\n    window.removeEventListener('blur', this.onDragEnd)\n  }\n\n  setVisible(visible: boolean): void {\n    this.visible = visible\n    if (!visible) this.onDragEnd()\n    this.applyVisible()\n    if (visible) this.update()\n  }\n\n  private applyVisible(): void {\n    for (const element of [this.hRuler, this.vRuler, this.corner, ...this.markers.values()]) {\n      if (element) element.style.display = this.visible ? 'block' : 'none'\n    }\n  }\n\n  update(): void {\n    if (!this.visible || !this.hCanvas || !this.vCanvas) return\n    this.drawHorizontal()\n    this.drawVertical()\n    this.updateMarkers()\n  }\n\n  private updateMarkers(): void {\n    const layout = this.deps.getLayout()\n    const page = this.getVerticalPage()\n    const scale = this.deps.getScale()\n    const [mt, mr, mb, ml] = this.deps.getPageMargins()\n    const start = this.deps.getPageOffsetX() + ml * scale\n    const end = this.deps.getPageOffsetX() + (layout?.pageWidth ?? 0) - mr * scale\n    const indent = this.deps.getParagraphIndent()\n    const positions: Record<Handle, number> = {\n      left: start, right: end,\n      top: (page?.rect.y ?? 0) - this.deps.getScrollY() + mt * scale,\n      bottom: (page?.rect.y ?? 0) + (page?.rect.height ?? 0) - this.deps.getScrollY() - mb * scale,\n      first: start + (indent?.first ?? 0) * scale,\n      hanging: start + (indent?.left ?? 0) * scale,\n      indent: start + (indent?.left ?? 0) * scale,\n      end: end - (indent?.right ?? 0) * scale\n    }\n    for (const [side, marker] of this.markers) {\n      const vertical = side === 'top' || side === 'bottom'\n      const isMargin = MARGINS.includes(side as MarginSide)\n      const position = Math.round(positions[side])\n      const max = vertical ? this.deps.getWrapperHeight() : this.deps.getWrapperWidth()\n      marker.style.display = layout && (!vertical || page) && (isMargin || indent) &&\n        position >= RULER_SIZE + 6 && position <= max - 6 ? 'block' : 'none'\n      marker.style[vertical ? 'top' : 'left'] = `${position - (isMargin ? vertical ? 3 : 10 : 6)}px`\n    }\n  }\n\n  private prepareCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {\n    const dpr = window.devicePixelRatio || 1\n    canvas.width = Math.max(1, Math.round(width * dpr))\n    canvas.height = Math.max(1, Math.round(height * dpr))\n    const ctx = canvas.getContext('2d')!\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n    ctx.clearRect(0, 0, width, height)\n    return ctx\n  }\n\n  /** The same 17px band is used horizontally and vertically (via a canvas transform). */\n  private drawBand(ctx: CanvasRenderingContext2D, start: number, end: number, origin: number, contentEnd: number, viewport: number): void {\n    const step = PX_PER_CM * this.deps.getScale()\n    const center = BAND_START + BAND_SIZE / 2\n    ctx.fillStyle = MARGIN_BACKGROUND\n    ctx.fillRect(start, BAND_START, end - start, BAND_SIZE)\n    ctx.fillStyle = '#fff'\n    ctx.fillRect(origin, BAND_START, Math.max(0, contentEnd - origin), BAND_SIZE)\n    ctx.strokeStyle = BORDER\n    ctx.lineWidth = 1\n    ctx.strokeRect(Math.round(start) + 0.5, BAND_START + 0.5, Math.round(end) - Math.round(start) - 1, BAND_SIZE - 1)\n    ctx.save()\n    ctx.beginPath()\n    ctx.rect(start + 1, BAND_START + 1, Math.max(0, end - start - 2), BAND_SIZE - 2)\n    ctx.clip()\n    ctx.strokeStyle = '#363636'\n    ctx.fillStyle = '#161616'\n    ctx.font = '11px Arial, sans-serif'\n    ctx.textAlign = 'center'\n    ctx.textBaseline = 'middle'\n    const firstTick = Math.ceil((Math.max(start, 0) - origin) / step * 4)\n    const lastTick = Math.floor((Math.min(end, viewport) - origin) / step * 4)\n    for (let tick = firstTick; tick <= lastTick; tick++) {\n      const x = Math.round(origin + tick * step / 4) + 0.5\n      if (tick % 4 === 0) {\n        if (tick !== 0) ctx.fillText(String(Math.abs(tick / 4)), x, center)\n      } else {\n        const height = tick % 2 === 0 ? 5 : 3\n        ctx.beginPath()\n        ctx.moveTo(x, Math.round(center - height / 2))\n        ctx.lineTo(x, Math.round(center + height / 2))\n        ctx.stroke()\n      }\n    }\n    ctx.restore()\n  }\n\n  private drawHorizontal(): void {\n    const width = this.deps.getWrapperWidth()\n    const ctx = this.prepareCanvas(this.hCanvas!, width, RULER_SIZE)\n    const layout = this.deps.getLayout()\n    if (!layout) return\n    const scale = this.deps.getScale()\n    const start = this.deps.getPageOffsetX()\n    const end = start + layout.pageWidth\n    const [, mr, , ml] = this.deps.getPageMargins()\n    const origin = start + ml * scale\n    const contentEnd = end - mr * scale\n    this.drawBand(ctx, start, end, origin, contentEnd, width)\n    // Default tab stops sit below the band, starting at the text origin.\n    const tabStep = PX_PER_CM * 1.25 * scale\n    ctx.strokeStyle = '#777'\n    ctx.beginPath()\n    for (let x = origin + tabStep; x < Math.min(contentEnd, width); x += tabStep) {\n      if (x < 0) continue\n      const aligned = Math.round(x) + 0.5\n      ctx.moveTo(aligned, 22)\n      ctx.lineTo(aligned, 25)\n    }\n    ctx.stroke()\n  }\n\n  private drawVertical(): void {\n    const page = this.getVerticalPage()\n    if (!page) {\n      this.vRuler!.style.display = 'none'\n      return\n    }\n    const start = page.rect.y - this.deps.getScrollY()\n    const end = start + page.rect.height\n    // Limit both the canvas and its background to the first page.\n    const height = Math.min(this.deps.getWrapperHeight(), Math.ceil(end))\n    this.vRuler!.style.display = 'block'\n    this.vRuler!.style.bottom = 'auto'\n    this.vRuler!.style.height = `${height}px`\n    const ctx = this.prepareCanvas(this.vCanvas!, RULER_SIZE, height)\n    const scale = this.deps.getScale()\n    const [mt, , mb] = this.deps.getPageMargins()\n    // Rotate, rather than reflect, so vertical labels remain readable.\n    ctx.transform(0, 1, -1, 0, BAND_START * 2 + BAND_SIZE, 0)\n    this.drawBand(ctx, start, end, start + mt * scale, end - mb * scale, height)\n  }\n\n  destroy(): void {\n    this.onDragEnd()\n    for (const element of [this.hRuler, this.vRuler, this.corner, ...this.markers.values()]) element?.remove()\n    this.markers.clear()\n    this.hRuler = this.vRuler = this.corner = null\n    this.hCanvas = this.vCanvas = null\n  }\n}\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 { 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  /** 获取当前文档布局，可能为 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: string, ...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: string, ...args: any[]) => { this.deps.onCommand?.(cmd, ...args) }\r\n\r\n\r\n    const mkBtn = (icon: string, cmd: string, 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('executeFont', 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    sizeSel.addEventListener('change', () => fire('executeSize', Number(sizeSel.value)))\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', 'executeBold', [], '加粗'))\r\n    tb.appendChild(mkBtn('format_italic', 'executeItalic', [], '斜体'))\r\n    tb.appendChild(mkBtn('format_underlined', 'executeUnderline', [], '下划线'))\r\n    tb.appendChild(mkBtn('format_strikethrough', 'executeStrikeout', [], '删除线'))\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 = 'executeColor'\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('executeColor', 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 = 'executeHighlight'\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('executeHighlight', 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', 'executeRowFlex', ['left'], '左对齐'))\r\n    tb.appendChild(mkBtn('format_align_center', 'executeRowFlex', ['center'], '居中'))\r\n    tb.appendChild(mkBtn('format_align_right', 'executeRowFlex', ['right'], '右对齐'))\r\n    tb.appendChild(mkBtn('format_align_justify', 'executeRowFlex', ['justify'], '两端对齐'))\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 清除格式\r\n    tb.appendChild(mkBtn('format_clear', 'executeFormat', [], '清除格式'))\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    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!this.toolbar || !layout || !range) return\r\n    const tb = this.toolbar\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(10, Math.round(rect.height * 0.5))\r\n    const y = Math.round(rect.y - this.deps.getScrollY()) - rect.height - gap\r\n    tb.style.display = 'flex'\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 === 'executeBold') active = !!run.bold\r\n      else if (cmd === 'executeItalic') active = !!run.italic\r\n      else if (cmd === 'executeUnderline') active = !!run.underline\r\n      else if (cmd === 'executeStrikeout') active = !!run.strikeout\r\n      else if (cmd === 'executeRowFlex') {\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 === 'executeColor') {\r\n        input.value = String(run.color ?? '#000000')\r\n      } else if (input.dataset.cmd === 'executeHighlight') {\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'\nimport { signBlock } from './block-signature'\n\ninterface BlockState {\n  id: number\n  signature: string\n  rect: Rect\n}\n\nexport interface RenderState {\n  blocks: Map<string, BlockState>\n  pageBlocks: Map<number, BlockState>\n  pageSignatures: Map<number, string>\n  geometry: string\n}\n\nlet nextRenderId = 0\n\n/** Separate a block's stable identity from its mutable paint signature. */\nexport function prepareRenderState(layout: DocumentLayout, previous?: RenderState): {\n  state: RenderState\n  dirty: number[]\n} {\n  const state: RenderState = {\n    blocks: new Map(),\n    pageBlocks: new Map(),\n    pageSignatures: new Map(),\n    geometry: JSON.stringify(layout.pages.map(p => [p.rect, p.contentRect, p.headerRect, p.footerRect]))\n  }\n  const dirty: number[] = []\n  const visit = (source: BlockNode, key: string, x: number, y: number, topLevel: boolean): BlockNode => {\n    // Header/footer and repeated table fragments can share source layout objects.\n    // Never assign occurrence IDs into those shared objects or cached geometry.\n    const b = { ...source, rect: { ...source.rect } }\n    if (b.kind === 'table') {\n      b.rows = b.rows.map((row, ri) => ({\n        ...row,\n        cells: row.cells.map((cell, ci) => ({\n          ...cell,\n          content: cell.content.map((child, bi) =>\n            visit(child, `${key}/${ri}/${ci}/${bi}`, 0, 0, false))\n        }))\n      }))\n    }\n    const old = previous?.blocks.get(key)\n    b.id = old?.id ?? ++nextRenderId\n    const signature = signBlock(b, layout)\n    const entry = {\n      id: b.id, signature,\n      rect: { ...b.rect, x: x + b.rect.x, y: y + b.rect.y }\n    }\n    state.blocks.set(key, entry)\n    if (topLevel) state.pageBlocks.set(b.id, entry)\n    if (!old || old.signature !== signature) dirty.push(b.id)\n    return b\n  }\n  for (const page of layout.pages) {\n    const parts: unknown[] = [page.rect, page.contentRect, page.headerRect, page.footerRect]\n    const zone = (blocks: BlockNode[], name: string, origin: Rect) => blocks.map((block, index) => {\n      const b = visit(block, `${page.index}/${name}/${index}`, origin.x, origin.y, true)\n      parts.push([b.rect, state.pageBlocks.get(b.id)!.signature])\n      return b\n    })\n    page.blocks = zone(page.blocks, 'main', page.contentRect)\n    if (page.headerBlocks && page.headerRect) page.headerBlocks = zone(page.headerBlocks, 'header', page.headerRect)\n    if (page.footerBlocks && page.footerRect) page.footerBlocks = zone(page.footerBlocks, 'footer', page.footerRect)\n    state.pageSignatures.set(page.index, JSON.stringify(parts))\n  }\n  return { state, dirty }\n}\n\n/** Diff against the last painted frame, not the last edit queued in that frame. */\nexport function computeDirtyRect(\n  painted: RenderState | undefined,\n  next: RenderState,\n  viewport: Rect\n): Rect | null {\n  if (!painted || painted.geometry !== next.geometry) return null\n  let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\n  const include = (rect: Rect) => {\n    left = Math.min(left, rect.x - 2)\n    top = Math.min(top, rect.y - 2)\n    right = Math.max(right, rect.x + rect.width + 2)\n    bottom = Math.max(bottom, rect.y + rect.height + 2)\n  }\n  const ids = new Set([...painted.pageBlocks.keys(), ...next.pageBlocks.keys()])\n  for (const id of ids) {\n    const old = painted.pageBlocks.get(id)\n    const current = next.pageBlocks.get(id)\n    if (old && current && old.signature === current.signature &&\n        JSON.stringify(old.rect) === JSON.stringify(current.rect)) continue\n    if (old) include(old.rect)\n    if (current) include(current.rect)\n  }\n  left = Math.max(left, viewport.x)\n  top = Math.max(top, viewport.y)\n  right = Math.min(right, viewport.x + viewport.width)\n  bottom = Math.min(bottom, viewport.y + viewport.height)\n  if (right <= left || bottom <= top) return { x: 0, y: 0, width: 0, height: 0 }\n  return { x: left, y: top, width: right - left, height: bottom - top }\n}\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\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 })\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\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\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,\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\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\n            existing.endGlyphTop = absGlyphTop\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\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 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}\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\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\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    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      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      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      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      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      // #region debug-point readonly-composition\r\n      if (this.options.readonly || this.options.disabled) void fetch('http://192.168.3.37:7777/event', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId: 'mobile-canvas-render', runId: 'input-pipeline', hypothesisId: 'E', location: 'Draw:compositionend', msg: 'Restricted composition callback', data: { readonly: this.options.readonly, disabled: this.options.disabled, hasText: !!text } }) }).catch(() => {})\r\n      // #endregion debug-point readonly-composition\r\n      if (text) 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.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 onMouseDown = (e: MouseEvent): void => {\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.tableWidget?.handleMouseDown(e)) return\r\n\r\n    // 图片选中/缩放\r\n    if (this.imageWidget?.handleMouseDown(e)) {\r\n      this.eventBus?.emit('imageMousedown', e)\r\n      return\r\n    }\r\n\r\n    // 图表选中/缩放\r\n    if (this.chartWidget?.handleMouseDown(e)) {\r\n      return\r\n    }\r\n\r\n    // 双击页眉/页脚区域：切换编辑区域\r\n    if (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    // 文本选区拖拽保持文本指针；表格边框悬浮和拖拽优先于链接指针。\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    e.preventDefault()\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) {\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    // #region debug-point scale-pipeline\r\n    const canvas = this.canvasHost.querySelector('canvas')\r\n    void fetch('http://192.168.3.37:7777/event', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId: 'mobile-canvas-render', runId: 'scale-pipeline', hypothesisId: 'D', location: 'Draw:setScale', msg: 'Scale pipeline', data: { requestedScale: scale, previousScale: this.options.scale, pageWidth: this.layout?.pageWidth, viewportWidth: this.viewportWidth, viewportHeight: this.viewportHeight, scrollerWidth: this.scroller.offsetWidth, matrix: canvas?.getContext('2d')?.getTransform().a, dpr: window.devicePixelRatio, readonly: this.options.readonly, disabled: this.options.disabled } }) }).catch(() => {})\r\n    // #endregion debug-point scale-pipeline\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  /**\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 (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 => key === 'eyeCare')) 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><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.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)\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","/**\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\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} from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager, IRangeStyle, IEditorAbility, Listener } from '@vervedoc/docx-editor-state'\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\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\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  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  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  commitPluginTransaction(action: (doc: IDocxDocumentMeta) => boolean | void): void {\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    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 (typeof text !== 'string' || !text) return\r\n    if (this.deleteSelection()) {\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      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.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\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    const elements = doc.elements || []\r\n    for (let i = 0; i < elements.length; i++) {\r\n      if ((elements[i] as any).revisionId === id) {\r\n        this.setRange(i, i)\r\n        return true\r\n      }\r\n    }\r\n    return false\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({ path: ctx.path.slice() as Path, text: (node as ITextElement).value })\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.deleteSelection()) return\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.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      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      const rest: ITextElement = { type: 'text', value: after } as ITextElement\r\n      // 继承字体/字号\r\n      const anyT = t as unknown as Record<string, unknown>\r\n      for (const k of ['font', 'size', 'bold', 'color']) {\r\n        if (anyT[k] != null) {\r\n          (rest as unknown as Record<string, unknown>)[k] = anyT[k]\r\n        }\r\n      }\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        if (g.block) {\r\n          ;(g.block as unknown as Record<string, unknown>).rowFlex = flex\r\n        }\r\n        for (const r of g.runs) {\r\n          ;(r as unknown as Record<string, unknown>).rowFlex = flex\r\n        }\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        for (const r of targets) {\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        for (const r of targets) {\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._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.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      fn(node as ITextElement)\r\n      return\r\n    })\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    const doc = this.draw.getActiveDocument()\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return\r\n      const node = getByPath(doc.elements, pos.path)\r\n      if (!node || node.type !== 'text') return\r\n      fn(node as ITextElement)\r\n      // 不可迁移：多个分支各自 commit\r\n      this._commit(doc)\r\n      return\r\n    }\r\n    const { start, end } = ordered\r\n\r\n    const adjusted = this.splitBoundaryRuns(doc, start, end)\r\n    this.range.setRange({ anchor: adjusted.start, focus: adjusted.end })\r\n    const selectedRuns = this.collectRunsInRange(doc.elements, adjusted.start, adjusted.end)\r\n    if (selectedRuns.length === 0) {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return\r\n      const node = getByPath(doc.elements, pos.path)\r\n      if (!node || node.type !== 'text') return\r\n      fn(node as ITextElement)\r\n      // 不可迁移：多个分支各自 commit\r\n      this._commit(doc)\r\n      return\r\n    }\r\n    if (toggleKey) {\r\n      const allSet = selectedRuns.every(r => Boolean((r as unknown as Record<string, unknown>)[toggleKey]))\r\n      for (const r of selectedRuns) {\r\n        (fn as (run: ITextElement) => void)(r)\r\n        if ((r as unknown as Record<string, unknown>)[toggleKey] === undefined) {\r\n          ;(r as unknown as Record<string, unknown>)[toggleKey] = !allSet\r\n        }\r\n      }\r\n    } else {\r\n      for (const r of selectedRuns) fn(r)\r\n    }\r\n    // 不可迁移：多个分支各自 commit\r\n    this._commit(doc)\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 = { ...t, value: after } as ITextElement\r\n            parent.splice(idx + 1, 0, second as IElement)\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 endParent = endPath.slice(0, -1)\r\n              if (isSamePath(startParent, endParent)) {\r\n                endPath[endPath.length - 1] = (endPath[endPath.length - 1] as number) + 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 = { ...t, value: after } as ITextElement\r\n            parent.splice(idx + 1, 0, second as IElement)\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).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    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    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 (title.level === level) continue\r\n        if (level !== null) {\r\n          title.level = level\r\n        } else {\r\n          const runs = title.valueList.length ? [...title.valueList] : [{ type: 'text', value: '' } as IElement]\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        parent.splice(start, end - start, {\r\n          type: 'title', value: '', level, valueList: parent.slice(start, end)\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  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  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    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    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    const h = Math.max(20, Math.round(height))\r\n    t.trList[rowIndex].height = h\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    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      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    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          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' || typeof el.value !== 'string') 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    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      parent.splice(idx, 0, { type: 'pageBreak', value: 'manual' } as IElement)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 插入超链接。\r\n   * @param payload 超链接参数，包含 url 与 valueList\r\n   */\r\n  insertHyperlink(payload: { url: string; valueList: IElement[] }): void {\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 link: IElement = { type: 'hyperlink', value: payload.url } as unknown as IElement\r\n      ;(link as unknown as Record<string, unknown>).valueList = payload.valueList.map(r => ({ ...r, type: 'text' } as IElement))\r\n      parent.splice(idx, 0, link)\r\n      return\r\n    })\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 {\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos || pos.path.length !== 1) return false\r\n      const index = Number(pos.path[0])\r\n      const element = doc.elements[index]\r\n      if (!element) return false\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          headerDistance: 0, footerDistance: 0, titlePage: false, breakType: 'nextPage' }]\r\n      }\r\n      const breaks = new Set(['continuous', 'nextPage', 'evenPage', 'oddPage'])\r\n      const sectionIndex = doc.elements.slice(0, index).filter(el => el.type === 'pageBreak' && breaks.has(el.value)).length\r\n      const next = cloneTree(doc.sections[sectionIndex])\r\n      next.breakType = 'continuous'\r\n      doc.sections.splice(sectionIndex + 1, 0, next)\r\n      const tail: IElement[] = []\r\n      if (element.type === 'text') {\r\n        tail.push({ ...element, value: element.value.slice(pos.offset) })\r\n        element.value = element.value.slice(0, pos.offset)\r\n      }\r\n      doc.elements.splice(index + 1, 0, { type: 'pageBreak', value: 'continuous' }, ...tail)\r\n      this.range.setCaret({ path: [index + 2], offset: 0 })\r\n      return\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              const targetScrollTop = Math.max(0, absY - scrollContainer.clientHeight / 2)\r\n              scrollContainer.scrollTop = targetScrollTop\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\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        // 从排版块中直接取编号文本（由排版引擎通过 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  /**\r\n   * 在当前光标处插入自动目录文本。\r\n   * @param type 目录类型：1 | 2 | 3，对应不同层级深度\r\n   */\r\n  insertAutoToc(type: 1 | 2 | 3): void {\r\n    const result = this.getAutoToc()\r\n    const items = type === 1 ? result.toc1 : type === 2 ? result.toc2 : result.toc3\r\n    if (items.length === 0) return\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\r\n      const tocElements: IElement[] = items.map(item => ({\r\n        type: 'text',\r\n        valueList: [{\r\n          type: 'text',\r\n          value: '  '.repeat(item.level - 1) + item.name + ' ' + '\\u00b7'.repeat(Math.max(3, 50 - item.name.length - item.level * 2)) + ' ' + String(item.pageNo)\r\n        }]\r\n      } as unknown as IElement))\r\n\r\n      parent.splice(idx, 0, ...tocElements)\r\n      return\r\n    })\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    this.draw.setPageSize(width, height)\r\n    this.listener?.emit('pageSizeChange', { width, height })\r\n    this.listener?.emit('contentChange')\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()\n    const section = doc.sections?.[0]\n    const w = Number(section?.pageWidth ?? doc.pageWidth ?? opts.pageWidth ?? 794)\n    const h = Number(section?.pageHeight ?? doc.pageHeight ?? opts.pageHeight ?? 1123)\n    if (direction === 'horizontal') {\r\n      this.setPaperSize(Math.max(w, h), Math.min(w, h))\n    } else {\r\n      this.setPaperSize(Math.min(w, h), Math.max(w, h))\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    this.draw.updateOptions({ columnCount: value } as Partial<IEditorOption>)\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  }\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    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    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    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    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    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 (!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    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    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    this.range.setRange(bookmark.range)\r\n    const pos = this.findVisiblePosNearby(doc.elements, bookmark.range.focus) ?? bookmark.range.focus\r\n    this.draw.scrollPositionIntoView?.(pos)\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    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      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])) return { path: [...parentPath, i] as Path, offset: 0 }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /* -------------------- 目录 -------------------- */\r\n\r\n  /**\r\n   * 插入目录，带 tocId 标识便于后续删除。\r\n   * @param payload 目录参数，可包含 type/mode 及其他自定义字段\r\n   */\r\n  insertToc(payload: { type?: 1 | 2 | 3; mode?: string; [key: string]: unknown }): void {\r\n    const type = (payload.type as 1 | 2 | 3) ?? 3\r\n    const result = this.getAutoToc()\r\n    const items = type === 1 ? result.toc1 : type === 2 ? result.toc2 : result.toc3\r\n    if (items.length === 0) return\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\r\n      const tocId = Date.now().toString()\r\n      const tocElements: IElement[] = items.map(item => ({\r\n        type: 'text',\r\n        valueList: [{\r\n          type: 'text',\r\n          value: '  '.repeat(item.level - 1) + item.name + ' ' + '\\u00b7'.repeat(Math.max(3, 50 - item.name.length - item.level * 2)) + ' ' + String(item.pageNo)\r\n        }],\r\n        tocId\r\n      } as unknown as IElement))\r\n\r\n      parent.splice(idx, 0, ...tocElements)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除所有目录元素（带 tocId 标识的元素） */\r\n  removeToc(): void {\r\n    this.execute(doc => {\r\n      const elements = doc.elements\r\n      for (let i = elements.length - 1; i >= 0; i--) {\r\n        if ((elements[i] as unknown as { tocId?: string }).tocId) {\r\n          elements.splice(i, 1)\r\n        }\r\n      }\r\n    })\r\n  }\r\n\r\n  /* -------------------- 撤销 / 重做 -------------------- */\r\n\r\n  /** 撤销上一步操作，恢复历史快照并通知选区样式与能力变更。 */\r\n  undo(): void {\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._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    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    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    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 (!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  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  private isSectionBoundary(element: IElement): boolean {\r\n    return element.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(element.value)\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        const inherited = Object.assign({}, ...doc.sections.slice(0, index + count + 1).map(section => section[key]))\r\n        survivor[key] = inherited\r\n      }\r\n      doc.sections.splice(index, count)\r\n    }\r\n  }\r\n\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  pasteFragment(fragment: Partial<IDocxDocumentMeta>): void {\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      for (const target of targets) {\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        for (const r of targets) {\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        for (const r of targets) {\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._historyManager?.canUndo() ?? false,\r\n      redo: 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._historyManager?.canUndo() ?? false,\r\n      redo: 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._historyManager?.canUndo() ?? false,\r\n      canRedo: 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.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('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    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  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  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  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  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  /**\r\n   * 插入超链接。\r\n   * @param payload 超链接参数，包含 url 和 valueList\r\n   */\r\n  executeHyperlink(payload: { url: string; valueList: IElement[] }): void { this.adapt.insertHyperlink(payload) }\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  /**\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 目录类型：1 | 2 | 3\r\n   */\r\n  executeInsertAutoToc(type: 1 | 2 | 3): 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 | 3; mode?: string; [key: string]: unknown }): void { this.adapt.insertToc(payload) }\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. */\n  executeSetRulerIndent(first: number, left: number, right: number): void {\n    this.adapt.setRulerIndent(first, left, right)\n  }\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) }\n  getCellProperties() { return this.adapt.getCellProperties() }\n  getTableBorders() { return this.adapt.getTableBorders() }\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  // console.log(exprs,bbox);\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\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\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 {\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'\nimport type { IElement, ITitleElement, ITextElement, PathSegment } from '@vervedoc/docx-editor-schema'\n\nconst levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\n\nexport function computeToc(elements: IElement[]) {\n  const toc: { id: string; level: number; name: string; number?: string }[] = []\n  const counters = new Map<string, number>()\n  walkTree(elements, (node, ctx) => {\n    if (node.type !== 'title') return\n    const t = node as ITitleElement\n    const name = (t.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\n    const level = levelMap[t.level] ?? 1\n    let number: string | undefined\n    const num = (t as unknown as { listNumbering?: { numFmt: string; lvlText: string; start: number; numId?: string; abstractNumId?: string; level?: number } }).listNumbering\n    if (num && num.numFmt !== 'bullet') {\n      const numId = num.numId ?? num.abstractNumId ?? 'default'\n      const numLevel = num.level ?? 0\n      const key = `${numId}:${numLevel}`\n      const prev = counters.get(key)\n      const current = (prev == null ? (num.start ?? 1) - 1 : prev) + 1\n      counters.set(key, current)\n      for (const k of counters.keys()) {\n        if (k.startsWith(`${numId}:`) && Number(k.slice(numId.length + 1)) > numLevel) counters.delete(k)\n      }\n      number = (num.lvlText ?? '%1.').replace(/%([1-9])/g, (_, d: string) => {\n        const lvl = Number(d) - 1\n        return String(lvl === numLevel ? current : counters.get(`${numId}:${lvl}`) ?? (num.start ?? 1))\n      })\n    }\n    toc.push({ id: JSON.stringify(ctx.path), level, name, number })\n  })\n  return { toc }\n}\n\nexport function computeSearch(elements: IElement[], keyword: string) {\n  const results: { path: PathSegment[]; offset: number; length: number }[] = []\n  if (!keyword) return { results, count: 0 }\n  const lowerKeyword = keyword.toLowerCase()\n  walkTree(elements, (node, ctx) => {\n    if (node.type !== 'text') return\n    const text = ((node as ITextElement).value || '').toLowerCase()\n    let idx = text.indexOf(lowerKeyword)\n    while (idx !== -1) {\n      results.push({ path: [...ctx.path], offset: idx, length: keyword.length })\n      idx = text.indexOf(lowerKeyword, idx + 1)\n    }\n  })\n  return { results, count: results.length }\n}\n","import type { IElement, PathSegment } from '@vervedoc/docx-editor-schema'\nimport { cloneTree } from '@vervedoc/docx-editor-schema'\nimport { computeToc, computeSearch } from './compute'\n\nexport interface TocResult {\n  toc: { id: string; level: number; name: string; number?: string }[]\n}\nexport interface SearchResult {\n  results: { path: PathSegment[]; offset: number; length: number }[]\n  count: number\n}\ntype TocListener = (result: TocResult) => void\ntype SearchListener = (result: SearchResult) => void\ntype CloneListener = (data: unknown) => void\ntype ErrorListener = (message: string) => void\n\nexport class WorkerManager {\n  private worker: Worker | null = null\n  private failed = false\n  private destroyed = false\n  private pending = false\n  private elements: IElement[] = []\n  private tocListeners = new Set<TocListener>()\n  private searchListeners = new Set<SearchListener>()\n  private cloneListeners = new Set<CloneListener>()\n  private errorListeners = new Set<ErrorListener>()\n\n  init(): void {\n    if (this.worker || this.failed || this.destroyed) return\n    try {\n      this.worker = new Worker(new URL('./editor-worker.ts', import.meta.url), { type: 'module' })\n      this.worker.onmessage = (e: MessageEvent) => {\n        const msg = e.data\n        switch (msg.type) {\n          case 'toc-result': this.tocListeners.forEach(fn => fn({ toc: msg.toc })); break\n          case 'search-result': this.searchListeners.forEach(fn => fn({ results: msg.results, count: msg.count })); break\n          case 'clone-result': this.cloneListeners.forEach(fn => fn(msg.data)); break\n          case 'error': this.fallback(msg.message); break\n        }\n      }\n      this.worker.onerror = e => this.fallback(e.message)\n      this.worker.onmessageerror = () => this.fallback('Worker message could not be decoded')\n    } catch (error) {\n      this.failed = true\n      this.errorListeners.forEach(fn => fn(String(error)))\n    }\n  }\n\n  private fallback(message: string): void {\n    this.worker?.terminate()\n    this.worker = null\n    this.failed = true\n    this.errorListeners.forEach(fn => fn(message))\n    const result = computeToc(this.elements)\n    this.tocListeners.forEach(fn => fn(result))\n  }\n\n  updateElements(elements: IElement[]): void {\n    if (this.destroyed) return\n    this.elements = elements\n    if (this.pending) return\n    this.pending = true\n    queueMicrotask(() => this.flush())\n  }\n\n  private flush(): void {\n    if (!this.pending || this.destroyed) return\n    this.pending = false\n    this.init()\n    if (this.worker) {\n      try { this.worker.postMessage({ type: 'update', elements: this.elements }) }\n      catch (error) { this.fallback(String(error)) }\n    } else {\n      const result = computeToc(this.elements)\n      this.tocListeners.forEach(fn => fn(result))\n    }\n  }\n\n  search(keyword: string): void {\n    if (this.destroyed) return\n    this.flush()\n    this.init()\n    if (this.worker) {\n      try { this.worker.postMessage({ type: 'search', keyword }); return }\n      catch (error) { this.fallback(String(error)) }\n    }\n    const result = computeSearch(this.elements, keyword)\n    this.searchListeners.forEach(fn => fn(result))\n  }\n\n  clone(data: unknown): void {\n    if (this.destroyed) return\n    this.init()\n    if (this.worker) {\n      try { this.worker.postMessage({ type: 'clone', data }); return }\n      catch (error) { this.fallback(String(error)) }\n    }\n    const result = cloneTree(data)\n    this.cloneListeners.forEach(fn => fn(result))\n  }\n\n  onTocResult(listener: TocListener): () => void {\n    this.tocListeners.add(listener)\n    return () => this.tocListeners.delete(listener)\n  }\n  onSearchResult(listener: SearchListener): () => void {\n    this.searchListeners.add(listener)\n    return () => this.searchListeners.delete(listener)\n  }\n  onCloneResult(listener: CloneListener): () => void {\n    this.cloneListeners.add(listener)\n    return () => this.cloneListeners.delete(listener)\n  }\n  onError(listener: ErrorListener): () => void {\n    this.errorListeners.add(listener)\n    return () => this.errorListeners.delete(listener)\n  }\n  destroy(): void {\n    this.destroyed = true\n    this.worker?.terminate()\n    this.worker = null\n    this.elements = []\n    this.tocListeners.clear()\n    this.searchListeners.clear()\n    this.cloneListeners.clear()\n    this.errorListeners.clear()\n  }\n}\n","/** Background composition is isolated from document search/TOC work. */\nexport class ThumbnailManager {\n  private worker: Worker | null = null\n  private epoch = 0\n  private sources: string[] = []\n  private color = ''\n  private scheduled = false\n  private sourcesDirty = false\n  private disposed = false\n  private failed = false\n  private invalidated = false\n\n  constructor(private publish: (images: string[]) => void) {}\n\n  invalidate(): void {\n    this.epoch++\n    this.color = ''\n    this.invalidated = true\n  }\n\n  update(sources: string[], color: string): void {\n    if (this.disposed || this.failed) return\n    this.invalidated = false\n    const changed = sources.length !== this.sources.length || sources.some((value, i) => value !== this.sources[i])\n    if (!changed && color === this.color) return\n    this.sources = sources\n    this.color = color\n    this.sourcesDirty ||= changed\n    this.epoch++\n    if (this.scheduled) return\n    this.scheduled = true\n    queueMicrotask(() => this.flush())\n  }\n\n  private flush(): void {\n    this.scheduled = false\n    if (this.disposed || this.failed || this.invalidated) return\n    try {\n      if (!this.worker) {\n        this.worker = new Worker(new URL('./thumbnail-worker.ts', import.meta.url), { type: 'module' })\n        this.worker.onmessage = (event: MessageEvent<{ id: number; images?: string[]; error?: string }>) => {\n          if (this.disposed || event.data.id !== this.epoch) return\n          if (event.data.error) { this.fail(event.data.error); return }\n          if (event.data.images) this.publish(event.data.images)\n        }\n        this.worker.onerror = event => this.fail(event.message)\n        this.worker.onmessageerror = () => this.fail('Thumbnail worker message could not be decoded')\n      }\n      this.worker.postMessage({\n        id: this.epoch, color: this.color,\n        ...(this.sourcesDirty ? { sources: this.sources } : {})\n      })\n      this.sourcesDirty = false\n    } catch (error) {\n      this.fail(String(error))\n    }\n  }\n\n  private fail(message: string): void {\n    this.failed = true\n    this.worker?.terminate()\n    this.worker = null\n    // Keep existing previews rather than falling back to blocking page rendering.\n    console.warn('[VerveDocs] Background thumbnails unavailable:', message)\n  }\n\n  destroy(): void {\n    this.disposed = true\n    this.epoch++\n    this.worker?.terminate()\n    this.worker = null\n    this.sources = []\n  }\n}\n","/**\r\n * VerveDocs Core —— DocxEditor\r\n *\r\n * 全新构造，零兼容：只接受 IDocxDocumentMeta。\r\n */\r\n\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'\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  /** 事件监听器（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\n  private adapt: CommandAdapt\n  private destroyed = false\n  private clipboardEpoch = 0\n\n  private clipboardGuard(): () => boolean {\n    const doc = this.draw.getDocument()\n    const epoch = this.clipboardEpoch\n    const zone = this.draw.getZone()\n    const range = JSON.stringify(this.range.getRange())\n    return () => !this.destroyed && epoch === this.clipboardEpoch &&\n      doc === this.draw.getDocument() && zone === this.draw.getZone() &&\n      range === JSON.stringify(this.range.getRange())\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\n  private thumbnailSources: string[] = []\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    const editorOptions = mergeOption(options)\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 => {\n      if (!this.destroyed) this.listener.emit('thumbnailChange', images)\n    })\n    this.listener.on('thumbnailAppearanceChange', () => this.refreshThumbnailAppearance())\n    for (const event of ['contentChange', 'documentSet'] as const) {\n      this.listener.on(event, () => this.thumbnailWorker.invalidate())\n    }\n    this.eventBus = new EventBus()\r\n    this.range = new RangeManager(this.listener)\n    for (const event of ['contentChange', 'documentSet', 'rangeChange', 'zoneChange'] as const) {\n      this.listener.on(event, () => { this.clipboardEpoch++ })\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,\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      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\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 }\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          const text = this.command.executeCopy()\r\n          if (!navigator.clipboard) return\r\n          const isCurrent = this.clipboardGuard()\r\n          const fragment = adapt.copyFragment()\n          const mime = 'web application/x-vervedocs+json'\n          const write = fragment && typeof ClipboardItem !== 'undefined' && ClipboardItem.supports?.(mime)\n            ? navigator.clipboard.write([new ClipboardItem({\n              'text/plain': new Blob([text], { type: 'text/plain' }),\n              [mime]: new Blob([JSON.stringify(fragment)], { type: 'application/x-vervedocs+json' })\n            })])\n            : navigator.clipboard.writeText(text)\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 (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      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,\n      getDocument: () => drawRef.getDocument(),\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        Object.assign(editorOptions, opts)\r\n        drawRef.setDocument(drawRef.getDocument())\r\n      },\r\n      setActiveGroup: (groupId: string | null) => { drawRef.setActiveGroup(groupId) },\r\n      setActiveRevision: (revisionId, color) => { drawRef.setActiveRevision(revisionId, color) },\n      getEventBus: () => this.eventBus,\r\n      setChartRenderer: (renderer) => drawRef.setChartRenderer(renderer),\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', () => {\n      this.worker.updateElements(this.draw.getDocument().elements)\n    })\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()\n        if (sources.length !== this.thumbnailSources.length || sources.some((value, i) => value !== this.thumbnailSources[i])) {\n          // Publish new content immediately; background composition follows asynchronously.\n          this.listener.emit('thumbnailChange', images)\n          this.thumbnailSources = sources\n        }\n        this.refreshThumbnailAppearance(sources)\n      }\n    })\n  }\n\n  private refreshThumbnailAppearance(sources?: string[]): void {\n    if (this.destroyed || !this.draw || !this.listener.hasListeners('thumbnailChange')) return\n    const options = this.draw.getOptions()\n    const background = options.background as { color?: string } | undefined\n    this.thumbnailWorker.update(sources ?? this.draw.getThumbnailForegrounds(),\n      options.eyeCare ? '#C7EDCC' : background?.color || '#ffffff')\n  }\n\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  /**\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()\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":["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","name","hash","i","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","_a","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","style","indentationBaseline","key","axis","container","PARA_KEYS","containerAny","childAny","pairBookmarkMarkers","markers","startMap","bookmarks","m","startPath","toDocxExportDocument","document","result","contentZones","boundaries","addBoundary","position","point","length","entries","bookmark","anchor","focus","start","end","marker","boundary","convert","entry","parts","offset","isParagraphTerminator","v","splitParagraphs","out","valueList","segs","splitValueList","runs","startIndex","vi","vStart","KeyMap","isApple","isMod","evt","has","prefix","Events","EE","context","once","addListener","emitter","event","listener","clearEvent","EventEmitter","names","events","handlers","l","ee","listeners","a1","a3","a4","a5","len","args","module","EventBus","__publicField","Listener","RangeManager","pos","range","ordered","delta","newOffset","LRU","limit","value","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","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","sectionWidths","columnGroups","columnSection","element","data","gap","width","rawBlocks","block","input","columnId","run","columns","anchorParagraphs","attachedImages","id","placedAnchors","headerBlocks","footerBlocks","headerOffsetY","last","headerContentHeight","footerOffsetY","pages","cursorY","currentBlocks","activeColumns","activeColumnId","columnIndex","columnTop","columnBottom","columnX","advanceColumn","pushPage","PAGE_FIT_EPSILON","previous","pageOriginY","headerPartId","footerPartId","pageHeaders","pageFooters","footerHeight","height","pageRect","contentRect","headerRect","footerRect","source","sourceColumnId","exclusions","placed","_f","attrs","distance","breakType","bh","_g","remaining","frags","fi","frag","floating","_h","_i","horizontal","_j","vertical","_k","resolve","ref","isX","origin","line","leading","align","_l","top","bottom","left","right","lastPage","totalHeight","page","availableWidth","paragraphs","blocks","gi","g","imgEl","issues","issue","feature","reason","reference","hasAnchor","paragraph","supported","item","imgDisplay","imgBlock","next","runsParentPath","pb","blockEl","anyEl","metrics","h","innerBlock","signature","cached","sameSources","paragraphKind","endIndex","runStartIndex","containerAttrs","collectedRunAttrs","r","ra","attr","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","lines","currentInlines","currentLineWidth","currentMaxSize","isFirstLine","firstLineOffset","flowY","lineRegion","exclusion","computeLineHeight","leftWidth","rightWidth","currentLineMaxWidth","lh","finalizeLine","isLastLine","region","lineXBase","inl","rawRun","hyperlinkUrl","vl","base","anyRun","rawFont","font","color","bgColor","strikeout","underline","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","add","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","_run","_path","paint","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","t","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","group","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","first","tbx","tby","ry","contentOX","contentOY","locateCaret","locateInBlocks","locateInParagraph","locateInTable","localX","charOffsetToX","pathStartsWith","offsetInInline","computeSelectionRects","collectSelectionInBlocks","collectSelectionInParagraph","segLeft","segRight","flush","inlStart","inlEnd","clipStartOff","clipEndOff","PREFIX","SVG","ContextMenu","target","items","isSub","div","main","icon","label","meta","sc","arrow","inputValue","min","max","unit","colorValue","colorInput","clear","parentEl","vw","vh","positionHandle","handle","viewport","visible","panelHtml$2","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","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$1","PX_PER_CM","ParagraphLayoutWidget","panes","lhType","lhValue","lhUnit","special","specialValue","updateLh","fixed","updateSpecial","outline","rule","spAfter","indentPx","alignMap","indent","FontLayoutWidget","cjk","fontValue","fontLabel","fontEntry","styleSel","sizeSel","cnName","doubleStrikeout","hidden","superscript","subscript","scale","styleVal","sizeVal","ParagraphWidget","onCommand","lastLine","firstInline","lastInline","alignment","menu","addButton","levels","labels","sub","alignments","svg","arrows","HeaderFooterWidget","make","textEl","f","caret","popup","styleRow","styleLabel","styleSelect","opt","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","existing","collectRevisionAnchors","CaretNavigation","localOff","isWord","para","targetY","newPos","ZoneManager","changed","trList","tdList","partId","TEXT_CURSOR","Draw","wasDragging","midY","assetLoaded","hanging","tableRects","selRects","rowCount","lastRow","lastColIdx","startCol","endCol","paperDirection","frame","images","pageStyles","error","visualSignature","foreground","bookmarkMarkers","diagnostics","notice","wrapperWidth","scrollLeft","skipAfterRender","pn","wm","CommandChain","CommandAdapt","draw","hm","resetHistory","action","coalesceKey","before","after","commit","startRunIdx","endRunIdx","startRun","endRun","startNode","endNode","toDelete","idxs","pageNo","scroller","wrapper","listPath","childIndex","newPath","anyT","flex","cursorIdx","targets","any","margin","toggleKey","adjusted","selectedRuns","allSet","startOffset","endPath","endOffset","sameRun","second","startParent","endParent","startIdx","endIdx","targetPath","fromStart","fromEnd","anchorNode","focusNode","replacements","isTerminator","paragraphKeys","restored","candidate","children","leadingSeparator","bullet","number","colWidth","trIndex","tdIndex","count","_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","link","normalized","sepAny","breaks","catalog","levelMap","blockPath","scrollContainer","targetScrollTop","empty","all","titleEl","tocElements","direction","keyword","PAD","textNodes","nodeIdx","match","needBefore","niBefore","prevValue","needAfter","niAfter","nextValue","replacement","collapsed","lastSeg","isVisible","tocId","currentOptions","lastNode","cloned","suffix","survivor","inherited","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","i18n","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","format","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","protocol","_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","snapshot","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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K,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,4EACL,IAAK,4DACL,IAAK,wCACL,IAAK,wCACL,IAAK,wCACL,IAAK,wCACL,IAAK,kDACL,IAAK,4BACL,IAAK,gCACL,IAAK,4BACL,IAAK,kCACL,IAAK,0CACL,IAAK,oDACL,IAAK,+BACL,IAAK,kCACL,IAAK,sEACL,IAAK,0BACL,IAAK,6EACL,IAAK,0IACL,IAAK,sMACL,IAAK,0FACL,IAAK,0EACL,IAAK,oCACL,IAAK,kBACL,IAAK,0BACL,IAAK,kCACL,IAAK,0CACL,IAAK,0CACL,IAAK,sDACL,IAAK,0EACL,IAAK,0EACL,IAAK,0GACL,IAAK,0EACL,IAAK,0EACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,KAAM,0CACN,KAAM,4EACN,KAAM,sDACN,KAAM,0DACN,KAAM,kDACN,KAAM,8CACN,KAAM,8EACN,KAAM,4DACN,KAAM,8BACN,KAAM,4CACN,KAAM,4DACN,KAAM,kCACN,KAAM,mEACN,KAAM,gDACN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","x_google_ignoreList":[2,8]}