@ssmeo/mcp-local-rag 0.18.6
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 -0
- package/README.de.md +441 -0
- package/README.es.md +441 -0
- package/README.fr.md +441 -0
- package/README.md +530 -0
- package/README.pt-BR.md +441 -0
- package/README.zh-CN.md +441 -0
- package/dist/bin/install-skills.d.ts +19 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +218 -0
- package/dist/bin/install-skills.js.map +1 -0
- package/dist/chunker/index.d.ts +24 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +2 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/semantic-chunker.d.ts +96 -0
- package/dist/chunker/semantic-chunker.d.ts.map +1 -0
- package/dist/chunker/semantic-chunker.js +362 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +32 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +231 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/chunker/token-containment.d.ts +39 -0
- package/dist/chunker/token-containment.d.ts.map +1 -0
- package/dist/chunker/token-containment.js +83 -0
- package/dist/chunker/token-containment.js.map +1 -0
- package/dist/cli/common.d.ts +34 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +121 -0
- package/dist/cli/common.js.map +1 -0
- package/dist/cli/delete.d.ts +3 -0
- package/dist/cli/delete.d.ts.map +1 -0
- package/dist/cli/delete.js +169 -0
- package/dist/cli/delete.js.map +1 -0
- package/dist/cli/file-collection.d.ts +2 -0
- package/dist/cli/file-collection.d.ts.map +1 -0
- package/dist/cli/file-collection.js +53 -0
- package/dist/cli/file-collection.js.map +1 -0
- package/dist/cli/ingest.d.ts +69 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +323 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/list.d.ts +27 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +207 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/options.d.ts +89 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +244 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/query.d.ts +17 -0
- package/dist/cli/query.d.ts.map +1 -0
- package/dist/cli/query.js +194 -0
- package/dist/cli/query.js.map +1 -0
- package/dist/cli/read-neighbors.d.ts +3 -0
- package/dist/cli/read-neighbors.d.ts.map +1 -0
- package/dist/cli/read-neighbors.js +192 -0
- package/dist/cli/read-neighbors.js.map +1 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +78 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync.d.ts +6 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +271 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli-main.d.ts +9 -0
- package/dist/cli-main.d.ts.map +1 -0
- package/dist/cli-main.js +60 -0
- package/dist/cli-main.js.map +1 -0
- package/dist/embedder/index.d.ts +143 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +429 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/embedder/remote.d.ts +51 -0
- package/dist/embedder/remote.d.ts.map +1 -0
- package/dist/embedder/remote.js +182 -0
- package/dist/embedder/remote.js.map +1 -0
- package/dist/features/list.d.ts +37 -0
- package/dist/features/list.d.ts.map +1 -0
- package/dist/features/list.js +41 -0
- package/dist/features/list.js.map +1 -0
- package/dist/features/sync.d.ts +219 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +461 -0
- package/dist/features/sync.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/compute.d.ts +63 -0
- package/dist/ingest/compute.d.ts.map +1 -0
- package/dist/ingest/compute.js +161 -0
- package/dist/ingest/compute.js.map +1 -0
- package/dist/ingest/file.d.ts +40 -0
- package/dist/ingest/file.d.ts.map +1 -0
- package/dist/ingest/file.js +74 -0
- package/dist/ingest/file.js.map +1 -0
- package/dist/ingest/visual.d.ts +52 -0
- package/dist/ingest/visual.d.ts.map +1 -0
- package/dist/ingest/visual.js +294 -0
- package/dist/ingest/visual.js.map +1 -0
- package/dist/parser/docx-parser.d.ts +12 -0
- package/dist/parser/docx-parser.d.ts.map +1 -0
- package/dist/parser/docx-parser.js +375 -0
- package/dist/parser/docx-parser.js.map +1 -0
- package/dist/parser/html-parser.d.ts +16 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +119 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +125 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +364 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-extract.d.ts +49 -0
- package/dist/parser/pdf-extract.d.ts.map +1 -0
- package/dist/parser/pdf-extract.js +114 -0
- package/dist/parser/pdf-extract.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +91 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +522 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/parser/title-extractor.d.ts +28 -0
- package/dist/parser/title-extractor.d.ts.map +1 -0
- package/dist/parser/title-extractor.js +105 -0
- package/dist/parser/title-extractor.js.map +1 -0
- package/dist/pdf-visual/captioner.d.ts +11 -0
- package/dist/pdf-visual/captioner.d.ts.map +1 -0
- package/dist/pdf-visual/captioner.js +48 -0
- package/dist/pdf-visual/captioner.js.map +1 -0
- package/dist/pdf-visual/captioners/fast.d.ts +7 -0
- package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/fast.js +108 -0
- package/dist/pdf-visual/captioners/fast.js.map +1 -0
- package/dist/pdf-visual/captioners/quality.d.ts +7 -0
- package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/quality.js +101 -0
- package/dist/pdf-visual/captioners/quality.js.map +1 -0
- package/dist/pdf-visual/captioners/shared.d.ts +81 -0
- package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/shared.js +156 -0
- package/dist/pdf-visual/captioners/shared.js.map +1 -0
- package/dist/pdf-visual/detector.d.ts +9 -0
- package/dist/pdf-visual/detector.d.ts.map +1 -0
- package/dist/pdf-visual/detector.js +269 -0
- package/dist/pdf-visual/detector.js.map +1 -0
- package/dist/pdf-visual/index.d.ts +13 -0
- package/dist/pdf-visual/index.d.ts.map +1 -0
- package/dist/pdf-visual/index.js +53 -0
- package/dist/pdf-visual/index.js.map +1 -0
- package/dist/pdf-visual/renderer.d.ts +9 -0
- package/dist/pdf-visual/renderer.d.ts.map +1 -0
- package/dist/pdf-visual/renderer.js +186 -0
- package/dist/pdf-visual/renderer.js.map +1 -0
- package/dist/pdf-visual/types.d.ts +53 -0
- package/dist/pdf-visual/types.d.ts.map +1 -0
- package/dist/pdf-visual/types.js +17 -0
- package/dist/pdf-visual/types.js.map +1 -0
- package/dist/server/error-utils.d.ts +63 -0
- package/dist/server/error-utils.d.ts.map +1 -0
- package/dist/server/error-utils.js +124 -0
- package/dist/server/error-utils.js.map +1 -0
- package/dist/server/index.d.ts +216 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1068 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/list-scanner.d.ts +30 -0
- package/dist/server/list-scanner.d.ts.map +1 -0
- package/dist/server/list-scanner.js +50 -0
- package/dist/server/list-scanner.js.map +1 -0
- package/dist/server/tool-definitions.d.ts +8 -0
- package/dist/server/tool-definitions.d.ts.map +1 -0
- package/dist/server/tool-definitions.js +181 -0
- package/dist/server/tool-definitions.js.map +1 -0
- package/dist/server/tool-input.d.ts +37 -0
- package/dist/server/tool-input.d.ts.map +1 -0
- package/dist/server/tool-input.js +211 -0
- package/dist/server/tool-input.js.map +1 -0
- package/dist/server/types.d.ts +307 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +3 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server-main.d.ts +40 -0
- package/dist/server-main.d.ts.map +1 -0
- package/dist/server-main.js +254 -0
- package/dist/server-main.js.map +1 -0
- package/dist/utils/base-dirs.d.ts +145 -0
- package/dist/utils/base-dirs.d.ts.map +1 -0
- package/dist/utils/base-dirs.js +344 -0
- package/dist/utils/base-dirs.js.map +1 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +61 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/limits.d.ts +26 -0
- package/dist/utils/limits.d.ts.map +1 -0
- package/dist/utils/limits.js +28 -0
- package/dist/utils/limits.js.map +1 -0
- package/dist/utils/list-sources.d.ts +38 -0
- package/dist/utils/list-sources.d.ts.map +1 -0
- package/dist/utils/list-sources.js +40 -0
- package/dist/utils/list-sources.js.map +1 -0
- package/dist/utils/raw-data-utils.d.ts +76 -0
- package/dist/utils/raw-data-utils.d.ts.map +1 -0
- package/dist/utils/raw-data-utils.js +202 -0
- package/dist/utils/raw-data-utils.js.map +1 -0
- package/dist/utils/scan.d.ts +114 -0
- package/dist/utils/scan.d.ts.map +1 -0
- package/dist/utils/scan.js +209 -0
- package/dist/utils/scan.js.map +1 -0
- package/dist/utils/scope-match.d.ts +38 -0
- package/dist/utils/scope-match.d.ts.map +1 -0
- package/dist/utils/scope-match.js +86 -0
- package/dist/utils/scope-match.js.map +1 -0
- package/dist/utils/sensitive-path.d.ts +9 -0
- package/dist/utils/sensitive-path.d.ts.map +1 -0
- package/dist/utils/sensitive-path.js +78 -0
- package/dist/utils/sensitive-path.js.map +1 -0
- package/dist/utils/sync-path-key.d.ts +14 -0
- package/dist/utils/sync-path-key.d.ts.map +1 -0
- package/dist/utils/sync-path-key.js +27 -0
- package/dist/utils/sync-path-key.js.map +1 -0
- package/dist/utils/type-guards.d.ts +18 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +34 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/visual-profile.d.ts +10 -0
- package/dist/utils/visual-profile.d.ts.map +1 -0
- package/dist/utils/visual-profile.js +15 -0
- package/dist/utils/visual-profile.js.map +1 -0
- package/dist/vectordb/index.d.ts +132 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +617 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/vectordb/search-filters.d.ts +15 -0
- package/dist/vectordb/search-filters.d.ts.map +1 -0
- package/dist/vectordb/search-filters.js +129 -0
- package/dist/vectordb/search-filters.js.map +1 -0
- package/dist/vectordb/types.d.ts +194 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +237 -0
- package/dist/vectordb/types.js.map +1 -0
- package/package.json +108 -0
- package/skills/mcp-local-rag/SKILL.md +234 -0
- package/skills/mcp-local-rag/references/cli-reference.md +190 -0
- package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
// PDF Header/Footer Filter
|
|
2
|
+
// - Detects and removes repeating patterns across pages
|
|
3
|
+
// - Semantic similarity-based header/footer detection (sentence-level)
|
|
4
|
+
import { splitIntoSentences } from '../chunker/sentence-splitter.js';
|
|
5
|
+
function buildPageLayout(pageNum, items) {
|
|
6
|
+
let rawText = '';
|
|
7
|
+
let previousItem;
|
|
8
|
+
const rawFragments = [];
|
|
9
|
+
const fragmentCounts = new Map();
|
|
10
|
+
const orderedItems = [...items].sort((left, right) => Math.round(right.y) - Math.round(left.y) || left.x - right.x);
|
|
11
|
+
for (let itemIndex = 0; itemIndex < orderedItems.length; itemIndex++) {
|
|
12
|
+
const item = orderedItems[itemIndex];
|
|
13
|
+
if (!item || item.text.trim().length === 0) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (previousItem) {
|
|
17
|
+
rawText += Math.round(previousItem.y) === Math.round(item.y) ? ' ' : '\n';
|
|
18
|
+
}
|
|
19
|
+
const rawStart = rawText.length;
|
|
20
|
+
rawText += item.text;
|
|
21
|
+
const rawEnd = rawText.length;
|
|
22
|
+
const blockOrdinal = item.blockOrdinal ?? 0;
|
|
23
|
+
const lineOrdinal = item.lineOrdinal ?? itemIndex;
|
|
24
|
+
const lineKey = `${blockOrdinal}:${lineOrdinal}`;
|
|
25
|
+
const fragmentOrdinal = fragmentCounts.get(lineKey) ?? 0;
|
|
26
|
+
fragmentCounts.set(lineKey, fragmentOrdinal + 1);
|
|
27
|
+
rawFragments.push({
|
|
28
|
+
pageNum,
|
|
29
|
+
blockOrdinal,
|
|
30
|
+
lineOrdinal,
|
|
31
|
+
fragmentOrdinal,
|
|
32
|
+
bbox: item.bbox ?? [item.x, item.y, item.x, item.y],
|
|
33
|
+
rawStart,
|
|
34
|
+
rawEnd,
|
|
35
|
+
});
|
|
36
|
+
previousItem = item;
|
|
37
|
+
}
|
|
38
|
+
return trimToPageText(rawText, rawFragments);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Trim the page's raw text and rebase every fragment onto it, dropping any
|
|
42
|
+
* fragment that consisted only of the trimmed whitespace.
|
|
43
|
+
*/
|
|
44
|
+
function trimToPageText(rawText, rawFragments) {
|
|
45
|
+
const leadingWhitespace = rawText.length - rawText.trimStart().length;
|
|
46
|
+
const trailingBoundary = rawText.trimEnd().length;
|
|
47
|
+
const text = rawText.slice(leadingWhitespace, trailingBoundary);
|
|
48
|
+
const textFragments = [];
|
|
49
|
+
for (const fragment of rawFragments) {
|
|
50
|
+
const clippedStart = Math.max(fragment.rawStart, leadingWhitespace);
|
|
51
|
+
const clippedEnd = Math.min(fragment.rawEnd, trailingBoundary);
|
|
52
|
+
if (clippedStart >= clippedEnd) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const pageTextStart = clippedStart - leadingWhitespace;
|
|
56
|
+
const pageTextEnd = clippedEnd - leadingWhitespace;
|
|
57
|
+
textFragments.push({
|
|
58
|
+
pageNum: fragment.pageNum,
|
|
59
|
+
blockOrdinal: fragment.blockOrdinal,
|
|
60
|
+
lineOrdinal: fragment.lineOrdinal,
|
|
61
|
+
fragmentOrdinal: fragment.fragmentOrdinal,
|
|
62
|
+
bbox: fragment.bbox,
|
|
63
|
+
text: text.slice(pageTextStart, pageTextEnd),
|
|
64
|
+
pageTextStart,
|
|
65
|
+
pageTextEnd,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return { text, textFragments };
|
|
69
|
+
}
|
|
70
|
+
function buildSentenceLayout(pageNum, sentences, items) {
|
|
71
|
+
let text = '';
|
|
72
|
+
const textFragments = [];
|
|
73
|
+
for (const sentence of sentences) {
|
|
74
|
+
if (text) {
|
|
75
|
+
text += ' ';
|
|
76
|
+
}
|
|
77
|
+
const start = text.length;
|
|
78
|
+
text += sentence.text;
|
|
79
|
+
const matchingItems = items.filter((item) => Math.round(item.y) === Math.round(sentence.y));
|
|
80
|
+
const first = matchingItems[0];
|
|
81
|
+
const boxes = matchingItems.map((item) => item.bbox ?? [item.x, item.y, item.x, item.y]);
|
|
82
|
+
const bbox = boxes.length
|
|
83
|
+
? [
|
|
84
|
+
Math.min(...boxes.map((box) => box[0])),
|
|
85
|
+
Math.min(...boxes.map((box) => box[1])),
|
|
86
|
+
Math.max(...boxes.map((box) => box[2])),
|
|
87
|
+
Math.max(...boxes.map((box) => box[3])),
|
|
88
|
+
]
|
|
89
|
+
: [0, 0, 0, 0];
|
|
90
|
+
textFragments.push({
|
|
91
|
+
pageNum,
|
|
92
|
+
blockOrdinal: first?.blockOrdinal ?? 0,
|
|
93
|
+
lineOrdinal: first?.lineOrdinal ?? textFragments.length,
|
|
94
|
+
fragmentOrdinal: 0,
|
|
95
|
+
bbox,
|
|
96
|
+
text: sentence.text,
|
|
97
|
+
pageTextStart: start,
|
|
98
|
+
pageTextEnd: text.length,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return { text, textFragments };
|
|
102
|
+
}
|
|
103
|
+
function joinPageItems(items) {
|
|
104
|
+
return buildPageLayout(0, items).text;
|
|
105
|
+
}
|
|
106
|
+
/** Join filtered pages into one text. */
|
|
107
|
+
export function joinFilteredPages(pages) {
|
|
108
|
+
return pages
|
|
109
|
+
.map((page) => joinPageItems(page.items))
|
|
110
|
+
.filter((text) => text.length > 0)
|
|
111
|
+
.join('\n\n');
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Split page items into sentences, each mapped to the Y of its first item, and
|
|
115
|
+
* merged when they share a Y.
|
|
116
|
+
*/
|
|
117
|
+
function splitItemsIntoSentencesWithY(items) {
|
|
118
|
+
if (items.length === 0) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
// Sort items by Y descending, then X ascending (reading order)
|
|
122
|
+
const sortedItems = [...items].sort((a, b) => {
|
|
123
|
+
const yDiff = b.y - a.y;
|
|
124
|
+
if (Math.abs(yDiff) > 1) {
|
|
125
|
+
return yDiff;
|
|
126
|
+
}
|
|
127
|
+
return a.x - b.x;
|
|
128
|
+
});
|
|
129
|
+
// Build text and track character positions to item mapping
|
|
130
|
+
const charToItem = [];
|
|
131
|
+
let fullText = '';
|
|
132
|
+
let prevY = null;
|
|
133
|
+
for (const item of sortedItems) {
|
|
134
|
+
// Insert newline when Y coordinate changes (different line)
|
|
135
|
+
// This matches joinPageItems behavior: same Y = space, different Y = newline
|
|
136
|
+
if (prevY !== null && Math.abs(prevY - item.y) > 1) {
|
|
137
|
+
fullText = `${fullText.trimEnd()}\n`;
|
|
138
|
+
}
|
|
139
|
+
charToItem.push({ start: fullText.length, item });
|
|
140
|
+
fullText += `${item.text} `;
|
|
141
|
+
prevY = item.y;
|
|
142
|
+
}
|
|
143
|
+
// Split into sentences
|
|
144
|
+
const sentences = splitIntoSentences(fullText);
|
|
145
|
+
// Map each sentence to Y coordinate of its first character's item
|
|
146
|
+
const sentencesWithY = [];
|
|
147
|
+
let searchStart = 0;
|
|
148
|
+
for (const sentence of sentences) {
|
|
149
|
+
// Find where this sentence starts in fullText
|
|
150
|
+
const sentenceStart = fullText.indexOf(sentence.trim(), searchStart);
|
|
151
|
+
// Benign skip (not error masking): this builds the Y-coordinate map used
|
|
152
|
+
// only for header/footer boundary detection. A miss means this sentence
|
|
153
|
+
// is omitted from boundary detection — it does NOT drop the sentence from
|
|
154
|
+
// the document body (that text comes from `fullText`). Misses are expected
|
|
155
|
+
// when `splitIntoSentences` normalizes whitespace differently than the
|
|
156
|
+
// reconstructed `fullText`, so logging here would be noise, not signal.
|
|
157
|
+
if (sentenceStart === -1) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Find the item that contains this position
|
|
161
|
+
let firstItemY = sortedItems[0]?.y ?? 0;
|
|
162
|
+
for (let i = charToItem.length - 1; i >= 0; i--) {
|
|
163
|
+
const entry = charToItem[i];
|
|
164
|
+
if (entry && entry.start <= sentenceStart) {
|
|
165
|
+
firstItemY = Math.round(entry.item.y);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
sentencesWithY.push({ text: sentence, y: firstItemY });
|
|
170
|
+
searchStart = sentenceStart + sentence.length;
|
|
171
|
+
}
|
|
172
|
+
// Merge sentences with same Y coordinate
|
|
173
|
+
return mergeSentencesByY(sentencesWithY);
|
|
174
|
+
}
|
|
175
|
+
/** Sentences sharing a Y coordinate are one sentence. */
|
|
176
|
+
function mergeSentencesByY(sentences) {
|
|
177
|
+
if (sentences.length === 0) {
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
const merged = [];
|
|
181
|
+
let current = null;
|
|
182
|
+
for (const sentence of sentences) {
|
|
183
|
+
if (current === null) {
|
|
184
|
+
current = { ...sentence };
|
|
185
|
+
}
|
|
186
|
+
else if (current.y === sentence.y) {
|
|
187
|
+
// Same Y: merge text
|
|
188
|
+
current.text += ` ${sentence.text}`;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
// Different Y: push current and start new
|
|
192
|
+
merged.push(current);
|
|
193
|
+
current = { ...sentence };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (current !== null) {
|
|
197
|
+
merged.push(current);
|
|
198
|
+
}
|
|
199
|
+
return merged;
|
|
200
|
+
}
|
|
201
|
+
// ============================================
|
|
202
|
+
// Sentence-Level Header/Footer Detection
|
|
203
|
+
// ============================================
|
|
204
|
+
/**
|
|
205
|
+
* Calculate cosine similarity between two vectors
|
|
206
|
+
*/
|
|
207
|
+
function cosineSimilarity(vec1, vec2) {
|
|
208
|
+
if (vec1.length !== vec2.length || vec1.length === 0) {
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
let dotProduct = 0;
|
|
212
|
+
let norm1 = 0;
|
|
213
|
+
let norm2 = 0;
|
|
214
|
+
for (let i = 0; i < vec1.length; i++) {
|
|
215
|
+
const v1 = vec1[i] ?? 0;
|
|
216
|
+
const v2 = vec2[i] ?? 0;
|
|
217
|
+
dotProduct += v1 * v2;
|
|
218
|
+
norm1 += v1 * v1;
|
|
219
|
+
norm2 += v2 * v2;
|
|
220
|
+
}
|
|
221
|
+
const denominator = Math.sqrt(norm1) * Math.sqrt(norm2);
|
|
222
|
+
if (denominator === 0) {
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
return dotProduct / denominator;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Median pairwise similarity — median rather than mean so one page with
|
|
229
|
+
* different header content (a chapter title change) cannot drag it down.
|
|
230
|
+
*/
|
|
231
|
+
function medianPairwiseSimilarity(embeddings) {
|
|
232
|
+
if (embeddings.length < 2) {
|
|
233
|
+
return 1.0;
|
|
234
|
+
}
|
|
235
|
+
const similarities = [];
|
|
236
|
+
for (let i = 0; i < embeddings.length; i++) {
|
|
237
|
+
for (let j = i + 1; j < embeddings.length; j++) {
|
|
238
|
+
const embI = embeddings[i];
|
|
239
|
+
const embJ = embeddings[j];
|
|
240
|
+
if (embI && embJ) {
|
|
241
|
+
similarities.push(cosineSimilarity(embI, embJ));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (similarities.length === 0) {
|
|
246
|
+
return 0;
|
|
247
|
+
}
|
|
248
|
+
// Sort and find median
|
|
249
|
+
similarities.sort((a, b) => a - b);
|
|
250
|
+
const mid = Math.floor(similarities.length / 2);
|
|
251
|
+
if (similarities.length % 2 === 0) {
|
|
252
|
+
// Even: average of two middle values
|
|
253
|
+
return ((similarities[mid - 1] ?? 0) + (similarities[mid] ?? 0)) / 2;
|
|
254
|
+
}
|
|
255
|
+
// Odd: middle value
|
|
256
|
+
return similarities[mid] ?? 0;
|
|
257
|
+
}
|
|
258
|
+
/** The sentence at the requested edge of a page's sampled sentences. */
|
|
259
|
+
function sentenceAtEdge(sentences, edge) {
|
|
260
|
+
if (edge === 'first') {
|
|
261
|
+
return sentences[0];
|
|
262
|
+
}
|
|
263
|
+
return sentences.length > 1 ? sentences.at(-1) : undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Sample pages from the center of the document
|
|
267
|
+
*
|
|
268
|
+
* Center pages are guaranteed to be content (not cover, TOC, or index).
|
|
269
|
+
*/
|
|
270
|
+
function sampleCenterPages(pages, sampleSize) {
|
|
271
|
+
const centerIndex = Math.floor(pages.length / 2);
|
|
272
|
+
const halfSample = Math.floor(sampleSize / 2);
|
|
273
|
+
const startIndex = Math.max(0, centerIndex - halfSample);
|
|
274
|
+
const endIndex = Math.min(pages.length, startIndex + sampleSize);
|
|
275
|
+
return pages.slice(startIndex, endIndex);
|
|
276
|
+
}
|
|
277
|
+
/** Default configuration for sentence-level pattern detection */
|
|
278
|
+
const DEFAULT_SENTENCE_PATTERN_CONFIG = {
|
|
279
|
+
similarityThreshold: 0.85,
|
|
280
|
+
minPages: 3,
|
|
281
|
+
samplePages: 5,
|
|
282
|
+
boostedThreshold: 0.75,
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Stage 1 of header/footer detection: on the sampled center pages, a small
|
|
286
|
+
* font near the top or bottom 10% of the page marks a candidate Y position.
|
|
287
|
+
*/
|
|
288
|
+
/** Median font size across the sampled pages; 0 when nothing has a size. */
|
|
289
|
+
function medianFontSizeOf(samplePages) {
|
|
290
|
+
const fontSizes = [];
|
|
291
|
+
for (const page of samplePages) {
|
|
292
|
+
for (const item of page.items) {
|
|
293
|
+
if (item.fontSize > 0) {
|
|
294
|
+
fontSizes.push(item.fontSize);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (fontSizes.length === 0) {
|
|
299
|
+
return 0;
|
|
300
|
+
}
|
|
301
|
+
fontSizes.sort((a, b) => a - b);
|
|
302
|
+
const mid = Math.floor(fontSizes.length / 2);
|
|
303
|
+
const lower = fontSizes[mid - 1] ?? 0;
|
|
304
|
+
const upper = fontSizes[mid] ?? 0;
|
|
305
|
+
return fontSizes.length % 2 === 0 ? (lower + upper) / 2 : upper;
|
|
306
|
+
}
|
|
307
|
+
/** Actual page height when a sampled page reports one, else the largest Y seen. */
|
|
308
|
+
function pageHeightOf(samplePages) {
|
|
309
|
+
const reported = samplePages.find((page) => page.pageHeight != null)?.pageHeight;
|
|
310
|
+
if (reported) {
|
|
311
|
+
return reported;
|
|
312
|
+
}
|
|
313
|
+
let maxY = 0;
|
|
314
|
+
for (const page of samplePages) {
|
|
315
|
+
for (const item of page.items) {
|
|
316
|
+
if (item.y > maxY) {
|
|
317
|
+
maxY = item.y;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return maxY;
|
|
322
|
+
}
|
|
323
|
+
/** Small-font items sitting in the top or bottom 10% of the page. */
|
|
324
|
+
function collectEdgeCandidateYs(samplePages, fontSizeThreshold, pageHeight) {
|
|
325
|
+
const headerCandidateYs = new Set();
|
|
326
|
+
const footerCandidateYs = new Set();
|
|
327
|
+
for (const page of samplePages) {
|
|
328
|
+
for (const item of page.items) {
|
|
329
|
+
if (item.fontSize >= fontSizeThreshold) {
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
const roundedY = Math.round(item.y);
|
|
333
|
+
// Header: top 10% of page (large Y values, since Y is inverted)
|
|
334
|
+
if (item.y > pageHeight * 0.9) {
|
|
335
|
+
headerCandidateYs.add(roundedY);
|
|
336
|
+
}
|
|
337
|
+
// Footer: bottom 10% of page (small Y values)
|
|
338
|
+
if (item.y < pageHeight * 0.1) {
|
|
339
|
+
footerCandidateYs.add(roundedY);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return { headerCandidateYs, footerCandidateYs };
|
|
344
|
+
}
|
|
345
|
+
export function detectBlockAttributeCandidates(pages, config = {}) {
|
|
346
|
+
const cfg = { ...DEFAULT_SENTENCE_PATTERN_CONFIG, ...config };
|
|
347
|
+
const emptyResult = {
|
|
348
|
+
medianFontSize: 0,
|
|
349
|
+
headerCandidateYs: new Set(),
|
|
350
|
+
footerCandidateYs: new Set(),
|
|
351
|
+
};
|
|
352
|
+
if (pages.length < cfg.minPages) {
|
|
353
|
+
return emptyResult;
|
|
354
|
+
}
|
|
355
|
+
const samplePages = sampleCenterPages(pages, cfg.samplePages);
|
|
356
|
+
const medianFontSize = medianFontSizeOf(samplePages);
|
|
357
|
+
if (medianFontSize === 0) {
|
|
358
|
+
return emptyResult;
|
|
359
|
+
}
|
|
360
|
+
const pageHeight = pageHeightOf(samplePages);
|
|
361
|
+
if (pageHeight === 0) {
|
|
362
|
+
return { ...emptyResult, medianFontSize };
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
medianFontSize,
|
|
366
|
+
...collectEdgeCandidateYs(samplePages, medianFontSize * 0.7, pageHeight),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Detect header/footer patterns at sentence level.
|
|
371
|
+
*
|
|
372
|
+
* Center pages are sampled because cover, TOC and index sit at the edges, and
|
|
373
|
+
* the median pairwise similarity resists an outlier page. Semantic similarity
|
|
374
|
+
* rather than exact matching is what makes variable text like "7 of 75" match.
|
|
375
|
+
*/
|
|
376
|
+
/**
|
|
377
|
+
* Shared boundary-pattern detection for the header and footer cases of
|
|
378
|
+
* {@link detectSentencePatterns}. The divergent part — which sentence each page
|
|
379
|
+
* contributes and how its Y is derived — is passed in, so this helper is
|
|
380
|
+
* identical for both boundaries.
|
|
381
|
+
*/
|
|
382
|
+
async function detectBoundaryPattern(params) {
|
|
383
|
+
const { label, sentences, sentenceYs, candidateYs, similarityThreshold, boostedThreshold, embedder, startIndex, endIndex, } = params;
|
|
384
|
+
const embeddings = await embedder.embedBatch(sentences);
|
|
385
|
+
const medianSim = medianPairwiseSimilarity(embeddings);
|
|
386
|
+
// Determine effective threshold (boosted if block hints match)
|
|
387
|
+
let threshold = similarityThreshold;
|
|
388
|
+
if (candidateYs && sentenceYs.some((y) => candidateYs.has(y))) {
|
|
389
|
+
threshold = boostedThreshold ?? 0.75;
|
|
390
|
+
}
|
|
391
|
+
const detected = medianSim >= threshold;
|
|
392
|
+
if (detected) {
|
|
393
|
+
console.error(`Sentence ${label} detected: sampled ${sentences.length} center pages (${startIndex + 1}-${endIndex}), median similarity: ${medianSim.toFixed(3)}`);
|
|
394
|
+
}
|
|
395
|
+
return { similarity: medianSim, detected };
|
|
396
|
+
}
|
|
397
|
+
export async function detectSentencePatterns(pages, embedder, config = {}) {
|
|
398
|
+
const cfg = { ...DEFAULT_SENTENCE_PATTERN_CONFIG, ...config };
|
|
399
|
+
const result = {
|
|
400
|
+
removeFirstSentence: false,
|
|
401
|
+
removeLastSentence: false,
|
|
402
|
+
headerSimilarity: 0,
|
|
403
|
+
footerSimilarity: 0,
|
|
404
|
+
};
|
|
405
|
+
// Need minimum pages to detect patterns reliably
|
|
406
|
+
if (pages.length < cfg.minPages) {
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
// 1. Sample pages from the CENTER of the document
|
|
410
|
+
const samplePages = sampleCenterPages(pages, cfg.samplePages);
|
|
411
|
+
const firstSamplePage = samplePages[0];
|
|
412
|
+
const startIndex = firstSamplePage === undefined ? 0 : pages.indexOf(firstSamplePage);
|
|
413
|
+
const endIndex = startIndex + samplePages.length;
|
|
414
|
+
// 2. Split each page into sentences with Y coordinate (merged by Y)
|
|
415
|
+
const pageSentences = samplePages.map((page) => splitItemsIntoSentencesWithY(page.items));
|
|
416
|
+
// 3. Collect first and last sentences from sampled pages
|
|
417
|
+
const firstSentences = [];
|
|
418
|
+
const lastSentences = [];
|
|
419
|
+
for (const sentences of pageSentences) {
|
|
420
|
+
const first = sentences[0];
|
|
421
|
+
if (first === undefined) {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
firstSentences.push(first.text);
|
|
425
|
+
const last = sentences.length > 1 ? sentences.at(-1) : undefined;
|
|
426
|
+
if (last !== undefined) {
|
|
427
|
+
lastSentences.push(last.text);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// 5. Detect header pattern (sampled first sentences are semantically similar)
|
|
431
|
+
if (firstSentences.length >= cfg.minPages) {
|
|
432
|
+
const firstSentenceYs = pageSentences
|
|
433
|
+
.filter((s) => s.length > 0)
|
|
434
|
+
.map((s) => Math.round(s[0]?.y ?? 0));
|
|
435
|
+
const { similarity, detected } = await detectBoundaryPattern({
|
|
436
|
+
label: 'header',
|
|
437
|
+
sentences: firstSentences,
|
|
438
|
+
sentenceYs: firstSentenceYs,
|
|
439
|
+
candidateYs: cfg.blockHints?.headerCandidateYs,
|
|
440
|
+
similarityThreshold: cfg.similarityThreshold,
|
|
441
|
+
boostedThreshold: cfg.boostedThreshold,
|
|
442
|
+
embedder,
|
|
443
|
+
startIndex,
|
|
444
|
+
endIndex,
|
|
445
|
+
});
|
|
446
|
+
result.headerSimilarity = similarity;
|
|
447
|
+
result.removeFirstSentence = detected;
|
|
448
|
+
}
|
|
449
|
+
// 6. Detect footer pattern (sampled last sentences are semantically similar)
|
|
450
|
+
if (lastSentences.length >= cfg.minPages) {
|
|
451
|
+
const lastSentenceYs = pageSentences
|
|
452
|
+
.filter((s) => s.length > 1)
|
|
453
|
+
.map((s) => Math.round(s.at(-1)?.y ?? 0));
|
|
454
|
+
const { similarity, detected } = await detectBoundaryPattern({
|
|
455
|
+
label: 'footer',
|
|
456
|
+
sentences: lastSentences,
|
|
457
|
+
sentenceYs: lastSentenceYs,
|
|
458
|
+
candidateYs: cfg.blockHints?.footerCandidateYs,
|
|
459
|
+
similarityThreshold: cfg.similarityThreshold,
|
|
460
|
+
boostedThreshold: cfg.boostedThreshold,
|
|
461
|
+
embedder,
|
|
462
|
+
startIndex,
|
|
463
|
+
endIndex,
|
|
464
|
+
});
|
|
465
|
+
result.footerSimilarity = similarity;
|
|
466
|
+
result.removeLastSentence = detected;
|
|
467
|
+
}
|
|
468
|
+
return result;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Main entry point for sentence-level header/footer filtering: removes
|
|
472
|
+
* repeating boundary sentences and returns one filtered text per page.
|
|
473
|
+
*
|
|
474
|
+
* Use this rather than {@link joinFilteredPages} when an embedder is available.
|
|
475
|
+
*/
|
|
476
|
+
export async function filterPageBoundarySentences(pages, embedder, config = {}) {
|
|
477
|
+
return (await filterPageBoundaryLayouts(pages, embedder, config)).map((page) => page.text);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Filter page boundaries while retaining native provenance for every survivor.
|
|
481
|
+
*/
|
|
482
|
+
export async function filterPageBoundaryLayouts(pages, embedder, config = {}) {
|
|
483
|
+
const cfg = { ...DEFAULT_SENTENCE_PATTERN_CONFIG, ...config };
|
|
484
|
+
// Need minimum pages to detect patterns
|
|
485
|
+
if (pages.length < cfg.minPages) {
|
|
486
|
+
return pages.map((page) => buildPageLayout(page.pageNum, page.items));
|
|
487
|
+
}
|
|
488
|
+
// Detect block attribute candidates for boosted threshold
|
|
489
|
+
const blockHints = detectBlockAttributeCandidates(pages, cfg);
|
|
490
|
+
// Detect patterns (with block hints for boosted threshold)
|
|
491
|
+
const patterns = await detectSentencePatterns(pages, embedder, { ...cfg, blockHints });
|
|
492
|
+
// If no patterns detected, return normally joined text per page
|
|
493
|
+
if (!patterns.removeFirstSentence && !patterns.removeLastSentence) {
|
|
494
|
+
return pages.map((page) => buildPageLayout(page.pageNum, page.items));
|
|
495
|
+
}
|
|
496
|
+
// Split each page into sentences with Y coordinate (merged by Y)
|
|
497
|
+
const pageSentences = pages.map((page) => splitItemsIntoSentencesWithY(page.items));
|
|
498
|
+
const sampledSentences = sampleCenterPages(pages, cfg.samplePages).map((page) => pageSentences[pages.indexOf(page)] ?? []);
|
|
499
|
+
const matchesRepeatedBoundary = (sentence, edge) => {
|
|
500
|
+
if (!sentence) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
// Page numbers may vary; other text and rounded position must repeat.
|
|
504
|
+
const key = (value) => `${Math.round(value.y)}:${value.text.replace(/\d+/g, '#').replace(/\s+/g, ' ').trim()}`;
|
|
505
|
+
const target = key(sentence);
|
|
506
|
+
return (sampledSentences.filter((sentences) => {
|
|
507
|
+
const candidate = sentenceAtEdge(sentences, edge);
|
|
508
|
+
return candidate !== undefined && key(candidate) === target;
|
|
509
|
+
}).length >= 2);
|
|
510
|
+
};
|
|
511
|
+
return pages.map((page, pageIndex) => {
|
|
512
|
+
let cleaned = [...(pageSentences[pageIndex] ?? [])];
|
|
513
|
+
if (patterns.removeFirstSentence && matchesRepeatedBoundary(cleaned[0], 'first')) {
|
|
514
|
+
cleaned = cleaned.slice(1);
|
|
515
|
+
}
|
|
516
|
+
if (patterns.removeLastSentence && matchesRepeatedBoundary(cleaned.at(-1), 'last')) {
|
|
517
|
+
cleaned = cleaned.slice(0, -1);
|
|
518
|
+
}
|
|
519
|
+
return buildSentenceLayout(page.pageNum, cleaned, page.items);
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
//# sourceMappingURL=pdf-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-filter.js","sourceRoot":"","sources":["../../src/parser/pdf-filter.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,wDAAwD;AACxD,uEAAuE;AAGvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAiEpE,SAAS,eAAe,CAAC,OAAe,EAAE,KAA6B;IACrE,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,YAA8C,CAAA;IAClD,MAAM,YAAY,GAAkB,EAAE,CAAA;IACtC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEhD,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAClC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAC9E,CAAA;IACD,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;QACpC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,SAAQ;QACV,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;QAC3E,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAA;QAC/B,OAAO,IAAI,IAAI,CAAC,IAAI,CAAA;QACpB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC,CAAA;QAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,SAAS,CAAA;QACjD,MAAM,OAAO,GAAG,GAAG,YAAY,IAAI,WAAW,EAAE,CAAA;QAChD,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACxD,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,GAAG,CAAC,CAAC,CAAA;QAChD,YAAY,CAAC,IAAI,CAAC;YAChB,OAAO;YACP,YAAY;YACZ,WAAW;YACX,eAAe;YACf,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YACnD,QAAQ;YACR,MAAM;SACP,CAAC,CAAA;QACF,YAAY,GAAG,IAAI,CAAA;IACrB,CAAC;IAED,OAAO,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;AAC9C,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,YAAoC;IAC3E,MAAM,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,CAAA;IACrE,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,CAAA;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAA;IAC/D,MAAM,aAAa,GAA2B,EAAE,CAAA;IAEhD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAA;QACnE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;QAC9D,IAAI,YAAY,IAAI,UAAU,EAAE,CAAC;YAC/B,SAAQ;QACV,CAAC;QACD,MAAM,aAAa,GAAG,YAAY,GAAG,iBAAiB,CAAA;QACtD,MAAM,WAAW,GAAG,UAAU,GAAG,iBAAiB,CAAA;QAClD,aAAa,CAAC,IAAI,CAAC;YACjB,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,WAAW,CAAC;YAC5C,aAAa;YACb,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;AAChC,CAAC;AAED,SAAS,mBAAmB,CAC1B,OAAe,EACf,SAAmC,EACnC,KAAsC;IAEtC,IAAI,IAAI,GAAG,EAAE,CAAA;IACb,MAAM,aAAa,GAA2B,EAAE,CAAA;IAChD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,IAAI,GAAG,CAAA;QACb,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAA;QACrB,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3F,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;QAC9B,MAAM,KAAK,GAA4C,aAAa,CAAC,GAAG,CACtE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CACxD,CAAA;QACD,MAAM,IAAI,GAAqC,KAAK,CAAC,MAAM;YACzD,CAAC,CAAC;gBACE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aACxC;YACH,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAChB,aAAa,CAAC,IAAI,CAAC;YACjB,OAAO;YACP,YAAY,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;YACtC,WAAW,EAAE,KAAK,EAAE,WAAW,IAAI,aAAa,CAAC,MAAM;YACvD,eAAe,EAAE,CAAC;YAClB,IAAI;YACJ,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,aAAa,EAAE,KAAK;YACpB,WAAW,EAAE,IAAI,CAAC,MAAM;SACzB,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;AAChC,CAAC;AAED,SAAS,aAAa,CAAC,KAA6B;IAClD,OAAO,eAAe,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAA;AACvC,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IACjD,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,IAAI,CAAC,MAAM,CAAC,CAAA;AACjB,CAAC;AAcD;;;GAGG;AACH,SAAS,4BAA4B,CAAC,KAA6B;IACjE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,+DAA+D;IAC/D,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACvB,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAClB,CAAC,CAAC,CAAA;IAEF,2DAA2D;IAC3D,MAAM,UAAU,GAAyD,EAAE,CAAA;IAC3E,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,IAAI,KAAK,GAAkB,IAAI,CAAA;IAE/B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,4DAA4D;QAC5D,6EAA6E;QAC7E,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YACnD,QAAQ,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;QACtC,CAAC;QAED,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACjD,QAAQ,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,CAAA;QAC3B,KAAK,GAAG,IAAI,CAAC,CAAC,CAAA;IAChB,CAAC;IAED,uBAAuB;IACvB,MAAM,SAAS,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;IAE9C,kEAAkE;IAClE,MAAM,cAAc,GAAoB,EAAE,CAAA;IAC1C,IAAI,WAAW,GAAG,CAAC,CAAA;IAEnB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,8CAA8C;QAC9C,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAA;QACpE,yEAAyE;QACzE,wEAAwE;QACxE,0EAA0E;QAC1E,2EAA2E;QAC3E,uEAAuE;QACvE,wEAAwE;QACxE,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;YACzB,SAAQ;QACV,CAAC;QAED,4CAA4C;QAC5C,IAAI,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QACvC,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;YAC3B,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,aAAa,EAAE,CAAC;gBAC1C,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACrC,MAAK;YACP,CAAC;QACH,CAAC;QAED,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;QACtD,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAA;IAC/C,CAAC;IAED,yCAAyC;IACzC,OAAO,iBAAiB,CAAC,cAAc,CAAC,CAAA;AAC1C,CAAC;AAED,yDAAyD;AACzD,SAAS,iBAAiB,CAAC,SAA0B;IACnD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,MAAM,GAAoB,EAAE,CAAA;IAClC,IAAI,OAAO,GAAyB,IAAI,CAAA;IAExC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAA;QAC3B,CAAC;aAAM,IAAI,OAAO,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC;YACpC,qBAAqB;YACrB,OAAO,CAAC,IAAI,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAA;QACrC,CAAC;aAAM,CAAC;YACN,0CAA0C;YAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACpB,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,+CAA+C;AAC/C,yCAAyC;AACzC,+CAA+C;AAE/C;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAc,EAAE,IAAc;IACtD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,CAAA;IACV,CAAC;IAED,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACvB,UAAU,IAAI,EAAE,GAAG,EAAE,CAAA;QACrB,KAAK,IAAI,EAAE,GAAG,EAAE,CAAA;QAChB,KAAK,IAAI,EAAE,GAAG,EAAE,CAAA;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACvD,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,OAAO,UAAU,GAAG,WAAW,CAAA;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB,CAAC,UAAsB;IACtD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;YAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;YAC1B,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBACjB,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;YACjD,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAA;IACV,CAAC;IAED,uBAAuB;IACvB,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAE/C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,qCAAqC;QACrC,OAAO,CAAC,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACtE,CAAC;IACD,oBAAoB;IACpB,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAED,wEAAwE;AACxE,SAAS,cAAc,CAAI,SAAuB,EAAE,IAAsB;IACxE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC,CAAC,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,KAAiB,EAAE,UAAkB;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC,CAAA;IAChE,OAAO,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;AAC1C,CAAC;AAkBD,iEAAiE;AACjE,MAAM,+BAA+B,GAA0B;IAC7D,mBAAmB,EAAE,IAAI;IACzB,QAAQ,EAAE,CAAC;IACX,WAAW,EAAE,CAAC;IACd,gBAAgB,EAAE,IAAI;CACvB,CAAA;AAeD;;;GAGG;AACH,4EAA4E;AAC5E,SAAS,gBAAgB,CAAC,WAAgC;IACxD,MAAM,SAAS,GAAa,EAAE,CAAA;IAC9B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACtB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,CAAA;IACV,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AACjE,CAAC;AAED,mFAAmF;AACnF,SAAS,YAAY,CAAC,WAAgC;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,EAAE,UAAU,CAAA;IAChF,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;gBAClB,IAAI,GAAG,IAAI,CAAC,CAAC,CAAA;YACf,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,qEAAqE;AACrE,SAAS,sBAAsB,CAC7B,WAAgC,EAChC,iBAAyB,EACzB,UAAkB;IAElB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAA;IAC3C,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAA;IAC3C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,QAAQ,IAAI,iBAAiB,EAAE,CAAC;gBACvC,SAAQ;YACV,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACnC,gEAAgE;YAChE,IAAI,IAAI,CAAC,CAAC,GAAG,UAAU,GAAG,GAAG,EAAE,CAAC;gBAC9B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YACjC,CAAC;YACD,8CAA8C;YAC9C,IAAI,IAAI,CAAC,CAAC,GAAG,UAAU,GAAG,GAAG,EAAE,CAAC;gBAC9B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,KAAiB,EACjB,MAAM,GAAqE,EAAE;IAE7E,MAAM,GAAG,GAAG,EAAE,GAAG,+BAA+B,EAAE,GAAG,MAAM,EAAE,CAAA;IAC7D,MAAM,WAAW,GAAwB;QACvC,cAAc,EAAE,CAAC;QACjB,iBAAiB,EAAE,IAAI,GAAG,EAAE;QAC5B,iBAAiB,EAAE,IAAI,GAAG,EAAE;KAC7B,CAAA;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAA;IAC7D,MAAM,cAAc,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;IACpD,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;IAC5C,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,GAAG,WAAW,EAAE,cAAc,EAAE,CAAA;IAC3C,CAAC;IAED,OAAO;QACL,cAAc;QACd,GAAG,sBAAsB,CAAC,WAAW,EAAE,cAAc,GAAG,GAAG,EAAE,UAAU,CAAC;KACzE,CAAA;AACH,CAAC;AAgBD;;;;;;GAMG;AACH;;;;;GAKG;AACH,KAAK,UAAU,qBAAqB,CAAC,MAUpC;IACC,MAAM,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,QAAQ,GACT,GAAG,MAAM,CAAA;IAEV,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IACvD,MAAM,SAAS,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAA;IAEtD,+DAA+D;IAC/D,IAAI,SAAS,GAAG,mBAAmB,CAAA;IACnC,IAAI,WAAW,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,SAAS,GAAG,gBAAgB,IAAI,IAAI,CAAA;IACtC,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,IAAI,SAAS,CAAA;IACvC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,YAAY,KAAK,sBAAsB,SAAS,CAAC,MAAM,kBAAkB,UAAU,GAAG,CAAC,IAAI,QAAQ,yBAAyB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CACnJ,CAAA;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAiB,EACjB,QAA2B,EAC3B,MAAM,GAAmC,EAAE;IAE3C,MAAM,GAAG,GAAG,EAAE,GAAG,+BAA+B,EAAE,GAAG,MAAM,EAAE,CAAA;IAE7D,MAAM,MAAM,GAA0B;QACpC,mBAAmB,EAAE,KAAK;QAC1B,kBAAkB,EAAE,KAAK;QACzB,gBAAgB,EAAE,CAAC;QACnB,gBAAgB,EAAE,CAAC;KACpB,CAAA;IAED,iDAAiD;IACjD,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,kDAAkD;IAClD,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAA;IAC7D,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IACtC,MAAM,UAAU,GAAG,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACrF,MAAM,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC,MAAM,CAAA;IAEhD,oEAAoE;IACpE,MAAM,aAAa,GAAsB,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAChE,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CACzC,CAAA;IAED,yDAAyD;IACzD,MAAM,cAAc,GAAa,EAAE,CAAA;IACnC,MAAM,aAAa,GAAa,EAAE,CAAA;IAElC,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,SAAQ;QACV,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAChE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,IAAI,cAAc,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,eAAe,GAAG,aAAa;aAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;aAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACvC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,qBAAqB,CAAC;YAC3D,KAAK,EAAE,QAAQ;YACf,SAAS,EAAE,cAAc;YACzB,UAAU,EAAE,eAAe;YAC3B,WAAW,EAAE,GAAG,CAAC,UAAU,EAAE,iBAAiB;YAC9C,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,QAAQ;YACR,UAAU;YACV,QAAQ;SACT,CAAC,CAAA;QACF,MAAM,CAAC,gBAAgB,GAAG,UAAU,CAAA;QACpC,MAAM,CAAC,mBAAmB,GAAG,QAAQ,CAAA;IACvC,CAAC;IAED,6EAA6E;IAC7E,IAAI,aAAa,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,cAAc,GAAG,aAAa;aACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;aAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC3C,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,qBAAqB,CAAC;YAC3D,KAAK,EAAE,QAAQ;YACf,SAAS,EAAE,aAAa;YACxB,UAAU,EAAE,cAAc;YAC1B,WAAW,EAAE,GAAG,CAAC,UAAU,EAAE,iBAAiB;YAC9C,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,QAAQ;YACR,UAAU;YACV,QAAQ;SACT,CAAC,CAAA;QACF,MAAM,CAAC,gBAAgB,GAAG,UAAU,CAAA;QACpC,MAAM,CAAC,kBAAkB,GAAG,QAAQ,CAAA;IACtC,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAiB,EACjB,QAA2B,EAC3B,MAAM,GAAmC,EAAE;IAE3C,OAAO,CAAC,MAAM,yBAAyB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC5F,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,KAAiB,EACjB,QAA2B,EAC3B,MAAM,GAAmC,EAAE;IAE3C,MAAM,GAAG,GAAG,EAAE,GAAG,+BAA+B,EAAE,GAAG,MAAM,EAAE,CAAA;IAE7D,wCAAwC;IACxC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,0DAA0D;IAC1D,MAAM,UAAU,GAAG,8BAA8B,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAE7D,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,CAAC,CAAA;IAEtF,gEAAgE;IAChE,IAAI,CAAC,QAAQ,CAAC,mBAAmB,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QAClE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,iEAAiE;IACjE,MAAM,aAAa,GAAsB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC1D,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CACzC,CAAA;IAED,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CACpE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CACnD,CAAA;IACD,MAAM,uBAAuB,GAAG,CAC9B,QAAmC,EACnC,IAAsB,EACb,EAAE;QACX,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAA;QACd,CAAC;QACD,sEAAsE;QACtE,MAAM,GAAG,GAAG,CAAC,KAAoB,EAAU,EAAE,CAC3C,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;QACzF,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC5B,OAAO,CACL,gBAAgB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;YACpC,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YACjD,OAAO,SAAS,KAAK,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,MAAM,CAAA;QAC7D,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CACf,CAAA;IACH,CAAC,CAAA;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;QACnC,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACnD,IAAI,QAAQ,CAAC,mBAAmB,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;YACjF,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;QACD,IAAI,QAAQ,CAAC,kBAAkB,IAAI,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;YACnF,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAChC,CAAC;QACD,OAAO,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of title extraction, including how the title was determined
|
|
3
|
+
*/
|
|
4
|
+
export interface TitleExtractionResult {
|
|
5
|
+
title: string;
|
|
6
|
+
source: 'metadata' | 'content' | 'filename';
|
|
7
|
+
}
|
|
8
|
+
/** `2024-annual-report.pdf` -> `2024 annual report`. */
|
|
9
|
+
export declare function fileNameToTitle(fileName: string): string;
|
|
10
|
+
/** Priority: YAML frontmatter title -> first `#` H1 -> file name. */
|
|
11
|
+
export declare function extractMarkdownTitle(text: string, fileName: string): TitleExtractionResult;
|
|
12
|
+
/** Priority: a first line followed by a blank line -> file name. */
|
|
13
|
+
export declare function extractTxtTitle(text: string, fileName: string): TitleExtractionResult;
|
|
14
|
+
/** Priority: Readability title -> file name. */
|
|
15
|
+
export declare function extractHtmlTitle(readabilityTitle: string, fileName: string): TitleExtractionResult;
|
|
16
|
+
/**
|
|
17
|
+
* Priority: PDF metadata `/Title` -> page-1 chunk 0 -> file name.
|
|
18
|
+
*
|
|
19
|
+
* A metadata title that looks like a file path (contains `/` or `\`) is
|
|
20
|
+
* rejected, since some producers write the source path there.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractPdfTitle(metadataTitle: string | undefined, firstPageChunkText: string | undefined, fileName: string, firstPageFontHint?: {
|
|
23
|
+
text: string;
|
|
24
|
+
fontSize: number;
|
|
25
|
+
}): TitleExtractionResult;
|
|
26
|
+
/** Priority: DOCX core title -> first non-empty `<h1>` -> file name. */
|
|
27
|
+
export declare function extractDocxTitle(document: Document, fileName: string, metadataTitle?: string): TitleExtractionResult;
|
|
28
|
+
//# sourceMappingURL=title-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"title-extractor.d.ts","sourceRoot":"","sources":["../../src/parser/title-extractor.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;CAC5C;AAMD,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMxD;AAMD,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAe1F;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAkBrF;AAED,gDAAgD;AAChD,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,qBAAqB,CAOvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD,qBAAqB,CA0BvB;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,GACrB,qBAAqB,CAevB"}
|