kordoc 4.16.0 → 4.16.2

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 (145) hide show
  1. package/README.md +344 -1135
  2. package/dist/{-VQNLLLPE.js → -4G6MA4X6.js} +11 -11
  3. package/dist/chunk-3IB7LBHC.js +57 -0
  4. package/dist/chunk-3IB7LBHC.js.map +1 -0
  5. package/dist/{chunk-6LMKQM7I.js → chunk-4VODJKFL.js} +3 -3
  6. package/dist/{chunk-UDX7TSOC.js → chunk-5KS5PWJR.js} +2 -2
  7. package/dist/chunk-62W7QCEX.cjs +57 -0
  8. package/dist/chunk-62W7QCEX.cjs.map +1 -0
  9. package/dist/{chunk-NNYF2AGC.js → chunk-7KNGSQU7.js} +4 -4
  10. package/dist/chunk-7KNGSQU7.js.map +1 -0
  11. package/dist/{chunk-DYENR3PX.js → chunk-AUWGDP4G.js} +2 -2
  12. package/dist/{chunk-H6KMTYYZ.cjs → chunk-CEIATRDW.cjs} +3 -3
  13. package/dist/{chunk-H6KMTYYZ.cjs.map → chunk-CEIATRDW.cjs.map} +1 -1
  14. package/dist/{chunk-N6TPODYL.js → chunk-DES2LGFZ.js} +2 -2
  15. package/dist/{chunk-PQRP4NSF.js → chunk-F4NRLLY4.js} +2 -2
  16. package/dist/{chunk-B5NEGP65.cjs → chunk-FKUDAIJI.cjs} +692 -33
  17. package/dist/chunk-FKUDAIJI.cjs.map +1 -0
  18. package/dist/{chunk-XWA625AN.js → chunk-FSDJLAOW.js} +3 -1
  19. package/dist/chunk-FSDJLAOW.js.map +1 -0
  20. package/dist/{chunk-PIMB2YNO.js → chunk-GO5IFOUF.js} +2 -2
  21. package/dist/{chunk-476OYHGZ.js → chunk-IQGIT2VX.js} +37 -7
  22. package/dist/chunk-IQGIT2VX.js.map +1 -0
  23. package/dist/chunk-J3IF6KGW.js +59 -0
  24. package/dist/chunk-J3IF6KGW.js.map +1 -0
  25. package/dist/{chunk-C75WE52C.js → chunk-JELRWAZC.js} +2 -2
  26. package/dist/{chunk-46DZF3RK.js → chunk-JFLAM3MM.js} +2 -2
  27. package/dist/{chunk-A3QDRMVD.js → chunk-KIOQ4N37.js} +2 -2
  28. package/dist/{chunk-TGD7UFHD.js → chunk-LEIAEWZ7.js} +4 -4
  29. package/dist/chunk-LEIAEWZ7.js.map +1 -0
  30. package/dist/{chunk-GOQBON77.js → chunk-MLIS253L.js} +2 -2
  31. package/dist/{chunk-JB5X5NNL.js → chunk-OXLPVQYK.js} +680 -21
  32. package/dist/chunk-OXLPVQYK.js.map +1 -0
  33. package/dist/{chunk-RC4C7Q33.js → chunk-P6ZDXTV6.js} +2 -2
  34. package/dist/{chunk-CB5XDCSL.js → chunk-QOCS7W7R.js} +5034 -4569
  35. package/dist/chunk-QOCS7W7R.js.map +1 -0
  36. package/dist/{chunk-3JWMDL3S.js → chunk-S2PL227Q.js} +2 -2
  37. package/dist/{chunk-HIVK5V27.js → chunk-SFEQYKYJ.js} +133 -110
  38. package/dist/chunk-SFEQYKYJ.js.map +1 -0
  39. package/dist/{chunk-NWODPYBD.cjs → chunk-STM3ORY7.cjs} +2 -2
  40. package/dist/{chunk-NWODPYBD.cjs.map → chunk-STM3ORY7.cjs.map} +1 -1
  41. package/dist/{chunk-43FKGDDO.js → chunk-TXUKTOG2.js} +213 -30
  42. package/dist/chunk-TXUKTOG2.js.map +1 -0
  43. package/dist/{chunk-XHOZB2WP.js → chunk-UTP2WCHS.js} +681 -22
  44. package/dist/chunk-UTP2WCHS.js.map +1 -0
  45. package/dist/{chunk-MH6MAL64.cjs → chunk-WDQTFAXY.cjs} +217 -114
  46. package/dist/chunk-WDQTFAXY.cjs.map +1 -0
  47. package/dist/{chunk-DRY3L5KQ.cjs → chunk-XTFN5WKS.cjs} +7 -7
  48. package/dist/chunk-XTFN5WKS.cjs.map +1 -0
  49. package/dist/chunks-NUNIKS2J.js +10 -0
  50. package/dist/cli.js +33 -30
  51. package/dist/cli.js.map +1 -1
  52. package/dist/{formula-FNQYHMIY.js → formula-EPKLPDU7.js} +3 -3
  53. package/dist/{formula-5775PTP2.js → formula-NARUOXRX.js} +4 -4
  54. package/dist/{formula-VEFKYXPB.cjs → formula-WIMV5TUX.cjs} +9 -9
  55. package/dist/{formula-VEFKYXPB.cjs.map → formula-WIMV5TUX.cjs.map} +1 -1
  56. package/dist/{image-ocr-PYZU4TO7.js → image-ocr-3WJ4QH3T.js} +8 -8
  57. package/dist/{image-ocr-YA2MQBRP.js → image-ocr-5BUJQ4TK.js} +6 -6
  58. package/dist/{image-ocr-6JZR734G.cjs → image-ocr-AXWXR6JV.cjs} +15 -15
  59. package/dist/{image-ocr-6JZR734G.cjs.map → image-ocr-AXWXR6JV.cjs.map} +1 -1
  60. package/dist/index.cjs +1900 -1406
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.d.cts +24 -6
  63. package/dist/index.d.ts +24 -6
  64. package/dist/index.js +1282 -788
  65. package/dist/index.js.map +1 -1
  66. package/dist/mcp.js +34 -28
  67. package/dist/mcp.js.map +1 -1
  68. package/dist/{model-bundle-O6J7ORVC.js → model-bundle-IMBW7D2Z.js} +5 -5
  69. package/dist/{models-YMOKZGCI.js → models-SY75IBOE.js} +5 -5
  70. package/dist/{parser-YAQV7FBO.cjs → parser-2LU4EVU3.cjs} +360 -219
  71. package/dist/parser-2LU4EVU3.cjs.map +1 -0
  72. package/dist/{parser-3B6I2XL7.js → parser-N6476XAC.js} +225 -84
  73. package/dist/parser-N6476XAC.js.map +1 -0
  74. package/dist/{parser-PXATL5DM.js → parser-ZQM3664Z.js} +222 -81
  75. package/dist/parser-ZQM3664Z.js.map +1 -0
  76. package/dist/pdf-ocr-6DEE23IP.js +15 -0
  77. package/dist/pdf-ocr-GHEJVPX2.cjs +16 -0
  78. package/dist/{pdf-ocr-T2JXQATA.cjs.map → pdf-ocr-GHEJVPX2.cjs.map} +1 -1
  79. package/dist/pdf-ocr-MQTWODVU.js +18 -0
  80. package/dist/{profile-io-ZTV2MKRT.js → profile-io-GJPKCYPT.js} +3 -3
  81. package/dist/{rasterize-MMUZ537K.js → rasterize-UOALJQDS.js} +3 -3
  82. package/dist/{redact-doc-S42XGV5D.js → redact-doc-22SYW3KH.js} +11 -11
  83. package/dist/{render-WCWPZKJ7.js → render-MJ4H3R23.js} +7 -7
  84. package/dist/seal-XWMRUTI4.js +10 -0
  85. package/dist/{setup-D35LKZCH.js → setup-2URYVUEO.js} +3 -3
  86. package/dist/visual-USPS4QRC.js +20 -0
  87. package/dist/{watch-AX64CIMN.js → watch-ALXZGTOB.js} +12 -12
  88. package/package.json +1 -1
  89. package/dist/chunk-43FKGDDO.js.map +0 -1
  90. package/dist/chunk-476OYHGZ.js.map +0 -1
  91. package/dist/chunk-B5NEGP65.cjs.map +0 -1
  92. package/dist/chunk-CB5XDCSL.js.map +0 -1
  93. package/dist/chunk-DRY3L5KQ.cjs.map +0 -1
  94. package/dist/chunk-HIVK5V27.js.map +0 -1
  95. package/dist/chunk-JB5X5NNL.js.map +0 -1
  96. package/dist/chunk-MH6MAL64.cjs.map +0 -1
  97. package/dist/chunk-NNYF2AGC.js.map +0 -1
  98. package/dist/chunk-QJERJZJ6.js +0 -11
  99. package/dist/chunk-QJERJZJ6.js.map +0 -1
  100. package/dist/chunk-TGD7UFHD.js.map +0 -1
  101. package/dist/chunk-UQ6TZDW6.js +0 -13
  102. package/dist/chunk-UQ6TZDW6.js.map +0 -1
  103. package/dist/chunk-XHOZB2WP.js.map +0 -1
  104. package/dist/chunk-XWA625AN.js.map +0 -1
  105. package/dist/chunk-ZY5K3LPM.cjs +0 -11
  106. package/dist/chunk-ZY5K3LPM.cjs.map +0 -1
  107. package/dist/chunks-JD25E5PM.js +0 -10
  108. package/dist/parser-3B6I2XL7.js.map +0 -1
  109. package/dist/parser-PXATL5DM.js.map +0 -1
  110. package/dist/parser-YAQV7FBO.cjs.map +0 -1
  111. package/dist/pdf-ocr-2TTO5PX2.js +0 -15
  112. package/dist/pdf-ocr-T2JXQATA.cjs +0 -16
  113. package/dist/pdf-ocr-WF2NQA6X.js +0 -18
  114. package/dist/seal-WHK4GOHR.js +0 -10
  115. package/dist/visual-WL4TDE5B.js +0 -20
  116. /package/dist/{-VQNLLLPE.js.map → -4G6MA4X6.js.map} +0 -0
  117. /package/dist/{chunk-6LMKQM7I.js.map → chunk-4VODJKFL.js.map} +0 -0
  118. /package/dist/{chunk-UDX7TSOC.js.map → chunk-5KS5PWJR.js.map} +0 -0
  119. /package/dist/{chunk-DYENR3PX.js.map → chunk-AUWGDP4G.js.map} +0 -0
  120. /package/dist/{chunk-N6TPODYL.js.map → chunk-DES2LGFZ.js.map} +0 -0
  121. /package/dist/{chunk-PQRP4NSF.js.map → chunk-F4NRLLY4.js.map} +0 -0
  122. /package/dist/{chunk-PIMB2YNO.js.map → chunk-GO5IFOUF.js.map} +0 -0
  123. /package/dist/{chunk-C75WE52C.js.map → chunk-JELRWAZC.js.map} +0 -0
  124. /package/dist/{chunk-46DZF3RK.js.map → chunk-JFLAM3MM.js.map} +0 -0
  125. /package/dist/{chunk-A3QDRMVD.js.map → chunk-KIOQ4N37.js.map} +0 -0
  126. /package/dist/{chunk-GOQBON77.js.map → chunk-MLIS253L.js.map} +0 -0
  127. /package/dist/{chunk-RC4C7Q33.js.map → chunk-P6ZDXTV6.js.map} +0 -0
  128. /package/dist/{chunk-3JWMDL3S.js.map → chunk-S2PL227Q.js.map} +0 -0
  129. /package/dist/{chunks-JD25E5PM.js.map → chunks-NUNIKS2J.js.map} +0 -0
  130. /package/dist/{formula-FNQYHMIY.js.map → formula-EPKLPDU7.js.map} +0 -0
  131. /package/dist/{formula-5775PTP2.js.map → formula-NARUOXRX.js.map} +0 -0
  132. /package/dist/{image-ocr-PYZU4TO7.js.map → image-ocr-3WJ4QH3T.js.map} +0 -0
  133. /package/dist/{image-ocr-YA2MQBRP.js.map → image-ocr-5BUJQ4TK.js.map} +0 -0
  134. /package/dist/{model-bundle-O6J7ORVC.js.map → model-bundle-IMBW7D2Z.js.map} +0 -0
  135. /package/dist/{models-YMOKZGCI.js.map → models-SY75IBOE.js.map} +0 -0
  136. /package/dist/{pdf-ocr-2TTO5PX2.js.map → pdf-ocr-6DEE23IP.js.map} +0 -0
  137. /package/dist/{pdf-ocr-WF2NQA6X.js.map → pdf-ocr-MQTWODVU.js.map} +0 -0
  138. /package/dist/{profile-io-ZTV2MKRT.js.map → profile-io-GJPKCYPT.js.map} +0 -0
  139. /package/dist/{rasterize-MMUZ537K.js.map → rasterize-UOALJQDS.js.map} +0 -0
  140. /package/dist/{redact-doc-S42XGV5D.js.map → redact-doc-22SYW3KH.js.map} +0 -0
  141. /package/dist/{render-WCWPZKJ7.js.map → render-MJ4H3R23.js.map} +0 -0
  142. /package/dist/{seal-WHK4GOHR.js.map → seal-XWMRUTI4.js.map} +0 -0
  143. /package/dist/{setup-D35LKZCH.js.map → setup-2URYVUEO.js.map} +0 -0
  144. /package/dist/{visual-WL4TDE5B.js.map → visual-USPS4QRC.js.map} +0 -0
  145. /package/dist/{watch-AX64CIMN.js.map → watch-ALXZGTOB.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  KordocError,
4
4
  OPTIONAL_DEP_INSTALL_HINT
5
- } from "./chunk-RC4C7Q33.js";
5
+ } from "./chunk-P6ZDXTV6.js";
6
6
 
7
7
  // src/render/rasterize.ts
8
8
  var densityExponent = null;
@@ -88,4 +88,4 @@ export {
88
88
  rasterizeSvg,
89
89
  rasterizePageSvg
90
90
  };
91
- //# sourceMappingURL=chunk-3JWMDL3S.js.map
91
+ //# sourceMappingURL=chunk-S2PL227Q.js.map
@@ -1,86 +1,14 @@
1
+ #!/usr/bin/env node
1
2
  import {
2
3
  HEADING_RATIO_H1,
3
4
  HEADING_RATIO_H2,
4
- HEADING_RATIO_H3
5
- } from "./chunk-QJERJZJ6.js";
6
- import {
7
- ensureModelsIn,
8
- getModelsDir
9
- } from "./chunk-PQRP4NSF.js";
5
+ HEADING_RATIO_H3,
6
+ tidyScriptTags
7
+ } from "./chunk-J3IF6KGW.js";
10
8
  import {
11
9
  safeMax,
12
10
  safeMin
13
- } from "./chunk-GOQBON77.js";
14
-
15
- // src/ocr/models.ts
16
- import { join } from "path";
17
- import { stat } from "fs/promises";
18
- var OCR_DET_MODEL = {
19
- name: "PP-OCRv5 mobile det",
20
- filename: "det.onnx",
21
- url: "https://huggingface.co/PaddlePaddle/PP-OCRv5_mobile_det_onnx/resolve/main/inference.onnx",
22
- sha256: "a431985659dc921974177a95adcfbb90fd9e51989a5e04d70d0b75f597b6e61d",
23
- sizeMb: 5
24
- };
25
- var OCR_REC_MODEL = {
26
- name: "PP-OCRv5 korean rec",
27
- filename: "rec_korean.onnx",
28
- url: "https://huggingface.co/PaddlePaddle/korean_PP-OCRv5_mobile_rec_onnx/resolve/main/inference.onnx",
29
- sha256: "92f0b7785e64fc9090106a241cf4c1eb97472824558272751b88a2a4476d3a08",
30
- sizeMb: 13
31
- };
32
- var OCR_REC_DICT = {
33
- name: "PP-OCRv5 korean dict",
34
- filename: "rec_korean.yml",
35
- url: "https://huggingface.co/PaddlePaddle/korean_PP-OCRv5_mobile_rec_onnx/resolve/main/inference.yml",
36
- sha256: "f757fa1c40e99edcf27e9cce879b93eb2a51fa46f5ef39095689b8c37dd75998",
37
- sizeMb: 1
38
- };
39
- var ALL_OCR_MODELS = [OCR_DET_MODEL, OCR_REC_MODEL, OCR_REC_DICT];
40
- function getOcrModelsDir() {
41
- return getModelsDir("ppocr");
42
- }
43
- async function ensureOcrModels(onProgress) {
44
- return ensureModelsIn(getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
45
- }
46
- async function ocrModelsCached() {
47
- const dir = getOcrModelsDir();
48
- for (const spec of ALL_OCR_MODELS) {
49
- try {
50
- if (!(await stat(join(dir, spec.filename))).size) return false;
51
- } catch {
52
- return false;
53
- }
54
- }
55
- return true;
56
- }
57
- function parseCharacterDict(yml) {
58
- const lines = yml.split("\n");
59
- const chars = [];
60
- let inDict = false;
61
- let dictIndent = -1;
62
- for (const line of lines) {
63
- if (!inDict) {
64
- const m2 = /^(\s*)character_dict:\s*$/.exec(line);
65
- if (m2) {
66
- inDict = true;
67
- dictIndent = m2[1].length;
68
- }
69
- continue;
70
- }
71
- const m = /^(\s*)- (.*)$/.exec(line);
72
- if (m && m[1].length >= dictIndent) {
73
- let v = m[2];
74
- if (v.length >= 2 && (v.startsWith("'") && v.endsWith("'") || v.startsWith('"') && v.endsWith('"'))) {
75
- v = v.slice(1, -1).replace(/''/g, "'");
76
- }
77
- chars.push(v);
78
- continue;
79
- }
80
- if (line.trim() !== "") break;
81
- }
82
- return chars;
83
- }
11
+ } from "./chunk-P6ZDXTV6.js";
84
12
 
85
13
  // src/pdf/line-extract.ts
86
14
  import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
@@ -1085,6 +1013,12 @@ function dropInsetClipGrids(clipGrids, lineGrids) {
1085
1013
  const near = (a, b) => Math.abs(a - b) <= SHADE_CLIP_TOL;
1086
1014
  return clipGrids.filter((c) => c.clipParent || c.rowYs.length !== 2 || !lineGrids.some((l) => l.rowYs.length >= 3 && near(c.bbox.x1, l.bbox.x1) && near(c.bbox.x2, l.bbox.x2) && l.rowYs.some((top, r) => r + 1 < l.rowYs.length && top - c.bbox.y2 >= INSET_CLIP_MIN && c.bbox.y1 - l.rowYs[r + 1] >= INSET_CLIP_MIN)));
1087
1015
  }
1016
+ function dropHeadBandClipGrids(clipGrids, lineGrids) {
1017
+ if (clipGrids.length === 0 || lineGrids.length === 0) return clipGrids;
1018
+ const near = (a, b) => Math.abs(a - b) <= SHADE_CLIP_TOL;
1019
+ const overlaps = (a, b) => Math.min(a.x2, b.x2) > Math.max(a.x1, b.x1) && Math.min(a.y2, b.y2) > Math.max(a.y1, b.y1);
1020
+ return clipGrids.filter((c) => c.clipParent || !c.cells?.length || !lineGrids.some((l) => l.rowYs.length > c.rowYs.length && l.colXs.length === c.colXs.length && c.colXs.every((x, k) => near(x, l.colXs[k])) && c.rowYs.every((y, k) => near(y, l.rowYs[k])) && !clipGrids.some((o) => o !== c && overlaps(o.bbox, l.bbox))));
1021
+ }
1088
1022
  function enforceMinWidth(colXs, minWidth) {
1089
1023
  if (colXs.length <= 2) return colXs;
1090
1024
  const result = [colXs[0]];
@@ -1921,6 +1855,60 @@ function hasHorizontalLine(horizontals, y, leftX, rightX, vertexRadius) {
1921
1855
  return false;
1922
1856
  }
1923
1857
 
1858
+ // src/pdf/script-items.ts
1859
+ function scriptKindsOfLine(sorted) {
1860
+ const kinds = sorted.map(() => null);
1861
+ if (sorted.length < 2) return kinds;
1862
+ const weight = /* @__PURE__ */ new Map();
1863
+ for (const it of sorted) {
1864
+ const k = Math.round(it.fontSize * 2) / 2;
1865
+ weight.set(k, (weight.get(k) ?? 0) + it.text.trim().length);
1866
+ }
1867
+ let bodyFs = 0, best = -1;
1868
+ for (const [fs, n] of weight) if (n > best || n === best && fs > bodyFs) {
1869
+ best = n;
1870
+ bodyFs = fs;
1871
+ }
1872
+ if (bodyFs <= 0) return kinds;
1873
+ const ys = sorted.filter((it) => Math.abs(it.fontSize - bodyFs) <= bodyFs * 0.12).map((it) => it.y).sort((a, b) => a - b);
1874
+ const bodyY = ys[ys.length >> 1];
1875
+ const isBody = (it) => it.fontSize > bodyFs * 0.85;
1876
+ for (let i = 1; i < sorted.length; i++) {
1877
+ const it = sorted[i], prev = sorted[i - 1];
1878
+ const t = it.text.trim();
1879
+ if (!t || t.length > 16 || isBody(it)) continue;
1880
+ if (!isBody(prev) && !kinds[i - 1]) continue;
1881
+ const gap = it.x - (prev.x + prev.w);
1882
+ if (gap > bodyFs * 0.35 || gap < -bodyFs * 0.5) continue;
1883
+ const dy = it.y - bodyY;
1884
+ if (dy >= bodyFs * 0.15) kinds[i] = "sup";
1885
+ else if (dy <= -bodyFs * 0.08) kinds[i] = "sub";
1886
+ }
1887
+ return kinds;
1888
+ }
1889
+ function tagScripts(text, lines) {
1890
+ const marks = [];
1891
+ let cursor = 0;
1892
+ for (const line of lines) {
1893
+ const kinds = scriptKindsOfLine(line);
1894
+ for (let k = 0; k < line.length; k++) {
1895
+ const t = line[k].text;
1896
+ if (!t) continue;
1897
+ const at = text.indexOf(t, cursor);
1898
+ if (at < 0 || /\S/.test(text.slice(cursor, at))) return text;
1899
+ if (kinds[k]) marks.push([at, at + t.length, kinds[k]]);
1900
+ cursor = at + t.length;
1901
+ }
1902
+ }
1903
+ if (!marks.length) return text;
1904
+ let out = text;
1905
+ for (let m = marks.length - 1; m >= 0; m--) {
1906
+ const [s, e, kind] = marks[m];
1907
+ out = out.slice(0, s) + `<${kind}>` + out.slice(s, e) + `</${kind}>` + out.slice(e);
1908
+ }
1909
+ return tidyScriptTags(out);
1910
+ }
1911
+
1924
1912
  // src/pdf/line-wrap.ts
1925
1913
  var MARKUP = /<\/?u>|~~/g;
1926
1914
  var bump = (m, k) => {
@@ -1970,6 +1958,13 @@ var WrapLexicon = class {
1970
1958
  joinedWord(left, right) {
1971
1959
  return this.isWord(left + right) && !this.pairs.has(left + " " + right);
1972
1960
  }
1961
+ /** 두 글자+두 글자 증거만 — 한 글자 쌍으로 물러서지 않는다 (표 칸 조각처럼 줄 꺾임이 아닌 자리에 쓸 때) */
1962
+ evidence2(left, right) {
1963
+ const n = left.length;
1964
+ if (n < 2 || right.length < 2) return null;
1965
+ const k1 = pairKey(left.charCodeAt(n - 2), left.charCodeAt(n - 1)), k2 = pairKey(right.charCodeAt(0), right.charCodeAt(1));
1966
+ return decideCounts(this.joined2.get(k1)?.get(k2) ?? 0, this.spaced2.get(k1)?.get(k2) ?? 0);
1967
+ }
1973
1968
  /** 꺾인 자리 증거: "" 붙음 · " " 띄움 · null 모름 (두 글자 증거가 갈리거나 없으면 한 글자) */
1974
1969
  evidence(left, right) {
1975
1970
  const n = left.length;
@@ -2128,6 +2123,7 @@ function cellLineFills(box, contentLeft, cellRight, lineRight, fontSize) {
2128
2123
  }
2129
2124
 
2130
2125
  // src/pdf/cell-text.ts
2126
+ var REGION_LABELS = /* @__PURE__ */ new Set(["\uC11C\uC6B8", "\uBD80\uC0B0", "\uB300\uAD6C", "\uC778\uCC9C", "\uAD11\uC8FC", "\uB300\uC804", "\uC6B8\uC0B0", "\uC138\uC885", "\uACBD\uAE30", "\uAC15\uC6D0", "\uCDA9\uBD81", "\uCDA9\uB0A8", "\uC804\uBD81", "\uC804\uB0A8", "\uACBD\uBD81", "\uACBD\uB0A8", "\uC81C\uC8FC", "\uC804\uAD6D"]);
2131
2127
  var CELL_PADDING = 2;
2132
2128
  var SPACE_GAP_RATIO = 0.17;
2133
2129
  function spaceGapThreshold(fontSize) {
@@ -2222,8 +2218,8 @@ function cellTextToString(items, wrap) {
2222
2218
  const textLines = merged.map((line) => {
2223
2219
  const s = sortLineByX(line);
2224
2220
  if (s.length === 1) return s[0].text;
2225
- if (s.length === 2 && /^[가-힣]$/.test(s[0].text) && /^[가-힣]$/.test(s[1].text) && !!wrap?.lex && (wrap.lex.isWord(s[0].text + s[1].text) || wrap.lex.evidence(s[0].text, s[1].text) === "") && s[1].x - (s[0].x + s[0].w) >= Math.max(s[0].fontSize, s[1].fontSize) * 1.5 && s[1].x + s[1].w - s[0].x >= wrap.box.x2 - wrap.box.x1 - Math.max(s[0].fontSize, s[1].fontSize) * 2) return s[0].text + s[1].text;
2226
- const evenSpaced = detectEvenSpacedItems(s);
2221
+ if (s.length === 2 && /^[가-힣]$/.test(s[0].text) && /^[가-힣]$/.test(s[1].text) && !!wrap?.lex && (wrap.lex.isWord(s[0].text + s[1].text) || wrap.lex.evidence(s[0].text, s[1].text) === "" || REGION_LABELS.has(s[0].text + s[1].text)) && s[1].x - (s[0].x + s[0].w) >= Math.max(s[0].fontSize, s[1].fontSize) * 1.5 && s[1].x + s[1].w - s[0].x >= wrap.box.x2 - wrap.box.x1 - Math.max(s[0].fontSize, s[1].fontSize) * 2) return s[0].text + s[1].text;
2222
+ const evenSpaced = detectEvenSpacedItems(s, true);
2227
2223
  let result = s[0].text;
2228
2224
  for (let j = 1; j < s.length; j++) {
2229
2225
  if (evenSpaced[j]) {
@@ -2244,7 +2240,8 @@ function cellTextToString(items, wrap) {
2244
2240
  }
2245
2241
  return result;
2246
2242
  });
2247
- if (!wrap) return mergeCellTextLines(textLines);
2243
+ const scripted = (s) => tagScripts(s, merged.map((l) => sortLineByX([...l])));
2244
+ if (!wrap) return scripted(mergeCellTextLines(textLines));
2248
2245
  let contentLeft = Infinity;
2249
2246
  for (const it of items) if (it.x < contentLeft) contentLeft = it.x;
2250
2247
  const lineEnds = merged.map((line) => {
@@ -2257,7 +2254,7 @@ function cellTextToString(items, wrap) {
2257
2254
  let cellRight = -Infinity;
2258
2255
  for (const e of lineEnds) if (e.right > cellRight) cellRight = e.right;
2259
2256
  const wraps = lineEnds.slice(0, -1).map((a, i) => cellLineWraps(wrap.box, contentLeft, a.right, a.fontSize, lineEnds[i + 1].firstCharW) || lineEnds.length >= 3 && !textLines[i + 1].startsWith("(") && cellLineFills(wrap.box, contentLeft, cellRight, a.right, a.fontSize));
2260
- return mergeCellTextLines(textLines, { wraps, lex: wrap.lex });
2257
+ return scripted(mergeCellTextLines(textLines, { wraps, lex: wrap.lex }));
2261
2258
  }
2262
2259
  function mergeSuperscriptRows(lines) {
2263
2260
  if (lines.length <= 1) return lines;
@@ -2293,9 +2290,13 @@ function mergeSuperscriptRows(lines) {
2293
2290
  }
2294
2291
  return result;
2295
2292
  }
2296
- function detectEvenSpacedItems(items) {
2293
+ function detectEvenSpacedItems(items, cellLine = false) {
2297
2294
  const result = new Array(items.length).fill(false);
2298
2295
  if (items.length < 3) return result;
2296
+ if (cellLine && items.every((it) => /^[가-힣]$/.test(it.text)) && items.slice(1).every((it) => !it.hasSpaceBefore || it.syntheticSpace) && items.slice(1).every((it, k) => it.x - (items[k].x + items[k].w) >= it.fontSize * 0.1)) {
2297
+ markEvenRun(items, result, 0, items.length);
2298
+ if (result.some(Boolean)) return result;
2299
+ }
2299
2300
  let runStart = -1;
2300
2301
  for (let i = 0; i < items.length; i++) {
2301
2302
  const isShortKorean = /^[가-힣]{1}$/.test(items[i].text) || /^[\d]{1}$/.test(items[i].text);
@@ -2602,7 +2603,7 @@ function normalizeItems(rawItems) {
2602
2603
  const x = Math.round(i.transform[4]);
2603
2604
  const y = Math.round(i.transform[5]);
2604
2605
  if (!i.str.trim()) {
2605
- spacePositions.push({ x, y });
2606
+ spacePositions.push({ x, y, synthetic: i.synthetic });
2606
2607
  continue;
2607
2608
  }
2608
2609
  const scaleX = Math.hypot(i.transform[0], i.transform[1]);
@@ -2658,7 +2659,10 @@ function normalizeItems(rawItems) {
2658
2659
  nearest = item;
2659
2660
  }
2660
2661
  }
2661
- if (nearest) nearest.hasSpaceBefore = true;
2662
+ if (nearest) {
2663
+ nearest.syntheticSpace = (nearest.hasSpaceBefore ? nearest.syntheticSpace === true : true) && sp.synthetic === true;
2664
+ nearest.hasSpaceBefore = true;
2665
+ }
2662
2666
  }
2663
2667
  }
2664
2668
  return deduped;
@@ -2801,6 +2805,13 @@ function mergeSuperscriptLines(lines) {
2801
2805
  for (const i of line) total += i.text.trim().length;
2802
2806
  return total > 0 && total <= 10;
2803
2807
  };
2808
+ const isMarkers = (line, host) => line.length > 1 && line.length <= 16 && line.every((i) => {
2809
+ if (i.text.trim().length > 3 || !i.text.trim()) return false;
2810
+ return host.some((h) => {
2811
+ const g = i.x - (h.x + h.w);
2812
+ return g <= h.fontSize * 0.35 && g >= -h.fontSize * 0.1;
2813
+ });
2814
+ });
2804
2815
  const result = [lines[0]];
2805
2816
  for (let i = 1; i < lines.length; i++) {
2806
2817
  const prev = result[result.length - 1];
@@ -2808,8 +2819,8 @@ function mergeSuperscriptLines(lines) {
2808
2819
  const a = band(prev);
2809
2820
  const b = band(curr);
2810
2821
  const overlap2 = Math.min(a.top, b.top) - Math.max(a.bottom, b.bottom);
2811
- const prevIsFrag = isFrag(prev) && a.height <= b.height * 0.8 && overlap2 >= a.height * 0.5;
2812
- const currIsFrag = isFrag(curr) && b.height <= a.height * 0.8 && overlap2 >= b.height * 0.5;
2822
+ const prevIsFrag = (isFrag(prev) || isMarkers(prev, curr)) && a.height <= b.height * 0.8 && overlap2 >= a.height * 0.5;
2823
+ const currIsFrag = (isFrag(curr) || isMarkers(curr, prev)) && b.height <= a.height * 0.8 && overlap2 >= b.height * 0.5;
2813
2824
  if (prevIsFrag || currIsFrag) {
2814
2825
  result[result.length - 1] = [...prev, ...curr];
2815
2826
  } else {
@@ -3007,10 +3018,13 @@ function pushLineParagraphs(out, yLines, pageNum, lex) {
3007
3018
  for (let i = 0; i < lines.length; ) {
3008
3019
  let text = lines[i].text;
3009
3020
  const items = [...lines[i].items];
3021
+ const srcLines = [lines[i].items];
3010
3022
  for (; i + 1 < lines.length && joins[i] !== "\n"; i++) {
3011
3023
  text += joins[i] + lines[i + 1].text;
3012
3024
  items.push(...lines[i + 1].items);
3025
+ srcLines.push(lines[i + 1].items);
3013
3026
  }
3027
+ text = tagScripts(text, srcLines.map((l) => sortLineByX([...l])));
3014
3028
  const block = { type: "paragraph", text, pageNumber: pageNum, bbox: computeBBox(items, pageNum), style: dominantStyle(items) };
3015
3029
  const faces = /* @__PURE__ */ new Map();
3016
3030
  for (const it of items) faces.set(it.fontName, (faces.get(it.fontName) ?? 0) + it.text.length);
@@ -3593,21 +3607,23 @@ function detectSpecialKoreanTables(blocks) {
3593
3607
  flushKvTable();
3594
3608
  return result;
3595
3609
  }
3596
- function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
3610
+ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables = false) {
3597
3611
  const ZONE_RATIO = 0.12;
3598
3612
  const MIN_REPEAT = 3;
3599
3613
  const topEntries = [];
3600
3614
  const bottomEntries = [];
3601
3615
  for (let bi = 0; bi < blocks.length; bi++) {
3602
3616
  const b = blocks[bi];
3603
- if (!b.bbox || !b.pageNumber || !b.text?.trim()) continue;
3617
+ const text = !tables ? b.text?.trim() : b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text.trim()).filter(Boolean).join(" | ") : void 0;
3618
+ if (!b.bbox || !b.pageNumber || !text) continue;
3604
3619
  const ph = pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber);
3605
3620
  if (!ph) continue;
3606
3621
  const blockTop = ph - (b.bbox.y + b.bbox.height);
3607
3622
  const blockBottom = ph - b.bbox.y;
3608
- const entry = { blockIdx: bi, page: b.pageNumber, text: b.text.trim() };
3609
- if (blockBottom <= ph * ZONE_RATIO) topEntries.push(entry);
3610
- else if (blockTop >= ph * (1 - ZONE_RATIO)) bottomEntries.push(entry);
3623
+ const entry = { blockIdx: bi, page: b.pageNumber, text };
3624
+ const boxMid = b.type === "table" && b.bbox.height <= ph * 0.05 ? (blockTop + blockBottom) / 2 : void 0;
3625
+ if ((boxMid ?? blockBottom) <= ph * ZONE_RATIO) topEntries.push(entry);
3626
+ else if ((boxMid ?? blockTop) >= ph * (1 - ZONE_RATIO)) bottomEntries.push(entry);
3611
3627
  }
3612
3628
  const removeSet = /* @__PURE__ */ new Set();
3613
3629
  for (const entries of [topEntries, bottomEntries]) {
@@ -3629,7 +3645,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
3629
3645
  for (const [p, count] of patternCount) {
3630
3646
  const pages = [...patternPages.get(p) ?? []];
3631
3647
  const span = pages.length ? Math.max(...pages) - Math.min(...pages) + 1 : 0;
3632
- const pageNumbered = (patternNumbers.get(p)?.size ?? 0) > 1;
3648
+ const pageNumbered = !tables && (patternNumbers.get(p)?.size ?? 0) > 1;
3633
3649
  if (count >= MIN_REPEAT && pages.length >= MIN_REPEAT && (pages.length >= span * 0.4 || pageNumbered)) {
3634
3650
  repeatedPatterns.add(p);
3635
3651
  }
@@ -3637,9 +3653,11 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
3637
3653
  for (const e of entries) {
3638
3654
  const norm = e.text.replace(/\d+/g, "#");
3639
3655
  if (!repeatedPatterns.has(norm)) continue;
3656
+ const noteMark = e.text.match(/^\d{1,3}\)/)?.[0];
3657
+ if (noteMark && notes?.get(e.page)?.marks.some((m) => m.mark === noteMark)) continue;
3640
3658
  const cand = blocks[e.blockIdx];
3641
3659
  const cb = cand.bbox;
3642
- const tableNote = /^(?:주\s*(?:\d+\s*[).:]|[::])|(?:자료|출처)\s*[::])/.test(e.text) && blocks.some((o) => {
3660
+ const tableNote = /^(?:주\s*(?:\d+\s*[).:]|[::])|(?:자료|출처)\s*[::])/.test(e.text.replace(/ \| /g, " ")) && blocks.some((o) => {
3643
3661
  if (o.type !== "table" || !o.bbox || o.bbox.page !== cb.page) return false;
3644
3662
  const gap = o.bbox.y - (cb.y + cb.height);
3645
3663
  return gap >= 0 && gap <= cb.height && cb.x >= o.bbox.x && cb.x + cb.width <= o.bbox.x + o.bbox.width;
@@ -5868,17 +5886,23 @@ function splitTwoColumnProse(items, cutX) {
5868
5886
  if (last && Math.abs(last[0].y - c.y) <= 3) last.push(c);
5869
5887
  else crossLines.push([c]);
5870
5888
  }
5871
- const bandItem = (arr) => arr.filter((i) => {
5889
+ const scriptOf = (i, cl) => {
5890
+ const fs = cl[0].fontSize, dy = i.y - cl[0].y;
5891
+ if (i.fontSize > fs * 0.85 || dy > fs * 0.6 || dy < -fs * 0.35) return false;
5892
+ return cl.some((c) => c !== i && c.fontSize > fs * 0.85 && i.x - (c.x + c.w) <= fs * 0.35 && i.x - (c.x + c.w) >= -fs * 0.1);
5893
+ };
5894
+ const bandItem = (arr, fits) => arr.filter((i) => {
5872
5895
  for (const cl of crossLines) {
5873
- if (Math.abs(cl[0].y - i.y) <= 3) {
5896
+ if (fits(i, cl)) {
5874
5897
  cl.push(i);
5875
5898
  return false;
5876
5899
  }
5877
5900
  }
5878
5901
  return true;
5879
5902
  });
5880
- const leftRest = bandItem(left);
5881
- const rightRest = bandItem(right);
5903
+ const sameY = (i, cl) => Math.abs(cl[0].y - i.y) <= 3;
5904
+ const leftRest = bandItem(bandItem(left, sameY), scriptOf);
5905
+ const rightRest = bandItem(bandItem(right, sameY), scriptOf);
5882
5906
  const boundYs = crossLines.map((cl) => cl[0].y);
5883
5907
  const bandOf = (y) => {
5884
5908
  let k = 0;
@@ -5890,7 +5914,7 @@ function splitTwoColumnProse(items, cutX) {
5890
5914
  const L = leftRest.filter((i) => bandOf(i.y) === k);
5891
5915
  const R = rightRest.filter((i) => bandOf(i.y) === k);
5892
5916
  groups.push(...columnPair(L, R));
5893
- if (k < crossLines.length) groups.push(crossLines[k]);
5917
+ if (k < crossLines.length) groups.push(crossLines[k].sort((a, b) => b.y - a.y || a.x - b.x));
5894
5918
  }
5895
5919
  return groups;
5896
5920
  }
@@ -5965,7 +5989,8 @@ function topTableBand(items) {
5965
5989
  h: i.h,
5966
5990
  fontSize: i.fontSize,
5967
5991
  fontName: i.fontName,
5968
- hasSpaceBefore: i.hasSpaceBefore
5992
+ hasSpaceBefore: i.hasSpaceBefore,
5993
+ syntheticSpace: i.syntheticSpace
5969
5994
  })), 1);
5970
5995
  if (!candidate.some((t) => t.table.cols >= 3 && t.table.rows >= 3 && t.usedItems.size >= top.length * 0.75)) continue;
5971
5996
  return { top, rest: lines.slice(n).flat() };
@@ -6211,7 +6236,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6211
6236
  if (underlines.size) horizontals = horizontals.filter((l) => !underlines.has(l));
6212
6237
  wrapUnderlineRuns(items);
6213
6238
  const lineGrids = detectTables ? buildTableGrids(horizontals, verticals) : [];
6214
- const tableClipGrids = dropInsetClipGrids(dropShadingClipGrids(clipGrids, lineGrids, extracted.fillRects, verticals), lineGrids);
6239
+ const tableClipGrids = dropHeadBandClipGrids(dropInsetClipGrids(dropShadingClipGrids(clipGrids, lineGrids, extracted.fillRects, verticals), lineGrids), lineGrids);
6215
6240
  const grids = [...tableClipGrids, ...dropGridsInside(lineGrids, tableClipGrids, clipResult.containers)];
6216
6241
  if (grids.length === 1 && grids[0].rowYs.length === 2 && grids[0].colXs.length === 2 && grids[0].bbox.x2 - grids[0].bbox.x1 > pageWidth * 1.2 && grids[0].bbox.y2 - grids[0].bbox.y1 > pageHeight * 1.2) {
6217
6242
  return extractPageBlocksFallback(items, pageNum, true, detectTables, lex);
@@ -6415,6 +6440,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6415
6440
  fontSize: i.fontSize,
6416
6441
  fontName: i.fontName,
6417
6442
  hasSpaceBefore: i.hasSpaceBefore,
6443
+ syntheticSpace: i.syntheticSpace,
6418
6444
  seq: i.seq
6419
6445
  }));
6420
6446
  const cellTextMap = mapTextToCells(textItems, cells);
@@ -6527,6 +6553,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6527
6553
  fontSize: i.fontSize,
6528
6554
  fontName: i.fontName,
6529
6555
  hasSpaceBefore: i.hasSpaceBefore,
6556
+ syntheticSpace: i.syntheticSpace,
6530
6557
  seq: i.seq
6531
6558
  })))), colSpan: 1, rowSpan: 1 })));
6532
6559
  finalRows++;
@@ -6623,7 +6650,8 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6623
6650
  h: i.h,
6624
6651
  fontSize: i.fontSize,
6625
6652
  fontName: i.fontName,
6626
- hasSpaceBefore: i.hasSpaceBefore
6653
+ hasSpaceBefore: i.hasSpaceBefore,
6654
+ syntheticSpace: i.syntheticSpace
6627
6655
  }));
6628
6656
  const proseColumns = findTwoColumnProseCutX(clusterItems) !== null || detectPersistentColumnGutter(remaining.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }))) !== null;
6629
6657
  const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum)).filter((cr) => {
@@ -6937,7 +6965,8 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
6937
6965
  h: i.h,
6938
6966
  fontSize: i.fontSize,
6939
6967
  fontName: i.fontName,
6940
- hasSpaceBefore: i.hasSpaceBefore
6968
+ hasSpaceBefore: i.hasSpaceBefore,
6969
+ syntheticSpace: i.syntheticSpace
6941
6970
  }));
6942
6971
  const textRects = items.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }));
6943
6972
  const earlyProseCut = fullPage && detectTables ? findTwoColumnProseCutX(clusterItems) ?? persistentGutter(textRects) ?? (figures.length > 0 ? detectColumnGutter([...textRects, ...figures]) : null) : null;
@@ -7016,19 +7045,13 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
7016
7045
  }
7017
7046
 
7018
7047
  export {
7019
- OCR_DET_MODEL,
7020
- OCR_REC_MODEL,
7021
- OCR_REC_DICT,
7022
- getOcrModelsDir,
7023
- ensureOcrModels,
7024
- ocrModelsCached,
7025
- parseCharacterDict,
7026
7048
  extractLines,
7027
7049
  extractImageRegions,
7028
7050
  filterHiddenText,
7029
7051
  collapseEvenSpacing,
7030
7052
  normalizeItems,
7031
7053
  WrapLexicon,
7054
+ startsNewItem,
7032
7055
  wrapJoiner,
7033
7056
  joinPageBreakWraps,
7034
7057
  latinSoftWrap,
@@ -7056,4 +7079,4 @@ export {
7056
7079
  trimTrailingEmptyTableCols,
7057
7080
  extractPageBlocksWithLines
7058
7081
  };
7059
- //# sourceMappingURL=chunk-HIVK5V27.js.map
7082
+ //# sourceMappingURL=chunk-SFEQYKYJ.js.map