kordoc 4.0.7 → 4.1.0
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.
- package/LICENSE +21 -21
- package/README.md +837 -806
- package/dist/{-6HWEFXVV.js → -AS4IABL2.js} +24 -11
- package/dist/{chunk-BKWHX3RC.js → chunk-37HJHCPA.js} +24 -15
- package/dist/chunk-37HJHCPA.js.map +1 -0
- package/dist/{chunk-U25XGCNH.cjs → chunk-37VKMUST.cjs} +174 -25
- package/dist/chunk-37VKMUST.cjs.map +1 -0
- package/dist/{chunk-5OKHAJ62.js → chunk-4KI23VHA.js} +162 -13
- package/dist/chunk-4KI23VHA.js.map +1 -0
- package/dist/{chunk-6GBLFQMA.js → chunk-5RPYBC2Q.js} +1 -1
- package/dist/chunk-5RPYBC2Q.js.map +1 -0
- package/dist/{chunk-NGSHDBQR.js → chunk-AX2R5Q2N.js} +7 -4
- package/dist/chunk-AX2R5Q2N.js.map +1 -0
- package/dist/{chunk-X34YWRL5.cjs → chunk-DCZVOIEO.cjs} +1 -1
- package/dist/chunk-DCZVOIEO.cjs.map +1 -0
- package/dist/chunk-DZIXKL7E.js +145 -0
- package/dist/chunk-DZIXKL7E.js.map +1 -0
- package/dist/chunk-F2ZU3IZG.js +82 -0
- package/dist/chunk-F2ZU3IZG.js.map +1 -0
- package/dist/{chunk-AIQ3ISQU.js → chunk-GE43BE46.js} +1 -1
- package/dist/chunk-GE43BE46.js.map +1 -0
- package/dist/{chunk-Q7EN4EUJ.js → chunk-GQVSHGG4.js} +12 -4
- package/dist/chunk-GQVSHGG4.js.map +1 -0
- package/dist/chunk-GS7T56RP.cjs.map +1 -1
- package/dist/{chunk-TJJTLM76.js → chunk-L2XQQTOY.js} +1422 -1121
- package/dist/chunk-L2XQQTOY.js.map +1 -0
- package/dist/{chunk-3TBUDJDE.js → chunk-MOL7MDBG.js} +1 -1
- package/dist/chunk-MOL7MDBG.js.map +1 -0
- package/dist/{chunk-CNM75ZSX.js → chunk-O5VS7RIR.js} +2 -2
- package/dist/chunk-O5VS7RIR.js.map +1 -0
- package/dist/{chunk-2SN3CKME.js → chunk-SSTK6IKK.js} +18 -21
- package/dist/chunk-SSTK6IKK.js.map +1 -0
- package/dist/chunk-UOO7LSDG.js +152 -0
- package/dist/chunk-UOO7LSDG.js.map +1 -0
- package/dist/{chunk-ONXVBURQ.js → chunk-WO52HVQJ.js} +2 -2
- package/dist/chunk-WO52HVQJ.js.map +1 -0
- package/dist/{chunk-CFQLK3LM.js → chunk-YOO6ET6M.js} +7 -3
- package/dist/chunk-YOO6ET6M.js.map +1 -0
- package/dist/chunks-WVMGF7JL.js +10 -0
- package/dist/cli.js +173 -38
- package/dist/cli.js.map +1 -1
- package/dist/{detect-NTR2FUEG.js → detect-YEZX2XCF.js} +2 -2
- package/dist/{formula-ZYUDQHD3.cjs → formula-5NKVS2LR.cjs} +1 -1
- package/dist/formula-5NKVS2LR.cjs.map +1 -0
- package/dist/{formula-KOQV353G.js → formula-JCNF43NE.js} +1 -1
- package/dist/formula-JCNF43NE.js.map +1 -0
- package/dist/{formula-MEDGYQXS.js → formula-RXVSQPXI.js} +1 -1
- package/dist/formula-RXVSQPXI.js.map +1 -0
- package/dist/index.cjs +1932 -1397
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -2
- package/dist/index.d.ts +106 -2
- package/dist/index.js +1626 -1091
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +275 -67
- package/dist/mcp.js.map +1 -1
- package/dist/page-range-737B4EZW.js +8 -0
- package/dist/page-range-LNMXJU6W.js +7 -0
- package/dist/page-range-P7SDW6LR.cjs +8 -0
- package/dist/page-range-P7SDW6LR.cjs.map +1 -0
- package/dist/{parser-E6U5TNAU.cjs → parser-N4A7UGDK.cjs} +314 -56
- package/dist/parser-N4A7UGDK.cjs.map +1 -0
- package/dist/{parser-5EHWYJMC.js → parser-PEOYBXBO.js} +287 -27
- package/dist/parser-PEOYBXBO.js.map +1 -0
- package/dist/{parser-UGB3NIVH.js → parser-XX4QTDFQ.js} +283 -25
- package/dist/parser-XX4QTDFQ.js.map +1 -0
- package/dist/{profile-io-CAKRPQRD.js → profile-io-PLDQFPJA.js} +3 -3
- package/dist/{provider-5K7O3Z2O.cjs → provider-4FAYHJ6N.cjs} +3 -3
- package/dist/provider-4FAYHJ6N.cjs.map +1 -0
- package/dist/{provider-H4WWSPOV.js → provider-C6IOGIS5.js} +3 -3
- package/dist/provider-C6IOGIS5.js.map +1 -0
- package/dist/{provider-7H4CPZYS.js → provider-UIBW2MIH.js} +3 -3
- package/dist/provider-UIBW2MIH.js.map +1 -0
- package/dist/rasterize-WWNQLKYW.js +40 -0
- package/dist/rasterize-WWNQLKYW.js.map +1 -0
- package/dist/redact-7ILEAUTS.js +12 -0
- package/dist/render-T7S6H6AN.js +10 -0
- package/dist/render-T7S6H6AN.js.map +1 -0
- package/dist/seal-7PTL6MXH.js +10 -0
- package/dist/seal-7PTL6MXH.js.map +1 -0
- package/dist/{setup-QSJ2INNS.js → setup-Q2PRE7UA.js} +5 -3
- package/dist/setup-Q2PRE7UA.js.map +1 -0
- package/dist/{watch-RMX427YR.js → watch-SFHXZALC.js} +78 -24
- package/dist/watch-SFHXZALC.js.map +1 -0
- package/package.json +97 -97
- package/dist/chunk-2SN3CKME.js.map +0 -1
- package/dist/chunk-3TBUDJDE.js.map +0 -1
- package/dist/chunk-5OKHAJ62.js.map +0 -1
- package/dist/chunk-6GBLFQMA.js.map +0 -1
- package/dist/chunk-AIQ3ISQU.js.map +0 -1
- package/dist/chunk-BKWHX3RC.js.map +0 -1
- package/dist/chunk-CFQLK3LM.js.map +0 -1
- package/dist/chunk-CNM75ZSX.js.map +0 -1
- package/dist/chunk-NGSHDBQR.js.map +0 -1
- package/dist/chunk-ONXVBURQ.js.map +0 -1
- package/dist/chunk-Q7EN4EUJ.js.map +0 -1
- package/dist/chunk-TJJTLM76.js.map +0 -1
- package/dist/chunk-U25XGCNH.cjs.map +0 -1
- package/dist/chunk-X34YWRL5.cjs.map +0 -1
- package/dist/formula-KOQV353G.js.map +0 -1
- package/dist/formula-MEDGYQXS.js.map +0 -1
- package/dist/formula-ZYUDQHD3.cjs.map +0 -1
- package/dist/page-range-CIRRJPXJ.js +0 -7
- package/dist/page-range-OF5I4PQY.js +0 -8
- package/dist/page-range-TPIRSA3J.cjs +0 -8
- package/dist/page-range-TPIRSA3J.cjs.map +0 -1
- package/dist/parser-5EHWYJMC.js.map +0 -1
- package/dist/parser-E6U5TNAU.cjs.map +0 -1
- package/dist/parser-UGB3NIVH.js.map +0 -1
- package/dist/provider-5K7O3Z2O.cjs.map +0 -1
- package/dist/provider-7H4CPZYS.js.map +0 -1
- package/dist/provider-H4WWSPOV.js.map +0 -1
- package/dist/render-P6663O4I.js +0 -10
- package/dist/seal-7PPTXKKV.js +0 -10
- package/dist/setup-QSJ2INNS.js.map +0 -1
- package/dist/watch-RMX427YR.js.map +0 -1
- /package/dist/{-6HWEFXVV.js.map → -AS4IABL2.js.map} +0 -0
- /package/dist/{detect-NTR2FUEG.js.map → chunks-WVMGF7JL.js.map} +0 -0
- /package/dist/{page-range-CIRRJPXJ.js.map → detect-YEZX2XCF.js.map} +0 -0
- /package/dist/{page-range-OF5I4PQY.js.map → page-range-737B4EZW.js.map} +0 -0
- /package/dist/{profile-io-CAKRPQRD.js.map → page-range-LNMXJU6W.js.map} +0 -0
- /package/dist/{render-P6663O4I.js.map → profile-io-PLDQFPJA.js.map} +0 -0
- /package/dist/{seal-7PPTXKKV.js.map → redact-7ILEAUTS.js.map} +0 -0
|
@@ -4,12 +4,13 @@ import {
|
|
|
4
4
|
HEADING_RATIO_H3,
|
|
5
5
|
KordocError,
|
|
6
6
|
blocksToMarkdown,
|
|
7
|
+
encodePng,
|
|
7
8
|
safeMax,
|
|
8
9
|
safeMin
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4KI23VHA.js";
|
|
10
11
|
import {
|
|
11
12
|
parsePageRange
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-GE43BE46.js";
|
|
13
14
|
|
|
14
15
|
// src/pdf/line-extract.ts
|
|
15
16
|
import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
@@ -577,6 +578,18 @@ function buildVertices(horizontals, verticals) {
|
|
|
577
578
|
}
|
|
578
579
|
function mergeVertices(vertices) {
|
|
579
580
|
if (vertices.length <= 1) return vertices;
|
|
581
|
+
let maxRadiusAll = 1;
|
|
582
|
+
for (const v of vertices) {
|
|
583
|
+
if (v.radius > maxRadiusAll) maxRadiusAll = v.radius;
|
|
584
|
+
}
|
|
585
|
+
const cell = Math.max(VERTEX_MERGE_FACTOR * maxRadiusAll, 1);
|
|
586
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
587
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
588
|
+
const key = Math.floor(vertices[i].x / cell) + "," + Math.floor(vertices[i].y / cell);
|
|
589
|
+
const arr = buckets.get(key);
|
|
590
|
+
if (arr) arr.push(i);
|
|
591
|
+
else buckets.set(key, [i]);
|
|
592
|
+
}
|
|
580
593
|
const merged = [];
|
|
581
594
|
const used = new Array(vertices.length).fill(false);
|
|
582
595
|
for (let i = 0; i < vertices.length; i++) {
|
|
@@ -584,7 +597,20 @@ function mergeVertices(vertices) {
|
|
|
584
597
|
let sumX = vertices[i].x, sumY = vertices[i].y;
|
|
585
598
|
let maxRadius = vertices[i].radius;
|
|
586
599
|
let count = 1;
|
|
587
|
-
|
|
600
|
+
const cx = Math.floor(vertices[i].x / cell);
|
|
601
|
+
const cy = Math.floor(vertices[i].y / cell);
|
|
602
|
+
const candidates = [];
|
|
603
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
604
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
605
|
+
const arr = buckets.get(cx + dx + "," + (cy + dy));
|
|
606
|
+
if (!arr) continue;
|
|
607
|
+
for (const j of arr) {
|
|
608
|
+
if (j > i && !used[j]) candidates.push(j);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
candidates.sort((a, b) => a - b);
|
|
613
|
+
for (const j of candidates) {
|
|
588
614
|
if (used[j]) continue;
|
|
589
615
|
const mergeTol = VERTEX_MERGE_FACTOR * Math.max(maxRadius, vertices[j].radius);
|
|
590
616
|
if (Math.abs(vertices[i].x - vertices[j].x) <= mergeTol && Math.abs(vertices[i].y - vertices[j].y) <= mergeTol) {
|
|
@@ -811,6 +837,7 @@ function splitStackedGroup(group) {
|
|
|
811
837
|
}
|
|
812
838
|
return bands.filter((b) => b.length > 0);
|
|
813
839
|
}
|
|
840
|
+
var GROUP_BUCKET_CELL = 100;
|
|
814
841
|
function groupConnectedLines(lines) {
|
|
815
842
|
const parent = lines.map((_, i) => i);
|
|
816
843
|
function find(x) {
|
|
@@ -824,10 +851,34 @@ function groupConnectedLines(lines) {
|
|
|
824
851
|
const ra = find(a), rb = find(b);
|
|
825
852
|
if (ra !== rb) parent[ra] = rb;
|
|
826
853
|
}
|
|
854
|
+
const cellMap = /* @__PURE__ */ new Map();
|
|
827
855
|
for (let i = 0; i < lines.length; i++) {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
856
|
+
const l = lines[i];
|
|
857
|
+
const cx1 = Math.floor((Math.min(l.x1, l.x2) - CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
858
|
+
const cx2 = Math.floor((Math.max(l.x1, l.x2) + CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
859
|
+
const cy1 = Math.floor((Math.min(l.y1, l.y2) - CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
860
|
+
const cy2 = Math.floor((Math.max(l.y1, l.y2) + CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
861
|
+
for (let cx = cx1; cx <= cx2; cx++) {
|
|
862
|
+
for (let cy = cy1; cy <= cy2; cy++) {
|
|
863
|
+
const key = cx + "," + cy;
|
|
864
|
+
const arr = cellMap.get(key);
|
|
865
|
+
if (arr) arr.push(i);
|
|
866
|
+
else cellMap.set(key, [i]);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
const tested = /* @__PURE__ */ new Set();
|
|
871
|
+
for (const arr of cellMap.values()) {
|
|
872
|
+
for (let a = 0; a < arr.length; a++) {
|
|
873
|
+
for (let b = a + 1; b < arr.length; b++) {
|
|
874
|
+
const i = Math.min(arr[a], arr[b]);
|
|
875
|
+
const j = Math.max(arr[a], arr[b]);
|
|
876
|
+
const key = i * lines.length + j;
|
|
877
|
+
if (tested.has(key)) continue;
|
|
878
|
+
tested.add(key);
|
|
879
|
+
if (linesIntersect(lines[i], lines[j])) {
|
|
880
|
+
union(i, j);
|
|
881
|
+
}
|
|
831
882
|
}
|
|
832
883
|
}
|
|
833
884
|
}
|
|
@@ -1220,6 +1271,172 @@ function normalizeUndersegmentedTable(originalCells, colXs, items) {
|
|
|
1220
1271
|
return rebuilt;
|
|
1221
1272
|
}
|
|
1222
1273
|
|
|
1274
|
+
// src/pdf/image-extract.ts
|
|
1275
|
+
import { OPS as OPS3, ImageKind } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
1276
|
+
var IMAGE_RESOLVE_TIMEOUT_MS = 5e3;
|
|
1277
|
+
function resolveImgData(page, objId) {
|
|
1278
|
+
const store = objId.startsWith("g_") ? page.commonObjs : page.objs;
|
|
1279
|
+
return new Promise((resolve) => {
|
|
1280
|
+
let done = false;
|
|
1281
|
+
const timer = setTimeout(() => {
|
|
1282
|
+
if (!done) {
|
|
1283
|
+
done = true;
|
|
1284
|
+
resolve(null);
|
|
1285
|
+
}
|
|
1286
|
+
}, IMAGE_RESOLVE_TIMEOUT_MS);
|
|
1287
|
+
try {
|
|
1288
|
+
store.get(objId, (data) => {
|
|
1289
|
+
if (!done) {
|
|
1290
|
+
done = true;
|
|
1291
|
+
clearTimeout(timer);
|
|
1292
|
+
resolve(data ?? null);
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
} catch {
|
|
1296
|
+
if (!done) {
|
|
1297
|
+
done = true;
|
|
1298
|
+
clearTimeout(timer);
|
|
1299
|
+
resolve(null);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
var MIN_DIM = 8;
|
|
1305
|
+
var MAX_PIXELS = 36e6;
|
|
1306
|
+
var MAX_IMAGES_PER_DOC = 200;
|
|
1307
|
+
var MAX_TOTAL_IMAGE_BYTES = 128 * 1024 * 1024;
|
|
1308
|
+
function createPdfImageState() {
|
|
1309
|
+
return { imageIndex: 0, totalBytes: 0, seen: /* @__PURE__ */ new Map(), capWarned: false };
|
|
1310
|
+
}
|
|
1311
|
+
function fnv1a(data) {
|
|
1312
|
+
let h = 2166136261;
|
|
1313
|
+
for (let i = 0; i < data.length; i++) {
|
|
1314
|
+
h ^= data[i];
|
|
1315
|
+
h = Math.imul(h, 16777619);
|
|
1316
|
+
}
|
|
1317
|
+
return h >>> 0;
|
|
1318
|
+
}
|
|
1319
|
+
function toRgba(img) {
|
|
1320
|
+
const { width: w, height: h, kind, data } = img;
|
|
1321
|
+
if (!data || !w || !h) return null;
|
|
1322
|
+
const rgba = new Uint8Array(w * h * 4);
|
|
1323
|
+
if (kind === ImageKind.RGBA_32BPP) {
|
|
1324
|
+
if (data.length < w * h * 4) return null;
|
|
1325
|
+
rgba.set(data.subarray(0, w * h * 4));
|
|
1326
|
+
return rgba;
|
|
1327
|
+
}
|
|
1328
|
+
if (kind === ImageKind.RGB_24BPP) {
|
|
1329
|
+
if (data.length < w * h * 3) return null;
|
|
1330
|
+
for (let i = 0, s = 0, d = 0; i < w * h; i++, s += 3, d += 4) {
|
|
1331
|
+
rgba[d] = data[s];
|
|
1332
|
+
rgba[d + 1] = data[s + 1];
|
|
1333
|
+
rgba[d + 2] = data[s + 2];
|
|
1334
|
+
rgba[d + 3] = 255;
|
|
1335
|
+
}
|
|
1336
|
+
return rgba;
|
|
1337
|
+
}
|
|
1338
|
+
if (kind === ImageKind.GRAYSCALE_1BPP) {
|
|
1339
|
+
const stride = w + 7 >> 3;
|
|
1340
|
+
if (data.length < stride * h) return null;
|
|
1341
|
+
for (let y = 0; y < h; y++) {
|
|
1342
|
+
for (let x = 0; x < w; x++) {
|
|
1343
|
+
const bit = data[y * stride + (x >> 3)] >> 7 - (x & 7) & 1;
|
|
1344
|
+
const v = bit ? 255 : 0;
|
|
1345
|
+
const d = (y * w + x) * 4;
|
|
1346
|
+
rgba[d] = v;
|
|
1347
|
+
rgba[d + 1] = v;
|
|
1348
|
+
rgba[d + 2] = v;
|
|
1349
|
+
rgba[d + 3] = 255;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
return rgba;
|
|
1353
|
+
}
|
|
1354
|
+
return null;
|
|
1355
|
+
}
|
|
1356
|
+
async function extractPageImages(page, fnArray, argsArray, pageNumber, state, warnings) {
|
|
1357
|
+
const blocks = [];
|
|
1358
|
+
const images = [];
|
|
1359
|
+
const pageSeenIds = /* @__PURE__ */ new Set();
|
|
1360
|
+
for (let i = 0; i < fnArray.length; i++) {
|
|
1361
|
+
const op = fnArray[i];
|
|
1362
|
+
let imgData = null;
|
|
1363
|
+
let dedupeId = null;
|
|
1364
|
+
if (op === OPS3.paintImageXObject || op === OPS3.paintImageXObjectRepeat) {
|
|
1365
|
+
const objId = argsArray[i]?.[0];
|
|
1366
|
+
if (typeof objId !== "string" || pageSeenIds.has(objId)) continue;
|
|
1367
|
+
pageSeenIds.add(objId);
|
|
1368
|
+
dedupeId = objId;
|
|
1369
|
+
} else if (op !== OPS3.paintInlineImageXObject) {
|
|
1370
|
+
continue;
|
|
1371
|
+
}
|
|
1372
|
+
if (state.imageIndex >= MAX_IMAGES_PER_DOC || state.totalBytes >= MAX_TOTAL_IMAGE_BYTES) {
|
|
1373
|
+
if (!state.capWarned) {
|
|
1374
|
+
state.capWarned = true;
|
|
1375
|
+
warnings.push({ page: pageNumber, message: `\uC774\uBBF8\uC9C0 \uCD94\uCD9C \uC0C1\uD55C \uB3C4\uB2EC (${MAX_IMAGES_PER_DOC}\uAC1C/128MB) \u2014 \uC774\uD6C4 \uC774\uBBF8\uC9C0 \uC0DD\uB7B5`, code: "SKIPPED_IMAGE" });
|
|
1376
|
+
}
|
|
1377
|
+
continue;
|
|
1378
|
+
}
|
|
1379
|
+
if (dedupeId) {
|
|
1380
|
+
imgData = await resolveImgData(page, dedupeId);
|
|
1381
|
+
} else {
|
|
1382
|
+
imgData = argsArray[i]?.[0];
|
|
1383
|
+
}
|
|
1384
|
+
if (!imgData?.data || !imgData.width || !imgData.height) continue;
|
|
1385
|
+
const { width: w, height: h } = imgData;
|
|
1386
|
+
if (w < MIN_DIM || h < MIN_DIM) continue;
|
|
1387
|
+
if (w * h > MAX_PIXELS) {
|
|
1388
|
+
warnings.push({ page: pageNumber, message: `\uC774\uBBF8\uC9C0 \uD06C\uAE30 \uCD08\uACFC\uB85C \uCD94\uCD9C \uC0DD\uB7B5 (${w}\xD7${h})`, code: "SKIPPED_IMAGE" });
|
|
1389
|
+
continue;
|
|
1390
|
+
}
|
|
1391
|
+
const hash = `${w}x${h}k${imgData.kind ?? "?"}h${fnv1a(imgData.data)}${dedupeId ? "" : "inline"}`;
|
|
1392
|
+
if (state.seen.has(hash)) continue;
|
|
1393
|
+
const rgba = toRgba(imgData);
|
|
1394
|
+
if (!rgba) continue;
|
|
1395
|
+
const png = encodePng(w, h, rgba);
|
|
1396
|
+
state.imageIndex++;
|
|
1397
|
+
state.totalBytes += png.length;
|
|
1398
|
+
const filename = `image_${String(state.imageIndex).padStart(3, "0")}.png`;
|
|
1399
|
+
state.seen.set(hash, filename);
|
|
1400
|
+
images.push({ filename, data: png, mimeType: "image/png" });
|
|
1401
|
+
blocks.push({ type: "image", text: filename, pageNumber });
|
|
1402
|
+
}
|
|
1403
|
+
return { blocks, images };
|
|
1404
|
+
}
|
|
1405
|
+
function injectPageImageBlocks(blocks, pageImages) {
|
|
1406
|
+
if (pageImages.size === 0) return;
|
|
1407
|
+
const lastIndexForPage = /* @__PURE__ */ new Map();
|
|
1408
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1409
|
+
const p = blocks[i].pageNumber;
|
|
1410
|
+
if (p !== void 0) lastIndexForPage.set(p, i);
|
|
1411
|
+
}
|
|
1412
|
+
const pageAtIndex = /* @__PURE__ */ new Map();
|
|
1413
|
+
for (const [p, last] of lastIndexForPage) pageAtIndex.set(last, p);
|
|
1414
|
+
const result = [];
|
|
1415
|
+
const injected = /* @__PURE__ */ new Set();
|
|
1416
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1417
|
+
result.push(blocks[i]);
|
|
1418
|
+
const p = pageAtIndex.get(i);
|
|
1419
|
+
if (p !== void 0 && pageImages.has(p)) {
|
|
1420
|
+
result.push(...pageImages.get(p));
|
|
1421
|
+
injected.add(p);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
for (const p of [...pageImages.keys()].sort((a, b) => a - b)) {
|
|
1425
|
+
if (injected.has(p)) continue;
|
|
1426
|
+
let at = result.length;
|
|
1427
|
+
for (let i = 0; i < result.length; i++) {
|
|
1428
|
+
const bp = result[i].pageNumber;
|
|
1429
|
+
if (bp !== void 0 && bp > p) {
|
|
1430
|
+
at = i;
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
result.splice(at, 0, ...pageImages.get(p));
|
|
1435
|
+
}
|
|
1436
|
+
blocks.length = 0;
|
|
1437
|
+
blocks.push(...result);
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1223
1440
|
// src/pdf/quality.ts
|
|
1224
1441
|
var RARE_JONG = /* @__PURE__ */ new Set([3, 5, 6, 9, 10, 11, 12, 13, 14, 15, 18, 24, 25, 26]);
|
|
1225
1442
|
var MOJIBAKE_MIN_HANGUL = 30;
|
|
@@ -2515,11 +2732,12 @@ function buildGridTable(lines, columns) {
|
|
|
2515
2732
|
if (filledCells < totalCells * 0.35 || merged.length < 2 || merged.length <= 3 && numCols >= 7) {
|
|
2516
2733
|
return merged.map((r) => r.filter((c) => c).join(" ")).join("\n");
|
|
2517
2734
|
}
|
|
2735
|
+
const escCell = (c) => c.replace(/\t/g, " ").replace(/\|/g, "\\|");
|
|
2518
2736
|
const md = [];
|
|
2519
|
-
md.push("| " + merged[0].join(" | ") + " |");
|
|
2737
|
+
md.push("| " + merged[0].map(escCell).join(" | ") + " |");
|
|
2520
2738
|
md.push("| " + merged[0].map(() => "---").join(" | ") + " |");
|
|
2521
2739
|
for (let r = 1; r < merged.length; r++) {
|
|
2522
|
-
md.push("| " + merged[r].join(" | ") + " |");
|
|
2740
|
+
md.push("| " + merged[r].map(escCell).join(" | ") + " |");
|
|
2523
2741
|
}
|
|
2524
2742
|
return md.join("\n");
|
|
2525
2743
|
}
|
|
@@ -2699,6 +2917,7 @@ function detectKoreanListBlocks(blocks) {
|
|
|
2699
2917
|
}
|
|
2700
2918
|
let familyStack = [];
|
|
2701
2919
|
let lastTopLevelList = null;
|
|
2920
|
+
let prevListIdx = -2;
|
|
2702
2921
|
const toRemove = /* @__PURE__ */ new Set();
|
|
2703
2922
|
for (let i = 0; i < blocks.length; i++) {
|
|
2704
2923
|
const b = blocks[i];
|
|
@@ -2727,7 +2946,7 @@ function detectKoreanListBlocks(blocks) {
|
|
|
2727
2946
|
if (depth === 0) {
|
|
2728
2947
|
blocks[i] = listBlock;
|
|
2729
2948
|
lastTopLevelList = listBlock;
|
|
2730
|
-
} else if (lastTopLevelList) {
|
|
2949
|
+
} else if (lastTopLevelList && i === prevListIdx + 1) {
|
|
2731
2950
|
if (!lastTopLevelList.children) lastTopLevelList.children = [];
|
|
2732
2951
|
lastTopLevelList.children.push(listBlock);
|
|
2733
2952
|
toRemove.add(i);
|
|
@@ -2735,6 +2954,7 @@ function detectKoreanListBlocks(blocks) {
|
|
|
2735
2954
|
blocks[i] = listBlock;
|
|
2736
2955
|
lastTopLevelList = listBlock;
|
|
2737
2956
|
}
|
|
2957
|
+
prevListIdx = i;
|
|
2738
2958
|
}
|
|
2739
2959
|
if (toRemove.size > 0) {
|
|
2740
2960
|
const sorted = [...toRemove].sort((a, b) => b - a);
|
|
@@ -2860,8 +3080,8 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
|
|
|
2860
3080
|
const blockTop = ph - (b.bbox.y + b.bbox.height);
|
|
2861
3081
|
const blockBottom = ph - b.bbox.y;
|
|
2862
3082
|
const entry = { blockIdx: bi, page: b.pageNumber, text: b.text.trim() };
|
|
2863
|
-
if (blockBottom <= ph * ZONE_RATIO)
|
|
2864
|
-
else if (blockTop >= ph * (1 - ZONE_RATIO))
|
|
3083
|
+
if (blockBottom <= ph * ZONE_RATIO) topEntries.push(entry);
|
|
3084
|
+
else if (blockTop >= ph * (1 - ZONE_RATIO)) bottomEntries.push(entry);
|
|
2865
3085
|
}
|
|
2866
3086
|
const removeSet = /* @__PURE__ */ new Set();
|
|
2867
3087
|
for (const entries of [topEntries, bottomEntries]) {
|
|
@@ -3034,6 +3254,8 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3034
3254
|
hasSpaceBefore: i.hasSpaceBefore
|
|
3035
3255
|
}));
|
|
3036
3256
|
const cellTextMap = mapTextToCells(textItems, cells);
|
|
3257
|
+
const assignedItems = /* @__PURE__ */ new Set();
|
|
3258
|
+
for (const arr of cellTextMap.values()) for (const it of arr) assignedItems.add(it);
|
|
3037
3259
|
const numRows = grid.rowYs.length - 1;
|
|
3038
3260
|
const numCols = grid.colXs.length - 1;
|
|
3039
3261
|
const irGrid = Array.from(
|
|
@@ -3053,9 +3275,11 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3053
3275
|
}
|
|
3054
3276
|
let finalGrid = irGrid;
|
|
3055
3277
|
let finalRows = numRows;
|
|
3278
|
+
let rebuiltUsed = false;
|
|
3056
3279
|
if (numRows <= 2 && numCols >= 3) {
|
|
3057
3280
|
const rebuilt = normalizeUndersegmentedTable(irGrid, grid.colXs, textItems);
|
|
3058
3281
|
if (rebuilt) {
|
|
3282
|
+
rebuiltUsed = true;
|
|
3059
3283
|
finalGrid = rebuilt.map((row) => row.map((rawText) => {
|
|
3060
3284
|
const cleaned = rawText.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
|
|
3061
3285
|
return {
|
|
@@ -3067,6 +3291,11 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3067
3291
|
finalRows = finalGrid.length;
|
|
3068
3292
|
}
|
|
3069
3293
|
}
|
|
3294
|
+
if (!rebuiltUsed) {
|
|
3295
|
+
for (let ti = 0; ti < textItems.length; ti++) {
|
|
3296
|
+
if (!assignedItems.has(textItems[ti])) usedItems.delete(tableItems[ti]);
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3070
3299
|
const irTable = {
|
|
3071
3300
|
rows: finalRows,
|
|
3072
3301
|
cols: numCols,
|
|
@@ -3123,6 +3352,8 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3123
3352
|
}
|
|
3124
3353
|
remaining = remaining.filter((_, idx) => !usedClusterIndices.has(idx));
|
|
3125
3354
|
}
|
|
3355
|
+
const groupSizes = [];
|
|
3356
|
+
let finalTextBlocks = [];
|
|
3126
3357
|
if (remaining.length > 0) {
|
|
3127
3358
|
const allY = remaining.map((i) => i.y);
|
|
3128
3359
|
const pageH = safeMax(allY) - safeMin(allY);
|
|
@@ -3132,16 +3363,28 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3132
3363
|
if (group.length === 0) continue;
|
|
3133
3364
|
const groupBlocks = extractPageBlocksFallback(group, pageNum);
|
|
3134
3365
|
for (const b of groupBlocks) textBlocks.push(b);
|
|
3366
|
+
groupSizes.push(groupBlocks.length);
|
|
3135
3367
|
}
|
|
3136
|
-
|
|
3137
|
-
for (const b of finalTextBlocks) blocks.push(b);
|
|
3368
|
+
finalTextBlocks = detectListBlocks(textBlocks);
|
|
3138
3369
|
}
|
|
3139
|
-
blocks.
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3370
|
+
const units = blocks.map((b) => [b]);
|
|
3371
|
+
let off = 0;
|
|
3372
|
+
for (const size of groupSizes) {
|
|
3373
|
+
const unit = finalTextBlocks.slice(off, off + size);
|
|
3374
|
+
off += size;
|
|
3375
|
+
if (unit.length > 0) units.push(unit);
|
|
3376
|
+
}
|
|
3377
|
+
const unitTopY = (u) => {
|
|
3378
|
+
let top = 0;
|
|
3379
|
+
for (const b of u) {
|
|
3380
|
+
if (b.bbox && b.bbox.y + b.bbox.height > top) top = b.bbox.y + b.bbox.height;
|
|
3381
|
+
}
|
|
3382
|
+
return top;
|
|
3383
|
+
};
|
|
3384
|
+
units.sort((a, b) => unitTopY(b) - unitTopY(a));
|
|
3385
|
+
const ordered = [];
|
|
3386
|
+
for (const u of units) for (const b of u) ordered.push(b);
|
|
3387
|
+
return mergeAdjacentTableBlocks(ordered);
|
|
3145
3388
|
}
|
|
3146
3389
|
return mergeAdjacentTableBlocks(blocks);
|
|
3147
3390
|
}
|
|
@@ -3387,7 +3630,7 @@ function mergeKoreanLines(text) {
|
|
|
3387
3630
|
|
|
3388
3631
|
// src/pdf/formula-ocr.ts
|
|
3389
3632
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
3390
|
-
const formulaMod = await import("./formula-
|
|
3633
|
+
const formulaMod = await import("./formula-RXVSQPXI.js");
|
|
3391
3634
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
3392
3635
|
await ensureFormulaModels((p) => {
|
|
3393
3636
|
if (p.phase === "download" && p.total) {
|
|
@@ -3582,6 +3825,9 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3582
3825
|
const pageHeights = /* @__PURE__ */ new Map();
|
|
3583
3826
|
const pagesWithLargeImage = /* @__PURE__ */ new Set();
|
|
3584
3827
|
const skippedImagePages = /* @__PURE__ */ new Map();
|
|
3828
|
+
const imageState = createPdfImageState();
|
|
3829
|
+
const extractedImages = [];
|
|
3830
|
+
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
3585
3831
|
let parsedPages = 0;
|
|
3586
3832
|
for (let i = 1; i <= effectivePageCount; i++) {
|
|
3587
3833
|
if (pageFilter && !pageFilter.has(i)) continue;
|
|
@@ -3619,9 +3865,19 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3619
3865
|
}
|
|
3620
3866
|
const pageBlocks = extractPageBlocksWithLines(visible, i, opList, viewport.width, viewport.height);
|
|
3621
3867
|
for (const b of pageBlocks) blocks.push(b);
|
|
3868
|
+
try {
|
|
3869
|
+
const { blocks: imgBlocks, images: pageImages } = await extractPageImages(page, opList.fnArray, opList.argsArray, i, imageState, warnings);
|
|
3870
|
+
if (imgBlocks.length > 0) pageImageBlocks.set(i, imgBlocks);
|
|
3871
|
+
extractedImages.push(...pageImages);
|
|
3872
|
+
} catch {
|
|
3873
|
+
}
|
|
3622
3874
|
let pageText = "";
|
|
3623
3875
|
for (const b of pageBlocks) {
|
|
3624
|
-
|
|
3876
|
+
let t = b.text || "";
|
|
3877
|
+
if (b.type === "table" && b.table) {
|
|
3878
|
+
const cellText = b.table.cells.map((row) => row.map((c) => c.text).join(" ")).join("\n");
|
|
3879
|
+
t = t ? t + "\n" + cellText : cellText;
|
|
3880
|
+
}
|
|
3625
3881
|
totalChars += t.replace(/\s/g, "").length;
|
|
3626
3882
|
totalTextBytes += t.length * 2;
|
|
3627
3883
|
pageText += pageText ? "\n" + t : t;
|
|
@@ -3640,11 +3896,11 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3640
3896
|
if (totalChars / Math.max(parsedPageCount, 1) < 10) {
|
|
3641
3897
|
if (options?.ocr) {
|
|
3642
3898
|
try {
|
|
3643
|
-
const { ocrPages } = await import("./provider-
|
|
3899
|
+
const { ocrPages } = await import("./provider-C6IOGIS5.js");
|
|
3644
3900
|
const ocrBlocks = await ocrPages(doc, options.ocr, pageFilter, effectivePageCount);
|
|
3645
3901
|
if (ocrBlocks.length > 0) {
|
|
3646
3902
|
const ocrMarkdown = ocrBlocks.map((b) => b.text || "").filter(Boolean).join("\n\n");
|
|
3647
|
-
return { markdown: ocrMarkdown, blocks: ocrBlocks, metadata, warnings, isImageBased: true, pageQuality, qualitySummary: summarizeDocumentQuality(pageQuality) };
|
|
3903
|
+
return { markdown: ocrMarkdown, blocks: ocrBlocks, metadata, warnings, isImageBased: true, pageQuality, qualitySummary: summarizeDocumentQuality(pageQuality), images: extractedImages.length > 0 ? extractedImages : void 0 };
|
|
3648
3904
|
}
|
|
3649
3905
|
} catch {
|
|
3650
3906
|
}
|
|
@@ -3681,6 +3937,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3681
3937
|
}
|
|
3682
3938
|
}
|
|
3683
3939
|
mergeCrossPageTables(blocks);
|
|
3940
|
+
injectPageImageBlocks(blocks, pageImageBlocks);
|
|
3684
3941
|
if (options?.formulaOcr && formulaBuffer) {
|
|
3685
3942
|
try {
|
|
3686
3943
|
await applyFormulaOcr(formulaBuffer, blocks, pageFilter, effectivePageCount, warnings, options.onProgress);
|
|
@@ -3709,7 +3966,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3709
3966
|
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3710
3967
|
isImageBased: isImageBased || void 0,
|
|
3711
3968
|
pageQuality,
|
|
3712
|
-
qualitySummary: summarizeDocumentQuality(pageQuality)
|
|
3969
|
+
qualitySummary: summarizeDocumentQuality(pageQuality),
|
|
3970
|
+
images: extractedImages.length > 0 ? extractedImages : void 0
|
|
3713
3971
|
};
|
|
3714
3972
|
} finally {
|
|
3715
3973
|
await doc.destroy().catch(() => {
|
|
@@ -3759,4 +4017,4 @@ export {
|
|
|
3759
4017
|
parsePdfDocument,
|
|
3760
4018
|
removeHeaderFooterBlocks
|
|
3761
4019
|
};
|
|
3762
|
-
//# sourceMappingURL=parser-
|
|
4020
|
+
//# sourceMappingURL=parser-XX4QTDFQ.js.map
|