kordoc 4.18.1 → 4.18.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 (144) hide show
  1. package/README.md +7 -6
  2. package/dist/{-X4KTLQC6.js → -I3CP33G4.js} +13 -11
  3. package/dist/{chunk-NQR3VKWN.js → chunk-4B2EXELH.js} +2 -2
  4. package/dist/{chunk-SQQ4ITJ5.js → chunk-6OKBTY72.js} +2 -2
  5. package/dist/{chunk-HUGBJVAA.js → chunk-B2E6C2LH.js} +12 -7
  6. package/dist/chunk-B2E6C2LH.js.map +1 -0
  7. package/dist/{chunk-X625PCZM.js → chunk-BL7KRE6X.js} +3 -3
  8. package/dist/{chunk-5PNQIF3V.js → chunk-C2CVOC5K.js} +4 -4
  9. package/dist/{chunk-AQUNBGXH.js → chunk-CKUIFTXJ.js} +2 -2
  10. package/dist/{chunk-TMC4A3FM.js → chunk-F5HING4Y.js} +10 -5
  11. package/dist/chunk-F5HING4Y.js.map +1 -0
  12. package/dist/{chunk-PWRY4W6Q.js → chunk-GM7XIZF2.js} +2 -2
  13. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  14. package/dist/{chunk-K35WIYBD.js → chunk-IA3UKDHA.js} +4 -4
  15. package/dist/chunk-IA3UKDHA.js.map +1 -0
  16. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  17. package/dist/{chunk-7DC2KL3V.cjs → chunk-KDMAYOWH.cjs} +158 -43
  18. package/dist/chunk-KDMAYOWH.cjs.map +1 -0
  19. package/dist/{chunk-Z4KCEERM.js → chunk-L5RLJPI3.js} +3 -3
  20. package/dist/{chunk-WWOTHS2E.js → chunk-L64QRUMK.js} +202 -7
  21. package/dist/chunk-L64QRUMK.js.map +1 -0
  22. package/dist/{chunk-6N5BOPJI.js → chunk-LACO375L.js} +2 -2
  23. package/dist/{chunk-KXR4CTFT.js → chunk-LSOD2A6N.js} +2 -2
  24. package/dist/{chunk-UTVMLJZE.js → chunk-M4P7YS2N.js} +389 -57
  25. package/dist/chunk-M4P7YS2N.js.map +1 -0
  26. package/dist/{chunk-VDIXNEWV.js → chunk-N5DQFA7L.js} +2 -2
  27. package/dist/{chunk-R2IFWAHI.js → chunk-NZM2SSI4.js} +2 -2
  28. package/dist/{chunk-KBZ3MQJX.js → chunk-O2DI4GHD.js} +2 -2
  29. package/dist/{chunk-I7YWXECO.js → chunk-OBILAVWC.js} +2 -2
  30. package/dist/{chunk-6V7QRQY3.js → chunk-OGAYGUJF.js} +122 -87
  31. package/dist/chunk-OGAYGUJF.js.map +1 -0
  32. package/dist/{chunk-IUMV45TX.cjs → chunk-OI5ZSSIC.cjs} +12 -12
  33. package/dist/chunk-OI5ZSSIC.cjs.map +1 -0
  34. package/dist/{chunk-Q5N4YS3T.cjs → chunk-QGFZU3JE.cjs} +16 -11
  35. package/dist/chunk-QGFZU3JE.cjs.map +1 -0
  36. package/dist/{chunk-2VFZQ634.js → chunk-QP7IXF7R.js} +2 -2
  37. package/dist/{chunk-CWJ5KY2F.js → chunk-T4MXCSBP.js} +137 -27
  38. package/dist/chunk-T4MXCSBP.js.map +1 -0
  39. package/dist/{chunk-PCSOJ523.cjs → chunk-UZGZRGYM.cjs} +2 -2
  40. package/dist/chunk-UZGZRGYM.cjs.map +1 -0
  41. package/dist/{chunk-MTTYJEKA.js → chunk-VSY5PAJ5.js} +2 -2
  42. package/dist/{chunk-IXAXI2S3.cjs → chunk-W2YYBPW5.cjs} +3 -3
  43. package/dist/chunk-W2YYBPW5.cjs.map +1 -0
  44. package/dist/{chunk-SIZ63E5G.cjs → chunk-YNLW6EGU.cjs} +3 -3
  45. package/dist/chunk-YNLW6EGU.cjs.map +1 -0
  46. package/dist/chunks-IFFRC5IQ.js +10 -0
  47. package/dist/cli.js +26 -26
  48. package/dist/{formula-LICM6K27.js → formula-AQZODKZF.js} +3 -3
  49. package/dist/{formula-T4Q2UHWO.js → formula-E3N7KDDG.js} +4 -4
  50. package/dist/{formula-W3GQC6L6.cjs → formula-VY4ITOMN.cjs} +9 -9
  51. package/dist/formula-VY4ITOMN.cjs.map +1 -0
  52. package/dist/{image-ocr-7PNHBD2G.cjs → image-ocr-6LYEBMVR.cjs} +15 -15
  53. package/dist/image-ocr-6LYEBMVR.cjs.map +1 -0
  54. package/dist/{image-ocr-WZJURDX6.js → image-ocr-IMYXOHHV.js} +6 -6
  55. package/dist/{image-ocr-XB2NFKGZ.js → image-ocr-LN3GSQPW.js} +9 -9
  56. package/dist/index.cjs +1037 -603
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.cts +7 -5
  59. package/dist/index.d.ts +7 -5
  60. package/dist/index.js +523 -89
  61. package/dist/index.js.map +1 -1
  62. package/dist/mcp.js +26 -27
  63. package/dist/mcp.js.map +1 -1
  64. package/dist/{model-bundle-O2XYR54X.js → model-bundle-IHKNDLOT.js} +5 -5
  65. package/dist/{models-SKK3NH3V.js → models-YXITRAMR.js} +5 -5
  66. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  67. package/dist/{parser-PJUZSMFR.cjs → parser-7KECZTTP.cjs} +176 -228
  68. package/dist/parser-7KECZTTP.cjs.map +1 -0
  69. package/dist/{parser-4D2M5BKY.js → parser-KB4BYQBZ.js} +14 -66
  70. package/dist/parser-KB4BYQBZ.js.map +1 -0
  71. package/dist/{parser-5G5G7HHG.js → parser-M3T2EWUN.js} +11 -63
  72. package/dist/parser-M3T2EWUN.js.map +1 -0
  73. package/dist/pdf-ocr-4S2OAHUX.js +15 -0
  74. package/dist/pdf-ocr-IGYCZ7G2.cjs +16 -0
  75. package/dist/pdf-ocr-IGYCZ7G2.cjs.map +1 -0
  76. package/dist/pdf-ocr-YEBFWU2K.js +19 -0
  77. package/dist/{profile-io-BAQTYPK7.js → profile-io-GQWQR7YQ.js} +3 -3
  78. package/dist/{rasterize-A2ZEACKV.js → rasterize-Y6TVFQ3M.js} +3 -3
  79. package/dist/{redact-doc-26KN2LSZ.js → redact-doc-TRPZ3HNW.js} +11 -11
  80. package/dist/{render-62ZUDMHB.js → render-GHT5HKBO.js} +7 -7
  81. package/dist/seal-3YTXSABW.js +10 -0
  82. package/dist/{setup-2A3E6WRE.js → setup-AGSCEHDB.js} +3 -3
  83. package/dist/visual-R3E35Q2K.js +20 -0
  84. package/dist/{watch-D2T5FEKT.js → watch-ALSEW4GB.js} +13 -13
  85. package/dist/watch-ALSEW4GB.js.map +1 -0
  86. package/package.json +1 -1
  87. package/dist/chunk-6V7QRQY3.js.map +0 -1
  88. package/dist/chunk-7DC2KL3V.cjs.map +0 -1
  89. package/dist/chunk-CWJ5KY2F.js.map +0 -1
  90. package/dist/chunk-HUGBJVAA.js.map +0 -1
  91. package/dist/chunk-IUMV45TX.cjs.map +0 -1
  92. package/dist/chunk-IXAXI2S3.cjs.map +0 -1
  93. package/dist/chunk-K35WIYBD.js.map +0 -1
  94. package/dist/chunk-PCSOJ523.cjs.map +0 -1
  95. package/dist/chunk-Q5N4YS3T.cjs.map +0 -1
  96. package/dist/chunk-SIZ63E5G.cjs.map +0 -1
  97. package/dist/chunk-TMC4A3FM.js.map +0 -1
  98. package/dist/chunk-UTVMLJZE.js.map +0 -1
  99. package/dist/chunk-WWOTHS2E.js.map +0 -1
  100. package/dist/chunks-ACUC63N3.js +0 -10
  101. package/dist/formula-W3GQC6L6.cjs.map +0 -1
  102. package/dist/image-ocr-7PNHBD2G.cjs.map +0 -1
  103. package/dist/parser-4D2M5BKY.js.map +0 -1
  104. package/dist/parser-5G5G7HHG.js.map +0 -1
  105. package/dist/parser-PJUZSMFR.cjs.map +0 -1
  106. package/dist/pdf-ocr-EGWOIB6O.cjs +0 -16
  107. package/dist/pdf-ocr-EGWOIB6O.cjs.map +0 -1
  108. package/dist/pdf-ocr-NJTFXBRC.js +0 -19
  109. package/dist/pdf-ocr-ZXR6Q6BK.js +0 -15
  110. package/dist/seal-3GXC2API.js +0 -10
  111. package/dist/visual-4ZBZRMCM.js +0 -20
  112. package/dist/watch-D2T5FEKT.js.map +0 -1
  113. /package/dist/{-X4KTLQC6.js.map → -I3CP33G4.js.map} +0 -0
  114. /package/dist/{chunk-NQR3VKWN.js.map → chunk-4B2EXELH.js.map} +0 -0
  115. /package/dist/{chunk-SQQ4ITJ5.js.map → chunk-6OKBTY72.js.map} +0 -0
  116. /package/dist/{chunk-X625PCZM.js.map → chunk-BL7KRE6X.js.map} +0 -0
  117. /package/dist/{chunk-5PNQIF3V.js.map → chunk-C2CVOC5K.js.map} +0 -0
  118. /package/dist/{chunk-AQUNBGXH.js.map → chunk-CKUIFTXJ.js.map} +0 -0
  119. /package/dist/{chunk-PWRY4W6Q.js.map → chunk-GM7XIZF2.js.map} +0 -0
  120. /package/dist/{chunk-Z4KCEERM.js.map → chunk-L5RLJPI3.js.map} +0 -0
  121. /package/dist/{chunk-6N5BOPJI.js.map → chunk-LACO375L.js.map} +0 -0
  122. /package/dist/{chunk-KXR4CTFT.js.map → chunk-LSOD2A6N.js.map} +0 -0
  123. /package/dist/{chunk-VDIXNEWV.js.map → chunk-N5DQFA7L.js.map} +0 -0
  124. /package/dist/{chunk-R2IFWAHI.js.map → chunk-NZM2SSI4.js.map} +0 -0
  125. /package/dist/{chunk-KBZ3MQJX.js.map → chunk-O2DI4GHD.js.map} +0 -0
  126. /package/dist/{chunk-I7YWXECO.js.map → chunk-OBILAVWC.js.map} +0 -0
  127. /package/dist/{chunk-2VFZQ634.js.map → chunk-QP7IXF7R.js.map} +0 -0
  128. /package/dist/{chunk-MTTYJEKA.js.map → chunk-VSY5PAJ5.js.map} +0 -0
  129. /package/dist/{chunks-ACUC63N3.js.map → chunks-IFFRC5IQ.js.map} +0 -0
  130. /package/dist/{formula-LICM6K27.js.map → formula-AQZODKZF.js.map} +0 -0
  131. /package/dist/{formula-T4Q2UHWO.js.map → formula-E3N7KDDG.js.map} +0 -0
  132. /package/dist/{image-ocr-WZJURDX6.js.map → image-ocr-IMYXOHHV.js.map} +0 -0
  133. /package/dist/{image-ocr-XB2NFKGZ.js.map → image-ocr-LN3GSQPW.js.map} +0 -0
  134. /package/dist/{model-bundle-O2XYR54X.js.map → model-bundle-IHKNDLOT.js.map} +0 -0
  135. /package/dist/{models-SKK3NH3V.js.map → models-YXITRAMR.js.map} +0 -0
  136. /package/dist/{pdf-ocr-NJTFXBRC.js.map → pdf-ocr-4S2OAHUX.js.map} +0 -0
  137. /package/dist/{pdf-ocr-ZXR6Q6BK.js.map → pdf-ocr-YEBFWU2K.js.map} +0 -0
  138. /package/dist/{profile-io-BAQTYPK7.js.map → profile-io-GQWQR7YQ.js.map} +0 -0
  139. /package/dist/{rasterize-A2ZEACKV.js.map → rasterize-Y6TVFQ3M.js.map} +0 -0
  140. /package/dist/{redact-doc-26KN2LSZ.js.map → redact-doc-TRPZ3HNW.js.map} +0 -0
  141. /package/dist/{render-62ZUDMHB.js.map → render-GHT5HKBO.js.map} +0 -0
  142. /package/dist/{seal-3GXC2API.js.map → seal-3YTXSABW.js.map} +0 -0
  143. /package/dist/{setup-2A3E6WRE.js.map → setup-AGSCEHDB.js.map} +0 -0
  144. /package/dist/{visual-4ZBZRMCM.js.map → visual-R3E35Q2K.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  // src/utils.ts
2
- var VERSION = true ? "4.18.1" : "0.0.0-dev";
2
+ var VERSION = true ? "4.18.2" : "0.0.0-dev";
3
3
  function toArrayBuffer(buf) {
4
4
  if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
5
5
  return buf.buffer;
@@ -154,4 +154,4 @@ export {
154
154
  OPTIONAL_DEP_INSTALL_HINT,
155
155
  classifyError
156
156
  };
157
- //# sourceMappingURL=chunk-VDIXNEWV.js.map
157
+ //# sourceMappingURL=chunk-N5DQFA7L.js.map
@@ -3,7 +3,7 @@ import {
3
3
  ensureModelsIn,
4
4
  getModelStatusIn,
5
5
  getModelsDir
6
- } from "./chunk-NQR3VKWN.js";
6
+ } from "./chunk-4B2EXELH.js";
7
7
 
8
8
  // src/ocr/models.ts
9
9
  import { join } from "path";
@@ -93,4 +93,4 @@ export {
93
93
  parseCharacterDict,
94
94
  ocrModelPath
95
95
  };
96
- //# sourceMappingURL=chunk-R2IFWAHI.js.map
96
+ //# sourceMappingURL=chunk-NZM2SSI4.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  blocksToMarkdown
3
- } from "./chunk-HUGBJVAA.js";
3
+ } from "./chunk-B2E6C2LH.js";
4
4
 
5
5
  // src/page-markdown.ts
6
6
  function blocksToPages(blocks, render = blocksToMarkdown) {
@@ -167,4 +167,4 @@ export {
167
167
  inlineImagesIntoMarkdown,
168
168
  blocksToPages
169
169
  };
170
- //# sourceMappingURL=chunk-KBZ3MQJX.js.map
170
+ //# sourceMappingURL=chunk-O2DI4GHD.js.map
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/utils.ts
4
4
  import { format } from "util";
5
- var VERSION = true ? "4.18.1" : "0.0.0-dev";
5
+ var VERSION = true ? "4.18.2" : "0.0.0-dev";
6
6
  function toArrayBuffer(buf) {
7
7
  if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
8
8
  return buf.buffer;
@@ -165,4 +165,4 @@ export {
165
165
  OPTIONAL_DEP_INSTALL_HINT,
166
166
  classifyError
167
167
  };
168
- //# sourceMappingURL=chunk-I7YWXECO.js.map
168
+ //# sourceMappingURL=chunk-OBILAVWC.js.map
@@ -1,88 +1,15 @@
1
+ #!/usr/bin/env node
1
2
  import {
2
3
  CELL_EDGES,
3
4
  HEADING_RATIO_H1,
4
5
  HEADING_RATIO_H2,
5
6
  HEADING_RATIO_H3,
6
7
  tidyScriptTags
7
- } from "./chunk-HUGBJVAA.js";
8
- import {
9
- ensureModelsIn,
10
- getModelsDir
11
- } from "./chunk-KXR4CTFT.js";
8
+ } from "./chunk-F5HING4Y.js";
12
9
  import {
13
10
  safeMax,
14
11
  safeMin
15
- } from "./chunk-VDIXNEWV.js";
16
-
17
- // src/ocr/models.ts
18
- import { join } from "path";
19
- import { stat } from "fs/promises";
20
- var OCR_DET_MODEL = {
21
- name: "PP-OCRv5 mobile det",
22
- filename: "det.onnx",
23
- url: "https://huggingface.co/PaddlePaddle/PP-OCRv5_mobile_det_onnx/resolve/main/inference.onnx",
24
- sha256: "a431985659dc921974177a95adcfbb90fd9e51989a5e04d70d0b75f597b6e61d",
25
- sizeMb: 5
26
- };
27
- var OCR_REC_MODEL = {
28
- name: "PP-OCRv5 korean rec",
29
- filename: "rec_korean.onnx",
30
- url: "https://huggingface.co/PaddlePaddle/korean_PP-OCRv5_mobile_rec_onnx/resolve/main/inference.onnx",
31
- sha256: "92f0b7785e64fc9090106a241cf4c1eb97472824558272751b88a2a4476d3a08",
32
- sizeMb: 13
33
- };
34
- var OCR_REC_DICT = {
35
- name: "PP-OCRv5 korean dict",
36
- filename: "rec_korean.yml",
37
- url: "https://huggingface.co/PaddlePaddle/korean_PP-OCRv5_mobile_rec_onnx/resolve/main/inference.yml",
38
- sha256: "f757fa1c40e99edcf27e9cce879b93eb2a51fa46f5ef39095689b8c37dd75998",
39
- sizeMb: 1
40
- };
41
- var ALL_OCR_MODELS = [OCR_DET_MODEL, OCR_REC_MODEL, OCR_REC_DICT];
42
- function getOcrModelsDir() {
43
- return getModelsDir("ppocr");
44
- }
45
- async function ensureOcrModels(onProgress) {
46
- return ensureModelsIn(getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
47
- }
48
- async function ocrModelsCached() {
49
- const dir = getOcrModelsDir();
50
- for (const spec of ALL_OCR_MODELS) {
51
- try {
52
- if (!(await stat(join(dir, spec.filename))).size) return false;
53
- } catch {
54
- return false;
55
- }
56
- }
57
- return true;
58
- }
59
- function parseCharacterDict(yml) {
60
- const lines = yml.split("\n");
61
- const chars = [];
62
- let inDict = false;
63
- let dictIndent = -1;
64
- for (const line of lines) {
65
- if (!inDict) {
66
- const m2 = /^(\s*)character_dict:\s*$/.exec(line);
67
- if (m2) {
68
- inDict = true;
69
- dictIndent = m2[1].length;
70
- }
71
- continue;
72
- }
73
- const m = /^(\s*)- (.*)$/.exec(line);
74
- if (m && m[1].length >= dictIndent) {
75
- let v = m[2];
76
- if (v.length >= 2 && (v.startsWith("'") && v.endsWith("'") || v.startsWith('"') && v.endsWith('"'))) {
77
- v = v.slice(1, -1).replace(/''/g, "'");
78
- }
79
- chars.push(v);
80
- continue;
81
- }
82
- if (line.trim() !== "") break;
83
- }
84
- return chars;
85
- }
12
+ } from "./chunk-OBILAVWC.js";
86
13
 
87
14
  // src/pdf/line-extract.ts
88
15
  import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
@@ -3477,7 +3404,9 @@ function findVerticalCutWithOutlierFilter(items, minGap) {
3477
3404
  const filtered = items.filter((i) => i.w >= narrowThreshold);
3478
3405
  if (filtered.length >= 2 && filtered.length < items.length && filtered.length >= items.length * 0.7) {
3479
3406
  const filteredCut = findVerticalCut(filtered);
3480
- if (filteredCut.gap > edgeCut.gap && filteredCut.gap >= minGap) {
3407
+ const sameRow = (a, b) => Math.abs(a.y - b.y) <= Math.max(a.fontSize, b.fontSize) * 0.5;
3408
+ const inLine = items.some((r) => r.w < narrowThreshold && r.x < filteredCut.position && r.x + r.w > filteredCut.position && filtered.some((o) => sameRow(o, r) && o.x + o.w <= r.x + 1) && filtered.some((o) => sameRow(o, r) && o.x >= r.x + r.w - 1));
3409
+ if (filteredCut.gap > edgeCut.gap && filteredCut.gap >= minGap && !inLine) {
3481
3410
  return filteredCut;
3482
3411
  }
3483
3412
  }
@@ -4197,7 +4126,7 @@ function detectSpecialKoreanTables(blocks) {
4197
4126
  }
4198
4127
  function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables = false) {
4199
4128
  const ZONE_RATIO = 0.12;
4200
- const MIN_REPEAT = 3;
4129
+ const MIN_REPEAT2 = 3;
4201
4130
  const topEntries = [];
4202
4131
  const bottomEntries = [];
4203
4132
  for (let bi = 0; bi < blocks.length; bi++) {
@@ -4234,7 +4163,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
4234
4163
  const pages = [...patternPages.get(p) ?? []];
4235
4164
  const span = pages.length ? Math.max(...pages) - Math.min(...pages) + 1 : 0;
4236
4165
  const pageNumbered = !tables && (patternNumbers.get(p)?.size ?? 0) > 1;
4237
- if (count >= MIN_REPEAT && pages.length >= MIN_REPEAT && (pages.length >= span * 0.4 || pageNumbered)) {
4166
+ if (count >= MIN_REPEAT2 && pages.length >= MIN_REPEAT2 && (pages.length >= span * 0.4 || pageNumbered)) {
4238
4167
  repeatedPatterns.add(p);
4239
4168
  }
4240
4169
  }
@@ -4382,6 +4311,78 @@ function mergeSliverColumns(grid, colXs, maxWidth) {
4382
4311
  return merged;
4383
4312
  }
4384
4313
 
4314
+ // src/pdf/side-tabs.ts
4315
+ var BAND = 0.12;
4316
+ var MAX_CHARS = 10;
4317
+ var MIN_REPEAT = 3;
4318
+ var RUN_GAP = 5;
4319
+ var TAB_CELL_CHARS = 24;
4320
+ var TAB_MIN_HEIGHT = 0.3;
4321
+ var SIDE_TAB_TABLES = /* @__PURE__ */ new WeakSet();
4322
+ function isSideTabTable(box, table, others, pageWidth, pageHeight) {
4323
+ if (table.cols !== 1 || box.x2 - box.x1 > pageWidth * BAND || box.y2 - box.y1 < pageHeight * TAB_MIN_HEIGHT) return false;
4324
+ const side = box.x1 >= pageWidth * (1 - BAND) ? "R" : box.x2 <= pageWidth * BAND ? "L" : null;
4325
+ if (!side) return false;
4326
+ const texts = table.cells.flat().map((c) => c.text.replace(/\s+/g, ""));
4327
+ if (!texts.some(Boolean) || texts.some((t) => [...t].length > TAB_CELL_CHARS)) return false;
4328
+ return others.every((it) => it.y < box.y1 || it.y > box.y2 || (side === "R" ? it.x + it.w <= box.x1 + 1 : it.x >= box.x2 - 1));
4329
+ }
4330
+ function removeSideTabs(blocks, pageWidths) {
4331
+ const edges = /* @__PURE__ */ new Map();
4332
+ for (const b of blocks) {
4333
+ if (!b.bbox || b.pageNumber === void 0 || [...b.text?.trim() ?? ""].length <= MAX_CHARS) continue;
4334
+ const e = edges.get(b.pageNumber) ?? { lefts: [], rights: [] };
4335
+ e.lefts.push(b.bbox.x);
4336
+ e.rights.push(b.bbox.x + b.bbox.width);
4337
+ edges.set(b.pageNumber, e);
4338
+ }
4339
+ const q = (xs, p) => {
4340
+ const v = [...xs].sort((a, b) => a - b);
4341
+ return v[Math.min(v.length - 1, Math.floor(p * v.length))];
4342
+ };
4343
+ const body = /* @__PURE__ */ new Map();
4344
+ for (const [page, e] of edges) body.set(page, { left: q(e.lefts, 0.2), right: q(e.rights, 0.8) });
4345
+ const all = [...body.values()];
4346
+ const fallback = all.length ? { left: q(all.map((e) => e.left), 0.5), right: q(all.map((e) => e.right), 0.5) } : void 0;
4347
+ const key = (b) => {
4348
+ const w = b.pageNumber !== void 0 ? pageWidths.get(b.pageNumber) : void 0;
4349
+ const text = b.text?.trim();
4350
+ const area = (b.pageNumber !== void 0 ? body.get(b.pageNumber) : void 0) ?? fallback;
4351
+ if (b.type === "table") {
4352
+ if (!w || !b.bbox || !b.table || !SIDE_TAB_TABLES.has(b.table)) return null;
4353
+ return `${b.bbox.x >= w * (1 - BAND) ? "R" : "L"}${Math.round(b.bbox.x / 8)}`;
4354
+ }
4355
+ if (!w || !area || !b.bbox || !text || [...text].length > MAX_CHARS) return null;
4356
+ const side = b.bbox.x + b.bbox.width <= Math.min(w * BAND, area.left - 1) ? "L" : b.bbox.x >= Math.max(w * (1 - BAND), area.right + 1) ? "R" : null;
4357
+ return side && text.replace(/\s+/g, "");
4358
+ };
4359
+ const pages = /* @__PURE__ */ new Map();
4360
+ for (const b of blocks) {
4361
+ const k = key(b);
4362
+ if (k) pages.set(k, (pages.get(k) ?? /* @__PURE__ */ new Set()).add(b.pageNumber));
4363
+ }
4364
+ const running = /* @__PURE__ */ new Set();
4365
+ for (const [k, ps] of pages) {
4366
+ const list = [...ps].sort((a, b) => a - b);
4367
+ const steps = list.slice(1).map((p, i) => p - list[i]).sort((a, b) => a - b);
4368
+ const gap = Math.max(RUN_GAP, (steps[steps.length >> 1] ?? 1) * 3);
4369
+ let run = [];
4370
+ const flush = () => {
4371
+ if (run.length >= MIN_REPEAT && run.length >= (run[run.length - 1] - run[0] + 1) * 0.4) for (const p of run) running.add(`${p}\0${k}`);
4372
+ run = [];
4373
+ };
4374
+ for (const p of list) {
4375
+ if (run.length && p - run[run.length - 1] > gap) flush();
4376
+ run.push(p);
4377
+ }
4378
+ flush();
4379
+ }
4380
+ return running.size ? blocks.filter((b) => {
4381
+ const k = key(b);
4382
+ return !k || !running.has(`${b.pageNumber}\0${k}`);
4383
+ }) : blocks;
4384
+ }
4385
+
4385
4386
  // src/pdf/table-roles.ts
4386
4387
  var TOC_BLOCKS = /* @__PURE__ */ new WeakSet();
4387
4388
  var PAGE_LABEL = /^(?:\d{1,4}|[ivxlc]{1,7})$/i;
@@ -4488,6 +4489,8 @@ var MIN_GAP_FACTOR = 2;
4488
4489
  var MIN_GAP_ABSOLUTE = 20;
4489
4490
  var MIN_COL_FILL_RATIO = 0.4;
4490
4491
  function detectClusterTables(items, pageNum, rejected) {
4492
+ const tab = sideTabGlyphs(items);
4493
+ if (tab.size) items = items.filter((i) => !tab.has(i));
4491
4494
  if (items.length < MIN_ROWS * MIN_COLS) return [];
4492
4495
  const { merged, originMap } = mergeEvenSpacedClusters(items);
4493
4496
  const rows = mergeOverlappingRows(groupByBaseline(merged));
@@ -4547,6 +4550,34 @@ function detectClusterTables(items, pageNum, rejected) {
4547
4550
  return !prose;
4548
4551
  });
4549
4552
  }
4553
+ var SIDE_TAB_MIN = 6;
4554
+ function sideTabGlyphs(items) {
4555
+ const found = /* @__PURE__ */ new Set();
4556
+ const singles = items.filter((i) => i.fontSize > 0 && [...i.text.trim()].length === 1);
4557
+ if (singles.length < SIDE_TAB_MIN) return found;
4558
+ const cols = [];
4559
+ for (const it of [...singles].sort((a, b) => a.x - b.x)) {
4560
+ const c = cols.find((col) => Math.abs(col[0].x - it.x) <= Math.max(1.5, it.fontSize * 0.25));
4561
+ if (c) c.push(it);
4562
+ else cols.push([it]);
4563
+ }
4564
+ for (const col of cols) {
4565
+ if (col.length < SIDE_TAB_MIN) continue;
4566
+ col.sort((a, b) => b.y - a.y);
4567
+ const fs = [...col.map((i) => i.fontSize)].sort((a, b) => a - b)[col.length >> 1];
4568
+ if (col.slice(1).some((it, k) => col[k].y - it.y > fs * 3)) continue;
4569
+ const members = new Set(col);
4570
+ const top = col[0].y + fs, bottom = col[col.length - 1].y - fs;
4571
+ const others = items.filter((i) => !members.has(i) && i.y <= top && i.y >= bottom);
4572
+ const left = Math.min(...col.map((i) => i.x)), right = Math.max(...col.map((i) => i.x + i.w));
4573
+ const outside = others.every((i) => i.x >= right + fs) || others.every((i) => i.x + i.w <= left - fs);
4574
+ if (!outside) continue;
4575
+ const alone = col.filter((g) => !others.some((i) => Math.abs(i.y - g.y) <= Y_TOL)).length;
4576
+ if (alone < col.length * 0.4) continue;
4577
+ for (const g of col) found.add(g);
4578
+ }
4579
+ return found;
4580
+ }
4550
4581
  function detectCompactStatisticalTables(rows, pageNum) {
4551
4582
  const found = [];
4552
4583
  const parts = /* @__PURE__ */ new Map();
@@ -6734,6 +6765,11 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6734
6765
  if (carry) carry.clip = void 0;
6735
6766
  return [];
6736
6767
  }
6768
+ const tab = sideTabGlyphs(items);
6769
+ if (tab.size) {
6770
+ const glyphs = [...tab].sort((a, b) => b.y - a.y).map((g) => ({ type: "paragraph", text: g.text.trim(), pageNumber: pageNum, bbox: computeBBox([g], pageNum), style: dominantStyle([g]) }));
6771
+ return [...glyphs, ...extractPageBlocksWithLines(items.filter((i) => !tab.has(i)), pageNum, opList, pageWidth, pageHeight, extraLines, detectTables, carry, lexicon)];
6772
+ }
6737
6773
  const lex = lexicon ?? new WrapLexicon();
6738
6774
  for (const line of streamLines(items)) lex.addLine(mergeLineSimple(line));
6739
6775
  const extracted = extractLines(opList.fnArray, opList.argsArray);
@@ -7095,6 +7131,11 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7095
7131
  const emptyPart = !hasContent && !!grid.cells && !grid.clipParent && !nestedAttached;
7096
7132
  if (!hasContent && !emptyPart) continue;
7097
7133
  if (emptyPart) EMPTY_PARTS.add(irTable);
7134
+ if (numCols === 1 && isSideTabTable(grid.bbox, irTable, items.filter((it) => !tableItems.includes(it)), pageWidth, pageHeight)) {
7135
+ SIDE_TAB_TABLES.add(irTable);
7136
+ blocks.push({ type: "table", table: irTable, pageNumber: pageNum, bbox: { page: pageNum, x: grid.bbox.x1, y: grid.bbox.y1, width: gridW, height: grid.bbox.y2 - grid.bbox.y1 } });
7137
+ continue;
7138
+ }
7098
7139
  if (grid.clipParent) {
7099
7140
  const nb = { page: pageNum, x: grid.bbox.x1, y: grid.bbox.y1, width: grid.bbox.x2 - grid.bbox.x1, height: grid.bbox.y2 - grid.bbox.y1 };
7100
7141
  pendingNested.push({ parent: grid.clipParent, block: { type: "table", table: irTable, pageNumber: pageNum, bbox: nb } });
@@ -7564,13 +7605,6 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
7564
7605
  }
7565
7606
 
7566
7607
  export {
7567
- OCR_DET_MODEL,
7568
- OCR_REC_MODEL,
7569
- OCR_REC_DICT,
7570
- getOcrModelsDir,
7571
- ensureOcrModels,
7572
- ocrModelsCached,
7573
- parseCharacterDict,
7574
7608
  extractLines,
7575
7609
  extractImageRegions,
7576
7610
  filterHiddenText,
@@ -7609,6 +7643,7 @@ export {
7609
7643
  trimTrailingEmptyTableCols,
7610
7644
  NO_EDGES,
7611
7645
  joinCellEdges,
7646
+ removeSideTabs,
7612
7647
  extractPageBlocksWithLines
7613
7648
  };
7614
- //# sourceMappingURL=chunk-6V7QRQY3.js.map
7649
+ //# sourceMappingURL=chunk-OGAYGUJF.js.map