token-goat 2.9.13 → 2.9.14
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/README.md +13 -0
- package/dist/token-goat-chunk-2ESBO4IN.mjs +209 -0
- package/dist/token-goat-chunk-3BTK54F3.mjs +1733 -0
- package/dist/{token-goat-chunk-2WC4ZUXN.mjs → token-goat-chunk-3XQPEJMV.mjs} +1 -1
- package/dist/token-goat-chunk-4SDX3QP3.mjs +122 -0
- package/dist/token-goat-chunk-7OGKZ7AP.mjs +142 -0
- package/dist/token-goat-chunk-AH6QILZM.mjs +26 -0
- package/dist/token-goat-chunk-AMYCQJX4.mjs +1548 -0
- package/dist/{token-goat-chunk-6B44WLIF.mjs → token-goat-chunk-ASVVF4JV.mjs} +10 -7
- package/dist/{token-goat-chunk-3ESRORNM.mjs → token-goat-chunk-DAMXYVIW.mjs} +12026 -11796
- package/dist/{token-goat-chunk-YOA4N6WA.mjs → token-goat-chunk-DBNY4RLN.mjs} +2 -2
- package/dist/token-goat-chunk-EG3663UT.mjs +226 -0
- package/dist/token-goat-chunk-EZNVAIR3.mjs +21 -0
- package/dist/token-goat-chunk-GMOUBOX4.mjs +386 -0
- package/dist/{token-goat-chunk-B3CTCQTH.mjs → token-goat-chunk-HF6H7RNK.mjs} +1 -1
- package/dist/{token-goat-chunk-ZZI3IDQZ.mjs → token-goat-chunk-IT6O3PNN.mjs} +2874 -7088
- package/dist/token-goat-chunk-NEI4NC54.mjs +424 -0
- package/dist/token-goat-chunk-O5WAMISC.mjs +167 -0
- package/dist/{token-goat-chunk-RDITECDL.mjs → token-goat-chunk-PGGDW7DZ.mjs} +28 -13
- package/dist/token-goat-chunk-POBYR64E.mjs +1632 -0
- package/dist/{token-goat-chunk-4NXUKV7D.mjs → token-goat-chunk-PRJVGIC5.mjs} +6 -4
- package/dist/{token-goat-chunk-U7X6LQD2.mjs → token-goat-chunk-RUDOKYPJ.mjs} +10160 -10053
- package/dist/token-goat-chunk-SAQ5PG4L.mjs +2634 -0
- package/dist/{token-goat-chunk-UMXJN7DI.mjs → token-goat-chunk-T2IWWTHB.mjs} +288 -2654
- package/dist/{token-goat-chunk-JOXLE672.mjs → token-goat-chunk-VZYD4OZB.mjs} +1164 -92
- package/dist/token-goat-chunk-XEH6KBWW.mjs +23 -0
- package/dist/token-goat-chunk-XQF5J25J.mjs +33 -0
- package/dist/token-goat-chunk-XTQAOTSO.mjs +89 -0
- package/dist/{token-goat-chunk-QWSUZWFP.mjs → token-goat-chunk-XVZ4MNQC.mjs} +587 -587
- package/dist/token-goat-chunk-Y4AFKTHK.mjs +22 -0
- package/dist/token-goat-chunk-YHGTGG6K.mjs +396 -0
- package/dist/{token-goat-chunk-FZU7GMUS.mjs → token-goat-chunk-YTQHZJXW.mjs} +20 -11
- package/dist/token-goat-chunk-Z6UXPYJA.mjs +62 -0
- package/dist/token-goat-chunk-ZD4EM4LR.mjs +30 -0
- package/dist/token-goat-chunk-ZFM4PWXL.mjs +585 -0
- package/dist/{token-goat-chunk-FQCNJV4V.mjs → token-goat-chunk-ZYNNQ36L.mjs} +116 -330
- package/dist/token-goat-hook.mjs +12 -8
- package/dist/token-goat.core.mjs +22 -10
- package/docs/cli.md +1 -0
- package/package.json +4 -2
- package/dist/token-goat-chunk-JVNPCQB7.mjs +0 -31
- package/dist/token-goat-chunk-P2PU4CR5.mjs +0 -26
- package/dist/token-goat-chunk-QKXBGBQR.mjs +0 -3653
- package/dist/token-goat-chunk-UM47DRD3.mjs +0 -242
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
isSupportedOcrLang,
|
|
6
6
|
loadConfig,
|
|
7
7
|
resolveOcrLangs
|
|
8
|
-
} from "./token-goat-chunk-
|
|
8
|
+
} from "./token-goat-chunk-SAQ5PG4L.mjs";
|
|
9
9
|
import {
|
|
10
10
|
ensureDirSync,
|
|
11
11
|
fenceUntrustedOcrText,
|
|
12
12
|
tokenGoatHome
|
|
13
|
-
} from "./token-goat-chunk-
|
|
13
|
+
} from "./token-goat-chunk-AMYCQJX4.mjs";
|
|
14
14
|
import {
|
|
15
15
|
init_define_import_meta_env
|
|
16
16
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
parse
|
|
5
|
+
} from "./token-goat-chunk-3BTK54F3.mjs";
|
|
6
|
+
import {
|
|
7
|
+
displaySafeText,
|
|
8
|
+
filtersFilteredToEmptyNotice
|
|
9
|
+
} from "./token-goat-chunk-AMYCQJX4.mjs";
|
|
10
|
+
import {
|
|
11
|
+
compileGuardedRegexCached
|
|
12
|
+
} from "./token-goat-chunk-GMOUBOX4.mjs";
|
|
13
|
+
import {
|
|
14
|
+
init_define_import_meta_env
|
|
15
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
16
|
+
|
|
17
|
+
// src/csv_query.ts
|
|
18
|
+
init_define_import_meta_env();
|
|
19
|
+
var DELIMITER_CANDIDATES = [",", " ", ";", "|"];
|
|
20
|
+
var DELIMITER_SAMPLE_ROWS = 5;
|
|
21
|
+
function detectDelimiter(content) {
|
|
22
|
+
const slice = content.slice(0, 1e4);
|
|
23
|
+
if (slice.trim() === "") return ",";
|
|
24
|
+
for (const cand of DELIMITER_CANDIDATES) {
|
|
25
|
+
let rows;
|
|
26
|
+
try {
|
|
27
|
+
rows = parse(slice, { columns: false, skip_empty_lines: true, trim: true, delimiter: cand, bom: true, relax_quotes: true, to: DELIMITER_SAMPLE_ROWS });
|
|
28
|
+
} catch {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if ((rows[0]?.length ?? 0) < 2) continue;
|
|
32
|
+
return cand;
|
|
33
|
+
}
|
|
34
|
+
return ",";
|
|
35
|
+
}
|
|
36
|
+
function parseRecords(content, opts) {
|
|
37
|
+
const delimiter = opts.delimiter ?? detectDelimiter(content);
|
|
38
|
+
if (opts.noHeader === true) {
|
|
39
|
+
const rows = parse(content, { columns: false, skip_empty_lines: true, trim: true, delimiter, bom: true, relax_column_count: true, relax_quotes: true });
|
|
40
|
+
return rows.map((row) => Object.fromEntries(row.map((cell, i) => [`col${i + 1}`, cell])));
|
|
41
|
+
}
|
|
42
|
+
const header = csvHeader(content, { ...opts, delimiter });
|
|
43
|
+
const dupes = header.filter((name, i) => name !== "" && header.indexOf(name) !== i);
|
|
44
|
+
if (dupes.length > 0) {
|
|
45
|
+
const unique = [...new Set(dupes)];
|
|
46
|
+
throw new Error(
|
|
47
|
+
`duplicate column ${unique.length === 1 ? "name" : "names"} in header: ${unique.join(", ")} \u2014 rename the duplicates or pass --no-header to address columns positionally as col1, col2, \u2026`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return parse(content, { columns: true, skip_empty_lines: true, trim: true, delimiter, bom: true, relax_column_count: true, relax_quotes: true });
|
|
51
|
+
}
|
|
52
|
+
function csvHeader(content, opts) {
|
|
53
|
+
if (opts.noHeader === true) return [];
|
|
54
|
+
const delimiter = opts.delimiter ?? detectDelimiter(content);
|
|
55
|
+
try {
|
|
56
|
+
const rows = parse(content, { columns: false, skip_empty_lines: true, trim: true, delimiter, bom: true, to: 1, relax_quotes: true });
|
|
57
|
+
return rows[0] ?? [];
|
|
58
|
+
} catch {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
var WHERE_SPEC_RE = /^((?:[^=<>~!]|!(?!=)|~(?!=))+)(!=|~=|>=|<=|=|>|<)(.*)$/;
|
|
63
|
+
function parseWhereSpecs(specs) {
|
|
64
|
+
if (specs === void 0 || specs.length === 0) return void 0;
|
|
65
|
+
return specs.map((spec) => {
|
|
66
|
+
const m = WHERE_SPEC_RE.exec(spec);
|
|
67
|
+
if (!m) throw new Error(`invalid --where spec: ${spec} (expected col=value, col!=value, col>value, col<value, col>=value, or col<=value, or col~=regex)`);
|
|
68
|
+
const op = m[2];
|
|
69
|
+
const value = m[3];
|
|
70
|
+
if ((op === ">" || op === "<" || op === ">=" || op === "<=") && value.trim() === "") {
|
|
71
|
+
throw new Error(`invalid --where spec: ${spec} (missing comparison value after '${op}')`);
|
|
72
|
+
}
|
|
73
|
+
if (op === "~=") {
|
|
74
|
+
const guarded = compileGuardedRegexCached(value);
|
|
75
|
+
if (!guarded.ok) throw new Error(`invalid --where spec: ${spec} (the pattern ${guarded.reason})`);
|
|
76
|
+
}
|
|
77
|
+
return { column: m[1].trim(), op, value };
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function resolveWhereColumn(where, allColumns) {
|
|
81
|
+
const rawSpec = where.column + where.op + where.value;
|
|
82
|
+
let best = where;
|
|
83
|
+
for (const col of allColumns) {
|
|
84
|
+
if (col.length <= best.column.length) continue;
|
|
85
|
+
if (!rawSpec.startsWith(col)) continue;
|
|
86
|
+
const rest = rawSpec.slice(col.length);
|
|
87
|
+
const m = /^(!=|~=|>=|<=|=|>|<)(.*)$/.exec(rest);
|
|
88
|
+
if (m) {
|
|
89
|
+
best = { column: col, op: m[1], value: m[2] };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return best;
|
|
93
|
+
}
|
|
94
|
+
function matchesWhere(row, where) {
|
|
95
|
+
const cell = row[where.column] ?? "";
|
|
96
|
+
switch (where.op) {
|
|
97
|
+
case "=":
|
|
98
|
+
return cell === where.value;
|
|
99
|
+
case "!=":
|
|
100
|
+
return cell !== where.value;
|
|
101
|
+
case "~=": {
|
|
102
|
+
const guarded = compileGuardedRegexCached(where.value);
|
|
103
|
+
return guarded.ok && guarded.re.test(cell);
|
|
104
|
+
}
|
|
105
|
+
case ">":
|
|
106
|
+
case "<":
|
|
107
|
+
case ">=":
|
|
108
|
+
case "<=": {
|
|
109
|
+
if (cell.trim() === "") return false;
|
|
110
|
+
const cellNum = Number(cell);
|
|
111
|
+
const valNum = Number(where.value);
|
|
112
|
+
const useNum = !Number.isNaN(cellNum) && !Number.isNaN(valNum);
|
|
113
|
+
const lhs = useNum ? cellNum : cell;
|
|
114
|
+
const rhs = useNum ? valNum : where.value;
|
|
115
|
+
switch (where.op) {
|
|
116
|
+
case ">":
|
|
117
|
+
return lhs > rhs;
|
|
118
|
+
case "<":
|
|
119
|
+
return lhs < rhs;
|
|
120
|
+
case ">=":
|
|
121
|
+
return lhs >= rhs;
|
|
122
|
+
case "<=":
|
|
123
|
+
return lhs <= rhs;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function queryCsv(content, opts) {
|
|
129
|
+
const records = parseRecords(content, opts);
|
|
130
|
+
const allColumns = records.length > 0 ? Object.keys(records[0]) : [];
|
|
131
|
+
const realHeader = records.length > 0 ? allColumns : csvHeader(content, opts);
|
|
132
|
+
const columns = opts.columns && opts.columns.length > 0 ? opts.columns : allColumns;
|
|
133
|
+
for (const c of columns) {
|
|
134
|
+
if (!realHeader.includes(c)) {
|
|
135
|
+
throw new Error(`unknown column: ${c} (available: ${realHeader.join(", ")})`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const wheres = (opts.wheres ?? []).map((w) => resolveWhereColumn(w, realHeader));
|
|
139
|
+
for (const w of wheres) {
|
|
140
|
+
if (!realHeader.includes(w.column)) {
|
|
141
|
+
throw new Error(`unknown column: ${w.column} (available: ${realHeader.join(", ")})`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
let filtered = records;
|
|
145
|
+
if (wheres.length > 0) {
|
|
146
|
+
filtered = records.filter((r) => wheres.every((w) => matchesWhere(r, w)));
|
|
147
|
+
}
|
|
148
|
+
const totalRows = filtered.length;
|
|
149
|
+
const limited = opts.head !== void 0 ? filtered.slice(0, opts.head) : filtered;
|
|
150
|
+
const rows = limited.map((r) => columns.map((c) => r[c] ?? ""));
|
|
151
|
+
return { header: columns, rows, totalRows, preFilterRows: records.length };
|
|
152
|
+
}
|
|
153
|
+
function quoteCsvCell(cell) {
|
|
154
|
+
if (cell.includes(",") || cell.includes('"') || cell.includes("\n") || cell.includes("\r")) {
|
|
155
|
+
return `"${cell.replace(/"/g, '""')}"`;
|
|
156
|
+
}
|
|
157
|
+
return cell;
|
|
158
|
+
}
|
|
159
|
+
function formatCsvTable(result, activeFilters = []) {
|
|
160
|
+
const lines = [
|
|
161
|
+
result.header.map(quoteCsvCell).join(","),
|
|
162
|
+
...result.rows.map((r) => r.map(quoteCsvCell).join(","))
|
|
163
|
+
];
|
|
164
|
+
if (result.totalRows > result.rows.length) {
|
|
165
|
+
lines.push(`...(${result.totalRows - result.rows.length} more rows elided; use --head to see more)`);
|
|
166
|
+
}
|
|
167
|
+
if (result.totalRows === 0 && result.preFilterRows > 0) {
|
|
168
|
+
lines.push(filtersFilteredToEmptyNotice(result.preFilterRows, activeFilters, "data row", "data rows"));
|
|
169
|
+
}
|
|
170
|
+
return lines.join("\n");
|
|
171
|
+
}
|
|
172
|
+
function profileCsv(content, opts = {}) {
|
|
173
|
+
const records = parseRecords(content, opts);
|
|
174
|
+
const columns = records.length > 0 ? Object.keys(records[0]) : [];
|
|
175
|
+
return columns.map((col) => {
|
|
176
|
+
const values = records.map((r) => r[col] ?? "");
|
|
177
|
+
const nullCount = values.filter((v) => v.trim() === "").length;
|
|
178
|
+
const nonEmpty = values.filter((v) => v.trim() !== "");
|
|
179
|
+
const distinct = new Set(nonEmpty);
|
|
180
|
+
const isNumber = nonEmpty.length > 0 && nonEmpty.every((v) => v.trim() !== "" && !Number.isNaN(Number(v)));
|
|
181
|
+
const isDate = !isNumber && nonEmpty.length > 0 && nonEmpty.every((v) => !Number.isNaN(Date.parse(v)));
|
|
182
|
+
const inferredType = isNumber ? "number" : isDate ? "date" : "string";
|
|
183
|
+
const profile = { name: col, inferredType, nullCount, distinctCount: distinct.size };
|
|
184
|
+
if (nonEmpty.length > 0) {
|
|
185
|
+
if (isNumber) {
|
|
186
|
+
const nums = nonEmpty.map(Number);
|
|
187
|
+
profile.min = String(nums.reduce((a, b) => Math.min(a, b)));
|
|
188
|
+
profile.max = String(nums.reduce((a, b) => Math.max(a, b)));
|
|
189
|
+
} else if (isDate) {
|
|
190
|
+
const sorted = [...nonEmpty].sort((a, b) => Date.parse(a) - Date.parse(b));
|
|
191
|
+
profile.min = sorted[0];
|
|
192
|
+
profile.max = sorted[sorted.length - 1];
|
|
193
|
+
} else {
|
|
194
|
+
const sorted = [...nonEmpty].sort();
|
|
195
|
+
profile.min = sorted[0];
|
|
196
|
+
profile.max = sorted[sorted.length - 1];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (distinct.size > 0 && distinct.size <= 10) {
|
|
200
|
+
const counts = /* @__PURE__ */ new Map();
|
|
201
|
+
for (const v of nonEmpty) counts.set(v, (counts.get(v) ?? 0) + 1);
|
|
202
|
+
profile.topValues = [...counts.entries()].sort((a, b) => b[1] - a[1]).map(([value, count]) => ({ value, count }));
|
|
203
|
+
}
|
|
204
|
+
return profile;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function formatCsvProfile(profiles) {
|
|
208
|
+
return profiles.map((p) => {
|
|
209
|
+
const lines = [
|
|
210
|
+
`${displaySafeText(p.name)} (${p.inferredType})`,
|
|
211
|
+
` nulls: ${p.nullCount} distinct: ${p.distinctCount}`
|
|
212
|
+
];
|
|
213
|
+
if (p.min !== void 0) lines.push(` range: ${displaySafeText(p.min)} .. ${displaySafeText(p.max ?? "")}`);
|
|
214
|
+
if (p.topValues !== void 0) lines.push(` values: ${p.topValues.map((t) => `${displaySafeText(t.value)} (${t.count})`).join(", ")}`);
|
|
215
|
+
return lines.join("\n");
|
|
216
|
+
}).join("\n\n");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export {
|
|
220
|
+
parseWhereSpecs,
|
|
221
|
+
queryCsv,
|
|
222
|
+
quoteCsvCell,
|
|
223
|
+
formatCsvTable,
|
|
224
|
+
profileCsv,
|
|
225
|
+
formatCsvProfile
|
|
226
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
docxOutline,
|
|
5
|
+
docxTables,
|
|
6
|
+
docxText,
|
|
7
|
+
formatDocxTables
|
|
8
|
+
} from "./token-goat-chunk-4SDX3QP3.mjs";
|
|
9
|
+
import "./token-goat-chunk-YHGTGG6K.mjs";
|
|
10
|
+
import "./token-goat-chunk-XTQAOTSO.mjs";
|
|
11
|
+
import "./token-goat-chunk-AH6QILZM.mjs";
|
|
12
|
+
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
13
|
+
import "./token-goat-chunk-AMYCQJX4.mjs";
|
|
14
|
+
import "./token-goat-chunk-GMOUBOX4.mjs";
|
|
15
|
+
import "./token-goat-chunk-A37V4PBF.mjs";
|
|
16
|
+
export {
|
|
17
|
+
docxOutline,
|
|
18
|
+
docxTables,
|
|
19
|
+
docxText,
|
|
20
|
+
formatDocxTables
|
|
21
|
+
};
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
init_define_import_meta_env
|
|
5
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
6
|
+
|
|
7
|
+
// src/regex_guard.ts
|
|
8
|
+
init_define_import_meta_env();
|
|
9
|
+
var GROUP_PREFIX = String.raw`\((?:\?(?::|<?[=!]|<\w+>|[a-z]*(?:-[a-z]*)?:))?`;
|
|
10
|
+
var NESTED_QUANTIFIER = new RegExp(GROUP_PREFIX + String.raw`[^()*+]*(?:[*+]|\{\d+,\d*\})[^()]*\)\s*(?:[*+]|\{\d+,\d*\})`);
|
|
11
|
+
function hasNestedQuantifier(source) {
|
|
12
|
+
return NESTED_QUANTIFIER.test(source);
|
|
13
|
+
}
|
|
14
|
+
var PROBE_ALPHABETS = ["a", "0", "a0"];
|
|
15
|
+
var PROBE_STEP = 4;
|
|
16
|
+
var PROBE_MAX_LENGTH = 512;
|
|
17
|
+
var PROBE_LENGTHS = Array.from({ length: PROBE_MAX_LENGTH / PROBE_STEP }, (_, i) => (i + 1) * PROBE_STEP);
|
|
18
|
+
var PROJECTED_LINE_LENGTH = 1e4;
|
|
19
|
+
var PROJECTION_BUDGET_MS = 1e3;
|
|
20
|
+
var TIMING_SIGNAL_MS = 1;
|
|
21
|
+
var PROBE_GROWTH_FACTOR = 12;
|
|
22
|
+
function climbsBetweenRungs(previous, elapsed) {
|
|
23
|
+
return previous !== void 0 && elapsed > TIMING_SIGNAL_MS && elapsed > previous * PROBE_GROWTH_FACTOR;
|
|
24
|
+
}
|
|
25
|
+
var PROBE_TERMINATORS = ["!", "a", "0", " ", "\uFFFF", "\n", "\u2028"];
|
|
26
|
+
var PROBE_BUDGET_MS = 25;
|
|
27
|
+
var MAX_COUNTED_REPEAT = 8;
|
|
28
|
+
var LITERAL_RUN_ATOM = /[^\\()[\]{}|^$*+?]/;
|
|
29
|
+
var QUANTIFIER_AT = /^[*+?{]/;
|
|
30
|
+
function timeMatch(re, input) {
|
|
31
|
+
const probe = new RegExp(re.source, re.flags.replace("g", ""));
|
|
32
|
+
const started = performance.now();
|
|
33
|
+
const matched = probe.test(input);
|
|
34
|
+
const first = performance.now() - started;
|
|
35
|
+
if (first <= TIMING_SIGNAL_MS) return { ms: first, matched };
|
|
36
|
+
const again = new RegExp(re.source, re.flags.replace("g", ""));
|
|
37
|
+
const restarted = performance.now();
|
|
38
|
+
again.test(input);
|
|
39
|
+
return { ms: Math.min(first, performance.now() - restarted), matched };
|
|
40
|
+
}
|
|
41
|
+
var ESCAPE_SAMPLES = {
|
|
42
|
+
s: " ",
|
|
43
|
+
S: "a",
|
|
44
|
+
d: "0",
|
|
45
|
+
D: "a",
|
|
46
|
+
w: "a",
|
|
47
|
+
W: "-",
|
|
48
|
+
t: " ",
|
|
49
|
+
n: "\n",
|
|
50
|
+
r: "\r",
|
|
51
|
+
f: "\f",
|
|
52
|
+
v: "\v",
|
|
53
|
+
"0": "\0",
|
|
54
|
+
b: "",
|
|
55
|
+
B: ""
|
|
56
|
+
};
|
|
57
|
+
var LOOKAROUND_AT = /^\(\?<?[=!]/;
|
|
58
|
+
var CLASS_CANDIDATES = ["a", "0", " ", "x", "-", "!", "~", " ", "\n", "A", "\xE9", "\u03B1", "\u0434", "\u05D0", "\u0627", "\u4E2D", "\u3042", "\u{1F600}"];
|
|
59
|
+
function firstMatch(source, flags, candidates) {
|
|
60
|
+
let re;
|
|
61
|
+
try {
|
|
62
|
+
re = new RegExp(source, flags);
|
|
63
|
+
} catch {
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
for (const candidate of candidates) if (re.test(candidate)) return candidate;
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
function classEnd(source, start) {
|
|
70
|
+
let i = start + 1;
|
|
71
|
+
if (source[i] === "^") i++;
|
|
72
|
+
if (source[i] === "]") i++;
|
|
73
|
+
for (; i < source.length; i++) {
|
|
74
|
+
if (source[i] === "\\") {
|
|
75
|
+
i++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (source[i] === "]") return i;
|
|
79
|
+
}
|
|
80
|
+
return -1;
|
|
81
|
+
}
|
|
82
|
+
var CLASS_SWEEP = [
|
|
83
|
+
...Array.from({ length: 95 }, (_, i) => String.fromCharCode(32 + i)),
|
|
84
|
+
...Array.from({ length: 1024 }, (_, i) => String.fromCharCode(160 + i * 63))
|
|
85
|
+
];
|
|
86
|
+
var SWEEP_TAILS = CLASS_SWEEP.flatMap((c, i) => {
|
|
87
|
+
const other = CLASS_SWEEP[(i + 1) % CLASS_SWEEP.length];
|
|
88
|
+
return [c.repeat(MAX_COUNTED_REPEAT + 1), c.repeat(MAX_COUNTED_REPEAT) + other];
|
|
89
|
+
});
|
|
90
|
+
var MAX_SWEEPS = 3;
|
|
91
|
+
var SWEEP_BUDGET_MS = 150;
|
|
92
|
+
var QUANTIFIED_GROUP = /\)\s*(?:[*+]|\{\d+(?:,\d*)?\})/;
|
|
93
|
+
function sampleClass(cls) {
|
|
94
|
+
const named = sampleCharacters(cls.slice(1, -1));
|
|
95
|
+
return firstMatch(cls, "", [...named, ...CLASS_CANDIDATES]) || firstMatch(cls, "", CLASS_SWEEP);
|
|
96
|
+
}
|
|
97
|
+
function sampleCharacters(source) {
|
|
98
|
+
const out = [];
|
|
99
|
+
const seen = /* @__PURE__ */ new Set();
|
|
100
|
+
const push = (c) => {
|
|
101
|
+
if (c === "" || seen.has(c)) return;
|
|
102
|
+
seen.add(c);
|
|
103
|
+
out.push(c);
|
|
104
|
+
};
|
|
105
|
+
for (let i = 0; i < source.length; i++) {
|
|
106
|
+
const c = source[i];
|
|
107
|
+
if (c === "[") {
|
|
108
|
+
const end = classEnd(source, i);
|
|
109
|
+
if (end !== -1) {
|
|
110
|
+
push(sampleClass(source.slice(i, end + 1)));
|
|
111
|
+
i = end;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (c !== "\\") {
|
|
116
|
+
if (/[^\s()[\]{}|^$*+?.-]/.test(c)) push(c);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const next = source[i + 1] ?? "";
|
|
120
|
+
i++;
|
|
121
|
+
if (next >= "0" && next <= "7") {
|
|
122
|
+
let digits = /^[0-7]{1,3}/.exec(source.slice(i))[0];
|
|
123
|
+
if (parseInt(digits, 8) > 255) digits = digits.slice(0, 2);
|
|
124
|
+
push(String.fromCharCode(parseInt(digits, 8)));
|
|
125
|
+
if (digits.length === 1 && next !== "0") push(next);
|
|
126
|
+
i += digits.length - 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (next === "x" || next === "u") {
|
|
130
|
+
if (next === "u" && source[i + 1] === "{") {
|
|
131
|
+
const close = source.indexOf("}", i + 2);
|
|
132
|
+
const digits2 = close === -1 ? "" : source.slice(i + 2, close);
|
|
133
|
+
if (/^[0-9a-fA-F]{1,6}$/.test(digits2)) {
|
|
134
|
+
push(String.fromCodePoint(parseInt(digits2, 16)));
|
|
135
|
+
i = close;
|
|
136
|
+
}
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const width = next === "x" ? 2 : 4;
|
|
140
|
+
const digits = source.slice(i + 1, i + 1 + width);
|
|
141
|
+
i += width;
|
|
142
|
+
if (/^[0-9a-fA-F]+$/.test(digits) && digits.length === width) push(String.fromCharCode(parseInt(digits, 16)));
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (next === "c" && /[a-zA-Z]/.test(source[i + 1] ?? "")) {
|
|
146
|
+
push(String.fromCharCode(source[i + 1].toUpperCase().charCodeAt(0) % 32));
|
|
147
|
+
i++;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if ((next === "p" || next === "P") && source[i + 1] === "{") {
|
|
151
|
+
const close = source.indexOf("}", i + 2);
|
|
152
|
+
if (close !== -1) {
|
|
153
|
+
push(firstMatch(source.slice(i - 1, close + 1), "u", CLASS_CANDIDATES));
|
|
154
|
+
i = close;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const sample = ESCAPE_SAMPLES[next];
|
|
159
|
+
push(sample ?? next);
|
|
160
|
+
}
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
var MAX_PATTERN_ALPHABETS = 12;
|
|
164
|
+
function probeAlphabets(source) {
|
|
165
|
+
const samples = sampleCharacters(source);
|
|
166
|
+
const counts = /* @__PURE__ */ new Map();
|
|
167
|
+
for (const ch of source) counts.set(ch, (counts.get(ch) ?? 0) + 1);
|
|
168
|
+
const counted = samples.map((c, i) => ({ c, i, n: counts.get(c) ?? 0 }));
|
|
169
|
+
counted.sort((a, b) => b.n - a.n || a.i - b.i);
|
|
170
|
+
const kept = counted.slice(0, MAX_PATTERN_ALPHABETS).map((s) => s.c);
|
|
171
|
+
const extra = kept.length > 1 ? [kept.join("")] : [];
|
|
172
|
+
return [...PROBE_ALPHABETS, ...kept, ...extra];
|
|
173
|
+
}
|
|
174
|
+
function growsExponentially(re) {
|
|
175
|
+
const relaxed = detune(re.source);
|
|
176
|
+
if (relaxed === null || !relaxed.hadLookaround) {
|
|
177
|
+
const cause = climbsPastBudget(re);
|
|
178
|
+
if (cause !== null) return cause;
|
|
179
|
+
}
|
|
180
|
+
if (relaxed === null) return null;
|
|
181
|
+
for (const body of relaxed.negativeBodies) {
|
|
182
|
+
let inner;
|
|
183
|
+
try {
|
|
184
|
+
inner = new RegExp(body, re.flags);
|
|
185
|
+
} catch {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const innerCause = growsExponentially(inner);
|
|
189
|
+
if (innerCause !== null) return innerCause;
|
|
190
|
+
}
|
|
191
|
+
let widened;
|
|
192
|
+
try {
|
|
193
|
+
widened = new RegExp(relaxed.source, re.flags);
|
|
194
|
+
} catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return growsExponentially(widened);
|
|
198
|
+
}
|
|
199
|
+
function climbsPastBudget(re) {
|
|
200
|
+
const probe = new RegExp(re.source, re.flags.replace("g", ""));
|
|
201
|
+
let sweptMs = 0;
|
|
202
|
+
let falsified = false;
|
|
203
|
+
for (const alphabet of probeAlphabets(re.source)) {
|
|
204
|
+
let sweeps = 0;
|
|
205
|
+
const body = (n) => alphabet.repeat(Math.ceil(n / alphabet.length)).slice(0, n);
|
|
206
|
+
const tail = PROBE_TERMINATORS.find((t) => !probe.test(body(PROBE_STEP) + t)) ?? PROBE_TERMINATORS[0];
|
|
207
|
+
const candidates = [tail, ...PROBE_TERMINATORS.filter((t) => t !== tail)];
|
|
208
|
+
let swept;
|
|
209
|
+
const timings = [];
|
|
210
|
+
let previous;
|
|
211
|
+
for (const length of PROBE_LENGTHS) {
|
|
212
|
+
let failing;
|
|
213
|
+
let last;
|
|
214
|
+
const attempt = (candidate) => {
|
|
215
|
+
const m = timeMatch(re, body(length) + candidate);
|
|
216
|
+
last = m;
|
|
217
|
+
if (m.ms > PROBE_BUDGET_MS) return "over-budget";
|
|
218
|
+
if (!m.matched) failing = m;
|
|
219
|
+
return m;
|
|
220
|
+
};
|
|
221
|
+
for (const candidate of swept === void 0 ? candidates : [swept, ...candidates]) {
|
|
222
|
+
if (attempt(candidate) === "over-budget") return "over-budget";
|
|
223
|
+
if (failing !== void 0) break;
|
|
224
|
+
}
|
|
225
|
+
if (failing === void 0 && sweeps < MAX_SWEEPS && sweptMs < SWEEP_BUDGET_MS) {
|
|
226
|
+
sweeps++;
|
|
227
|
+
const sweepStarted = Date.now();
|
|
228
|
+
for (const candidate of SWEEP_TAILS) {
|
|
229
|
+
if (attempt(candidate) === "over-budget") return "over-budget";
|
|
230
|
+
if (failing !== void 0) {
|
|
231
|
+
swept = candidate;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
sweptMs += Date.now() - sweepStarted;
|
|
236
|
+
}
|
|
237
|
+
if (failing !== void 0) falsified = true;
|
|
238
|
+
const elapsed = (failing ?? last).ms;
|
|
239
|
+
if (climbsBetweenRungs(previous, elapsed)) return "ratio";
|
|
240
|
+
previous = elapsed;
|
|
241
|
+
timings.push(elapsed);
|
|
242
|
+
}
|
|
243
|
+
if (projectsPastBudget(timings)) return "projection";
|
|
244
|
+
}
|
|
245
|
+
if (!falsified && QUANTIFIED_GROUP.test(re.source)) return "unfalsifiable";
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
function groupEnd(source, start) {
|
|
249
|
+
let depth = 0;
|
|
250
|
+
let inClass = false;
|
|
251
|
+
for (let i = start; i < source.length; i++) {
|
|
252
|
+
const c = source[i];
|
|
253
|
+
if (c === "\\") {
|
|
254
|
+
i++;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (inClass) {
|
|
258
|
+
if (c === "]") inClass = false;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (c === "[") inClass = true;
|
|
262
|
+
else if (c === "(") depth++;
|
|
263
|
+
else if (c === ")" && --depth === 0) return i;
|
|
264
|
+
}
|
|
265
|
+
return -1;
|
|
266
|
+
}
|
|
267
|
+
function detune(source) {
|
|
268
|
+
let out = "";
|
|
269
|
+
let changed = false;
|
|
270
|
+
let hadLookaround = false;
|
|
271
|
+
const negativeBodies = [];
|
|
272
|
+
let inClass = false;
|
|
273
|
+
for (let i = 0; i < source.length; i++) {
|
|
274
|
+
const c = source[i];
|
|
275
|
+
if (c === "\\") {
|
|
276
|
+
out += c + (source[i + 1] ?? "");
|
|
277
|
+
i++;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (inClass) {
|
|
281
|
+
out += c;
|
|
282
|
+
if (c === "]") inClass = false;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (c === "[") {
|
|
286
|
+
out += c;
|
|
287
|
+
inClass = true;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if (c === "{") {
|
|
291
|
+
const counted = /^\{(\d+)(,(\d*))?\}/.exec(source.slice(i));
|
|
292
|
+
if (counted !== null) {
|
|
293
|
+
const min = Math.min(parseInt(counted[1], 10), MAX_COUNTED_REPEAT);
|
|
294
|
+
const upper = counted[3];
|
|
295
|
+
const max = upper === void 0 || upper === "" ? "" : String(Math.min(parseInt(upper, 10), MAX_COUNTED_REPEAT));
|
|
296
|
+
const rebuilt = counted[2] === void 0 ? `{${min}}` : `{${min},${max}}`;
|
|
297
|
+
if (rebuilt !== counted[0]) changed = true;
|
|
298
|
+
out += rebuilt;
|
|
299
|
+
i += counted[0].length - 1;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (c === "(" && LOOKAROUND_AT.test(source.slice(i, i + 4))) {
|
|
304
|
+
const end = groupEnd(source, i);
|
|
305
|
+
if (end === -1) return null;
|
|
306
|
+
const behind = source[i + 2] === "<";
|
|
307
|
+
const negative = source[i + (behind ? 3 : 2)] === "!";
|
|
308
|
+
const body = source.slice(i + (behind ? 4 : 3), end);
|
|
309
|
+
if (negative) negativeBodies.push(body);
|
|
310
|
+
else out += `(?:${body})`;
|
|
311
|
+
i = end;
|
|
312
|
+
changed = true;
|
|
313
|
+
hadLookaround = true;
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (LITERAL_RUN_ATOM.test(c)) {
|
|
317
|
+
let run = 1;
|
|
318
|
+
while (source[i + run] === c) run++;
|
|
319
|
+
const quantified = QUANTIFIER_AT.test(source.slice(i + run, i + run + 1));
|
|
320
|
+
const collapsible = quantified ? run - 1 : run;
|
|
321
|
+
if (collapsible > MAX_COUNTED_REPEAT) {
|
|
322
|
+
out += c.repeat(MAX_COUNTED_REPEAT) + (quantified ? c : "");
|
|
323
|
+
i += run - 1;
|
|
324
|
+
changed = true;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
out += c;
|
|
329
|
+
}
|
|
330
|
+
return changed ? { source: out, hadLookaround, negativeBodies } : null;
|
|
331
|
+
}
|
|
332
|
+
function projectsPastBudget(timings) {
|
|
333
|
+
const hi = timings.length - 1;
|
|
334
|
+
const hiLength = PROBE_LENGTHS[hi];
|
|
335
|
+
if (hiLength === void 0) return false;
|
|
336
|
+
const lo = PROBE_LENGTHS.findIndex((l) => l * 2 >= hiLength);
|
|
337
|
+
const loLength = PROBE_LENGTHS[lo];
|
|
338
|
+
const top = timings[hi];
|
|
339
|
+
const prior = timings[lo];
|
|
340
|
+
if (top === void 0 || prior === void 0 || loLength === void 0 || loLength >= hiLength) return false;
|
|
341
|
+
if (top <= TIMING_SIGNAL_MS || prior <= 0) return false;
|
|
342
|
+
const exponent = Math.log2(top / prior) / Math.log2(hiLength / loLength);
|
|
343
|
+
return top * (PROJECTED_LINE_LENGTH / hiLength) ** exponent > PROJECTION_BUDGET_MS;
|
|
344
|
+
}
|
|
345
|
+
var MAX_PATTERN_LENGTH = 4096;
|
|
346
|
+
function compileGuardedRegex(pattern, flags = "") {
|
|
347
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
348
|
+
return { ok: false, reason: `is longer than ${MAX_PATTERN_LENGTH} characters, which is past what can be checked for a stall` };
|
|
349
|
+
}
|
|
350
|
+
let re;
|
|
351
|
+
try {
|
|
352
|
+
re = new RegExp(pattern, flags);
|
|
353
|
+
} catch (e) {
|
|
354
|
+
return { ok: false, reason: e instanceof Error ? e.message : "is not a valid regular expression" };
|
|
355
|
+
}
|
|
356
|
+
const cause = growsExponentially(re);
|
|
357
|
+
if (cause !== null) {
|
|
358
|
+
return {
|
|
359
|
+
ok: false,
|
|
360
|
+
reason: hasNestedQuantifier(pattern) ? "repeats a group that already repeats, which can take exponential time to match" : "takes time that climbs steeply with the length of the line, which can stall on ordinary text",
|
|
361
|
+
cause
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
return { ok: true, re };
|
|
365
|
+
}
|
|
366
|
+
var GUARDED_CACHE_LIMIT = 64;
|
|
367
|
+
var guardedCache = /* @__PURE__ */ new Map();
|
|
368
|
+
function compileGuardedRegexCached(pattern, flags = "") {
|
|
369
|
+
const key = `${flags}/${pattern}`;
|
|
370
|
+
const hit = guardedCache.get(key);
|
|
371
|
+
if (hit !== void 0) return hit;
|
|
372
|
+
const result = compileGuardedRegex(pattern, flags);
|
|
373
|
+
if (guardedCache.size >= GUARDED_CACHE_LIMIT) {
|
|
374
|
+
const oldest = guardedCache.keys().next();
|
|
375
|
+
if (!oldest.done) guardedCache.delete(oldest.value);
|
|
376
|
+
}
|
|
377
|
+
guardedCache.set(key, result);
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export {
|
|
382
|
+
hasNestedQuantifier,
|
|
383
|
+
growsExponentially,
|
|
384
|
+
compileGuardedRegex,
|
|
385
|
+
compileGuardedRegexCached
|
|
386
|
+
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
stripMultilineStringSpan,
|
|
10
10
|
stripNestedBlockCommentSpan,
|
|
11
11
|
stripStringLiterals
|
|
12
|
-
} from "./token-goat-chunk-
|
|
12
|
+
} from "./token-goat-chunk-POBYR64E.mjs";
|
|
13
13
|
import {
|
|
14
14
|
init_define_import_meta_env
|
|
15
15
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|