kordoc 4.17.2 → 4.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/{-2UA2JHVA.js → -SQRLFE4N.js} +11 -11
  2. package/dist/{chunk-4HRJISJF.js → chunk-4D52VUGA.js} +3 -3
  3. package/dist/{chunk-6OCKAXIS.js → chunk-6DXSRQ65.js} +2 -2
  4. package/dist/{chunk-XZA6X34R.js → chunk-7TE6TK52.js} +2 -2
  5. package/dist/{chunk-KQIYC2ZU.js → chunk-AAQR4RIX.js} +2 -2
  6. package/dist/{chunk-GPC72VSF.cjs → chunk-AFXX3YSP.cjs} +262 -171
  7. package/dist/chunk-AFXX3YSP.cjs.map +1 -0
  8. package/dist/{chunk-6DOCSYEM.cjs → chunk-AOONZC4S.cjs} +3 -3
  9. package/dist/chunk-AOONZC4S.cjs.map +1 -0
  10. package/dist/{chunk-A2W2JQ3S.js → chunk-DD6AY6EI.js} +2 -2
  11. package/dist/{chunk-KZVQK5NS.cjs → chunk-EXBZHI25.cjs} +2 -2
  12. package/dist/chunk-EXBZHI25.cjs.map +1 -0
  13. package/dist/{chunk-FGL4IGOT.js → chunk-FSCVZR4A.js} +4 -4
  14. package/dist/{chunk-HAW2VL62.cjs → chunk-GNORDND5.cjs} +12 -12
  15. package/dist/chunk-GNORDND5.cjs.map +1 -0
  16. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  17. package/dist/{chunk-GYTL6WT3.js → chunk-HQ6TM2JE.js} +3 -3
  18. package/dist/{chunk-WJLICIYV.js → chunk-HY33WBAH.js} +24 -21
  19. package/dist/{chunk-WJLICIYV.js.map → chunk-HY33WBAH.js.map} +1 -1
  20. package/dist/{chunk-O4CB7D2Q.js → chunk-IERSVUW6.js} +2 -2
  21. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  22. package/dist/chunk-KIYHQQVO.cjs +170 -0
  23. package/dist/chunk-KIYHQQVO.cjs.map +1 -0
  24. package/dist/{chunk-SDRKHEVT.js → chunk-NNNRN6BY.js} +255 -164
  25. package/dist/chunk-NNNRN6BY.js.map +1 -0
  26. package/dist/{chunk-MDCTITUG.js → chunk-O5T5OIJM.js} +2 -2
  27. package/dist/{chunk-WL3BWROT.js → chunk-ODVIUG6Q.js} +22 -12
  28. package/dist/chunk-ODVIUG6Q.js.map +1 -0
  29. package/dist/{chunk-C4MVZXB5.js → chunk-P2ZPPRM7.js} +2 -2
  30. package/dist/chunk-PNXJYEOR.js +170 -0
  31. package/dist/chunk-PNXJYEOR.js.map +1 -0
  32. package/dist/{chunk-YGKC6E6A.js → chunk-PTMYCK7R.js} +2 -2
  33. package/dist/{chunk-4TSYMJDL.js → chunk-PVJFCDND.js} +38 -13
  34. package/dist/chunk-PVJFCDND.js.map +1 -0
  35. package/dist/{chunk-ZDX5PIWR.js → chunk-RCS7WXOM.js} +2 -2
  36. package/dist/{chunk-VU26WGE5.js → chunk-SSY6FQLS.js} +200 -97
  37. package/dist/chunk-SSY6FQLS.js.map +1 -0
  38. package/dist/{chunk-JY2NBFIG.js → chunk-TMHMJUYU.js} +302 -75
  39. package/dist/chunk-TMHMJUYU.js.map +1 -0
  40. package/dist/{chunk-5JZEY5IL.js → chunk-VJP7O6BL.js} +2 -2
  41. package/dist/{chunk-2XHXABCX.js → chunk-W3OY3SLY.js} +3 -3
  42. package/dist/chunk-W3OY3SLY.js.map +1 -0
  43. package/dist/{chunk-WWMKIHF7.cjs → chunk-WNF3TSV3.cjs} +129 -104
  44. package/dist/chunk-WNF3TSV3.cjs.map +1 -0
  45. package/dist/{chunk-3N272C5L.js → chunk-YBIWPCUX.js} +39 -14
  46. package/dist/chunk-YBIWPCUX.js.map +1 -0
  47. package/dist/chunks-VNSLMJQD.js +10 -0
  48. package/dist/cli.js +26 -26
  49. package/dist/{formula-5RETDCIC.cjs → formula-U37MTMBD.cjs} +9 -9
  50. package/dist/formula-U37MTMBD.cjs.map +1 -0
  51. package/dist/{formula-MBLN2DG4.js → formula-U3MJXXIL.js} +4 -4
  52. package/dist/{formula-QZZDW5GW.js → formula-WZH5CMA3.js} +3 -3
  53. package/dist/{image-ocr-EREKAS47.js → image-ocr-HYWDBN72.js} +6 -6
  54. package/dist/{image-ocr-PSPVRLB5.cjs → image-ocr-OXU55EW3.cjs} +15 -15
  55. package/dist/image-ocr-OXU55EW3.cjs.map +1 -0
  56. package/dist/{image-ocr-CJSO3QSR.js → image-ocr-V6MICC6R.js} +9 -8
  57. package/dist/{image-ocr-CJSO3QSR.js.map → image-ocr-V6MICC6R.js.map} +1 -1
  58. package/dist/index.cjs +1194 -864
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.js +531 -201
  61. package/dist/index.js.map +1 -1
  62. package/dist/mcp.js +22 -22
  63. package/dist/{model-bundle-MA4MMCRJ.js → model-bundle-AHBUQ6SD.js} +5 -5
  64. package/dist/{models-SEJ7LNSN.js → models-UF7B5LLG.js} +5 -5
  65. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  66. package/dist/{parser-M5WHRX25.js → parser-F6N6ID25.js} +22 -13
  67. package/dist/parser-F6N6ID25.js.map +1 -0
  68. package/dist/{parser-QILYPWSI.cjs → parser-IXRGUYZW.cjs} +207 -198
  69. package/dist/parser-IXRGUYZW.cjs.map +1 -0
  70. package/dist/{parser-VH3F4EQU.js → parser-T4FBG2FR.js} +23 -14
  71. package/dist/parser-T4FBG2FR.js.map +1 -0
  72. package/dist/pdf-ocr-2CITOAIG.cjs +16 -0
  73. package/dist/pdf-ocr-2CITOAIG.cjs.map +1 -0
  74. package/dist/pdf-ocr-RG2MFWBX.js +15 -0
  75. package/dist/pdf-ocr-U7Z4IUMA.js +19 -0
  76. package/dist/{profile-io-5YB627EO.js → profile-io-GM3NVLV3.js} +3 -3
  77. package/dist/{rasterize-V2XHHS2I.js → rasterize-4A3LJXTG.js} +3 -3
  78. package/dist/{redact-doc-5MK5L5IQ.js → redact-doc-SQ7C3LIG.js} +11 -11
  79. package/dist/{render-SYZMHYK6.js → render-6LTQZG4W.js} +7 -7
  80. package/dist/seal-ROSVLTRQ.js +10 -0
  81. package/dist/{setup-ZPLJENSK.js → setup-DGBJOROA.js} +3 -3
  82. package/dist/visual-6W34SFIW.js +20 -0
  83. package/dist/{watch-FNWHVKK3.js → watch-DJVJRSLE.js} +12 -12
  84. package/package.json +1 -1
  85. package/dist/chunk-2XHXABCX.js.map +0 -1
  86. package/dist/chunk-3N272C5L.js.map +0 -1
  87. package/dist/chunk-4TSYMJDL.js.map +0 -1
  88. package/dist/chunk-6DOCSYEM.cjs.map +0 -1
  89. package/dist/chunk-GPC72VSF.cjs.map +0 -1
  90. package/dist/chunk-HAW2VL62.cjs.map +0 -1
  91. package/dist/chunk-JY2NBFIG.js.map +0 -1
  92. package/dist/chunk-KZVQK5NS.cjs.map +0 -1
  93. package/dist/chunk-SDRKHEVT.js.map +0 -1
  94. package/dist/chunk-UX3HHAWH.js +0 -248
  95. package/dist/chunk-UX3HHAWH.js.map +0 -1
  96. package/dist/chunk-VU26WGE5.js.map +0 -1
  97. package/dist/chunk-WL3BWROT.js.map +0 -1
  98. package/dist/chunk-WWMKIHF7.cjs.map +0 -1
  99. package/dist/chunk-YIANW5QX.cjs +0 -248
  100. package/dist/chunk-YIANW5QX.cjs.map +0 -1
  101. package/dist/chunks-EBWJR55V.js +0 -10
  102. package/dist/formula-5RETDCIC.cjs.map +0 -1
  103. package/dist/image-ocr-PSPVRLB5.cjs.map +0 -1
  104. package/dist/parser-M5WHRX25.js.map +0 -1
  105. package/dist/parser-QILYPWSI.cjs.map +0 -1
  106. package/dist/parser-VH3F4EQU.js.map +0 -1
  107. package/dist/pdf-ocr-3SZUM3CN.cjs +0 -16
  108. package/dist/pdf-ocr-3SZUM3CN.cjs.map +0 -1
  109. package/dist/pdf-ocr-QB2TB5W5.js +0 -18
  110. package/dist/pdf-ocr-XC33L43D.js +0 -15
  111. package/dist/seal-IPKIQHYB.js +0 -10
  112. package/dist/visual-RTTGNOAE.js +0 -20
  113. /package/dist/{-2UA2JHVA.js.map → -SQRLFE4N.js.map} +0 -0
  114. /package/dist/{chunk-4HRJISJF.js.map → chunk-4D52VUGA.js.map} +0 -0
  115. /package/dist/{chunk-6OCKAXIS.js.map → chunk-6DXSRQ65.js.map} +0 -0
  116. /package/dist/{chunk-XZA6X34R.js.map → chunk-7TE6TK52.js.map} +0 -0
  117. /package/dist/{chunk-KQIYC2ZU.js.map → chunk-AAQR4RIX.js.map} +0 -0
  118. /package/dist/{chunk-A2W2JQ3S.js.map → chunk-DD6AY6EI.js.map} +0 -0
  119. /package/dist/{chunk-FGL4IGOT.js.map → chunk-FSCVZR4A.js.map} +0 -0
  120. /package/dist/{chunk-GYTL6WT3.js.map → chunk-HQ6TM2JE.js.map} +0 -0
  121. /package/dist/{chunk-O4CB7D2Q.js.map → chunk-IERSVUW6.js.map} +0 -0
  122. /package/dist/{chunk-MDCTITUG.js.map → chunk-O5T5OIJM.js.map} +0 -0
  123. /package/dist/{chunk-C4MVZXB5.js.map → chunk-P2ZPPRM7.js.map} +0 -0
  124. /package/dist/{chunk-YGKC6E6A.js.map → chunk-PTMYCK7R.js.map} +0 -0
  125. /package/dist/{chunk-ZDX5PIWR.js.map → chunk-RCS7WXOM.js.map} +0 -0
  126. /package/dist/{chunk-5JZEY5IL.js.map → chunk-VJP7O6BL.js.map} +0 -0
  127. /package/dist/{chunks-EBWJR55V.js.map → chunks-VNSLMJQD.js.map} +0 -0
  128. /package/dist/{formula-MBLN2DG4.js.map → formula-U3MJXXIL.js.map} +0 -0
  129. /package/dist/{formula-QZZDW5GW.js.map → formula-WZH5CMA3.js.map} +0 -0
  130. /package/dist/{image-ocr-EREKAS47.js.map → image-ocr-HYWDBN72.js.map} +0 -0
  131. /package/dist/{model-bundle-MA4MMCRJ.js.map → model-bundle-AHBUQ6SD.js.map} +0 -0
  132. /package/dist/{models-SEJ7LNSN.js.map → models-UF7B5LLG.js.map} +0 -0
  133. /package/dist/{pdf-ocr-QB2TB5W5.js.map → pdf-ocr-RG2MFWBX.js.map} +0 -0
  134. /package/dist/{pdf-ocr-XC33L43D.js.map → pdf-ocr-U7Z4IUMA.js.map} +0 -0
  135. /package/dist/{profile-io-5YB627EO.js.map → profile-io-GM3NVLV3.js.map} +0 -0
  136. /package/dist/{rasterize-V2XHHS2I.js.map → rasterize-4A3LJXTG.js.map} +0 -0
  137. /package/dist/{redact-doc-5MK5L5IQ.js.map → redact-doc-SQ7C3LIG.js.map} +0 -0
  138. /package/dist/{render-SYZMHYK6.js.map → render-6LTQZG4W.js.map} +0 -0
  139. /package/dist/{seal-IPKIQHYB.js.map → seal-ROSVLTRQ.js.map} +0 -0
  140. /package/dist/{setup-ZPLJENSK.js.map → setup-DGBJOROA.js.map} +0 -0
  141. /package/dist/{visual-RTTGNOAE.js.map → visual-6W34SFIW.js.map} +0 -0
  142. /package/dist/{watch-FNWHVKK3.js.map → watch-DJVJRSLE.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,9 +1,19 @@
1
1
  import {
2
+ blocksToPages,
3
+ inlineImagesIntoMarkdown
4
+ } from "./chunk-PNXJYEOR.js";
5
+ import {
6
+ parsePageRange
7
+ } from "./chunk-V4BH5SRQ.js";
8
+ import {
9
+ CELL_EDGES,
10
+ HEADING_RATIO_H1,
11
+ HEADING_RATIO_H2,
12
+ HEADING_RATIO_H3,
2
13
  MAX_COLS,
3
14
  MAX_ROWS,
4
15
  MAX_TABLE_CELLS,
5
16
  blocksToMarkdown,
6
- blocksToPages,
7
17
  buildTable,
8
18
  convertTableToText,
9
19
  dedupeRunningHeaders,
@@ -12,25 +22,15 @@ import {
12
22
  escapeLiteralDollar,
13
23
  flattenLayoutTables,
14
24
  hasStructuredCellContent,
15
- inlineImagesIntoMarkdown,
16
25
  mapPuaText,
17
26
  markNonLayoutTable,
18
- noteSuffix
19
- } from "./chunk-SDRKHEVT.js";
20
- import {
21
- parsePageRange
22
- } from "./chunk-V4BH5SRQ.js";
23
- import {
24
- CELL_EDGES,
25
- HEADING_RATIO_H1,
26
- HEADING_RATIO_H2,
27
- HEADING_RATIO_H3,
27
+ noteSuffix,
28
28
  plainScripts,
29
29
  stripScriptTags,
30
30
  tidyScriptTags,
31
31
  unframeLayoutTables,
32
32
  wrapScript
33
- } from "./chunk-UX3HHAWH.js";
33
+ } from "./chunk-NNNRN6BY.js";
34
34
  import {
35
35
  KordocError,
36
36
  OPTIONAL_DEP_INSTALL_HINT,
@@ -47,7 +47,7 @@ import {
47
47
  toArrayBuffer,
48
48
  unescapeHtml,
49
49
  unzipLimitBytes
50
- } from "./chunk-YGKC6E6A.js";
50
+ } from "./chunk-PTMYCK7R.js";
51
51
 
52
52
  // src/plain-markdown.ts
53
53
  function toPlainMarkdown(md2) {
@@ -583,7 +583,7 @@ function createSectionShared() {
583
583
  return {
584
584
  numState: /* @__PURE__ */ new Map(),
585
585
  pageText: { headers: [], footers: [] },
586
- track: { deleteDepth: 0, warned: false },
586
+ track: { deleteDepth: 0, warned: false, deletedObjects: /* @__PURE__ */ new WeakSet(), deletedImageRefs: /* @__PURE__ */ new Set() },
587
587
  pageState: { base: 0, allUsable: true }
588
588
  };
589
589
  }
@@ -959,6 +959,131 @@ function detectHwpxHeadings(blocks, styleMap) {
959
959
  }
960
960
  }
961
961
 
962
+ // src/hwpx/section-shape.ts
963
+ var DELETABLE_OBJECT_TAGS = /* @__PURE__ */ new Set([
964
+ "tbl",
965
+ "pic",
966
+ "shape",
967
+ "drawingObject",
968
+ "drawText",
969
+ "caption",
970
+ "rect",
971
+ "ellipse",
972
+ "polygon",
973
+ "line",
974
+ "arc",
975
+ "curve",
976
+ "connectLine",
977
+ "container"
978
+ ]);
979
+ function collectImageRefs(el, refs, depth = 0) {
980
+ if (depth > MAX_XML_DEPTH) return;
981
+ const tag = (el.tagName || el.localName || "").replace(/^[^:]+:/, "");
982
+ const ref = el.getAttribute("binaryItemIDRef") || (["img", "imgRect", "imgClip"].includes(tag) ? el.getAttribute("href") : "");
983
+ if (ref) refs.add(ref);
984
+ const children = el.childNodes;
985
+ for (let i = 0; i < (children?.length ?? 0); i++) {
986
+ const child = children[i];
987
+ if (child.nodeType === 1) collectImageRefs(child, refs, depth + 1);
988
+ }
989
+ }
990
+ function markDeletedObjects(node, deletedObjects, refs) {
991
+ let deleteDepth = 0;
992
+ const walk = (parent, depth) => {
993
+ if (depth > MAX_XML_DEPTH) return;
994
+ const children = parent.childNodes;
995
+ for (let i = 0; i < (children?.length ?? 0); i++) {
996
+ const child = children[i];
997
+ if (child.nodeType !== 1) continue;
998
+ const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
999
+ if (tag === "deleteBegin") {
1000
+ deleteDepth++;
1001
+ continue;
1002
+ }
1003
+ if (tag === "deleteEnd") {
1004
+ if (deleteDepth > 0) deleteDepth--;
1005
+ continue;
1006
+ }
1007
+ if (deleteDepth > 0 && DELETABLE_OBJECT_TAGS.has(tag)) {
1008
+ deletedObjects.add(child);
1009
+ collectImageRefs(child, refs);
1010
+ continue;
1011
+ }
1012
+ if (tag === "switch") {
1013
+ const branch = findChildByLocalName(child, "case") ?? findChildByLocalName(child, "default");
1014
+ if (branch) walk(branch, depth + 1);
1015
+ } else if (tag !== "hiddenComment" && tag !== "shapeComment" && tag !== "parameters") walk(child, depth + 1);
1016
+ }
1017
+ };
1018
+ walk(node, 0);
1019
+ }
1020
+ function inIndependentDeletionStory(track, extract) {
1021
+ const hostDeleteDepth = track.deleteDepth;
1022
+ track.deleteDepth = 0;
1023
+ try {
1024
+ return extract();
1025
+ } finally {
1026
+ track.deleteDepth = hostDeleteDepth;
1027
+ }
1028
+ }
1029
+ function extractImageRef(el, depth = 0, deletedObjects) {
1030
+ if (depth > MAX_XML_DEPTH) return null;
1031
+ const children = el.childNodes;
1032
+ if (!children) return null;
1033
+ for (let i = 0; i < children.length; i++) {
1034
+ const child = children[i];
1035
+ if (child.nodeType !== 1 || deletedObjects?.has(child)) continue;
1036
+ const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1037
+ if (tag === "imgRect" || tag === "img" || tag === "imgClip") {
1038
+ const ref = child.getAttribute("binaryItemIDRef") || child.getAttribute("href") || "";
1039
+ if (ref) return ref;
1040
+ }
1041
+ const nested = extractImageRef(child, depth + 1, deletedObjects);
1042
+ if (nested) return nested;
1043
+ }
1044
+ const directRef = el.getAttribute("binaryItemIDRef") || "";
1045
+ if (directRef) return directRef;
1046
+ return null;
1047
+ }
1048
+ function userShapeComment(el) {
1049
+ const commentEl = findChildByLocalName(el, "shapeComment");
1050
+ if (!commentEl) return void 0;
1051
+ const text = extractTextFromNode(commentEl);
1052
+ if (!text) return void 0;
1053
+ if (/^그림입니다/.test(text)) return void 0;
1054
+ if (/^(?:모서리가 둥근 |둥근 )?[^\n]{1,20}입니다\.?$/.test(text)) return void 0;
1055
+ return text;
1056
+ }
1057
+ function findDescendant(node, targetTag, depth = 0, deletedObjects) {
1058
+ if (depth > 5) return null;
1059
+ const children = node.childNodes;
1060
+ if (!children) return null;
1061
+ for (let i = 0; i < children.length; i++) {
1062
+ const child = children[i];
1063
+ if (child.nodeType !== 1 || deletedObjects?.has(child)) continue;
1064
+ const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1065
+ if (tag === targetTag) return child;
1066
+ const found = findDescendant(child, targetTag, depth + 1, deletedObjects);
1067
+ if (found) return found;
1068
+ }
1069
+ return null;
1070
+ }
1071
+ function findTopLevelTbls(el, out, deletedObjects, depth = 0) {
1072
+ if (depth > MAX_XML_DEPTH) return;
1073
+ const kids = el.childNodes;
1074
+ if (!kids) return;
1075
+ for (let i = 0; i < kids.length; i++) {
1076
+ const ch = kids[i];
1077
+ if (ch.nodeType !== 1 || deletedObjects.has(ch)) continue;
1078
+ const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
1079
+ if (tag === "tbl") {
1080
+ out.push(ch);
1081
+ continue;
1082
+ }
1083
+ findTopLevelTbls(ch, out, deletedObjects, depth + 1);
1084
+ }
1085
+ }
1086
+
962
1087
  // src/hwpx/equation.ts
963
1088
  var CONVERT_MAP = {
964
1089
  TIMES: "\\times",
@@ -1664,11 +1789,11 @@ var numAttr = (el, name) => {
1664
1789
  const n = v == null ? NaN : Number(v);
1665
1790
  return Number.isFinite(n) ? n : 0;
1666
1791
  };
1667
- var findDescendant = (root, local, maxDepth = 8) => {
1792
+ var findDescendant2 = (root, local, maxDepth = 8) => {
1668
1793
  if (maxDepth < 0) return null;
1669
1794
  for (const c of childElements(root)) {
1670
1795
  if (localName2(c) === local) return c;
1671
- const found = findDescendant(c, local, maxDepth - 1);
1796
+ const found = findDescendant2(c, local, maxDepth - 1);
1672
1797
  if (found) return found;
1673
1798
  }
1674
1799
  return null;
@@ -1709,7 +1834,7 @@ function tableIntraBreaks(tbl2) {
1709
1834
  return sum;
1710
1835
  }
1711
1836
  function detectHwpxSectionPages(root) {
1712
- const colPr = findDescendant(root, "colPr");
1837
+ const colPr = findDescendant2(root, "colPr");
1713
1838
  const multiCol = colPr ? numAttr(colPr, "colCount") > 1 : false;
1714
1839
  const paraPage = /* @__PURE__ */ new Map();
1715
1840
  let cur = 0;
@@ -1957,25 +2082,6 @@ function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1957
2082
  walkSection(doc.documentElement, blocks, null, [], ctx);
1958
2083
  return blocks;
1959
2084
  }
1960
- function extractImageRef(el, depth = 0) {
1961
- if (depth > MAX_XML_DEPTH) return null;
1962
- const children = el.childNodes;
1963
- if (!children) return null;
1964
- for (let i = 0; i < children.length; i++) {
1965
- const child = children[i];
1966
- if (child.nodeType !== 1) continue;
1967
- const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1968
- if (tag === "imgRect" || tag === "img" || tag === "imgClip") {
1969
- const ref = child.getAttribute("binaryItemIDRef") || child.getAttribute("href") || "";
1970
- if (ref) return ref;
1971
- }
1972
- const nested = extractImageRef(child, depth + 1);
1973
- if (nested) return nested;
1974
- }
1975
- const directRef = el.getAttribute("binaryItemIDRef") || "";
1976
- if (directRef) return directRef;
1977
- return null;
1978
- }
1979
2085
  function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1980
2086
  if (depth > MAX_XML_DEPTH) return;
1981
2087
  const children = node.childNodes;
@@ -1983,6 +2089,7 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1983
2089
  for (let i = 0; i < children.length; i++) {
1984
2090
  const el = children[i];
1985
2091
  if (el.nodeType !== 1) continue;
2092
+ if (ctx.shared.track.deletedObjects.has(el)) continue;
1986
2093
  const tag = el.tagName || el.localName || "";
1987
2094
  const localTag = tag.replace(/^[^:]+:/, "");
1988
2095
  switch (localTag) {
@@ -2194,8 +2301,10 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
2194
2301
  }
2195
2302
  }
2196
2303
  function handleShape(el, sink, ctx) {
2197
- const imgRef = extractImageRef(el);
2198
- const drawTextChild = findDescendant2(el, "drawText");
2304
+ const capEl = findChildByLocalName(el, "caption");
2305
+ if (capEl) markDeletedObjects(capEl, ctx.shared.track.deletedObjects, ctx.shared.track.deletedImageRefs);
2306
+ const imgRef = extractImageRef(el, 0, ctx.shared.track.deletedObjects);
2307
+ const drawTextChild = findDescendant(el, "drawText", 0, ctx.shared.track.deletedObjects);
2199
2308
  if (imgRef) {
2200
2309
  const block = { type: "image", text: imgRef, pageNumber: ctx.page };
2201
2310
  const alt2 = userShapeComment(el);
@@ -2205,7 +2314,6 @@ function handleShape(el, sink, ctx) {
2205
2314
  if (drawTextChild) {
2206
2315
  extractDrawTextBlocks(drawTextChild, sink, ctx);
2207
2316
  }
2208
- const capEl = findChildByLocalName(el, "caption");
2209
2317
  if (capEl) {
2210
2318
  const capText = collectSubListText(capEl, ctx);
2211
2319
  if (capText) sink.push({ type: "paragraph", text: capText, pageNumber: ctx.page });
@@ -2215,15 +2323,6 @@ function handleShape(el, sink, ctx) {
2215
2323
  ctx.warnings.push({ page: ctx.page, message: `\uC2A4\uD0B5\uB41C \uC694\uC18C: ${localTag}`, code: "SKIPPED_IMAGE" });
2216
2324
  }
2217
2325
  }
2218
- function userShapeComment(el) {
2219
- const commentEl = findChildByLocalName(el, "shapeComment");
2220
- if (!commentEl) return void 0;
2221
- const text = extractTextFromNode(commentEl);
2222
- if (!text) return void 0;
2223
- if (/^그림입니다/.test(text)) return void 0;
2224
- if (/^(?:모서리가 둥근 |둥근 )?[^\n]{1,20}입니다\.?$/.test(text)) return void 0;
2225
- return text;
2226
- }
2227
2326
  function mergeBlocksIntoCell(cell2, sink) {
2228
2327
  for (const b of sink) {
2229
2328
  if ((b.type === "paragraph" || b.type === "heading") && b.text) {
@@ -2281,7 +2380,7 @@ function hasPageAutoNum(el, depth = 0) {
2281
2380
  return false;
2282
2381
  }
2283
2382
  function collectSubListText(el, ctx, depth = 0) {
2284
- return collectSubListContent(el, ctx, depth).text;
2383
+ return inIndependentDeletionStory(ctx.shared.track, () => collectSubListContent(el, ctx, depth).text);
2285
2384
  }
2286
2385
  function collectSubListContent(el, ctx, depth = 0, sep = "\n") {
2287
2386
  const out = { text: "", blocks: [], hasStructure: false };
@@ -2291,7 +2390,7 @@ function collectSubListContent(el, ctx, depth = 0, sep = "\n") {
2291
2390
  if (!children) return out;
2292
2391
  for (let i = 0; i < children.length; i++) {
2293
2392
  const ch = children[i];
2294
- if (ch.nodeType !== 1) continue;
2393
+ if (ch.nodeType !== 1 || ctx.shared.track.deletedObjects.has(ch)) continue;
2295
2394
  const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
2296
2395
  if (tag === "p" || tag === "para") {
2297
2396
  let t = extractParagraphInfo(ch, ctx.styleMap, ctx).text;
@@ -2302,7 +2401,7 @@ function collectSubListContent(el, ctx, depth = 0, sep = "\n") {
2302
2401
  out.blocks.push({ type: "paragraph", text: t, pageNumber: ctx.page });
2303
2402
  }
2304
2403
  const tbls = [];
2305
- findTopLevelTbls(ch, tbls);
2404
+ findTopLevelTbls(ch, tbls, ctx.shared.track.deletedObjects);
2306
2405
  for (const tbl2 of tbls) {
2307
2406
  const built = buildSubListTable(tbl2, ctx, depth);
2308
2407
  if (built.text) parts.push(built.text);
@@ -2340,7 +2439,7 @@ function drawTextParaTexts(para2, ctx) {
2340
2439
  if (!kids) return;
2341
2440
  for (let i = 0; i < kids.length; i++) {
2342
2441
  const ch = kids[i];
2343
- if (ch.nodeType !== 1) continue;
2442
+ if (ch.nodeType !== 1 || ctx.shared.track.deletedObjects.has(ch)) continue;
2344
2443
  const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
2345
2444
  if (tag === "tbl" || tag === "footNote" || tag === "endNote") continue;
2346
2445
  if (tag === "drawText") {
@@ -2370,21 +2469,6 @@ function buildSubListTable(el, ctx, depth) {
2370
2469
  completeTable(st, [], built, ctx);
2371
2470
  return { text: flat, block: built.find((b) => b.type === "table") ?? null };
2372
2471
  }
2373
- function findTopLevelTbls(el, out, depth = 0) {
2374
- if (depth > MAX_XML_DEPTH) return;
2375
- const kids = el.childNodes;
2376
- if (!kids) return;
2377
- for (let i = 0; i < kids.length; i++) {
2378
- const ch = kids[i];
2379
- if (ch.nodeType !== 1) continue;
2380
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
2381
- if (tag === "tbl") {
2382
- out.push(ch);
2383
- continue;
2384
- }
2385
- findTopLevelTbls(ch, out, depth + 1);
2386
- }
2387
- }
2388
2472
  function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth = 0, onTbl) {
2389
2473
  if (depth > MAX_XML_DEPTH) return tableCtx;
2390
2474
  const children = node.childNodes;
@@ -2396,6 +2480,7 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
2396
2480
  for (let i = 0; i < kids.length; i++) {
2397
2481
  const el = kids[i];
2398
2482
  if (el.nodeType !== 1) continue;
2483
+ if (ctx.shared.track.deletedObjects.has(el)) continue;
2399
2484
  const tag = el.tagName || el.localName || "";
2400
2485
  const localTag = tag.replace(/^[^:]+:/, "");
2401
2486
  if (localTag === "tbl") {
@@ -2473,21 +2558,10 @@ function formButtonText(el, radio) {
2473
2558
  const caption = (el.getAttribute("caption") ?? "").trim();
2474
2559
  return caption && width >= FORM_CAPTION_MIN_WIDTH ? `${mark} ${caption}` : mark;
2475
2560
  }
2476
- function findDescendant2(node, targetTag, depth = 0) {
2477
- if (depth > 5) return null;
2478
- const children = node.childNodes;
2479
- if (!children) return null;
2480
- for (let i = 0; i < children.length; i++) {
2481
- const child = children[i];
2482
- if (child.nodeType !== 1) continue;
2483
- const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
2484
- if (tag === targetTag) return child;
2485
- const found = findDescendant2(child, targetTag, depth + 1);
2486
- if (found) return found;
2487
- }
2488
- return null;
2489
- }
2490
2561
  function extractDrawTextBlocks(drawTextNode, blocks, ctx) {
2562
+ inIndependentDeletionStory(ctx.shared.track, () => extractDrawTextStory(drawTextNode, blocks, ctx));
2563
+ }
2564
+ function extractDrawTextStory(drawTextNode, blocks, ctx) {
2491
2565
  const children = drawTextNode.childNodes;
2492
2566
  if (!children) return;
2493
2567
  for (let i = 0; i < children.length; i++) {
@@ -2496,7 +2570,7 @@ function extractDrawTextBlocks(drawTextNode, blocks, ctx) {
2496
2570
  const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
2497
2571
  if (tag === "subList" || tag === "p" || tag === "para") {
2498
2572
  if (tag === "subList") {
2499
- extractDrawTextBlocks(child, blocks, ctx);
2573
+ extractDrawTextStory(child, blocks, ctx);
2500
2574
  } else {
2501
2575
  const info = extractParagraphInfo(child, ctx.styleMap, ctx);
2502
2576
  let text = info.text.trim();
@@ -2610,6 +2684,11 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2610
2684
  const k = kids[j];
2611
2685
  if (k.nodeType !== 1) continue;
2612
2686
  const ktag = (k.tagName || k.localName || "").replace(/^[^:]+:/, "");
2687
+ if (isInDeletedRange(ctx) && DELETABLE_OBJECT_TAGS.has(ktag)) {
2688
+ ctx.shared.track.deletedObjects.add(k);
2689
+ collectImageRefs(k, ctx.shared.track.deletedImageRefs);
2690
+ continue;
2691
+ }
2613
2692
  switch (ktag) {
2614
2693
  // 머리말/꼬리말 — 문서당 1회 수집, 본문 앞/뒤 배치
2615
2694
  // 페이지 번호 크롬(autoNum PAGE + 문자 없는 잔여 텍스트, 예: "- 1 -")은 본문 정보가
@@ -2700,6 +2779,11 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2700
2779
  }
2701
2780
  if (child.nodeType !== 1) continue;
2702
2781
  const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
2782
+ if (isInDeletedRange(ctx) && DELETABLE_OBJECT_TAGS.has(tag)) {
2783
+ ctx.shared.track.deletedObjects.add(child);
2784
+ collectImageRefs(child, ctx.shared.track.deletedImageRefs);
2785
+ continue;
2786
+ }
2703
2787
  switch (tag) {
2704
2788
  case "t":
2705
2789
  walk(child, depth + 1);
@@ -3437,7 +3521,7 @@ function collectImageBlocks2(blocks, out, ownerCell, depth = 0) {
3437
3521
  if (block.children?.length) collectImageBlocks2(block.children, out, ownerCell, depth + 1);
3438
3522
  }
3439
3523
  }
3440
- async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUnreferenced) {
3524
+ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUnreferenced, deletedRefs) {
3441
3525
  const images = [];
3442
3526
  let imageIndex = 0;
3443
3527
  const usedPaths = /* @__PURE__ */ new Set();
@@ -3506,6 +3590,8 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUn
3506
3590
  const binEntries = zip.file(/(?:^|\/)BinData\//i);
3507
3591
  for (const file of binEntries) {
3508
3592
  if (file.dir || usedPaths.has(file.name) || isPathTraversal(file.name)) continue;
3593
+ const basename = file.name.slice(file.name.lastIndexOf("/") + 1);
3594
+ if (deletedRefs?.has(file.name) || deletedRefs?.has(basename) || deletedRefs?.has(file.name.replace(/\.[^/.]+$/, "")) || deletedRefs?.has(basename.replace(/\.[^.]+$/, ""))) continue;
3509
3595
  try {
3510
3596
  const data = await file.async("uint8array");
3511
3597
  decompressed.total += data.length;
@@ -3839,7 +3925,7 @@ async function parseHwpxDocument(buffer, options) {
3839
3925
  }
3840
3926
  const blocks = allBlocks;
3841
3927
  applyPageText(blocks, shared);
3842
- const images = await extractImagesFromZip(zip, blocks, decompressed, warnings, !options?.pages);
3928
+ const images = await extractImagesFromZip(zip, blocks, decompressed, warnings, !options?.pages, shared.track.deletedImageRefs);
3843
3929
  const shown = options?.layoutTables === "keep" ? blocks : unframeLayoutTables(blocks, !!options?.keepTrailingEmptyCols);
3844
3930
  detectHwpxHeadings(shown, styleMap);
3845
3931
  const outline = shown.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
@@ -25386,7 +25472,7 @@ function gaejosikMarker(depth, bullet2 = "\u25CB") {
25386
25472
  }
25387
25473
  function gaejosikSizes(bodyHeight, ov = {}) {
25388
25474
  const s = bodyHeight / 1500;
25389
- const r = (v, pt2) => pt2 ? Math.round(pt2 * 100) : Math.round(v * s);
25475
+ const r = (v, pt3) => pt3 ? Math.round(pt3 * 100) : Math.round(v * s);
25390
25476
  return {
25391
25477
  /** □ 대항목 — HY헤드라인M 16pt */
25392
25478
  dae: r(1600, ov.dae),
@@ -25747,13 +25833,13 @@ var SPACINGS = [0, -3, -5];
25747
25833
  function safety(faceClass, approx) {
25748
25834
  return faceClass.startsWith("font:") ? 0.98 : approx;
25749
25835
  }
25750
- function fitOneLine(text, font, pt2, availHu, minPt = Math.max(pt2 - 3, 10), minRatio = 85) {
25836
+ function fitOneLine(text, font, pt3, availHu, minPt = Math.max(pt3 - 3, 10), minRatio = 85) {
25751
25837
  const faceClass = faceClassForGen(font);
25752
25838
  const avail = availHu * safety(faceClass, 0.98);
25753
25839
  const fits = (p, r, s) => measureTextWidth(text, p * 100, r, { spacingPct: s, faceClass }) <= avail;
25754
- if (fits(pt2, 100, 0)) return { pt: pt2, ratio: 100, spacing: 0, overflow: false };
25840
+ if (fits(pt3, 100, 0)) return { pt: pt3, ratio: 100, spacing: 0, overflow: false };
25755
25841
  const ratios = RATIOS.filter((r) => r >= minRatio);
25756
- for (let p = pt2; p >= minPt; p--) {
25842
+ for (let p = pt3; p >= minPt; p--) {
25757
25843
  for (const r of ratios) for (const s of SPACINGS) {
25758
25844
  if (fits(p, r, s)) return { pt: p, ratio: r, spacing: s, overflow: false };
25759
25845
  }
@@ -25784,9 +25870,9 @@ function worstLooseness(text, starts, firstW, contW, h, ratio, spacing, faceClas
25784
25870
  }
25785
25871
  return worst;
25786
25872
  }
25787
- function fitParagraph(text, font, pt2, firstW, contW, minRatio = 88, orphanRatio = ORPHAN_RATIO) {
25873
+ function fitParagraph(text, font, pt3, firstW, contW, minRatio = 88, orphanRatio = ORPHAN_RATIO) {
25788
25874
  const faceClass = faceClassForGen(font);
25789
- const h = pt2 * 100;
25875
+ const h = pt3 * 100;
25790
25876
  const k = safety(faceClass, 0.95);
25791
25877
  const f = firstW * k, c = contW * k;
25792
25878
  const ladder = [[100, 0], ...SQUEEZE.filter(([r]) => r >= minRatio)];
@@ -25840,9 +25926,9 @@ function fitParagraph(text, font, pt2, firstW, contW, minRatio = 88, orphanRatio
25840
25926
  return best && (best.r !== 100 || best.sp !== 0) ? { ratio: best.r, spacing: best.sp } : null;
25841
25927
  }
25842
25928
  var LIST_BREAK = /* @__PURE__ */ new Set([..."\xB7,\u3001/"]);
25843
- function fitCharBreaks(text, font, pt2, firstW, contW, minRatio = 88) {
25929
+ function fitCharBreaks(text, font, pt3, firstW, contW, minRatio = 88) {
25844
25930
  const faceClass = faceClassForGen(font);
25845
- const h = pt2 * 100;
25931
+ const h = pt3 * 100;
25846
25932
  const k = safety(faceClass, 0.95);
25847
25933
  if (!text.split(/ +/).some((w) => measureTextWidth(w, h, 100, { faceClass }) > contW * k)) return null;
25848
25934
  let best = null;
@@ -26180,7 +26266,7 @@ function buildReportCover(inp, ctx) {
26180
26266
  const cAppr = cv ? reg.char({ font: cv.infoFont, pt: cv.approvalPt }) : c12;
26181
26267
  const center = reg.para({ align: "CENTER", lineSp: 100 });
26182
26268
  const centerAt = (k) => cv ? reg.para({ align: "CENTER", lineSp: cv.lineSp[k] }) : center;
26183
- const blank2 = (pt2 = 15) => para("", reg.para({ align: "LEFT", lineSp: 160 }), reg.char({ font: "\uD55C\uCEF4\uB3CB\uC6C0", pt: pt2 }));
26269
+ const blank2 = (pt3 = 15) => para("", reg.para({ align: "LEFT", lineSp: 160 }), reg.char({ font: "\uD55C\uCEF4\uB3CB\uC6C0", pt: pt3 }));
26184
26270
  const infoRows = [["\uBB38\uC11C\uBC88\uD638", inp.docInfo?.docNum ?? ""], ["\uACB0\uC7AC\uC77C\uC790", inp.docInfo?.date ?? ""], ["\uACF5\uAC1C\uC5EC\uBD80", inp.docInfo?.disclosure ?? ""], ["\uBC29\uCE68\uBC88\uD638", inp.docInfo?.policyNo ?? ""]];
26185
26271
  const infoW = Math.round(ctx.W * 0.36);
26186
26272
  const [lw, vw] = scale([4200, 12800], infoW);
@@ -26312,13 +26398,13 @@ function buildSeoulChecklist(inp, ctx) {
26312
26398
  ["\uD574\uB2F9\uC5C6\uC74C", 12, false, void 0, "CENTER", bf.get({ l: GOLD01, r: GOLD01, t: "none", b: OR07, fill: WHITE })],
26313
26399
  ["\uBE44 \uACE0", 12, false, void 0, "CENTER", bf.get({ l: GOLD01, r: "none", t: "none", b: OR07, fill: WHITE })]
26314
26400
  ];
26315
- rows.push(hdr.map(([t, pt2, bold, color, align, b], c) => tc({
26401
+ rows.push(hdr.map(([t, pt3, bold, color, align, b], c) => tc({
26316
26402
  bf: b,
26317
26403
  row: 2,
26318
26404
  col: c,
26319
26405
  w: COLS[c],
26320
26406
  h: 3142,
26321
- paras: p(runXml([t, 0, 100, color, pt2], bold), align === "DISTRIBUTE" ? { align: "DISTRIBUTE", left: 500, right: 500, lineSp: 160 } : center(c === 1 ? 160 : 110))
26407
+ paras: p(runXml([t, 0, 100, color, pt3], bold), align === "DISTRIBUTE" ? { align: "DISTRIBUTE", left: 500, right: 500, lineSp: 160 } : center(c === 1 ? 160 : 110))
26322
26408
  })).join(""));
26323
26409
  let row = 3, no = 0;
26324
26410
  const last = GROUPS.at(-1).cats.at(-1).items.at(-1);
@@ -28944,17 +29030,34 @@ function profileColWidths(tp, colCnt) {
28944
29030
  return null;
28945
29031
  }
28946
29032
  var CELL_PAD = 1200;
28947
- function cellContentWidth(text, charHeight) {
29033
+ function markdownCellLines(text) {
29034
+ return text.split(/<br\s*\/?>/i).map((seg) => {
29035
+ if (!/[\\`*_!\[<~\x00]/.test(seg)) return seg.trim();
29036
+ return parseInlineMarkdown(seg.replace(/!\[[^\]]*\]\([^)]*\)/g, "")).map((span2) => span2.text).join("").trim();
29037
+ });
29038
+ }
29039
+ function markdownTableLines(rows) {
29040
+ const cache = /* @__PURE__ */ new Map();
29041
+ return rows.map((row) => row.map((cell2) => {
29042
+ let lines = cache.get(cell2);
29043
+ if (!lines) {
29044
+ lines = markdownCellLines(cell2);
29045
+ cache.set(cell2, lines);
29046
+ }
29047
+ return lines;
29048
+ }));
29049
+ }
29050
+ function cellContentWidth(lines, charHeight) {
28948
29051
  let max = 0;
28949
- for (const seg of text.replace(/!\[[^\]]*\]\([^)\s]+\)/g, "").replace(/\*\*|__|`/g, "").split(/<br\s*\/?>/i)) {
29052
+ for (const seg of lines) {
28950
29053
  const w = measureTextWidth(seg.trim(), charHeight, 100, { faceClass: curFace });
28951
29054
  if (w > max) max = w;
28952
29055
  }
28953
29056
  return max;
28954
29057
  }
28955
- function cellMinWordWidth(text, charHeight) {
29058
+ function cellMinWordWidth(lines, charHeight) {
28956
29059
  let max = 0;
28957
- for (const seg of text.replace(/!\[[^\]]*\]\([^)\s]+\)/g, "").replace(/\*\*|__|`/g, "").split(/<br\s*\/?>/i)) {
29060
+ for (const seg of lines) {
28958
29061
  for (const word of seg.trim().split(/[ \t]+/)) {
28959
29062
  const w = measureTextWidth(word, charHeight, 100, { faceClass: curFace });
28960
29063
  if (w > max) max = w;
@@ -28966,8 +29069,8 @@ var REMARK_HEAD = /^(비고|비고란|비고사항|참고|참고사항|출처|(
28966
29069
  var CONTENT_HEAD = /(내용|사항|실적|계획|방안|사유|개요|설명|임무|역할|현황|성과)$/u;
28967
29070
  var REMARK_SHARE = 0.25;
28968
29071
  var CONTENT_WEIGHT = 2;
28969
- function colRoles(headers) {
28970
- const clean = headers.map((h) => (h ?? "").replace(/!\[[^\]]*\]\([^)\s]+\)/g, "").replace(/\*\*|__|`|\s+/g, ""));
29072
+ function colRoles(headers, markdown = true) {
29073
+ const clean = headers.map((h) => markdown ? markdownCellLines(h ?? "").join("").replace(/\s+/g, "") : (h ?? "").replace(/!\[[^\]]*\]\([^)\s]+\)/g, "").replace(/\*\*|__|`|\s+/g, ""));
28971
29074
  const roles = clean.map((h) => REMARK_HEAD.test(h) ? "remark" : h.length <= 12 && CONTENT_HEAD.test(h) ? "content" : null);
28972
29075
  const last = roles.length - 1;
28973
29076
  if (roles.length >= 3 && roles.includes("content") && roles[last] === null) roles[last] = "remark";
@@ -29041,14 +29144,12 @@ function computeColWidths(colMax, totalWidth, colMinWord = [], roles = [], slack
29041
29144
  }
29042
29145
  return widths;
29043
29146
  }
29044
- function estimateRowHeight(cells, widths, charHeight) {
29147
+ function estimateRowHeight(cellWidths, widths, charHeight) {
29045
29148
  let maxLines = 1;
29046
- cells.forEach((cell2, c) => {
29149
+ cellWidths.forEach((cell2, c) => {
29047
29150
  const usable = Math.max((widths[c] ?? widths[widths.length - 1]) - CELL_PAD, 1e3);
29048
29151
  let lines = 0;
29049
- for (const seg of cell2.replace(/\*\*|__|`/g, "").split(/<br\s*\/?>/i)) {
29050
- lines += Math.max(1, Math.ceil(measureTextWidth(seg.trim(), charHeight, 100, { faceClass: curFace }) / usable));
29051
- }
29152
+ for (const w of cell2) lines += Math.max(1, Math.ceil(w / usable));
29052
29153
  if (lines > maxLines) maxLines = lines;
29053
29154
  });
29054
29155
  return maxLines * Math.round(charHeight * 1.6) + 282;
@@ -29058,7 +29159,7 @@ function requiredTableWidth(rows, charHeight, faceClass = "hcr") {
29058
29159
  curFace = faceClass;
29059
29160
  const colCnt = Math.max(...rows.map((r) => r.length), 1);
29060
29161
  const colMax = Array(colCnt).fill(0);
29061
- for (const row of rows) row.forEach((cell2, c) => {
29162
+ for (const row of markdownTableLines(rows)) row.forEach((cell2, c) => {
29062
29163
  const w = cellContentWidth(cell2, charHeight);
29063
29164
  if (w > colMax[c]) colMax[c] = w;
29064
29165
  });
@@ -29077,8 +29178,10 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0, images
29077
29178
  const colMax = Array(colCnt).fill(0);
29078
29179
  const colMaxBody = Array(colCnt).fill(0);
29079
29180
  const colMinWord = Array(colCnt).fill(0);
29080
- rows.forEach((row, r) => row.forEach((cell2, c) => {
29081
- const w = cellContentWidth(cell2, measureH);
29181
+ const cellLines = markdownTableLines(rows);
29182
+ const cellWidths = cellLines.map((row) => row.map((lines) => lines.map((line) => measureTextWidth(line, measureH, 100, { faceClass: curFace }))));
29183
+ cellLines.forEach((row, r) => row.forEach((cell2, c) => {
29184
+ const w = cellWidths[r][c].reduce((max, width) => Math.max(max, width), 0);
29082
29185
  if (w > colMax[c]) colMax[c] = w;
29083
29186
  if (r > 0 && w > colMaxBody[c]) colMaxBody[c] = w;
29084
29187
  const mw = cellMinWordWidth(cell2, measureH);
@@ -29091,7 +29194,7 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0, images
29091
29194
  const tblId = nextTableId();
29092
29195
  const useHeaderStyle = !style && (theme.tableHeader !== theme.body || theme.tableHeaderBold);
29093
29196
  const mapId = style ? (id) => id === CHAR_NORMAL ? style.charPr : id === CHAR_BOLD ? style.boldCharPr : id : void 0;
29094
- const rowHeights = rows.map((row) => style ? estimateRowHeight(row, colWidths, measureH) : 1500);
29197
+ const rowHeights = cellWidths.map((row) => style ? estimateRowHeight(row, colWidths, measureH) : 1500);
29095
29198
  const trElements = rows.map((row, rowIdx) => {
29096
29199
  const cells = row.length < colCnt ? [...row, ...Array(colCnt - row.length).fill("")] : row;
29097
29200
  const isHeaderRow = rowIdx === 0;
@@ -29196,7 +29299,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
29196
29299
  const cellLines = cellParsed.map((p) => p.lines);
29197
29300
  placed.forEach((cell2, i) => {
29198
29301
  const w = Math.max(...cellLines[i].map((l) => measureTextWidth(l.trim(), measureH, 100, { faceClass: curFace })), 0) / cell2.colSpan;
29199
- const mw = cell2.colSpan === 1 ? Math.max(...cellLines[i].map((l) => cellMinWordWidth(l, measureH)), 0) : 0;
29302
+ const mw = cell2.colSpan === 1 ? cellMinWordWidth(cellLines[i].flatMap((line) => line.replace(/!\[[^\]]*\]\([^)\s]+\)/g, "").replace(/\*\*|__|`/g, "").split(/<br\s*\/?>/i)), measureH) : 0;
29200
29303
  for (let dc = 0; dc < cell2.colSpan; dc++) {
29201
29304
  const c = cell2.c + dc;
29202
29305
  if (w > colMax[c]) colMax[c] = w;
@@ -29206,7 +29309,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
29206
29309
  });
29207
29310
  const headers = Array.from({ length: colCnt }, () => "");
29208
29311
  for (const [i, cell2] of placed.entries()) if (cell2.r === 0 && cell2.c < colCnt) headers[cell2.c] = cellLines[i].join(" ");
29209
- const roles = style ? colRoles(headers) : [];
29312
+ const roles = style ? colRoles(headers, false) : [];
29210
29313
  const colWidths = profileColWidths(prof, colCnt) ?? computeColWidths(colMax, totalWidth, colMinWord, roles, colSlack(curFace));
29211
29314
  const colCentered = colWidths.map((w, c) => roles[c] !== "content" && colMaxBody[c] + CELL_PAD <= w);
29212
29315
  const cellH = style ? Math.round(measureH * 1.6) + 282 : 1500;
@@ -30309,7 +30412,7 @@ function gaejosikMarkerOf(bullet2) {
30309
30412
  }
30310
30413
  function seoulGaejosikScheme(bodyPt = 15, lineSp = 180, bullet2 = "\u3147") {
30311
30414
  const d = bodyPt - 15;
30312
- const lv = (font, pt2, bold, leadTa, extra = {}) => ({ font, pt: pt2 + d, bold, leadTa, ...extra });
30415
+ const lv = (font, pt3, bold, leadTa, extra = {}) => ({ font, pt: pt3 + d, bold, leadTa, ...extra });
30313
30416
  return {
30314
30417
  kind: "gaejosik",
30315
30418
  lineSp,
@@ -30347,7 +30450,7 @@ var MINISTRY_FRAME = {
30347
30450
  };
30348
30451
  function ministryScheme(bodyPt = 15, lineSp = 145) {
30349
30452
  const d = bodyPt - 15;
30350
- const lv = (font, pt2, bold, leadTa, extra = {}) => ({ font, pt: pt2 + d, bold, leadTa, ...extra });
30453
+ const lv = (font, pt3, bold, leadTa, extra = {}) => ({ font, pt: pt3 + d, bold, leadTa, ...extra });
30351
30454
  return {
30352
30455
  kind: "gaejosik",
30353
30456
  lineSp,
@@ -30400,7 +30503,7 @@ var BANGCHIM_FRAME = {
30400
30503
  };
30401
30504
  function seoulBangchimScheme(bodyPt = 15, lineSp = 190) {
30402
30505
  const d = bodyPt - 15;
30403
- const lv = (font, pt2, bold, leadTa, extra = {}) => ({ font, pt: pt2 + d, bold, leadTa, ...extra });
30506
+ const lv = (font, pt3, bold, leadTa, extra = {}) => ({ font, pt: pt3 + d, bold, leadTa, ...extra });
30404
30507
  return {
30405
30508
  kind: "gaejosik",
30406
30509
  lineSp,
@@ -30472,8 +30575,8 @@ function applySchemeOverrides(s, g3) {
30472
30575
  }
30473
30576
  return out;
30474
30577
  }
30475
- function taHu(pt2) {
30476
- return Math.round(pt2 * 50);
30578
+ function taHu(pt3) {
30579
+ return Math.round(pt3 * 50);
30477
30580
  }
30478
30581
  function pickScheme(g3, bodyHasBoxMarkers, numbered = false) {
30479
30582
  if (g3.preset === "bangchim") {
@@ -30724,11 +30827,11 @@ function buildOutline(blocks, opts) {
30724
30827
  }
30725
30828
 
30726
30829
  // src/hwpx/gen-marker.ts
30727
- function markerLayout(font, pt2, leadTa, marker) {
30728
- const left = leadTa * taHu(pt2);
30830
+ function markerLayout(font, pt3, leadTa, marker) {
30831
+ const left = leadTa * taHu(pt3);
30729
30832
  if (!marker) return { left, hang: 0, markerW: 0 };
30730
- const markerW = Math.round(measureTextWidth(marker, pt2 * 100, 100, { faceClass: faceClassForGen(font) }));
30731
- return { left, hang: markerW + taHu(pt2), markerW };
30833
+ const markerW = Math.round(measureTextWidth(marker, pt3 * 100, 100, { faceClass: faceClassForGen(font) }));
30834
+ return { left, hang: markerW + taHu(pt3), markerW };
30732
30835
  }
30733
30836
  function markerRunXml(marker, charPr2, lay) {
30734
30837
  return `<hp:run charPrIDRef="${charPr2}"><hp:t>${escapeTextXml(marker)}<hp:tab width="${lay.hang - lay.markerW}" leader="0" type="1"/></hp:t></hp:run>`;
@@ -30815,14 +30918,14 @@ function ministryRuns(marker, text, ctx, base, keywordColor, emphasisColor) {
30815
30918
  function plain(text) {
30816
30919
  return text.replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/`([^`]+)`/g, "$1");
30817
30920
  }
30818
- function textW(text, font, pt2) {
30819
- return measureTextWidth(text, pt2 * 100, 100, { faceClass: faceClassForGen(font) });
30921
+ function textW(text, font, pt3) {
30922
+ return measureTextWidth(text, pt3 * 100, 100, { faceClass: faceClassForGen(font) });
30820
30923
  }
30821
30924
  function buildMinistryCover(inp, ctx) {
30822
30925
  const { reg, bf } = ctx;
30823
30926
  const c = MINISTRY.cover;
30824
30927
  const out = [];
30825
- const blank2 = (pt2 = 15) => para("", reg.para({ align: "LEFT", lineSp: 145 }), reg.char({ font: MINISTRY.bodyFont, pt: pt2 }));
30928
+ const blank2 = (pt3 = 15) => para("", reg.para({ align: "LEFT", lineSp: 145 }), reg.char({ font: MINISTRY.bodyFont, pt: pt3 }));
30826
30929
  const center = reg.para({ align: "CENTER", lineSp: 130 });
30827
30930
  if (inp.label) {
30828
30931
  const red = ["0.12 mm", "#FF0000"];
@@ -31158,7 +31261,7 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
31158
31261
  let pendingNewPageNum = isMinistry && (!!g3.cover || !!g3.toc);
31159
31262
  let chapterStyle = g3.h2Marker === "box" || g3.h2Marker === "number" || g3.h2Marker === "none" || g3.h2Marker === "band" || g3.h2Marker === "square" ? g3.h2Marker : "roman";
31160
31263
  if (!gaejosik) chapterStyle = "number";
31161
- const leadLeft = (depth, pt2) => (scheme.levels[Math.min(depth, 7)]?.leadTa ?? 0) * taHu(pt2);
31264
+ const leadLeft = (depth, pt3) => (scheme.levels[Math.min(depth, 7)]?.leadTa ?? 0) * taHu(pt3);
31162
31265
  const renderItem = (node, styleId = 0) => {
31163
31266
  const depth = Math.min(node.depth, 7);
31164
31267
  const sub = gaejosik && node.legalMarker;
@@ -31313,10 +31416,10 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
31313
31416
  let style = tableStyle;
31314
31417
  const face = faceClassForGen(scheme.table.font);
31315
31418
  const avail = W2 - DATA_TABLE_INSET;
31316
- for (const pt2 of [scheme.table.pt, scheme.table.pt - 1, scheme.table.pt - 2]) {
31317
- if (pt2 < 9) break;
31318
- if (requiredTableWidth(b.rows, pt2 * 100, face) <= avail || pt2 === scheme.table.pt - 2) {
31319
- if (pt2 !== scheme.table.pt) style = { ...tableStyle, charPr: reg.char({ font: scheme.table.font, pt: pt2 }), boldCharPr: reg.char({ font: scheme.table.font, pt: pt2, bold: true }), charHeight: pt2 * 100 };
31419
+ for (const pt3 of [scheme.table.pt, scheme.table.pt - 1, scheme.table.pt - 2]) {
31420
+ if (pt3 < 9) break;
31421
+ if (requiredTableWidth(b.rows, pt3 * 100, face) <= avail || pt3 === scheme.table.pt - 2) {
31422
+ if (pt3 !== scheme.table.pt) style = { ...tableStyle, charPr: reg.char({ font: scheme.table.font, pt: pt3 }), boldCharPr: reg.char({ font: scheme.table.font, pt: pt3, bold: true }), charHeight: pt3 * 100 };
31320
31423
  break;
31321
31424
  }
31322
31425
  }
@@ -38707,7 +38810,7 @@ function findFirst(el, name, depth = 0) {
38707
38810
  }
38708
38811
  return null;
38709
38812
  }
38710
- var OBJ_TAGS = /* @__PURE__ */ new Set(["tbl", "pic", "container", "equation", "rect", "ellipse", "polygon", "curv", "line", "arc", "ole", "textart"]);
38813
+ var OBJ_TAGS = /* @__PURE__ */ new Set(["tbl", "pic", "container", "equation", "rect", "ellipse", "polygon", "curv", "curve", "line", "arc", "ole", "textart"]);
38711
38814
  var CHAR_CTRL_1SLOT = /* @__PURE__ */ new Set(["lineBreak", "hyphen", "nbSpace", "fwSpace"]);
38712
38815
  function pushFillers(chars, n, prId) {
38713
38816
  for (let i = 0; i < n; i++) chars.push({ ch: "", prId });
@@ -38737,10 +38840,51 @@ function pushTextSlots(t, chars, prId, depth) {
38737
38840
  }
38738
38841
  }
38739
38842
  }
38843
+ var deletedStarts = /* @__PURE__ */ new WeakMap();
38844
+ var deletedControls = /* @__PURE__ */ new WeakMap();
38845
+ function isDeletedControl(el) {
38846
+ return deletedControls.get(el) === true;
38847
+ }
38848
+ function deletionDelta(ctrl, depth, xmlDepth = 0) {
38849
+ if (xmlDepth > 64) return depth;
38850
+ if (ln(ctrl) === "deleteBegin") return depth + 1;
38851
+ if (ln(ctrl) === "deleteEnd") return Math.max(0, depth - 1);
38852
+ if (ln(ctrl) === "ctrl") for (const ch of elements(ctrl)) depth = deletionDelta(ch, depth, xmlDepth + 1);
38853
+ return depth;
38854
+ }
38855
+ function prepareDeletedRanges(root, depth = 0) {
38856
+ if (depth > 64) return;
38857
+ let deleted = 0;
38858
+ for (const p of elements(root)) {
38859
+ if (ln(p) !== "p") continue;
38860
+ deletedStarts.set(p, deleted);
38861
+ const scan = (el, xmlDepth) => {
38862
+ if (xmlDepth > 64) return;
38863
+ if (ln(el) === "ctrl") for (const ch of elements(el)) scan(ch, xmlDepth + 1);
38864
+ else {
38865
+ if (ln(el) === "deleteBegin" || ln(el) === "deleteEnd") deleted = deletionDelta(el, deleted);
38866
+ deletedControls.set(el, deleted > 0);
38867
+ }
38868
+ };
38869
+ for (const ch of elements(p)) {
38870
+ if (ln(ch) === "run") for (const el of elements(ch)) scan(el, depth + 2);
38871
+ else if (ln(ch) === "deleteBegin" || ln(ch) === "deleteEnd") scan(ch, depth + 1);
38872
+ }
38873
+ }
38874
+ function nested(el, depth2) {
38875
+ if (depth2 > 64) return;
38876
+ for (const ch of elements(el)) {
38877
+ if (ln(ch) === "subList") prepareDeletedRanges(ch, depth2 + 1);
38878
+ else nested(ch, depth2 + 1);
38879
+ }
38880
+ }
38881
+ nested(root, depth);
38882
+ }
38740
38883
  function buildPara(p) {
38741
38884
  const chars = [];
38742
38885
  const objs = [];
38743
38886
  let segs = [];
38887
+ let deleted = deletedStarts.get(p) ?? 0;
38744
38888
  for (const runEl of elements(p)) {
38745
38889
  const tag = ln(runEl);
38746
38890
  if (tag === "run") {
@@ -38748,7 +38892,9 @@ function buildPara(p) {
38748
38892
  for (const ch of elements(runEl)) {
38749
38893
  const cn = ln(ch);
38750
38894
  if (cn === "t") {
38895
+ const start = chars.length;
38751
38896
  pushTextSlots(ch, chars, prId, 0);
38897
+ if (deleted) for (let i = start; i < chars.length; i++) chars[i] = { ch: "", prId };
38752
38898
  } else if (OBJ_TAGS.has(cn)) {
38753
38899
  const sz = findChildByLocalName(ch, "sz");
38754
38900
  const pos = findChildByLocalName(ch, "pos");
@@ -38756,7 +38902,7 @@ function buildPara(p) {
38756
38902
  const h = num2(sz, "height") || num2(findChildByLocalName(ch, "curSz"), "height") || num2(findChildByLocalName(ch, "orgSz"), "height");
38757
38903
  const inline = pos?.getAttribute("treatAsChar") === "1";
38758
38904
  const om = inline && cn === "tbl" ? findChildByLocalName(ch, "outMargin") : null;
38759
- objs.push({
38905
+ if (!deleted) objs.push({
38760
38906
  el: ch,
38761
38907
  tag: cn,
38762
38908
  index: chars.length,
@@ -38768,9 +38914,12 @@ function buildPara(p) {
38768
38914
  });
38769
38915
  pushFillers(chars, 8, prId);
38770
38916
  } else {
38917
+ if (cn === "ctrl" || cn === "deleteBegin" || cn === "deleteEnd") deleted = deletionDelta(ch, deleted);
38771
38918
  pushFillers(chars, 8, prId);
38772
38919
  }
38773
38920
  }
38921
+ } else if (tag === "deleteBegin" || tag === "deleteEnd") {
38922
+ deleted = deletionDelta(runEl, deleted);
38774
38923
  } else if (tag === "linesegarray") {
38775
38924
  segs = elements(runEl).filter((s) => ln(s) === "lineseg").map((s) => ({
38776
38925
  textpos: num2(s, "textpos"),
@@ -39107,18 +39256,179 @@ var RegionCollector = class {
39107
39256
  }
39108
39257
  };
39109
39258
 
39259
+ // src/render/page-stories.ts
39260
+ function pageStories(root, masters, paraPages, pageCount, pageBase, geom) {
39261
+ const secPr = findFirst(root, "secPr"), visibility = secPr && findChildByLocalName(secPr, "visibility");
39262
+ const pagePr = secPr && findChildByLocalName(secPr, "pagePr"), margin = pagePr && findChildByLocalName(pagePr, "margin");
39263
+ const declarations = [];
39264
+ const hidden = /* @__PURE__ */ new Map();
39265
+ for (const p of elements(root)) if (ln(p) === "p") {
39266
+ const page = paraPages.get(p)?.[0] ?? 0;
39267
+ for (const run of elements(p)) if (ln(run) === "run") {
39268
+ for (const ctrl of elements(run)) if (ln(ctrl) === "ctrl") {
39269
+ for (const el of elements(ctrl)) {
39270
+ if (isDeletedControl(el)) continue;
39271
+ const kind = ln(el);
39272
+ if (kind === "header" || kind === "footer") declarations.push({ el, page, kind });
39273
+ else if (kind === "pageHiding") {
39274
+ const kinds = hidden.get(page) ?? /* @__PURE__ */ new Set();
39275
+ for (const name of ["Header", "Footer", "MasterPage"]) if (num2(el, `hide${name}`)) kinds.add(name);
39276
+ hidden.set(page, kinds);
39277
+ }
39278
+ }
39279
+ }
39280
+ }
39281
+ }
39282
+ const parity = (type, n) => type === "BOTH" || type === "ODD" && n % 2 === 1 || type === "EVEN" && n % 2 === 0;
39283
+ const out = [];
39284
+ for (let page = 0; page < pageCount; page++) {
39285
+ const n = pageBase + page + 1;
39286
+ const hides = (name) => hidden.get(page)?.has(name) === true || page === 0 && num2(visibility, `hideFirst${name}`) !== 0;
39287
+ if (!hides("MasterPage")) {
39288
+ const matching = masters.filter((m) => m.getAttribute("type") === (n % 2 ? "ODD" : "EVEN"));
39289
+ const both = masters.filter((m) => (m.getAttribute("type") || "BOTH") === "BOTH");
39290
+ const normal = (matching.length ? matching : both).slice(-1);
39291
+ const specific = masters.filter((m) => m.getAttribute("type") === "LAST_PAGE" ? page === pageCount - 1 : m.getAttribute("type") === "OPTIONAL_PAGE" && num2(m, "pageNumber") === page + 1);
39292
+ const special = specific.slice(-1);
39293
+ const selected = special.length && !num2(special[0], "pageDuplicate") ? special : [...normal, ...special];
39294
+ for (const master of selected) {
39295
+ const sub = findChildByLocalName(master, "subList");
39296
+ if (sub) out.push({ sub, page, x: geom.ML, y: geom.MT, width: geom.BODY_W, layer: num2(master, "pageFront") ? 2 : -2 });
39297
+ }
39298
+ }
39299
+ for (const kind of ["header", "footer"]) {
39300
+ if (hides(kind === "header" ? "Header" : "Footer")) continue;
39301
+ const eligible = declarations.filter((d) => d.kind === kind && d.page <= page && parity(d.el.getAttribute("applyPageType") || "BOTH", n));
39302
+ const decl = eligible[eligible.length - 1];
39303
+ const sub = decl && findChildByLocalName(decl.el, "subList");
39304
+ if (sub) out.push({ sub, page, x: geom.ML, y: kind === "header" ? num2(margin, "top", 5668) : geom.PH - num2(margin, "bottom", 4252) - num2(margin, "footer"), width: geom.BODY_W });
39305
+ }
39306
+ }
39307
+ return out;
39308
+ }
39309
+
39310
+ // src/render/shape-geometry.ts
39311
+ var pt = (u) => String(Math.round(u) / 100);
39312
+ var esc = (s) => s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
39313
+ var SHAPE_TAGS = /* @__PURE__ */ new Set(["rect", "ellipse", "line", "polygon", "curv", "curve", "arc"]);
39314
+ function rotatedBounds(box, rotations) {
39315
+ if (!rotations.length) return box;
39316
+ let points = [[box.x, box.y], [box.x + box.w, box.y], [box.x + box.w, box.y + box.h], [box.x, box.y + box.h]];
39317
+ for (let i = rotations.length - 1; i >= 0; i--) {
39318
+ const { angle, cx, cy } = rotations[i];
39319
+ const a = angle * Math.PI / 180, c = Math.cos(a), s = Math.sin(a);
39320
+ points = points.map(([x2, y2]) => [cx + c * (x2 - cx) - s * (y2 - cy), cy + s * (x2 - cx) + c * (y2 - cy)]);
39321
+ }
39322
+ const x = Math.min(...points.map((p) => p[0])), y = Math.min(...points.map((p) => p[1]));
39323
+ return { x, y, w: Math.max(...points.map((p) => p[0])) - x, h: Math.max(...points.map((p) => p[1])) - y };
39324
+ }
39325
+ function objectGeometry(el, x, y, w, h) {
39326
+ const rot = findChildByLocalName(el, "rotationInfo");
39327
+ const angle = num2(rot, "angle") % 360;
39328
+ if (!angle) return { x, y, w, h, bbox: { x, y, w, h }, transform: "" };
39329
+ const org = findChildByLocalName(el, "orgSz");
39330
+ const cx = x + num2(rot, "centerX", num2(org, "width", w) / 2) * (w / (num2(org, "width") || w || 1));
39331
+ const cy = y + num2(rot, "centerY", num2(org, "height", h) / 2) * (h / (num2(org, "height") || h || 1));
39332
+ const rotation = { angle, cx: Math.round(cx), cy: Math.round(cy) };
39333
+ return { x, y, w, h, bbox: rotatedBounds({ x, y, w, h }, [rotation]), rotation, transform: `rotate(${angle} ${pt(cx)} ${pt(cy)})` };
39334
+ }
39335
+ function shapeFill(el, defs, images, warn) {
39336
+ const brush = findChildByLocalName(el, "fillBrush");
39337
+ const win = brush && findChildByLocalName(brush, "winBrush");
39338
+ const face = win?.getAttribute("faceColor");
39339
+ if (face && face.toLowerCase() !== "none") return esc(face);
39340
+ const grad = brush && findChildByLocalName(brush, "gradation");
39341
+ if (grad) {
39342
+ const colors = elements(grad).filter((c) => ln(c) === "color").map((c) => c.getAttribute("value") || "#000000");
39343
+ if (!colors.length) return "none";
39344
+ const type = grad.getAttribute("type") ?? "LINEAR";
39345
+ if (type !== "LINEAR" && type !== "RADIAL") {
39346
+ warn(`gradient:${type}`, `\uADF8\uB77C\uB370\uC774\uC158(${type}) \uBBF8\uC9C0\uC6D0 \u2014 \uCCAB \uC0C9\uC73C\uB85C \uCC44\uC6C0`);
39347
+ return esc(colors[0]);
39348
+ }
39349
+ const id = `paint${defs.length}`;
39350
+ const opacity = Math.max(0, Math.min(1, 1 - num2(grad, "alpha") / 255));
39351
+ const stops = colors.map((color, i) => `<stop offset="${colors.length === 1 ? 0 : i / (colors.length - 1)}" stop-color="${esc(color)}" stop-opacity="${opacity}"/>`).join("");
39352
+ if (type === "RADIAL") defs.push(`<radialGradient id="${id}" cx="${num2(grad, "centerX", 50)}%" cy="${num2(grad, "centerY", 50)}%">${stops}</radialGradient>`);
39353
+ else {
39354
+ const a = num2(grad, "angle") * Math.PI / 180, dx = Math.cos(a) / 2, dy = -Math.sin(a) / 2;
39355
+ defs.push(`<linearGradient id="${id}" x1="${0.5 - dx}" y1="${0.5 - dy}" x2="${0.5 + dx}" y2="${0.5 + dy}">${stops}</linearGradient>`);
39356
+ }
39357
+ return `url(#${id})`;
39358
+ }
39359
+ const imgBrush = brush && findChildByLocalName(brush, "imgBrush");
39360
+ const img = imgBrush && findChildByLocalName(imgBrush, "img");
39361
+ if (imgBrush && img) {
39362
+ const ref = img.getAttribute("binaryItemIDRef") ?? "";
39363
+ const loaded = images.get(ref);
39364
+ if (!loaded) {
39365
+ warn(`brush-image:${ref}`, `\uADF8\uB9BC \uCC44\uC6C0 \uC774\uBBF8\uC9C0(${ref}) \uC5C6\uC74C \u2014 \uCC44\uC6C0 \uC0DD\uB7B5`);
39366
+ return "none";
39367
+ }
39368
+ const mode = imgBrush.getAttribute("mode") ?? "TOTAL";
39369
+ if (mode !== "TOTAL") {
39370
+ warn(`brush-mode:${mode}`, `\uADF8\uB9BC \uCC44\uC6C0(${mode}) \uBBF8\uC9C0\uC6D0 \u2014 \uCC44\uC6C0 \uC0DD\uB7B5`);
39371
+ return "none";
39372
+ }
39373
+ if (loaded.paintId) return `url(#${loaded.paintId})`;
39374
+ const id = `paint${defs.length}`;
39375
+ defs.push(`<pattern id="${id}" width="1" height="1" patternContentUnits="objectBoundingBox"><image href="${esc(loaded.dataUri)}" width="1" height="1" preserveAspectRatio="none"/></pattern>`);
39376
+ loaded.paintId = id;
39377
+ return `url(#${id})`;
39378
+ }
39379
+ return "none";
39380
+ }
39381
+ function shapeGeometry(o, x, y, defs, images, warn) {
39382
+ const el = o.el, org = findChildByLocalName(el, "orgSz"), cur = findChildByLocalName(el, "curSz");
39383
+ const ow = num2(org, "width"), oh = num2(org, "height");
39384
+ const w = num2(cur, "width") || ow || o.width, h = num2(cur, "height") || oh || o.height;
39385
+ const sx = ow > 0 ? w / ow : 1, sy = oh > 0 ? h / oh : 1;
39386
+ const line = findChildByLocalName(el, "lineShape"), style = line?.getAttribute("style") ?? "SOLID";
39387
+ const color = esc(line?.getAttribute("color") || "#000000");
39388
+ const strokeW = style === "NONE" ? 0 : Math.max(0.2, num2(line, "width", 33) / 100 * 2.834645);
39389
+ const dash = /DASH|DOT/.test(style) ? ` stroke-dasharray="${style.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
39390
+ const stroke = strokeW ? ` stroke="${color}" stroke-width="${strokeW.toFixed(2)}"${dash}` : "";
39391
+ const fill = ` fill="${shapeFill(el, defs, images, warn)}"`;
39392
+ let svg = "";
39393
+ if (o.tag === "rect") svg = `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}"${fill}${stroke}/>`;
39394
+ else if (o.tag === "ellipse") svg = `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}"${fill}${stroke}/>`;
39395
+ else if (o.tag === "line") {
39396
+ const s = findChildByLocalName(el, "startPt"), e = findChildByLocalName(el, "endPt");
39397
+ svg = `<line x1="${pt(x + num2(s, "x") * sx)}" y1="${pt(y + num2(s, "y") * sy)}" x2="${pt(x + num2(e, "x") * sx)}" y2="${pt(y + num2(e, "y") * sy)}" stroke="${color}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}/>`;
39398
+ } else if (o.tag === "polygon" || o.tag === "curv") {
39399
+ const pts = elements(el).filter((c) => ln(c) === "pt").map((c) => `${pt(x + num2(c, "x") * sx)},${pt(y + num2(c, "y") * sy)}`);
39400
+ if (pts.length >= 2) svg = `<polygon points="${pts.join(" ")}"${fill}${stroke}/>`;
39401
+ } else if (o.tag === "curve") {
39402
+ const segs = elements(el).filter((c) => ln(c) === "seg");
39403
+ if (segs.some((s) => s.getAttribute("type") !== "LINE")) warn("curve:bezier", "\uBE44\uC120\uD615 \uACE1\uC120 \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5");
39404
+ else if (segs.length) {
39405
+ let path = "", lastX, lastY;
39406
+ for (const s of segs) {
39407
+ const x1 = num2(s, "x1"), y1 = num2(s, "y1"), x2 = num2(s, "x2"), y2 = num2(s, "y2");
39408
+ if (x1 !== lastX || y1 !== lastY) path += `M${pt(x + x1 * sx)} ${pt(y + y1 * sy)}`;
39409
+ path += `L${pt(x + x2 * sx)} ${pt(y + y2 * sy)}`;
39410
+ lastX = x2;
39411
+ lastY = y2;
39412
+ }
39413
+ svg = `<path d="${path}"${fill}${stroke}/>`;
39414
+ }
39415
+ } else if (o.tag === "arc") svg = `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}" fill="none"${stroke || ` stroke="${color}" stroke-width="0.3"`}/>`;
39416
+ return { ...objectGeometry(el, x, y, w, h), svg };
39417
+ }
39418
+
39110
39419
  // src/render/svg-render.ts
39111
39420
  function escapeXml7(s) {
39112
39421
  return s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
39113
39422
  }
39114
- var pt = (u) => String(Math.round(u) / 100);
39423
+ var pt2 = (u) => String(Math.round(u) / 100);
39115
39424
  var ptNum = (u) => Math.round(u) / 100;
39116
39425
  function pageNo(ctx) {
39117
39426
  return ctx.pageBase + ctx.page + 1;
39118
39427
  }
39119
39428
  function bboxOf(ctx, x, y, w, h) {
39120
- const clippedH = Math.max(0, Math.min(h, ctx.pageH - y));
39121
- return { page: pageNo(ctx), x: ptNum(x), y: ptNum(y), width: ptNum(Math.max(0, w)), height: ptNum(clippedH) };
39429
+ const b = rotatedBounds({ x, y, w, h }, ctx.regionRotations);
39430
+ const clippedH = Math.max(0, Math.min(b.h, ctx.pageH - b.y));
39431
+ return { page: pageNo(ctx), x: ptNum(b.x), y: ptNum(b.y), width: ptNum(Math.max(0, b.w)), height: ptNum(clippedH) };
39122
39432
  }
39123
39433
  function regionOpenTag(id, type, page) {
39124
39434
  return `<g data-kordoc-id="${id}" data-kordoc-type="${type}" data-kordoc-page="${page}">`;
@@ -39211,7 +39521,10 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
39211
39521
  if (m.chars.some((c) => c.ch !== "")) {
39212
39522
  warnOnce(ctx, "no-lineseg", "\uC870\uD310 \uCE90\uC2DC \uC5C6\uB294 \uBB38\uB2E8 \uD14D\uC2A4\uD2B8 \uC0DD\uB7B5 \u2014 reflow \uC635\uC158\uC73C\uB85C \uD569\uC131 \uAC00\uB2A5");
39213
39523
  }
39214
- for (const o of m.objs) drawObject(o, ox, oy, 0, areaW, ctx, depth);
39524
+ for (const o of m.objs) {
39525
+ const { x, y } = o.inline ? { x: ox, y: oy } : anchorObject(o, ox, oy, 0, areaW, ctx);
39526
+ drawObject(o, x, y, 0, areaW, ctx, depth);
39527
+ }
39215
39528
  return;
39216
39529
  }
39217
39530
  const plans = planLines(m, ctx.styles);
@@ -39270,13 +39583,13 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
39270
39583
  const renderSeg = (text, cx, hit) => {
39271
39584
  const sw = measureTextWidth(text, st.height, st.ratio, { spacingPct: st.spacing, faceClass: faceClassOf(st.face) }) * scale2;
39272
39585
  if (hit) {
39273
- emit(ctx, `<rect x="${pt(cx)}" y="${pt(oy + seg.vertpos)}" width="${pt(sw)}" height="${pt(seg.textheight)}" fill="#ffd54f" fill-opacity="0.45"/>`);
39586
+ emit(ctx, `<rect x="${pt2(cx)}" y="${pt2(oy + seg.vertpos)}" width="${pt2(sw)}" height="${pt2(seg.textheight)}" fill="#ffd54f" fill-opacity="0.45"/>`);
39274
39587
  }
39275
39588
  if (text.trim().length > 0) {
39276
- const attrs = [`x="${pt(cx)}"`, `y="${pt(y)}"`, `font-size="${pt(st.height)}"`];
39589
+ const attrs = [`x="${pt2(cx)}"`, `y="${pt2(y)}"`, `font-size="${pt2(st.height)}"`];
39277
39590
  if (st.fontFamily) attrs.push(`font-family="${escapeXml7(st.fontFamily)}"`);
39278
39591
  if ([...text].length > 1 && sw > 50) {
39279
- attrs.push(`textLength="${pt(sw)}"`, `lengthAdjust="${scale2 < 1 ? "spacingAndGlyphs" : "spacing"}"`);
39592
+ attrs.push(`textLength="${pt2(sw)}"`, `lengthAdjust="${scale2 < 1 ? "spacingAndGlyphs" : "spacing"}"`);
39280
39593
  }
39281
39594
  if (st.bold) attrs.push(`font-weight="bold"`);
39282
39595
  if (st.italic) attrs.push(`font-style="italic"`);
@@ -39378,6 +39691,19 @@ function anchorObject(o, ox, oy, baseV, areaW, ctx) {
39378
39691
  return { x, y };
39379
39692
  }
39380
39693
  function drawObject(o, x, y, baseV, areaW, ctx, depth) {
39694
+ if (!o.inline && depth === 0 && ctx.paintJobs) {
39695
+ const wrap = o.el.getAttribute("textWrap");
39696
+ const layer = wrap === "BEHIND_TEXT" ? -1 : wrap === "IN_FRONT_OF_TEXT" ? 1 : 0;
39697
+ const page = ctx.page, parents = [...ctx.parentStack];
39698
+ ctx.paintJobs.push({ page, layer, z: num2(o.el, "zOrder"), draw: () => {
39699
+ ctx.page = page;
39700
+ const saved = ctx.parentStack;
39701
+ ctx.parentStack = parents;
39702
+ drawObject(o, x, y, baseV, areaW, ctx, depth);
39703
+ ctx.parentStack = saved;
39704
+ } });
39705
+ return;
39706
+ }
39381
39707
  if (o.tag === "tbl") drawTable(o.el, x, y, ctx, depth + 1);
39382
39708
  else if (o.tag === "pic") drawPic(o.el, x, y, ctx);
39383
39709
  else if (o.tag === "container") {
@@ -39397,62 +39723,29 @@ function drawObject(o, x, y, baseV, areaW, ctx, depth) {
39397
39723
  warnOnce(ctx, `shape:${o.tag}`, `\uAC1C\uCCB4(${o.tag}) \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5`);
39398
39724
  }
39399
39725
  }
39400
- var SHAPE_TAGS = /* @__PURE__ */ new Set(["rect", "ellipse", "line", "polygon", "curv", "arc"]);
39401
- function shapeStrokePt(v) {
39402
- return Math.max(0.2, v / 100 * 2.834645);
39403
- }
39404
39726
  function drawShape(o, x, y, ctx, depth) {
39405
- const el = o.el;
39406
- const orgSz = findChildByLocalName(el, "orgSz");
39407
- const curSz = findChildByLocalName(el, "curSz");
39408
- const ow = num2(orgSz, "width"), oh = num2(orgSz, "height");
39409
- const w = num2(curSz, "width") || ow || o.width;
39410
- const h = num2(curSz, "height") || oh || o.height;
39411
- const sx = ow > 0 ? w / ow : 1;
39412
- const sy = oh > 0 ? h / oh : 1;
39413
- const lineShape = findChildByLocalName(el, "lineShape");
39414
- const lstyle = lineShape?.getAttribute("style") ?? "SOLID";
39415
- const strokeCol = lineShape?.getAttribute("color") || "#000000";
39416
- const hasStroke = lstyle !== "NONE";
39417
- const strokeW = hasStroke ? shapeStrokePt(lineShape ? num2(lineShape, "width") : 33) : 0;
39418
- const dash = /DASH|DOT/.test(lstyle) ? ` stroke-dasharray="${lstyle.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
39419
- const strokeAttr = hasStroke ? ` stroke="${escapeXml7(strokeCol)}" stroke-width="${strokeW.toFixed(2)}"${dash}` : "";
39420
- const fillBrush = findChildByLocalName(el, "fillBrush");
39421
- const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
39422
- const face = winBrush?.getAttribute("faceColor");
39423
- const fill = face && face.toLowerCase() !== "none" ? face : "none";
39424
- const fillAttr = ` fill="${fill === "none" ? "none" : escapeXml7(fill)}"`;
39727
+ const geometry = shapeGeometry(o, x, y, ctx.defs, ctx.images, (key, msg2) => warnOnce(ctx, key, msg2));
39728
+ const b = geometry;
39729
+ if (geometry.rotation) ctx.regionRotations.push(geometry.rotation);
39425
39730
  ctx.stats.shapes++;
39426
- const shapeId = ctx.regions.add("shape", bboxOf(ctx, x, y, w, h), { parentId: parentId(ctx) });
39731
+ const shapeId = ctx.regions.add("shape", bboxOf(ctx, b.x, b.y, b.w, b.h), { parentId: parentId(ctx) });
39427
39732
  emit(ctx, regionOpenTag(shapeId, "shape", pageNo(ctx)));
39428
39733
  ctx.parentStack.push(shapeId);
39429
- if (o.tag === "rect") {
39430
- emit(ctx, `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}"${fillAttr}${strokeAttr}/>`);
39431
- } else if (o.tag === "ellipse") {
39432
- emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}"${fillAttr}${strokeAttr}/>`);
39433
- } else if (o.tag === "line") {
39434
- const s = findChildByLocalName(el, "startPt"), e = findChildByLocalName(el, "endPt");
39435
- const x1 = x + num2(s, "x") * sx, y1 = y + num2(s, "y") * sy;
39436
- const x2 = x + num2(e, "x") * sx, y2 = y + num2(e, "y") * sy;
39437
- emit(ctx, `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml7(strokeCol)}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}/>`);
39438
- } else if (o.tag === "polygon" || o.tag === "curv") {
39439
- const pts = [];
39440
- for (const c of elements(el)) if (ln(c) === "pt") pts.push(`${pt(x + num2(c, "x") * sx)},${pt(y + num2(c, "y") * sy)}`);
39441
- if (pts.length >= 2) emit(ctx, `<polygon points="${pts.join(" ")}"${fillAttr}${strokeAttr}/>`);
39442
- } else if (o.tag === "arc") {
39443
- emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}" fill="none"${strokeAttr || ` stroke="${escapeXml7(strokeCol)}" stroke-width="0.3"`}/>`);
39444
- }
39445
- const dt = findChildByLocalName(el, "drawText");
39734
+ if (geometry.transform) emit(ctx, `<g transform="${geometry.transform}">`);
39735
+ emit(ctx, geometry.svg);
39736
+ const dt = findChildByLocalName(o.el, "drawText");
39446
39737
  const sub = dt ? findChildByLocalName(dt, "subList") : null;
39447
39738
  if (sub) {
39448
- for (const p of elements(sub)) if (ln(p) === "p") drawPara(p, x, y, w, ctx, depth + 1);
39739
+ for (const p of elements(sub)) if (ln(p) === "p") drawPara(p, x, y, geometry.w, ctx, depth + 1);
39449
39740
  }
39741
+ if (geometry.rotation) ctx.regionRotations.pop();
39742
+ if (geometry.transform) emit(ctx, "</g>");
39450
39743
  ctx.parentStack.pop();
39451
39744
  emit(ctx, "</g>");
39452
39745
  }
39453
39746
  function edgeLine(x1, y1, x2, y2, e) {
39454
39747
  const dash = /DASH|DOT/.test(e.type) ? ` stroke-dasharray="${e.type.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
39455
- return `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml7(e.color)}" stroke-width="${e.widthPt.toFixed(2)}"${dash}/>`;
39748
+ return `<line x1="${pt2(x1)}" y1="${pt2(y1)}" x2="${pt2(x2)}" y2="${pt2(y2)}" stroke="${escapeXml7(e.color)}" stroke-width="${e.widthPt.toFixed(2)}"${dash}/>`;
39456
39749
  }
39457
39750
  function drawTable(tbl2, tx, ty, ctx, depth) {
39458
39751
  if (depth > 16) {
@@ -39487,7 +39780,7 @@ function drawTable(tbl2, tx, ty, ctx, depth) {
39487
39780
  }));
39488
39781
  for (const g3 of geom) {
39489
39782
  const bf = g3.c.bfId != null ? ctx.styles.borderFill.get(g3.c.bfId) : void 0;
39490
- if (bf?.fill) emit(ctx, `<rect x="${pt(g3.x)}" y="${pt(g3.y)}" width="${pt(g3.w)}" height="${pt(g3.h)}" fill="${escapeXml7(bf.fill)}"/>`);
39783
+ if (bf?.fill) emit(ctx, `<rect x="${pt2(g3.x)}" y="${pt2(g3.y)}" width="${pt2(g3.w)}" height="${pt2(g3.h)}" fill="${escapeXml7(bf.fill)}"/>`);
39491
39784
  }
39492
39785
  for (const g3 of geom) {
39493
39786
  const { c } = g3;
@@ -39532,7 +39825,7 @@ function drawPic(pic, x, y, ctx) {
39532
39825
  const imgId = ctx.regions.add("image", bboxOf(ctx, x, y, w, h), { sourceId: ref ?? void 0, parentId: parentId(ctx) });
39533
39826
  emit(ctx, regionOpenTag(imgId, "image", pageNo(ctx)));
39534
39827
  if (!loaded) {
39535
- emit(ctx, `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" fill="#eee" stroke="#c00" stroke-width="0.5"/>`);
39828
+ emit(ctx, `<rect x="${pt2(x)}" y="${pt2(y)}" width="${pt2(w)}" height="${pt2(h)}" fill="#eee" stroke="#c00" stroke-width="0.5"/>`);
39536
39829
  warnOnce(ctx, `img:${ref}`, `\uC774\uBBF8\uC9C0 \uBC14\uC774\uB108\uB9AC \uB204\uB77D: ${ref ?? "(ref \uC5C6\uC74C)"}`);
39537
39830
  emit(ctx, "</g>");
39538
39831
  return;
@@ -39551,10 +39844,10 @@ function drawPic(pic, x, y, ctx) {
39551
39844
  if (cropped) {
39552
39845
  emit(
39553
39846
  ctx,
39554
- `<svg x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" viewBox="${pt(cl)} ${pt(ct)} ${pt(cr - cl)} ${pt(cb - ct)}" preserveAspectRatio="none"><use href="#${symId}" x="0" y="0" width="${pt(refW)}" height="${pt(refH)}"/></svg>`
39847
+ `<svg x="${pt2(x)}" y="${pt2(y)}" width="${pt2(w)}" height="${pt2(h)}" viewBox="${pt2(cl)} ${pt2(ct)} ${pt2(cr - cl)} ${pt2(cb - ct)}" preserveAspectRatio="none"><use href="#${symId}" x="0" y="0" width="${pt2(refW)}" height="${pt2(refH)}"/></svg>`
39555
39848
  );
39556
39849
  } else {
39557
- emit(ctx, `<use href="#${symId}" x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}"/>`);
39850
+ emit(ctx, `<use href="#${symId}" x="${pt2(x)}" y="${pt2(y)}" width="${pt2(w)}" height="${pt2(h)}"/>`);
39558
39851
  }
39559
39852
  emit(ctx, "</g>");
39560
39853
  }
@@ -39582,8 +39875,9 @@ function readSectionGeom(root) {
39582
39875
  const BODY_W = PW - ML - num2(margin, "right", 8504);
39583
39876
  return { PW, PH, ML, MT, BODY_W, BODY_H };
39584
39877
  }
39585
- function renderSectionToPages(root, geom, ctxBase, doReflow, reflowMode) {
39878
+ function renderSectionToPages(root, geom, ctxBase, doReflow, reflowMode, masters = [], hasDeletionMarkers = true) {
39586
39879
  const { PW, PH, ML, MT, BODY_W, BODY_H } = geom;
39880
+ if (hasDeletionMarkers) prepareDeletedRanges(root);
39587
39881
  if (doReflow) reflowSection(root, ctxBase.styles, { BODY_W, BODY_H }, reflowMode);
39588
39882
  const colPr = findFirst(root, "colPr");
39589
39883
  const multiCol = num2(colPr, "colCount", 1) > 1;
@@ -39621,12 +39915,35 @@ function renderSectionToPages(root, geom, ctxBase, doReflow, reflowMode) {
39621
39915
  pages: Array.from({ length: nPages }, () => []),
39622
39916
  page: 0,
39623
39917
  geom,
39624
- pageH
39918
+ pageH,
39919
+ paintJobs: [],
39920
+ regionRotations: []
39625
39921
  };
39922
+ for (const story of pageStories(root, masters, paraSegPages, nPages, ctx.pageBase, geom)) {
39923
+ prepareDeletedRanges(story.sub);
39924
+ if (doReflow) reflowSection(story.sub, ctx.styles, { BODY_W: story.width, BODY_H: 0 }, reflowMode);
39925
+ const draw = () => {
39926
+ ctx.page = story.page;
39927
+ for (const p of elements(story.sub)) if (ln(p) === "p") drawPara(p, story.x, story.y, story.width, ctx, 0);
39928
+ };
39929
+ if (story.layer !== void 0) ctx.paintJobs.push({ page: story.page, layer: story.layer, z: 0, draw });
39930
+ else draw();
39931
+ }
39932
+ ctx.page = 0;
39626
39933
  for (const p of elements(root)) {
39627
39934
  if (ln(p) !== "p") continue;
39628
39935
  drawPara(p, ML, MT, BODY_W, ctx, 0, paraSegPages.get(p));
39629
39936
  }
39937
+ const normal = ctx.pages;
39938
+ const jobs = ctx.paintJobs;
39939
+ ctx.paintJobs = null;
39940
+ const behind = Array.from({ length: nPages }, () => []);
39941
+ const front = Array.from({ length: nPages }, () => []);
39942
+ for (const job of jobs.sort((a, b) => a.layer - b.layer || a.z - b.z)) {
39943
+ ctx.pages = job.layer < 0 ? behind : front;
39944
+ job.draw();
39945
+ }
39946
+ ctx.pages = normal.map((buf, page) => [...behind[page], ...buf, ...front[page]]);
39630
39947
  return { pages: ctx.pages, pageH };
39631
39948
  }
39632
39949
  function renderSectionRoots(sections, input) {
@@ -39644,9 +39961,9 @@ function renderSectionRoots(sections, input) {
39644
39961
  pageBase: 0
39645
39962
  };
39646
39963
  const rendered = [];
39647
- for (const { root, index } of sections) {
39964
+ for (const { root, index, masterPages, hasDeletionMarkers } of sections) {
39648
39965
  const geom = readSectionGeom(root);
39649
- const { pages, pageH } = renderSectionToPages(root, geom, ctxBase, input.reflow, input.reflowMode);
39966
+ const { pages, pageH } = renderSectionToPages(root, geom, ctxBase, input.reflow, input.reflowMode, masterPages, hasDeletionMarkers);
39650
39967
  rendered.push({ pages, PW: geom.PW, pageH, clipId: `pgclip${index}` });
39651
39968
  ctxBase.pageBase += pages.length;
39652
39969
  }
@@ -39676,6 +39993,17 @@ async function renderHwpxInternal(input, options) {
39676
39993
  if (xml.length > MAX_DECOMPRESS_SIZE) throw new KordocError("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
39677
39994
  secXmls.push(xml);
39678
39995
  }
39996
+ const masterPages = /* @__PURE__ */ new Map();
39997
+ const masterXmls = [];
39998
+ for (const file of zip.file(/Contents\/masterpage[^/]*\.xml$/i)) {
39999
+ const xml = await file.async("string");
40000
+ if (xml.length > MAX_DECOMPRESS_SIZE) throw new KordocError("\uBC14\uD0D5\uCABD XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
40001
+ const root = createXmlParser().parseFromString(xml, "text/xml").documentElement;
40002
+ if (root && ln(root) === "masterPage") {
40003
+ masterPages.set(root.getAttribute("id") || file.name.replace(/^.*\/|\.xml$/g, ""), root);
40004
+ masterXmls.push(xml);
40005
+ }
40006
+ }
39679
40007
  const binmap = /* @__PURE__ */ new Map();
39680
40008
  const hpf = zip.file(/content\.hpf$/i)[0];
39681
40009
  if (hpf) {
@@ -39687,7 +40015,7 @@ async function renderHwpxInternal(input, options) {
39687
40015
  const MAX_TOTAL_IMAGE_BYTES = 128 * 1024 * 1024;
39688
40016
  const images = /* @__PURE__ */ new Map();
39689
40017
  const refs = /* @__PURE__ */ new Set();
39690
- for (const xml of secXmls) for (const m of xml.matchAll(/binaryItemIDRef="([^"]+)"/g)) refs.add(m[1]);
40018
+ for (const xml of [...secXmls, ...masterXmls]) for (const m of xml.matchAll(/binaryItemIDRef="([^"]+)"/g)) refs.add(m[1]);
39691
40019
  let totalImgBytes = 0;
39692
40020
  for (const ref of refs) {
39693
40021
  if (images.size >= MAX_IMAGE_REFS) {
@@ -39730,7 +40058,9 @@ async function renderHwpxInternal(input, options) {
39730
40058
  warnings.push(`\uAD6C\uC5ED ${si} XML \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uC0DD\uB7B5`);
39731
40059
  continue;
39732
40060
  }
39733
- roots.push({ root, index: si });
40061
+ const secPr = findFirst(root, "secPr");
40062
+ const referenced = secPr ? elements(secPr).filter((el) => ln(el) === "masterPage").map((el) => masterPages.get(el.getAttribute("idRef") || "")).filter((el) => !!el) : [];
40063
+ roots.push({ root, index: si, masterPages: referenced, hasDeletionMarkers: secXml.includes("deleteBegin") || secXml.includes("deleteEnd") });
39734
40064
  }
39735
40065
  if (roots.length === 0) {
39736
40066
  if (noCacheSkipped) {
@@ -39750,11 +40080,11 @@ async function renderHwpxToSvg(input, options) {
39750
40080
  let pageNo2 = 0;
39751
40081
  for (const rs of r.sections) {
39752
40082
  maxPW = Math.max(maxPW, rs.PW);
39753
- clipDefs.push(`<clipPath id="${rs.clipId}"><rect x="0" y="0" width="${pt(rs.PW)}" height="${pt(rs.pageH)}"/></clipPath>`);
40083
+ clipDefs.push(`<clipPath id="${rs.clipId}"><rect x="0" y="0" width="${pt2(rs.PW)}" height="${pt2(rs.pageH)}"/></clipPath>`);
39754
40084
  for (const buf of rs.pages) {
39755
40085
  pageNo2++;
39756
40086
  groups.push(
39757
- `<g data-page="${pageNo2}" transform="translate(0 ${pt(y)})"><rect width="${pt(rs.PW)}" height="${pt(rs.pageH)}" fill="white" stroke="#c9c7c4" stroke-width="0.75"/><g clip-path="url(#${rs.clipId})">
40087
+ `<g data-page="${pageNo2}" transform="translate(0 ${pt2(y)})"><rect width="${pt2(rs.PW)}" height="${pt2(rs.pageH)}" fill="white" stroke="#c9c7c4" stroke-width="0.75"/><g clip-path="url(#${rs.clipId})">
39758
40088
  ${buf.join("\n")}
39759
40089
  </g></g>`
39760
40090
  );
@@ -39762,7 +40092,7 @@ ${buf.join("\n")}
39762
40092
  }
39763
40093
  }
39764
40094
  const totalH = Math.max(0, y - GAP);
39765
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt(maxPW)} ${pt(totalH)}" width="${pt(maxPW)}pt" height="${pt(totalH)}pt" font-family="${SVG_FONT_FAMILY}" xml:space="preserve">
40095
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt2(maxPW)} ${pt2(totalH)}" width="${pt2(maxPW)}pt" height="${pt2(totalH)}pt" font-family="${SVG_FONT_FAMILY}" xml:space="preserve">
39766
40096
  <defs>${clipDefs.join("")}${r.defs.join("")}</defs>
39767
40097
  ${groups.join("\n")}
39768
40098
  </svg>`;
@@ -39789,9 +40119,9 @@ function assemblePageSvgs(r, format2, select) {
39789
40119
  const clipId = `pgclip${pageNo2}`;
39790
40120
  pageSvgs.set(
39791
40121
  pageNo2,
39792
- `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt(rs.PW)} ${pt(rs.pageH)}" width="${pt(rs.PW)}pt" height="${pt(rs.pageH)}pt" font-family="${SVG_FONT_FAMILY}" xml:space="preserve" data-page="${pageNo2}">
39793
- <defs><clipPath id="${clipId}"><rect x="0" y="0" width="${pt(rs.PW)}" height="${pt(rs.pageH)}"/></clipPath>${defs.join("")}</defs>
39794
- <rect width="${pt(rs.PW)}" height="${pt(rs.pageH)}" fill="white"/>
40122
+ `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt2(rs.PW)} ${pt2(rs.pageH)}" width="${pt2(rs.PW)}pt" height="${pt2(rs.pageH)}pt" font-family="${SVG_FONT_FAMILY}" xml:space="preserve" data-page="${pageNo2}">
40123
+ <defs><clipPath id="${clipId}"><rect x="0" y="0" width="${pt2(rs.PW)}" height="${pt2(rs.pageH)}"/></clipPath>${defs.join("")}</defs>
40124
+ <rect width="${pt2(rs.PW)}" height="${pt2(rs.pageH)}" fill="white"/>
39795
40125
  <g clip-path="url(#${clipId})">
39796
40126
  ${body}
39797
40127
  </g>
@@ -40729,7 +41059,7 @@ function scriptsOff(r, off) {
40729
41059
  }
40730
41060
  async function parseImage(buffer, options) {
40731
41061
  try {
40732
- const { parseImageDocument } = await import("./image-ocr-EREKAS47.js");
41062
+ const { parseImageDocument } = await import("./image-ocr-HYWDBN72.js");
40733
41063
  const { blocks, warnings } = await parseImageDocument(buffer, options);
40734
41064
  stripScriptTags({ blocks });
40735
41065
  return {
@@ -40789,7 +41119,7 @@ async function parseHwp(buffer, options) {
40789
41119
  async function parsePdf(buffer, options) {
40790
41120
  let parsePdfDocument;
40791
41121
  try {
40792
- const mod = await import("./parser-VH3F4EQU.js");
41122
+ const mod = await import("./parser-T4FBG2FR.js");
40793
41123
  parsePdfDocument = mod.parsePdfDocument;
40794
41124
  } catch {
40795
41125
  return {