token-goat 2.9.29 → 2.9.30
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 +34 -40
- package/SECURITY.md +28 -10
- package/THIRD_PARTY_NOTICES.md +40 -3
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
- package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
- package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
- package/dist/{token-goat-chunk-PGTH2U4C.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
- package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
- package/dist/{token-goat-chunk-L7H3U27L.mjs → token-goat-chunk-54K3EUV3.mjs} +1 -1
- package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
- package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
- package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
- package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
- package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
- package/dist/{token-goat-chunk-GLXRTTLE.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -8
- package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-664RTTUV.mjs} +28 -15
- package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
- package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
- package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
- package/dist/{token-goat-chunk-IVWI2OCK.mjs → token-goat-chunk-7F2UBPD3.mjs} +40 -11
- package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7IN2MKDS.mjs} +682 -501
- package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
- package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-A3CK6N5Z.mjs} +618 -72
- package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-AFLYLHDH.mjs} +44 -31
- package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
- package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-APGZXSPS.mjs} +39 -146
- package/dist/{token-goat-chunk-D4ETHJD6.mjs → token-goat-chunk-ARDNEC2U.mjs} +9 -7
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
- package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
- package/dist/{token-goat-chunk-BGYOZ6DO.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -7
- package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
- package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-C63JQV5K.mjs} +45 -6
- package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
- package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
- package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-CYCEYAEO.mjs} +76 -16
- package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
- package/dist/{token-goat-chunk-ASLWOQ3I.mjs → token-goat-chunk-DZX2YDPT.mjs} +2 -1
- package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
- package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
- package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
- package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
- package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
- package/dist/{token-goat-chunk-RTMVLHWX.mjs → token-goat-chunk-FBNQNSJK.mjs} +2555 -5127
- package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
- package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
- package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
- package/dist/{token-goat-chunk-DNRPXHYH.mjs → token-goat-chunk-GFBSN7BD.mjs} +29 -401
- package/dist/{token-goat-chunk-XYWPOSCN.mjs → token-goat-chunk-GOLEOXZP.mjs} +763 -211
- package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
- package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
- package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
- package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
- package/dist/{token-goat-chunk-HUYUHODZ.mjs → token-goat-chunk-HOJLCGDP.mjs} +12965 -11748
- package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-HYBFA5X3.mjs} +118 -19
- package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
- package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
- package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
- package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
- package/dist/{token-goat-chunk-FTP4U4QA.mjs → token-goat-chunk-JDU3EXSU.mjs} +12 -11
- package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
- package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-JN4XMLSD.mjs} +5 -1
- package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
- package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
- package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
- package/dist/{token-goat-chunk-2WOUYWLM.mjs → token-goat-chunk-KWPNJBDH.mjs} +27 -3
- package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-LOBGHXPB.mjs} +30 -8
- package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
- package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
- package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
- package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
- package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
- package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
- package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
- package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
- package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-PU7V3FD6.mjs} +8721 -11104
- package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
- package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
- package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-QCLDAQTS.mjs} +31 -20
- package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
- package/dist/{token-goat-chunk-VZQEWRVH.mjs → token-goat-chunk-RC35RBUL.mjs} +4 -4
- package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-RHXKCZX3.mjs} +873 -504
- package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
- package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
- package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
- package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-SQSSNQPE.mjs} +2295 -1718
- package/dist/{token-goat-chunk-2AWQ2R5X.mjs → token-goat-chunk-T4FK7VOV.mjs} +2 -2
- package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
- package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
- package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
- package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
- package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-VES7EL7O.mjs} +7 -1
- package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-VL3YIFHZ.mjs} +389 -14
- package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-VPBBTSJR.mjs} +356 -129
- package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
- package/dist/{token-goat-chunk-LZNBQTDK.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -7
- package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
- package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
- package/dist/{token-goat-chunk-H5J3C56Q.mjs → token-goat-chunk-Y776AENC.mjs} +112 -26
- package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
- package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-Z44YO3QZ.mjs} +4 -0
- package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
- package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-ZCDTCVIS.mjs} +48 -29
- package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
- package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
- package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
- package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-ZQSJMO2R.mjs} +338 -170
- package/dist/token-goat-hook-client.cjs +87 -23
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +46 -30
- package/dist/token-goat.core.mjs +6 -6
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +80 -46
- package/docs/install.md +47 -14
- package/docs/security.md +7 -7
- package/package.json +17 -7
- package/scripts/verify-native-dist.mjs +386 -0
- package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
- package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
- package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
- package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
- package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
- package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
- package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
- package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
- package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
- package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
- package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
atomicWriteText,
|
|
5
|
+
ensureDirSync,
|
|
6
|
+
extractErrorMessage,
|
|
7
|
+
withFileLock
|
|
8
|
+
} from "./token-goat-chunk-GOLEOXZP.mjs";
|
|
9
|
+
import {
|
|
10
|
+
displaySafeText
|
|
11
|
+
} from "./token-goat-chunk-FNFBKLRD.mjs";
|
|
12
|
+
import {
|
|
13
|
+
dataDir
|
|
14
|
+
} from "./token-goat-chunk-VES7EL7O.mjs";
|
|
15
|
+
import {
|
|
16
|
+
init_define_import_meta_env
|
|
17
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
18
|
+
|
|
19
|
+
// src/worker_lifecycle.ts
|
|
20
|
+
init_define_import_meta_env();
|
|
21
|
+
import { spawn } from "node:child_process";
|
|
22
|
+
import * as fs from "node:fs";
|
|
23
|
+
import * as os from "node:os";
|
|
24
|
+
import * as path from "node:path";
|
|
25
|
+
import { fileURLToPath } from "node:url";
|
|
26
|
+
|
|
27
|
+
// src/env_proxy.ts
|
|
28
|
+
init_define_import_meta_env();
|
|
29
|
+
var PROXY_VARS = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"];
|
|
30
|
+
function proxyConfigured(env = process.env) {
|
|
31
|
+
return PROXY_VARS.some((k) => (env[k] ?? "").trim() !== "");
|
|
32
|
+
}
|
|
33
|
+
function nodeFetchHonoursEnvProxy(version = process.versions.node) {
|
|
34
|
+
const [major = 0, minor = 0] = version.split(".").map((n) => Number.parseInt(n, 10));
|
|
35
|
+
if (major >= 24) return true;
|
|
36
|
+
return major === 22 && minor >= 21;
|
|
37
|
+
}
|
|
38
|
+
function fetchBypassesProxy(env = process.env, nodeVersion = process.versions.node) {
|
|
39
|
+
return env["NODE_USE_ENV_PROXY"] === void 0 && proxyConfigured(env) && nodeFetchHonoursEnvProxy(nodeVersion);
|
|
40
|
+
}
|
|
41
|
+
function rerunWithEnvProxy(spawn2, argv = process.argv, env = process.env, nodeVersion = process.versions.node) {
|
|
42
|
+
if (!fetchBypassesProxy(env, nodeVersion)) return null;
|
|
43
|
+
const result = spawn2(process.execPath, [...process.execArgv, ...argv.slice(1)], { env: withEnvProxyEnabled(env, nodeVersion), stdio: "inherit" });
|
|
44
|
+
return result.status ?? 1;
|
|
45
|
+
}
|
|
46
|
+
function withEnvProxyEnabled(env, nodeVersion = process.versions.node) {
|
|
47
|
+
if (env["NODE_USE_ENV_PROXY"] !== void 0 || !proxyConfigured(env) || !nodeFetchHonoursEnvProxy(nodeVersion)) return env;
|
|
48
|
+
return { ...env, NODE_USE_ENV_PROXY: "1" };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/worker_lifecycle.ts
|
|
52
|
+
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
53
|
+
function resolvePollIntervalMs(explicit) {
|
|
54
|
+
if (explicit !== void 0) return explicit;
|
|
55
|
+
const parsed = parseInt(process.env["TG_WORKER_POLL_MS"] ?? "", 10);
|
|
56
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_POLL_INTERVAL_MS;
|
|
57
|
+
}
|
|
58
|
+
var WORKER_HEARTBEAT_STALE_MS = 6e4;
|
|
59
|
+
var WORKER_HEARTBEAT_REFRESH_MS = 5e3;
|
|
60
|
+
var WORKER_STARTUP_GRACE_MS = 1e4;
|
|
61
|
+
var heartbeatWriteTimes = /* @__PURE__ */ new Map();
|
|
62
|
+
function drainHeartbeatPathFor(dir) {
|
|
63
|
+
return path.join(dir, "queue", "drain-heartbeat");
|
|
64
|
+
}
|
|
65
|
+
function writeDrainHeartbeat(dir, force = false) {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
if (!force && now - (heartbeatWriteTimes.get(dir) ?? 0) < WORKER_HEARTBEAT_REFRESH_MS) return;
|
|
68
|
+
try {
|
|
69
|
+
atomicWriteText(drainHeartbeatPathFor(dir), `${process.pid}
|
|
70
|
+
`);
|
|
71
|
+
heartbeatWriteTimes.set(dir, now);
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function hasFreshWorkerHeartbeat(dir, pid) {
|
|
76
|
+
try {
|
|
77
|
+
const heartbeatPath = drainHeartbeatPathFor(dir);
|
|
78
|
+
if (Date.now() - fs.statSync(heartbeatPath).mtimeMs > WORKER_HEARTBEAT_STALE_MS) return false;
|
|
79
|
+
return fs.readFileSync(heartbeatPath, "utf8").trim() === String(pid);
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function pidFileIsWithinStartupGrace(dir) {
|
|
85
|
+
try {
|
|
86
|
+
return Date.now() - fs.statSync(workerPidPath(dir)).mtimeMs < WORKER_STARTUP_GRACE_MS;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function workerPidPath(dir = dataDir()) {
|
|
92
|
+
return path.join(dir, "worker.pid");
|
|
93
|
+
}
|
|
94
|
+
function workerStampPath(dir = dataDir()) {
|
|
95
|
+
return path.join(dir, "worker.stamp");
|
|
96
|
+
}
|
|
97
|
+
function workerErrorLogPath(dir) {
|
|
98
|
+
return path.join(dir, "worker-errors.log");
|
|
99
|
+
}
|
|
100
|
+
function oneLogLine(line) {
|
|
101
|
+
return displaySafeText(line.replace(/[\n\r]+$/, "")) + "\n";
|
|
102
|
+
}
|
|
103
|
+
function appendWorkerErrorLog(dir, line) {
|
|
104
|
+
try {
|
|
105
|
+
fs.appendFileSync(workerErrorLogPath(dir), oneLogLine(line));
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function pidAlive(pid) {
|
|
110
|
+
try {
|
|
111
|
+
process.kill(pid, 0);
|
|
112
|
+
return true;
|
|
113
|
+
} catch (err) {
|
|
114
|
+
return err.code === "EPERM";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function readPidFile(dir) {
|
|
118
|
+
try {
|
|
119
|
+
const raw = fs.readFileSync(workerPidPath(dir), "utf8").trim();
|
|
120
|
+
if (!/^\d+$/.test(raw)) return null;
|
|
121
|
+
return parseInt(raw, 10);
|
|
122
|
+
} catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function isWorkerRunning(dir = dataDir()) {
|
|
127
|
+
const pid = readPidFile(dir);
|
|
128
|
+
if (pid === null) return false;
|
|
129
|
+
return pidAlive(pid) && hasFreshWorkerHeartbeat(dir, pid);
|
|
130
|
+
}
|
|
131
|
+
function workerHealthCheckMarkerPath(dir) {
|
|
132
|
+
return path.join(dir, "worker-healthcheck.marker");
|
|
133
|
+
}
|
|
134
|
+
var WORKER_HEALTHCHECK_MIN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
135
|
+
function ensureWorkerAlive(dir = dataDir()) {
|
|
136
|
+
if (process.env["TOKEN_GOAT_NO_WORKER_SPAWN"] === "1") return;
|
|
137
|
+
const markerPath = workerHealthCheckMarkerPath(dir);
|
|
138
|
+
try {
|
|
139
|
+
const stat = fs.statSync(markerPath);
|
|
140
|
+
if (Date.now() - stat.mtimeMs < WORKER_HEALTHCHECK_MIN_INTERVAL_MS) return;
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
ensureDirSync(dir);
|
|
145
|
+
fs.writeFileSync(markerPath, "");
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
const livePid = readPidFile(dir);
|
|
149
|
+
if (livePid !== null && pidAlive(livePid) && hasFreshWorkerHeartbeat(dir, livePid)) {
|
|
150
|
+
if (workerBundleMatches(dir)) return;
|
|
151
|
+
stopWorker(dir, livePid);
|
|
152
|
+
const nowPid = readPidFile(dir);
|
|
153
|
+
if (nowPid !== null && nowPid !== livePid) return;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
startDetachedWorker({ dataDir: dir });
|
|
157
|
+
} catch (e) {
|
|
158
|
+
if (e instanceof WorkerAlreadyRunningError) return;
|
|
159
|
+
try {
|
|
160
|
+
appendWorkerErrorLog(
|
|
161
|
+
dir,
|
|
162
|
+
`${(/* @__PURE__ */ new Date()).toISOString()} ensureWorkerAlive: auto-restart failed: ${extractErrorMessage(e)}
|
|
163
|
+
`
|
|
164
|
+
);
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function stopWorker(dir = dataDir(), expectedPid) {
|
|
170
|
+
const pid = readPidFile(dir);
|
|
171
|
+
if (pid === null) return false;
|
|
172
|
+
if (expectedPid !== void 0 && pid !== expectedPid) return false;
|
|
173
|
+
const running = isWorkerRunning(dir);
|
|
174
|
+
if (running) {
|
|
175
|
+
try {
|
|
176
|
+
process.kill(pid);
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (readPidFile(dir) === pid) {
|
|
181
|
+
try {
|
|
182
|
+
fs.rmSync(workerPidPath(dir), { force: true });
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return running;
|
|
187
|
+
}
|
|
188
|
+
var WorkerAlreadyRunningError = class extends Error {
|
|
189
|
+
constructor(message = "worker already running") {
|
|
190
|
+
super(message);
|
|
191
|
+
this.name = "WorkerAlreadyRunningError";
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
var WorkerDataDirUnwritableError = class extends Error {
|
|
195
|
+
constructor(dir, cause) {
|
|
196
|
+
super(`the data directory ${displaySafeText(dir)} cannot be written (${extractErrorMessage(cause)}), and the worker keeps its pid file, queue and index there; make it writable and run \`token-goat worker start\` again`, { cause });
|
|
197
|
+
this.name = "WorkerDataDirUnwritableError";
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
function dataDirWriteRefusal(dir) {
|
|
201
|
+
const probe = path.join(dir, `.write-probe-${process.pid}`);
|
|
202
|
+
try {
|
|
203
|
+
fs.writeFileSync(probe, "");
|
|
204
|
+
} catch (e) {
|
|
205
|
+
return e;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
fs.rmSync(probe, { force: true });
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
213
|
+
function discardSpawnedWorker(child, pid) {
|
|
214
|
+
try {
|
|
215
|
+
process.kill(pid);
|
|
216
|
+
} catch {
|
|
217
|
+
}
|
|
218
|
+
child.unref();
|
|
219
|
+
}
|
|
220
|
+
function claimWorkerPidFile(dir, pid) {
|
|
221
|
+
const pidPath = workerPidPath(dir);
|
|
222
|
+
try {
|
|
223
|
+
fs.writeFileSync(pidPath, `${pid}
|
|
224
|
+
`, { flag: "wx" });
|
|
225
|
+
return true;
|
|
226
|
+
} catch (e) {
|
|
227
|
+
if (e.code !== "EEXIST") throw e;
|
|
228
|
+
}
|
|
229
|
+
return withFileLock(`${pidPath}.reclaim`, () => reclaimStalePidFile(dir, pid), { waitMs: 0 }) ?? false;
|
|
230
|
+
}
|
|
231
|
+
function reclaimStalePidFile(dir, pid) {
|
|
232
|
+
const pidPath = workerPidPath(dir);
|
|
233
|
+
const existingPid = readPidFile(dir);
|
|
234
|
+
if (existingPid !== null && pidAlive(existingPid) && (hasFreshWorkerHeartbeat(dir, existingPid) || pidFileIsWithinStartupGrace(dir))) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
fs.rmSync(pidPath, { force: true });
|
|
239
|
+
} catch {
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
fs.writeFileSync(pidPath, `${pid}
|
|
243
|
+
`, { flag: "wx" });
|
|
244
|
+
return true;
|
|
245
|
+
} catch (e2) {
|
|
246
|
+
if (e2.code === "EEXIST") return false;
|
|
247
|
+
throw e2;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function daemonEntryScript() {
|
|
251
|
+
const self = fileURLToPath(import.meta.url);
|
|
252
|
+
const launcher = path.join(path.dirname(self), "token-goat.mjs");
|
|
253
|
+
try {
|
|
254
|
+
if (fs.existsSync(launcher)) return launcher;
|
|
255
|
+
} catch {
|
|
256
|
+
}
|
|
257
|
+
return self;
|
|
258
|
+
}
|
|
259
|
+
function currentDaemonStamp() {
|
|
260
|
+
const entry = daemonEntryScript();
|
|
261
|
+
try {
|
|
262
|
+
const st = fs.statSync(entry);
|
|
263
|
+
return `${entry}|${st.size}|${Math.trunc(st.mtimeMs)}`;
|
|
264
|
+
} catch {
|
|
265
|
+
return entry;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function workerBundleMatches(dir) {
|
|
269
|
+
let raw;
|
|
270
|
+
try {
|
|
271
|
+
raw = fs.readFileSync(workerStampPath(dir), "utf8").trim();
|
|
272
|
+
} catch {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
const parts = raw.split("|");
|
|
276
|
+
if (parts.length !== 3) return false;
|
|
277
|
+
const [entry, sizeStr, mtimeStr] = parts;
|
|
278
|
+
if (entry !== daemonEntryScript()) return true;
|
|
279
|
+
const size = Number(sizeStr);
|
|
280
|
+
const mtimeMs = Number(mtimeStr);
|
|
281
|
+
if (!Number.isFinite(size) || !Number.isFinite(mtimeMs)) return false;
|
|
282
|
+
try {
|
|
283
|
+
const st = fs.statSync(entry);
|
|
284
|
+
return st.size === size && Math.trunc(st.mtimeMs) === mtimeMs;
|
|
285
|
+
} catch {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function startDetachedWorker(opts) {
|
|
290
|
+
const pollIntervalMs = resolvePollIntervalMs(opts?.pollIntervalMs);
|
|
291
|
+
const dir = path.resolve(opts?.dataDir ?? dataDir());
|
|
292
|
+
try {
|
|
293
|
+
ensureDirSync(dir);
|
|
294
|
+
} catch (e) {
|
|
295
|
+
if (e.code !== "EEXIST" || !fs.existsSync(dir)) throw e;
|
|
296
|
+
}
|
|
297
|
+
const refusal = dataDirWriteRefusal(dir);
|
|
298
|
+
if (refusal !== void 0) throw new WorkerDataDirUnwritableError(dir, refusal);
|
|
299
|
+
const cwd = fs.existsSync(os.tmpdir()) ? os.tmpdir() : dir;
|
|
300
|
+
const child = spawn(
|
|
301
|
+
process.execPath,
|
|
302
|
+
[daemonEntryScript(), "--worker-daemon"],
|
|
303
|
+
{
|
|
304
|
+
cwd,
|
|
305
|
+
detached: true,
|
|
306
|
+
stdio: "ignore",
|
|
307
|
+
windowsHide: true,
|
|
308
|
+
env: {
|
|
309
|
+
...withEnvProxyEnabled(process.env),
|
|
310
|
+
TG_WORKER_POLL_MS: String(pollIntervalMs),
|
|
311
|
+
TG_WORKER_DATA_DIR: dir
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
);
|
|
315
|
+
child.on("error", () => void 0);
|
|
316
|
+
const pid = child.pid;
|
|
317
|
+
if (pid === void 0) {
|
|
318
|
+
throw new Error("startDetachedWorker: spawn produced no pid");
|
|
319
|
+
}
|
|
320
|
+
let claimed;
|
|
321
|
+
try {
|
|
322
|
+
claimed = claimWorkerPidFile(dir, pid);
|
|
323
|
+
} catch (e) {
|
|
324
|
+
discardSpawnedWorker(child, pid);
|
|
325
|
+
throw e;
|
|
326
|
+
}
|
|
327
|
+
if (!claimed) {
|
|
328
|
+
discardSpawnedWorker(child, pid);
|
|
329
|
+
throw new WorkerAlreadyRunningError();
|
|
330
|
+
}
|
|
331
|
+
try {
|
|
332
|
+
fs.writeFileSync(workerStampPath(dir), currentDaemonStamp());
|
|
333
|
+
} catch {
|
|
334
|
+
}
|
|
335
|
+
child.unref();
|
|
336
|
+
return pid;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export {
|
|
340
|
+
proxyConfigured,
|
|
341
|
+
nodeFetchHonoursEnvProxy,
|
|
342
|
+
fetchBypassesProxy,
|
|
343
|
+
rerunWithEnvProxy,
|
|
344
|
+
resolvePollIntervalMs,
|
|
345
|
+
drainHeartbeatPathFor,
|
|
346
|
+
writeDrainHeartbeat,
|
|
347
|
+
workerPidPath,
|
|
348
|
+
workerStampPath,
|
|
349
|
+
workerErrorLogPath,
|
|
350
|
+
oneLogLine,
|
|
351
|
+
appendWorkerErrorLog,
|
|
352
|
+
readPidFile,
|
|
353
|
+
isWorkerRunning,
|
|
354
|
+
ensureWorkerAlive,
|
|
355
|
+
stopWorker,
|
|
356
|
+
WorkerAlreadyRunningError,
|
|
357
|
+
WorkerDataDirUnwritableError,
|
|
358
|
+
dataDirWriteRefusal,
|
|
359
|
+
claimWorkerPidFile,
|
|
360
|
+
currentDaemonStamp,
|
|
361
|
+
startDetachedWorker
|
|
362
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
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/code_fold.ts
|
|
8
|
+
init_define_import_meta_env();
|
|
9
|
+
var FOLDABLE_KINDS = /* @__PURE__ */ new Set(["function", "method", "func", "def", "fn", "procedure", "constructor", "variable"]);
|
|
10
|
+
var MIN_FOLDED_ROWS = 3;
|
|
11
|
+
function planBodyFolds(rows, spans, keep, minSpan) {
|
|
12
|
+
if (rows.length === 0 || spans.length === 0 || keep < 1) return [];
|
|
13
|
+
const rowAt = /* @__PURE__ */ new Map();
|
|
14
|
+
for (let i = 0; i < rows.length; i++) {
|
|
15
|
+
const row = rows[i];
|
|
16
|
+
if (row !== void 0) rowAt.set(row.no, i);
|
|
17
|
+
}
|
|
18
|
+
const ordered = [...spans].sort((a, b) => a.lineStart - b.lineStart || b.lineEnd - a.lineEnd);
|
|
19
|
+
let firstDeliveredLine = null;
|
|
20
|
+
for (const line of rowAt.keys()) if (firstDeliveredLine === null || line < firstDeliveredLine) firstDeliveredLine = line;
|
|
21
|
+
const folds = [];
|
|
22
|
+
let foldedThrough = -1;
|
|
23
|
+
for (const span of ordered) {
|
|
24
|
+
if (!FOLDABLE_KINDS.has(span.kind)) continue;
|
|
25
|
+
if (span.lineEnd - span.lineStart + 1 < minSpan) continue;
|
|
26
|
+
if (span.lineStart <= foldedThrough) continue;
|
|
27
|
+
if (firstDeliveredLine !== null && span.lineStart < firstDeliveredLine) continue;
|
|
28
|
+
const firstFolded = span.lineStart + keep;
|
|
29
|
+
if (firstFolded > span.lineEnd) continue;
|
|
30
|
+
let startIdx = -1;
|
|
31
|
+
let endIdx = -1;
|
|
32
|
+
for (let line = firstFolded; line <= span.lineEnd; line++) {
|
|
33
|
+
const idx = rowAt.get(line);
|
|
34
|
+
if (idx === void 0) continue;
|
|
35
|
+
if (startIdx < 0) startIdx = idx;
|
|
36
|
+
endIdx = idx;
|
|
37
|
+
}
|
|
38
|
+
if (startIdx < 0 || endIdx < startIdx) continue;
|
|
39
|
+
const len = endIdx - startIdx + 1;
|
|
40
|
+
const firstRow = rows[startIdx];
|
|
41
|
+
const lastRow = rows[endIdx];
|
|
42
|
+
if (firstRow === void 0 || lastRow === void 0) continue;
|
|
43
|
+
if (lastRow.no - firstRow.no + 1 !== len) continue;
|
|
44
|
+
if (len < MIN_FOLDED_ROWS) continue;
|
|
45
|
+
folds.push({ startIdx, len, name: span.name, kind: "body", declLine: span.lineStart, firstLine: firstRow.no, lastLine: lastRow.no });
|
|
46
|
+
foldedThrough = span.lineEnd;
|
|
47
|
+
}
|
|
48
|
+
return folds;
|
|
49
|
+
}
|
|
50
|
+
var SLASH_STAR = { line: ["//"], open: "/*", close: "*/" };
|
|
51
|
+
function advanceTemplateState(text, inTemplate) {
|
|
52
|
+
let t = inTemplate;
|
|
53
|
+
for (let i = 0; i < text.length; i++) {
|
|
54
|
+
const c = text[i];
|
|
55
|
+
if (c === "\\") {
|
|
56
|
+
i++;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (c === "`") {
|
|
60
|
+
t = !t;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (t) continue;
|
|
64
|
+
if (c === "/" && text[i + 1] === "/") return t;
|
|
65
|
+
if (c === "'" || c === '"') {
|
|
66
|
+
const q = c;
|
|
67
|
+
i++;
|
|
68
|
+
while (i < text.length && text[i] !== q) {
|
|
69
|
+
if (text[i] === "\\") i++;
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return t;
|
|
75
|
+
}
|
|
76
|
+
var HASH = { line: ["#"] };
|
|
77
|
+
var DOUBLE_DASH = { line: ["--"] };
|
|
78
|
+
var COMMENT_SYNTAX = new Map([
|
|
79
|
+
...["ts", "tsx", "js", "jsx", "mjs", "cjs", "java", "c", "h", "cc", "cpp", "hpp", "cs", "go", "rs", "swift", "kt", "scala", "php", "dart"].map(
|
|
80
|
+
(ext) => [ext, SLASH_STAR]
|
|
81
|
+
),
|
|
82
|
+
...["py", "rb", "sh", "bash", "zsh", "pl", "r"].map((ext) => [ext, HASH]),
|
|
83
|
+
...["sql", "lua", "hs"].map((ext) => [ext, DOUBLE_DASH])
|
|
84
|
+
]);
|
|
85
|
+
function commentSyntaxFor(path) {
|
|
86
|
+
const dot = path.lastIndexOf(".");
|
|
87
|
+
if (dot < 0) return null;
|
|
88
|
+
return COMMENT_SYNTAX.get(path.slice(dot + 1).toLowerCase()) ?? null;
|
|
89
|
+
}
|
|
90
|
+
function planCommentFolds(rows, syntax, commentKeep, commentMinBlock, occupied) {
|
|
91
|
+
if (syntax === null || rows.length === 0 || commentKeep < 1 || commentMinBlock < 1) return [];
|
|
92
|
+
const folds = [];
|
|
93
|
+
let i = 0;
|
|
94
|
+
let inBlock = false;
|
|
95
|
+
const tracksTemplates = syntax.open === "/*";
|
|
96
|
+
let inTemplate = false;
|
|
97
|
+
while (i < rows.length) {
|
|
98
|
+
const start = i;
|
|
99
|
+
while (i < rows.length) {
|
|
100
|
+
const text = rows[i]?.text ?? "";
|
|
101
|
+
const trimmed = text.trim();
|
|
102
|
+
if (tracksTemplates) {
|
|
103
|
+
const wasInTemplate = inTemplate;
|
|
104
|
+
inTemplate = advanceTemplateState(text, inTemplate);
|
|
105
|
+
if (wasInTemplate || inTemplate) {
|
|
106
|
+
inBlock = false;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (inBlock) {
|
|
111
|
+
if (syntax.close !== void 0 && trimmed.includes(syntax.close)) inBlock = false;
|
|
112
|
+
i++;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (syntax.open !== void 0 && trimmed.startsWith(syntax.open)) {
|
|
116
|
+
if (syntax.close === void 0 || !trimmed.slice(syntax.open.length).includes(syntax.close)) inBlock = true;
|
|
117
|
+
i++;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (syntax.line.some((p) => trimmed.startsWith(p))) {
|
|
121
|
+
i++;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
const runLen = i - start;
|
|
127
|
+
if (runLen >= commentMinBlock) {
|
|
128
|
+
const foldStart = start + commentKeep;
|
|
129
|
+
const len = i - foldStart;
|
|
130
|
+
const firstRow = rows[foldStart];
|
|
131
|
+
const lastRow = rows[i - 1];
|
|
132
|
+
if (len >= MIN_FOLDED_ROWS && firstRow !== void 0 && lastRow !== void 0 && lastRow.no - firstRow.no + 1 === len) {
|
|
133
|
+
let clear = true;
|
|
134
|
+
for (let k = foldStart; k < i; k++) {
|
|
135
|
+
if (occupied.has(k)) {
|
|
136
|
+
clear = false;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (clear) folds.push({ startIdx: foldStart, len, name: "comment", kind: "comment", firstLine: firstRow.no, lastLine: lastRow.no });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (i === start) i++;
|
|
144
|
+
}
|
|
145
|
+
return folds;
|
|
146
|
+
}
|
|
147
|
+
function mergeFolds(body, comment) {
|
|
148
|
+
const merged = [...body, ...comment].sort((a, b) => a.startIdx - b.startIdx || b.len - a.len);
|
|
149
|
+
const out = [];
|
|
150
|
+
let through = -1;
|
|
151
|
+
for (const fold of merged) {
|
|
152
|
+
if (fold.startIdx <= through) continue;
|
|
153
|
+
out.push(fold);
|
|
154
|
+
through = fold.startIdx + fold.len - 1;
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
var MAX_FOLD_DETAIL = 400;
|
|
159
|
+
var FOLD_DETAIL_SUFFIX_BUDGET = 16;
|
|
160
|
+
var PROSE_FOLD_MIN_CHARS = 400;
|
|
161
|
+
var PROSE_FOLD_MAX_KEEP_RATIO = 0.6;
|
|
162
|
+
var PROSE_FOLD_MIN_SENTENCE = 40;
|
|
163
|
+
var PROSE_STRUCTURAL_RE = /^\s*(?:#{1,6}\s|```|~~~|\||>|\d+[.)]\s*$|[-*+]\s*$)/;
|
|
164
|
+
var PROSE_FENCE_RE = /^\s*(?:```|~~~)/;
|
|
165
|
+
var PROSE_ABBREV_RE = /(?:\b(?:e\.g|i\.e|vs|cf|etc|approx|al|Dr|Mr|Ms|St|Fig|No)\.|\b[^\W\d_]\.)$/;
|
|
166
|
+
function proseSentenceEnd(text) {
|
|
167
|
+
for (const m of text.matchAll(/[.!?][*_`)\]"'”’]*(?=\s|$)/gu)) {
|
|
168
|
+
const term = m.index + 1;
|
|
169
|
+
const end = m.index + m[0].length;
|
|
170
|
+
if (end < PROSE_FOLD_MIN_SENTENCE) continue;
|
|
171
|
+
if (PROSE_ABBREV_RE.test(text.slice(0, term))) continue;
|
|
172
|
+
return end;
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
function planProseFolds(rows, claimed) {
|
|
177
|
+
const folds = [];
|
|
178
|
+
let inFence = false;
|
|
179
|
+
for (let i = 0; i < rows.length; i++) {
|
|
180
|
+
if (claimed.has(i)) continue;
|
|
181
|
+
const row = rows[i];
|
|
182
|
+
if (row === void 0) continue;
|
|
183
|
+
const text = row.text;
|
|
184
|
+
if (PROSE_FENCE_RE.test(text)) {
|
|
185
|
+
inFence = !inFence;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (inFence) continue;
|
|
189
|
+
if (text.length < PROSE_FOLD_MIN_CHARS) continue;
|
|
190
|
+
if (PROSE_STRUCTURAL_RE.test(text)) continue;
|
|
191
|
+
const end = proseSentenceEnd(text);
|
|
192
|
+
if (end === null || end > text.length * PROSE_FOLD_MAX_KEEP_RATIO) continue;
|
|
193
|
+
folds.push({ startIdx: i, len: 1, name: "paragraph", kind: "prose", keep: text.slice(0, end), firstLine: row.no, lastLine: row.no });
|
|
194
|
+
}
|
|
195
|
+
return folds;
|
|
196
|
+
}
|
|
197
|
+
function foldDetail(path, folds, maxLen = MAX_FOLD_DETAIL) {
|
|
198
|
+
const head = `${path}::`;
|
|
199
|
+
const ids = folds.map((f) => f.kind === "body" ? f.name : `#${f.firstLine}-${f.lastLine}`);
|
|
200
|
+
const budget = maxLen - head.length - FOLD_DETAIL_SUFFIX_BUDGET;
|
|
201
|
+
const kept = [];
|
|
202
|
+
let used = 0;
|
|
203
|
+
for (const id of ids) {
|
|
204
|
+
const add = kept.length === 0 ? id.length : id.length + 1;
|
|
205
|
+
if (used + add > budget) break;
|
|
206
|
+
kept.push(id);
|
|
207
|
+
used += add;
|
|
208
|
+
}
|
|
209
|
+
const dropped = ids.length - kept.length;
|
|
210
|
+
if (kept.length === 0) return `${head}+${ids.length} folds`;
|
|
211
|
+
return dropped > 0 ? `${head}${kept.join(",")},+${dropped} more` : `${head}${kept.join(",")}`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export {
|
|
215
|
+
planBodyFolds,
|
|
216
|
+
commentSyntaxFor,
|
|
217
|
+
planCommentFolds,
|
|
218
|
+
mergeFolds,
|
|
219
|
+
planProseFolds,
|
|
220
|
+
foldDetail
|
|
221
|
+
};
|
|
@@ -3107,6 +3107,21 @@ function encodePng(width, height, rgba) {
|
|
|
3107
3107
|
const iendChunk = makePngChunk("IEND", Buffer.alloc(0));
|
|
3108
3108
|
return Buffer.concat([signature, ihdrChunk, idatChunk, iendChunk]);
|
|
3109
3109
|
}
|
|
3110
|
+
function bmpHasAlpha(buf, layout) {
|
|
3111
|
+
const { compression, bpp, pixelOffset, rowStride, width, height } = layout;
|
|
3112
|
+
if (bpp !== 32) return false;
|
|
3113
|
+
const dibSize = buf.readUInt32LE(14);
|
|
3114
|
+
if (compression === 3 && dibSize >= 56 && buf.length >= 14 + 56) {
|
|
3115
|
+
return buf.readUInt32LE(14 + 52) !== 0;
|
|
3116
|
+
}
|
|
3117
|
+
for (let y = 0; y < height; y++) {
|
|
3118
|
+
const rowOffset = pixelOffset + y * rowStride;
|
|
3119
|
+
for (let x = 0; x < width; x++) {
|
|
3120
|
+
if (buf[rowOffset + x * 4 + 3] !== 0) return true;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
return false;
|
|
3124
|
+
}
|
|
3110
3125
|
function decodeBmp(buf) {
|
|
3111
3126
|
if (buf.length < 54 || buf[0] !== 66 || buf[1] !== 77) {
|
|
3112
3127
|
throw new Error("Invalid BMP signature");
|
|
@@ -3125,8 +3140,12 @@ function decodeBmp(buf) {
|
|
|
3125
3140
|
throw new Error("Unsupported BMP bit depth: " + bpp);
|
|
3126
3141
|
}
|
|
3127
3142
|
assertDecodableSize("BMP", width, height, 4);
|
|
3128
|
-
const outRgba = Buffer.alloc(width * height * 4);
|
|
3129
3143
|
const rowStride = Math.floor((bpp * width + 31) / 32) * 4;
|
|
3144
|
+
if (pixelOffset + (height - 1) * rowStride + width * (bpp / 8) > buf.length) {
|
|
3145
|
+
throw new Error("BMP pixel data truncated");
|
|
3146
|
+
}
|
|
3147
|
+
const outRgba = Buffer.alloc(width * height * 4);
|
|
3148
|
+
const alphaIsReal = bmpHasAlpha(buf, { compression, bpp, pixelOffset, rowStride, width, height });
|
|
3130
3149
|
for (let y = 0; y < height; y++) {
|
|
3131
3150
|
const srcY = topDown ? y : height - 1 - y;
|
|
3132
3151
|
const rowOffset = pixelOffset + srcY * rowStride;
|
|
@@ -3143,7 +3162,7 @@ function decodeBmp(buf) {
|
|
|
3143
3162
|
outRgba[outIdx] = buf[pxOffset + 2] ?? 0;
|
|
3144
3163
|
outRgba[outIdx + 1] = buf[pxOffset + 1] ?? 0;
|
|
3145
3164
|
outRgba[outIdx + 2] = buf[pxOffset] ?? 0;
|
|
3146
|
-
outRgba[outIdx + 3] = buf[pxOffset + 3] ?? 255;
|
|
3165
|
+
outRgba[outIdx + 3] = alphaIsReal ? buf[pxOffset + 3] ?? 255 : 255;
|
|
3147
3166
|
}
|
|
3148
3167
|
}
|
|
3149
3168
|
}
|
|
@@ -10,18 +10,22 @@ import {
|
|
|
10
10
|
querySheet,
|
|
11
11
|
rangeSheet,
|
|
12
12
|
xlsxColumns
|
|
13
|
-
} from "./token-goat-chunk-
|
|
14
|
-
import "./token-goat-chunk-
|
|
13
|
+
} from "./token-goat-chunk-RZRTDST7.mjs";
|
|
14
|
+
import "./token-goat-chunk-N2NMER56.mjs";
|
|
15
15
|
import "./token-goat-chunk-3BTK54F3.mjs";
|
|
16
|
-
import "./token-goat-chunk-
|
|
16
|
+
import "./token-goat-chunk-4FVIAHSI.mjs";
|
|
17
|
+
import "./token-goat-chunk-7IN2MKDS.mjs";
|
|
18
|
+
import "./token-goat-chunk-U4N3BN2W.mjs";
|
|
19
|
+
import "./token-goat-chunk-YZAAZU2S.mjs";
|
|
20
|
+
import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
21
|
+
import "./token-goat-chunk-IVKIZWAB.mjs";
|
|
17
22
|
import "./token-goat-chunk-XTQAOTSO.mjs";
|
|
18
23
|
import "./token-goat-chunk-AH6QILZM.mjs";
|
|
19
|
-
import "./token-goat-chunk-XYWPOSCN.mjs";
|
|
20
|
-
import "./token-goat-chunk-TCQANXYC.mjs";
|
|
21
|
-
import "./token-goat-chunk-NMTKNYGF.mjs";
|
|
22
|
-
import "./token-goat-chunk-MELOKFDJ.mjs";
|
|
23
24
|
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
24
|
-
import "./token-goat-chunk-
|
|
25
|
+
import "./token-goat-chunk-GOLEOXZP.mjs";
|
|
26
|
+
import "./token-goat-chunk-AM5V6GSX.mjs";
|
|
27
|
+
import "./token-goat-chunk-FNFBKLRD.mjs";
|
|
28
|
+
import "./token-goat-chunk-VES7EL7O.mjs";
|
|
25
29
|
import "./token-goat-chunk-A37V4PBF.mjs";
|
|
26
30
|
export {
|
|
27
31
|
XlsxScanTooLargeError,
|