kordoc 4.24.3 → 4.24.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 (125) hide show
  1. package/README.md +5 -5
  2. package/dist/{-Q56U3KCA.js → -WND2HWVH.js} +11 -11
  3. package/dist/{chunk-3EWXRIPH.js → chunk-3LSHLWTX.js} +3 -3
  4. package/dist/{chunk-HNX2I7D6.js → chunk-44E52JJ7.js} +2 -2
  5. package/dist/{chunk-XNNMMYFO.js → chunk-47MTLP4U.js} +2 -2
  6. package/dist/{chunk-42FSKT7R.js → chunk-4XVL3OBP.js} +2 -2
  7. package/dist/{chunk-OAOM7IEI.js → chunk-5AHG3XY3.js} +11 -11
  8. package/dist/{chunk-6ZRZLV3J.cjs → chunk-6A4KYMQR.cjs} +2 -2
  9. package/dist/{chunk-6ZRZLV3J.cjs.map → chunk-6A4KYMQR.cjs.map} +1 -1
  10. package/dist/{chunk-EWCJCWTT.js → chunk-6CPBNK5O.js} +2 -2
  11. package/dist/{chunk-FZT34MUI.js → chunk-A5JDO52L.js} +4 -4
  12. package/dist/{chunk-4X73CGIL.js → chunk-AKIJTKEA.js} +2 -2
  13. package/dist/{chunk-YG4YOPK6.cjs → chunk-BODFTRWA.cjs} +3 -3
  14. package/dist/{chunk-YG4YOPK6.cjs.map → chunk-BODFTRWA.cjs.map} +1 -1
  15. package/dist/{chunk-XAZ5RGVG.js → chunk-BYYZUFPC.js} +11 -8
  16. package/dist/chunk-BYYZUFPC.js.map +1 -0
  17. package/dist/{chunk-Q2QKRE4P.js → chunk-D4YWVZHD.js} +2 -2
  18. package/dist/{chunk-33NZN73M.js → chunk-DTADAHJD.js} +2 -2
  19. package/dist/{chunk-XZOAE2Q7.js → chunk-E7N6BUJT.js} +12 -9
  20. package/dist/chunk-E7N6BUJT.js.map +1 -0
  21. package/dist/{chunk-I2QETSZN.js → chunk-FK3JPTHI.js} +2 -2
  22. package/dist/{chunk-AEEQN6L3.js → chunk-GGVHKYKZ.js} +2 -2
  23. package/dist/{chunk-PMX5CPK5.js → chunk-JHUW5PKO.js} +8 -7
  24. package/dist/chunk-JHUW5PKO.js.map +1 -0
  25. package/dist/{chunk-VFEI2GIE.cjs → chunk-KFQNG2EA.cjs} +3 -3
  26. package/dist/{chunk-VFEI2GIE.cjs.map → chunk-KFQNG2EA.cjs.map} +1 -1
  27. package/dist/{chunk-PHZDAHZC.js → chunk-LBOXKGAH.js} +3 -3
  28. package/dist/{chunk-JILIA5EV.cjs → chunk-LJ7U7MFN.cjs} +31 -28
  29. package/dist/chunk-LJ7U7MFN.cjs.map +1 -0
  30. package/dist/{chunk-W6O7KBOD.js → chunk-MC4DPT4I.js} +2 -2
  31. package/dist/{chunk-KXHNIHLC.js → chunk-MMPBJGWQ.js} +2 -2
  32. package/dist/{chunk-NKDPCALC.js → chunk-QTJTBCTZ.js} +4 -4
  33. package/dist/{chunk-N65EY5BI.cjs → chunk-TPKP3WQU.cjs} +6 -6
  34. package/dist/{chunk-N65EY5BI.cjs.map → chunk-TPKP3WQU.cjs.map} +1 -1
  35. package/dist/{chunk-EEXIFCXC.js → chunk-VBY3JQL2.js} +2 -2
  36. package/dist/{chunk-TZ753B6A.js → chunk-WMDGGQXJ.js} +2 -2
  37. package/dist/{chunk-HTG3VVET.cjs → chunk-WN5X4DT3.cjs} +24 -24
  38. package/dist/{chunk-HTG3VVET.cjs.map → chunk-WN5X4DT3.cjs.map} +1 -1
  39. package/dist/{chunk-HU7POUBS.js → chunk-YBCW544D.js} +2 -2
  40. package/dist/{chunk-J45OVEUM.js → chunk-YEYNBH5W.js} +112 -23
  41. package/dist/chunk-YEYNBH5W.js.map +1 -0
  42. package/dist/chunks-2UDUNVGQ.js +10 -0
  43. package/dist/cli.js +30 -30
  44. package/dist/{formula-2BPHF6O7.cjs → formula-6DJAY3KI.cjs} +9 -9
  45. package/dist/{formula-2BPHF6O7.cjs.map → formula-6DJAY3KI.cjs.map} +1 -1
  46. package/dist/{formula-IREEAC4T.js → formula-MPBZ7OMN.js} +3 -3
  47. package/dist/{formula-EA5GDCUD.js → formula-NA3LD35B.js} +4 -4
  48. package/dist/{image-ocr-LGOFUS3O.js → image-ocr-6TGDXUAS.js} +9 -9
  49. package/dist/{image-ocr-CCTE7HX3.cjs → image-ocr-REM4LZKX.cjs} +17 -17
  50. package/dist/{image-ocr-CCTE7HX3.cjs.map → image-ocr-REM4LZKX.cjs.map} +1 -1
  51. package/dist/{image-ocr-JQJC5HWK.js → image-ocr-THA5BASF.js} +6 -6
  52. package/dist/index.cjs +740 -650
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.js +118 -28
  55. package/dist/index.js.map +1 -1
  56. package/dist/mcp.js +23 -23
  57. package/dist/{model-bundle-YW62Y6UD.js → model-bundle-3YDTJ6EQ.js} +5 -5
  58. package/dist/{models-AAL3IS2R.js → models-M7AX7VIN.js} +5 -5
  59. package/dist/{parse-worker-v2-3JAHV7NY.js → parse-worker-v2-3ZMFWDFW.js} +12 -12
  60. package/dist/{parser-HE45CCSG.cjs → parser-GIDYL5LH.cjs} +158 -158
  61. package/dist/{parser-HE45CCSG.cjs.map → parser-GIDYL5LH.cjs.map} +1 -1
  62. package/dist/{parser-ZBP5GOQK.js → parser-MNNJSFEZ.js} +9 -9
  63. package/dist/{parser-4FCKKJ2N.js → parser-TD4VZDGY.js} +12 -12
  64. package/dist/{pdf-ocr-HFAEOA7W.js → pdf-ocr-5HEVZKG5.js} +6 -6
  65. package/dist/{pdf-ocr-Q4TPGDDI.js → pdf-ocr-6BAOQ6CY.js} +9 -9
  66. package/dist/pdf-ocr-NOSNTEDS.cjs +31 -0
  67. package/dist/{pdf-ocr-7MDCLWAA.cjs.map → pdf-ocr-NOSNTEDS.cjs.map} +1 -1
  68. package/dist/{profile-io-EDQTKLLL.js → profile-io-H4WQIGN6.js} +3 -3
  69. package/dist/{rasterize-VD2XGHUJ.js → rasterize-EOPWJWBO.js} +3 -3
  70. package/dist/{redact-doc-TBIBQJCT.js → redact-doc-BBZVAA3I.js} +11 -11
  71. package/dist/{render-J5KAZAQH.js → render-ZZ4CGJ6J.js} +7 -7
  72. package/dist/seal-RRYFKTEQ.js +10 -0
  73. package/dist/{setup-5LYHCQRU.js → setup-UIPKBNLA.js} +3 -3
  74. package/dist/visual-DLLRTF6C.js +21 -0
  75. package/dist/{watch-YP4IWM75.js → watch-OXQ6O5HD.js} +12 -12
  76. package/package.json +1 -1
  77. package/dist/chunk-J45OVEUM.js.map +0 -1
  78. package/dist/chunk-JILIA5EV.cjs.map +0 -1
  79. package/dist/chunk-PMX5CPK5.js.map +0 -1
  80. package/dist/chunk-XAZ5RGVG.js.map +0 -1
  81. package/dist/chunk-XZOAE2Q7.js.map +0 -1
  82. package/dist/chunks-REYSCBPB.js +0 -10
  83. package/dist/pdf-ocr-7MDCLWAA.cjs +0 -31
  84. package/dist/seal-H2JNAZU7.js +0 -10
  85. package/dist/visual-7EO6GR3M.js +0 -21
  86. /package/dist/{-Q56U3KCA.js.map → -WND2HWVH.js.map} +0 -0
  87. /package/dist/{chunk-3EWXRIPH.js.map → chunk-3LSHLWTX.js.map} +0 -0
  88. /package/dist/{chunk-HNX2I7D6.js.map → chunk-44E52JJ7.js.map} +0 -0
  89. /package/dist/{chunk-XNNMMYFO.js.map → chunk-47MTLP4U.js.map} +0 -0
  90. /package/dist/{chunk-42FSKT7R.js.map → chunk-4XVL3OBP.js.map} +0 -0
  91. /package/dist/{chunk-OAOM7IEI.js.map → chunk-5AHG3XY3.js.map} +0 -0
  92. /package/dist/{chunk-EWCJCWTT.js.map → chunk-6CPBNK5O.js.map} +0 -0
  93. /package/dist/{chunk-FZT34MUI.js.map → chunk-A5JDO52L.js.map} +0 -0
  94. /package/dist/{chunk-4X73CGIL.js.map → chunk-AKIJTKEA.js.map} +0 -0
  95. /package/dist/{chunk-Q2QKRE4P.js.map → chunk-D4YWVZHD.js.map} +0 -0
  96. /package/dist/{chunk-33NZN73M.js.map → chunk-DTADAHJD.js.map} +0 -0
  97. /package/dist/{chunk-I2QETSZN.js.map → chunk-FK3JPTHI.js.map} +0 -0
  98. /package/dist/{chunk-AEEQN6L3.js.map → chunk-GGVHKYKZ.js.map} +0 -0
  99. /package/dist/{chunk-PHZDAHZC.js.map → chunk-LBOXKGAH.js.map} +0 -0
  100. /package/dist/{chunk-W6O7KBOD.js.map → chunk-MC4DPT4I.js.map} +0 -0
  101. /package/dist/{chunk-KXHNIHLC.js.map → chunk-MMPBJGWQ.js.map} +0 -0
  102. /package/dist/{chunk-NKDPCALC.js.map → chunk-QTJTBCTZ.js.map} +0 -0
  103. /package/dist/{chunk-EEXIFCXC.js.map → chunk-VBY3JQL2.js.map} +0 -0
  104. /package/dist/{chunk-TZ753B6A.js.map → chunk-WMDGGQXJ.js.map} +0 -0
  105. /package/dist/{chunk-HU7POUBS.js.map → chunk-YBCW544D.js.map} +0 -0
  106. /package/dist/{chunks-REYSCBPB.js.map → chunks-2UDUNVGQ.js.map} +0 -0
  107. /package/dist/{formula-IREEAC4T.js.map → formula-MPBZ7OMN.js.map} +0 -0
  108. /package/dist/{formula-EA5GDCUD.js.map → formula-NA3LD35B.js.map} +0 -0
  109. /package/dist/{image-ocr-LGOFUS3O.js.map → image-ocr-6TGDXUAS.js.map} +0 -0
  110. /package/dist/{image-ocr-JQJC5HWK.js.map → image-ocr-THA5BASF.js.map} +0 -0
  111. /package/dist/{model-bundle-YW62Y6UD.js.map → model-bundle-3YDTJ6EQ.js.map} +0 -0
  112. /package/dist/{models-AAL3IS2R.js.map → models-M7AX7VIN.js.map} +0 -0
  113. /package/dist/{parse-worker-v2-3JAHV7NY.js.map → parse-worker-v2-3ZMFWDFW.js.map} +0 -0
  114. /package/dist/{parser-ZBP5GOQK.js.map → parser-MNNJSFEZ.js.map} +0 -0
  115. /package/dist/{parser-4FCKKJ2N.js.map → parser-TD4VZDGY.js.map} +0 -0
  116. /package/dist/{pdf-ocr-HFAEOA7W.js.map → pdf-ocr-5HEVZKG5.js.map} +0 -0
  117. /package/dist/{pdf-ocr-Q4TPGDDI.js.map → pdf-ocr-6BAOQ6CY.js.map} +0 -0
  118. /package/dist/{profile-io-EDQTKLLL.js.map → profile-io-H4WQIGN6.js.map} +0 -0
  119. /package/dist/{rasterize-VD2XGHUJ.js.map → rasterize-EOPWJWBO.js.map} +0 -0
  120. /package/dist/{redact-doc-TBIBQJCT.js.map → redact-doc-BBZVAA3I.js.map} +0 -0
  121. /package/dist/{render-J5KAZAQH.js.map → render-ZZ4CGJ6J.js.map} +0 -0
  122. /package/dist/{seal-H2JNAZU7.js.map → seal-RRYFKTEQ.js.map} +0 -0
  123. /package/dist/{setup-5LYHCQRU.js.map → setup-UIPKBNLA.js.map} +0 -0
  124. /package/dist/{visual-7EO6GR3M.js.map → visual-DLLRTF6C.js.map} +0 -0
  125. /package/dist/{watch-YP4IWM75.js.map → watch-OXQ6O5HD.js.map} +0 -0
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  blocksToPages,
3
3
  bmpToPng,
4
4
  inlineImagesIntoMarkdown
5
- } from "./chunk-W6O7KBOD.js";
5
+ } from "./chunk-MC4DPT4I.js";
6
6
  import {
7
7
  parsePageRange
8
8
  } from "./chunk-V4BH5SRQ.js";
@@ -43,7 +43,7 @@ import {
43
43
  validateOcrOptions,
44
44
  visibleText,
45
45
  wrapScript
46
- } from "./chunk-EEXIFCXC.js";
46
+ } from "./chunk-VBY3JQL2.js";
47
47
  import {
48
48
  KordocError,
49
49
  OPTIONAL_DEP_INSTALL_HINT,
@@ -61,7 +61,7 @@ import {
61
61
  toArrayBuffer,
62
62
  unescapeHtml,
63
63
  unzipLimitBytes
64
- } from "./chunk-I2QETSZN.js";
64
+ } from "./chunk-FK3JPTHI.js";
65
65
 
66
66
  // src/plain-markdown.ts
67
67
  function toPlainMarkdown(md2) {
@@ -24620,7 +24620,7 @@ var MIN_SIDE = 24;
24620
24620
  async function ocrEmbeddedImages(blocks, options, warnings) {
24621
24621
  const ocr = options?.ocr;
24622
24622
  if (ocr !== true && ocr !== "force" && typeof ocr !== "function") return false;
24623
- const { parseImageDocument } = await import("./image-ocr-JQJC5HWK.js");
24623
+ const { parseImageDocument } = await import("./image-ocr-THA5BASF.js");
24624
24624
  let inserted = false, unreadable = 0;
24625
24625
  let failed = null;
24626
24626
  const walk = async (list, depth) => {
@@ -44217,7 +44217,7 @@ function hwpFaceToCssStack(face) {
44217
44217
  const head = FONT_ALIASES[trimmed] ?? cssQuote(trimmed);
44218
44218
  return `${head},${generic}`;
44219
44219
  }
44220
- function collectHangulFonts(root, lang = "HANGUL", hftIds) {
44220
+ function collectHangulFonts(root, lang = "HANGUL", hftIds, substKoPub = false) {
44221
44221
  const map = /* @__PURE__ */ new Map();
44222
44222
  const findFaces = (el, depth) => {
44223
44223
  if (depth > 24) return null;
@@ -44253,7 +44253,7 @@ function collectHangulFonts(root, lang = "HANGUL", hftIds) {
44253
44253
  const id = e.getAttribute("id");
44254
44254
  let face = e.getAttribute("face");
44255
44255
  let type = e.getAttribute("type");
44256
- if (face && type === "TTF" && /^한양/.test(face)) {
44256
+ if (face && type === "TTF" && (/^한양/.test(face) || substKoPub && /^KoPub/.test(face))) {
44257
44257
  const sub = Array.from(e.childNodes).find((c) => c.nodeType === 1 && (c.tagName || "").replace(/^[^:]+:/, "") === "substFont");
44258
44258
  const sf = sub?.getAttribute("face");
44259
44259
  if (sf) {
@@ -44344,10 +44344,11 @@ function parseRenderStyles(headXml, opts) {
44344
44344
  const hv = Number.parseFloat(root.getAttribute("version") ?? "");
44345
44345
  const oldUnit = Number.isFinite(hv) && hv < 1.4;
44346
44346
  const hftHangul = /* @__PURE__ */ new Set(), hftLatin = /* @__PURE__ */ new Set();
44347
- const hangulFonts = collectHangulFonts(root, "HANGUL", hftHangul);
44348
- const latinFonts = collectHangulFonts(root, "LATIN", hftLatin);
44347
+ const sk = !!opts?.substKoPub;
44348
+ const hangulFonts = collectHangulFonts(root, "HANGUL", hftHangul, sk);
44349
+ const latinFonts = collectHangulFonts(root, "LATIN", hftLatin, sk);
44349
44350
  const hftHanja = /* @__PURE__ */ new Set(), hftJapanese = /* @__PURE__ */ new Set(), hftSymbol = /* @__PURE__ */ new Set();
44350
- const langFonts = { hanja: [collectHangulFonts(root, "HANJA", hftHanja), hftHanja], japanese: [collectHangulFonts(root, "JAPANESE", hftJapanese), hftJapanese], symbol: [collectHangulFonts(root, "SYMBOL", hftSymbol), hftSymbol] };
44351
+ const langFonts = { hanja: [collectHangulFonts(root, "HANJA", hftHanja, sk), hftHanja], japanese: [collectHangulFonts(root, "JAPANESE", hftJapanese, sk), hftJapanese], symbol: [collectHangulFonts(root, "SYMBOL", hftSymbol, sk), hftSymbol] };
44351
44352
  const autoTabPr = /* @__PURE__ */ new Set();
44352
44353
  const paraTabRef = /* @__PURE__ */ new Map();
44353
44354
  const paraBullet = /* @__PURE__ */ new Map();
@@ -52517,7 +52518,8 @@ function solveRowHeights(cells, rowCount, maxTotal = Number.POSITIVE_INFINITY, s
52517
52518
  }
52518
52519
  const last = rowCount - 1, over = total - maxTotal;
52519
52520
  const lastCells = cells.filter((c) => c.rowAddr + c.rowSpan - 1 === last);
52520
- if (shrinkLast && over > 0 && last >= 0 && lastCells.length && lastCells.every((c) => c.rowSpan === 1 && c.contentH != null && c.contentH <= h[last] - over)) h[last] -= over;
52521
+ const spanH = (c) => h.slice(c.rowAddr, c.rowAddr + c.rowSpan).reduce((t, x) => t + x, 0);
52522
+ if (shrinkLast && over > 0 && last >= 0 && lastCells.length && lastCells.every((c) => c.contentH != null && c.contentH <= (c.rowSpan === 1 ? h[last] : spanH(c)) - over)) h[last] -= over;
52521
52523
  return h;
52522
52524
  }
52523
52525
 
@@ -52785,7 +52787,7 @@ function cellContentExtent(cell2, memo) {
52785
52787
  const pushed = baseV - (Math.max(0, vo) + num2(om, "top") + o.height + num2(om, "bottom"));
52786
52788
  const anchor = pushed >= (paraStart > 0 ? paraStart - 100 : -100) ? pushed : baseV - (memo?.paraGeom?.get(p.getAttribute("paraPrIDRef") ?? "")?.spaceBefore ?? 0);
52787
52789
  const oh = o.tag === "tbl" ? Math.max(o.height, measureTableHeight(o.el, memo)) : o.height;
52788
- ext = Math.max(ext, anchor + num2(om, "top") + Math.max(0, vo) + oh);
52790
+ ext = Math.max(ext, anchor + num2(om, "top") + Math.max(0, vo) + oh + num2(om, "bottom"));
52789
52791
  }
52790
52792
  }
52791
52793
  memo?.cell.set(cell2.el, ext);
@@ -52852,7 +52854,7 @@ function measureTableRowHeights(tbl2, memo) {
52852
52854
  const rows = solveRowHeights(
52853
52855
  // 여러 행 칸은 내용(+ 칸 여백)이 저장 높이보다 크면 내용 높이로 — 솔버가 모자란 만큼 그 칸 마지막 행을 키운다
52854
52856
  // (같은 판 PDF: 두 줄 든 2행 병합 칸 내용 2882 > 저장 2564 → 둘째 행이 318 자라고 첫 행은 그대로)
52855
- cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: (c.rs > 1 ? Math.max(c.h, cellContentExtent(c, memo) + c.marginT + c.marginB) : c.h) - sp * (c.rs - 1), contentH: c.rs === 1 ? cellContentExtent(c, memo) + c.marginT + c.marginB : void 0 })),
52857
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: (c.rs > 1 ? Math.max(c.h, cellContentExtent(c, memo) + c.marginT + c.marginB) : c.h) - sp * (c.rs - 1), contentH: cellContentExtent(c, memo) + c.marginT + c.marginB })),
52856
52858
  nRows,
52857
52859
  num2(findChildByLocalName(tbl2, "sz"), "height") - (sp > 0 ? sp * (nRows + 1) : 0) || Number.POSITIVE_INFINITY,
52858
52860
  !inCell(tbl2) && !cells.some((c) => c.ra + c.rs === nRows && splitSaved(c))
@@ -54401,6 +54403,53 @@ function flowEndNotes(root, bodyH) {
54401
54403
  });
54402
54404
  }
54403
54405
 
54406
+ // src/render/font-env.ts
54407
+ function hasKoPubSubst(headXml) {
54408
+ return /<hh:font\b[^>]*\bface="KoPub[^"]*"[^>]*\btype="TTF"[^>]*>\s*<hh:substFont\b/.test(headXml);
54409
+ }
54410
+ function lineStarts(root) {
54411
+ const out = [];
54412
+ for (const p of Array.from(root.getElementsByTagName("hp:p"))) {
54413
+ const lsa = elements(p).find((e) => ln(e) === "linesegarray");
54414
+ const segs = lsa ? elements(lsa).filter((e) => ln(e) === "lineseg") : [];
54415
+ out.push(segs.length >= 2 ? segs.map((s) => s.getAttribute("textpos") ?? "0").join(",") : null);
54416
+ }
54417
+ return out;
54418
+ }
54419
+ function matchCount(xml, saved, styles) {
54420
+ const root = createXmlParser().parseFromString(xml, "text/xml").documentElement;
54421
+ const pagePr = root.getElementsByTagName("hp:pagePr")[0];
54422
+ if (!pagePr) return 0;
54423
+ const margin = pagePr.getElementsByTagName("hp:margin")[0];
54424
+ let PW = num2(pagePr, "width", 59528), PH = num2(pagePr, "height", 84188);
54425
+ if (pagePr.getAttribute("landscape") === "NARROWLY" && PW < PH) [PW, PH] = [PH, PW];
54426
+ const gutterTB = pagePr.getAttribute("gutterType") === "TOP_BOTTOM", gutter = num2(margin ?? null, "gutter", 0);
54427
+ const BODY_W = PW - num2(margin ?? null, "left", 8504) - num2(margin ?? null, "right", 8504) - (gutterTB ? 0 : gutter);
54428
+ const BODY_H = PH - num2(margin ?? null, "top", 5668) - num2(margin ?? null, "header", 0) - num2(margin ?? null, "bottom", 4252) - num2(margin ?? null, "footer", 0) - (gutterTB ? gutter : 0);
54429
+ for (const p of Array.from(root.getElementsByTagName("hp:p"))) {
54430
+ const lsa = elements(p).find((e) => ln(e) === "linesegarray");
54431
+ if (lsa) p.removeChild(lsa);
54432
+ }
54433
+ reflowSection(root, styles, { BODY_W, BODY_H });
54434
+ const got = lineStarts(root);
54435
+ let n = 0;
54436
+ saved.forEach((s, i) => {
54437
+ if (s !== null && s === got[i]) n++;
54438
+ });
54439
+ return n;
54440
+ }
54441
+ function kopubSubstituted(secXmls, base, alt2) {
54442
+ let a = 0, b = 0, seen = 0;
54443
+ for (const xml of secXmls) {
54444
+ const saved = lineStarts(createXmlParser().parseFromString(xml, "text/xml").documentElement);
54445
+ a += matchCount(xml, saved, base);
54446
+ b += matchCount(xml, saved, alt2);
54447
+ seen += saved.filter((x) => x !== null).length;
54448
+ if (seen >= 60) break;
54449
+ }
54450
+ return b >= a + 5 && b > a * 1.1;
54451
+ }
54452
+
54404
54453
  // src/render/scene.ts
54405
54454
  function regionId(type, seq) {
54406
54455
  return `${type}-${String(seq).padStart(6, "0")}`;
@@ -54828,11 +54877,11 @@ function planTableRows(tbl2, cells, rowH, ty, MT, BODY_H, slack = 0, floatSpan,
54828
54877
  continue;
54829
54878
  }
54830
54879
  }
54831
- if (splittable && y + h > pageBottom) {
54880
+ if (splittable && y + h + outB > pageBottom) {
54832
54881
  const from = /* @__PURE__ */ new Map();
54833
54882
  const lines = new Map(rowCells.map((c) => [c.el, cellLines(c)]));
54834
- while (y + h > pageBottom && BODY_H > rowY[hdrRows]) {
54835
- const avail = pageBottom - y;
54883
+ while (y + h + outB > pageBottom && BODY_H > rowY[hdrRows]) {
54884
+ const avail = pageBottom - y - outB;
54836
54885
  let rem = 0, placed = false, allFit = true, blocked = false;
54837
54886
  const cuts = [];
54838
54887
  for (const c of rowCells) {
@@ -55441,30 +55490,53 @@ function planLines(m, styles, numText = "") {
55441
55490
  }
55442
55491
  }
55443
55492
  const stretch = align === "JUSTIFY" || align === "DISTRIBUTE" || align === "DISTRIBUTE_SPACE";
55444
- let spaceAdd = 0, spaceFrom = fixedTo;
55493
+ let spaceAdd = 0, spaceFrom = fixedTo, charAdd = 0;
55494
+ const squeeze = (spFrom) => {
55495
+ const short = nat.text - lastSp - avail;
55496
+ let nSp = 0, cap = 0, nG = 0;
55497
+ for (let k = spFrom; k < textEnd; k++) {
55498
+ const c = m.chars[k];
55499
+ if (c.ch === " ") {
55500
+ nSp++;
55501
+ cap += charW(c, styles, m.chars[k - 1]) * 0.2;
55502
+ } else if (c.ch && !c.tab) nG++;
55503
+ }
55504
+ if (nSp > 0) {
55505
+ spaceAdd = -Math.min(short, cap) / nSp;
55506
+ spaceFrom = spFrom;
55507
+ }
55508
+ if (short > cap && nG > 0) charAdd = -(short - (nSp > 0 ? cap : 0)) / nG;
55509
+ };
55445
55510
  if (nat.text > 0 && stretch && (!isLast || align === "DISTRIBUTE" || align === "DISTRIBUTE_SPACE")) {
55446
55511
  let nSp = 0, spFrom = fixedTo;
55447
- while (spFrom < textEnd && (m.chars[spFrom].ch === " " || m.chars[spFrom].ch === "")) spFrom++;
55512
+ while (spFrom < textEnd && (m.chars[spFrom].ch === " " || m.chars[spFrom].ch === "") && !m.chars[spFrom].ctrl) spFrom++;
55448
55513
  for (let k = spFrom; k < textEnd; k++) if (m.chars[k].ch === " ") nSp++;
55449
55514
  if (nSp > 0 && align !== "DISTRIBUTE") {
55450
55515
  spaceAdd = (avail - nat.text + lastSp) / nSp;
55451
55516
  spaceFrom = spFrom;
55517
+ if (spaceAdd < 0) squeeze(spFrom);
55452
55518
  } else scale2 = avail > 0 ? avail / nat.text : 1;
55453
55519
  } else if (nat.text + nat.obj > 0 && (isLast || !stretch)) {
55454
55520
  const w = nat.text + nat.obj - lastSp;
55455
55521
  if (align === "CENTER") xoff = Math.max(0, (lineW - w) / 2);
55456
55522
  else if (align === "RIGHT") xoff = Math.max(0, lineW - w);
55457
55523
  }
55524
+ if (spaceAdd === 0 && charAdd === 0 && scale2 === 1 && nat.text - lastSp > avail) {
55525
+ let spFrom = fixedTo;
55526
+ while (spFrom < textEnd && (m.chars[spFrom].ch === " " || m.chars[spFrom].ch === "") && !m.chars[spFrom].ctrl) spFrom++;
55527
+ squeeze(spFrom);
55528
+ }
55458
55529
  if (!Number.isFinite(scale2) || scale2 <= 0) scale2 = 1;
55459
55530
  scale2 = Math.min(4, Math.max(0.25, scale2));
55460
- plans.push({ seg, xoff: xoff + lead, scale: scale2, spaceAdd, spFrom: spaceFrom, start, end, tabs, fixedTo, textEnd, ...i === 0 && bu ? { bullet: { ch: bu.ch, w: bulletW, prId: bu.charPrId ?? firstPr } } : {} });
55531
+ plans.push({ seg, xoff: xoff + lead, scale: scale2, spaceAdd, spFrom: spaceFrom, ...charAdd ? { charAdd } : {}, start, end, tabs, fixedTo, textEnd, ...i === 0 && bu ? { bullet: { ch: bu.ch, w: bulletW, prId: bu.charPrId ?? firstPr } } : {} });
55461
55532
  }
55462
55533
  return plans;
55463
55534
  }
55464
55535
  function advanceTo(m, styles, plan, upto) {
55465
55536
  let x = 0;
55466
55537
  for (let i = plan.start; i < upto && i < m.chars.length; i++) {
55467
- x += m.chars[i].tab ? plan.tabs.get(i) ?? 0 : charW(m.chars[i], styles, m.chars[i - 1]) * (i < plan.fixedTo ? 1 : plan.scale) + (i >= plan.spFrom && i < plan.textEnd && m.chars[i].ch === " " ? plan.spaceAdd : 0);
55538
+ const c = m.chars[i], inStretch = i >= plan.spFrom && i < plan.textEnd;
55539
+ x += c.tab ? plan.tabs.get(i) ?? 0 : charW(c, styles, m.chars[i - 1]) * (i < plan.fixedTo ? 1 : plan.scale) + (inStretch && c.ch === " " ? plan.spaceAdd : 0) + (inStretch && plan.charAdd && c.ch && c.ch !== " " ? plan.charAdd : 0);
55468
55540
  }
55469
55541
  for (const o of m.objs) if (o.inline && o.index >= plan.start && o.index < upto) x += o.omL + o.width + o.omR;
55470
55542
  return x;
@@ -55582,7 +55654,7 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55582
55654
  return n;
55583
55655
  };
55584
55656
  const renderSeg = (text, cx, hit) => {
55585
- const sw = measure(text) * scale2 + (plan.spaceAdd && i >= plan.fixedTo ? plan.spaceAdd * spacesIn(text) : 0);
55657
+ const sw = measure(text) * scale2 + (plan.spaceAdd && i >= plan.fixedTo ? plan.spaceAdd * spacesIn(text) : 0) + (plan.charAdd && i >= plan.fixedTo ? plan.charAdd * [...text].filter((ch) => ch !== " ").length : 0);
55586
55658
  if (st.shade) emit(ctx, `<rect x="${pt2(cx)}" y="${pt2(glyphY(st.height) - Math.round(st.height * 0.85))}" width="${pt2(sw)}" height="${pt2(st.height)}" fill="${escapeXml7(st.shade)}"/>`);
55587
55659
  if (hit) {
55588
55660
  emit(ctx, `<rect x="${pt2(cx)}" y="${pt2(oy + seg.vertpos)}" width="${pt2(sw)}" height="${pt2(seg.textheight)}" fill="#ffd54f" fill-opacity="0.45"/>`);
@@ -55664,11 +55736,15 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55664
55736
  let anchorLineV;
55665
55737
  let anchorLineH = 0;
55666
55738
  let anchorSeg;
55667
- for (const pl of plans) if (pl.start <= o.index) {
55668
- anchorLineV = pl.seg.vertpos;
55669
- anchorLineH = pl.seg.textheight;
55670
- anchorSeg = pl.seg;
55671
- }
55739
+ let anchorK = -1;
55740
+ plans.forEach((pl, k) => {
55741
+ if (pl.start <= o.index) {
55742
+ anchorLineV = pl.seg.vertpos;
55743
+ anchorLineH = pl.seg.textheight;
55744
+ anchorSeg = pl.seg;
55745
+ anchorK = k;
55746
+ }
55747
+ });
55672
55748
  let objBaseV = baseV;
55673
55749
  const pTop = depth === 0 ? ctx.paraTops?.get(p) : void 0;
55674
55750
  const wrapA = o.el.getAttribute("textWrap") ?? "TOP_AND_BOTTOM";
@@ -55687,6 +55763,11 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55687
55763
  let stay = tbFloats < 2 && !m.objs.some((q) => q.inline) && !m.chars.some((c) => c.ch !== "" && !c.nb && c.ch.trim() !== "");
55688
55764
  const sbA = m.paraPrId != null ? ctx.styles.paraGeom.get(m.paraPrId)?.spaceBefore ?? 0 : 0;
55689
55765
  if (stay && wrapA === "TOP_AND_BOTTOM" && linePushedBy(o, anchorLineV ?? baseV, pTop ?? (depth > 0 ? cellParaTop(p, ctx.styles.paraGeom) : void 0))) stay = false;
55766
+ let carried;
55767
+ if (segPages && anchorK > 0 && segPages[anchorK] !== segPages[0] && segPages[anchorK - 1] === segPages[0] && wrapA === "TOP_AND_BOTTOM" && (findChildByLocalName(o.el, "pos")?.getAttribute("vertRelTo") ?? "PARA") === "PARA") {
55768
+ const s0 = plans[anchorK - 1].seg;
55769
+ carried = s0.vertpos + s0.textheight + (s0.spacing ?? 0);
55770
+ }
55690
55771
  const firstLine = anchorLineV === void 0 || anchorLineV === baseV;
55691
55772
  let { x, y } = anchorObject(
55692
55773
  o,
@@ -55703,6 +55784,10 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55703
55784
  // 문단 중간 글자 앵커인데 첫 줄부터 앵커 줄만큼 좁게 저장됐으면 개체는 문단 위에 있다(같은 판 한컴 PDF: 둘째 줄 앵커 사진, 네 줄 모두 34602)
55704
55785
  m.chars.slice(o.index).some((c) => c.ch.trim() !== "") && !!anchorSeg && plans.length > 0 && plans[0].seg !== anchorSeg && Math.abs(plans[0].seg.horzsize - anchorSeg.horzsize) <= 100 && anchorSeg.horzpos + anchorSeg.horzsize < aw - 1e3 ? "top" : m.chars.slice(o.index).some((c) => c.ch.trim() !== "") ? "mid" : "end"
55705
55786
  );
55787
+ if (carried !== void 0) {
55788
+ const posC = findChildByLocalName(o.el, "pos"), rawC = num2(posC, "vertOffset");
55789
+ y = oy + carried + num2(findChildByLocalName(o.el, "outMargin"), "top") + Math.max(0, rawC >= 2 ** 31 ? rawC - 2 ** 32 : rawC);
55790
+ }
55706
55791
  let stackTop = depth === 0 ? pTop ?? 0 : cellParaTop(p, ctx.styles.paraGeom);
55707
55792
  if (tbFloats >= 2 && wrapA === "TOP_AND_BOTTOM" && stackTop !== void 0) {
55708
55793
  if (!tbStack) {
@@ -56611,7 +56696,8 @@ async function renderHwpxInternal(input, options) {
56611
56696
  const verFile = zip.file("version.xml");
56612
56697
  const verXml = verFile ? await readZipEntry(verFile, "text") : void 0;
56613
56698
  const appMajor = hwpxAppMajor(verXml), appBuild = hwpxAppBuild(verXml);
56614
- const styles = headFile ? parseRenderStyles(await readZipEntry(headFile, "text"), { appMajor, appBuild }) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
56699
+ const headXml = headFile ? await readZipEntry(headFile, "text") : void 0;
56700
+ let styles = headXml ? parseRenderStyles(headXml, { appMajor, appBuild }) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
56615
56701
  if (!headFile) warnings.push("header.xml \uC5C6\uC74C \u2014 \uAE30\uBCF8 \uC2A4\uD0C0\uC77C\uB85C \uB80C\uB354");
56616
56702
  const secXmls = [];
56617
56703
  for (const f of secFiles) {
@@ -56619,6 +56705,10 @@ async function renderHwpxInternal(input, options) {
56619
56705
  if (xml.length > MAX_DECOMPRESS_SIZE) throw new KordocError("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
56620
56706
  secXmls.push(xml);
56621
56707
  }
56708
+ if (headXml && hasKoPubSubst(headXml)) {
56709
+ const alt2 = parseRenderStyles(headXml, { appMajor, appBuild, substKoPub: true });
56710
+ if (kopubSubstituted(secXmls, styles, alt2)) styles = alt2;
56711
+ }
56622
56712
  const masterPages = /* @__PURE__ */ new Map();
56623
56713
  const masterXmls = [];
56624
56714
  for (const file of zip.file(/Contents\/masterpage[^/]*\.xml$/i)) {
@@ -57729,7 +57819,7 @@ function scriptsOff(r, off) {
57729
57819
  }
57730
57820
  async function parseImage(buffer, options) {
57731
57821
  try {
57732
- const { parseImageDocument } = await import("./image-ocr-JQJC5HWK.js");
57822
+ const { parseImageDocument } = await import("./image-ocr-THA5BASF.js");
57733
57823
  const { blocks, warnings, lines } = await parseImageDocument(buffer, options);
57734
57824
  stripScriptTags({ blocks });
57735
57825
  return {
@@ -57793,7 +57883,7 @@ async function parseHwp(buffer, options) {
57793
57883
  async function parsePdf(buffer, options) {
57794
57884
  let parsePdfDocument;
57795
57885
  try {
57796
- const mod = await import("./parser-ZBP5GOQK.js");
57886
+ const mod = await import("./parser-MNNJSFEZ.js");
57797
57887
  parsePdfDocument = mod.parsePdfDocument;
57798
57888
  } catch {
57799
57889
  return {