ghc-proxy 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,320 @@
1
1
  import { i as __toESM, r as __require, t as __commonJSMin } from "./main.mjs";
2
- import { open } from "node:fs/promises";
3
- import "node:stream";
2
+ //#region node_modules/@borewit/text-codec/lib/index.js
3
+ const WINDOWS_1252_EXTRA = {
4
+ 128: "€",
5
+ 130: "‚",
6
+ 131: "ƒ",
7
+ 132: "„",
8
+ 133: "…",
9
+ 134: "†",
10
+ 135: "‡",
11
+ 136: "ˆ",
12
+ 137: "‰",
13
+ 138: "Š",
14
+ 139: "‹",
15
+ 140: "Œ",
16
+ 142: "Ž",
17
+ 145: "‘",
18
+ 146: "’",
19
+ 147: "“",
20
+ 148: "”",
21
+ 149: "•",
22
+ 150: "–",
23
+ 151: "—",
24
+ 152: "˜",
25
+ 153: "™",
26
+ 154: "š",
27
+ 155: "›",
28
+ 156: "œ",
29
+ 158: "ž",
30
+ 159: "Ÿ"
31
+ };
32
+ const WINDOWS_1252_REVERSE = {};
33
+ for (const [code, char] of Object.entries(WINDOWS_1252_EXTRA)) WINDOWS_1252_REVERSE[char] = Number.parseInt(code, 10);
34
+ let _utf8Decoder;
35
+ function utf8Decoder() {
36
+ if (typeof globalThis.TextDecoder === "undefined") return void 0;
37
+ return _utf8Decoder !== null && _utf8Decoder !== void 0 ? _utf8Decoder : _utf8Decoder = new globalThis.TextDecoder("utf-8");
38
+ }
39
+ const CHUNK = 32768;
40
+ const REPLACEMENT = 65533;
41
+ /**
42
+ * Decode text from binary data
43
+ */
44
+ function textDecode(bytes, encoding = "utf-8") {
45
+ switch (encoding.toLowerCase()) {
46
+ case "utf-8":
47
+ case "utf8": {
48
+ const dec = utf8Decoder();
49
+ return dec ? dec.decode(bytes) : decodeUTF8(bytes);
50
+ }
51
+ case "utf-16le": return decodeUTF16LE(bytes);
52
+ case "us-ascii":
53
+ case "ascii": return decodeASCII(bytes);
54
+ case "latin1":
55
+ case "iso-8859-1": return decodeLatin1(bytes);
56
+ case "windows-1252": return decodeWindows1252(bytes);
57
+ default: throw new RangeError(`Encoding '${encoding}' not supported`);
58
+ }
59
+ }
60
+ function flushChunk(parts, chunk) {
61
+ if (chunk.length === 0) return;
62
+ parts.push(String.fromCharCode.apply(null, chunk));
63
+ chunk.length = 0;
64
+ }
65
+ function pushCodeUnit(parts, chunk, codeUnit) {
66
+ chunk.push(codeUnit);
67
+ if (chunk.length >= CHUNK) flushChunk(parts, chunk);
68
+ }
69
+ function pushCodePoint(parts, chunk, cp) {
70
+ if (cp <= 65535) {
71
+ pushCodeUnit(parts, chunk, cp);
72
+ return;
73
+ }
74
+ cp -= 65536;
75
+ pushCodeUnit(parts, chunk, 55296 + (cp >> 10));
76
+ pushCodeUnit(parts, chunk, 56320 + (cp & 1023));
77
+ }
78
+ function decodeUTF8(bytes) {
79
+ const parts = [];
80
+ const chunk = [];
81
+ let i = 0;
82
+ if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) i = 3;
83
+ while (i < bytes.length) {
84
+ const b1 = bytes[i];
85
+ if (b1 <= 127) {
86
+ pushCodeUnit(parts, chunk, b1);
87
+ i++;
88
+ continue;
89
+ }
90
+ if (b1 < 194 || b1 > 244) {
91
+ pushCodeUnit(parts, chunk, REPLACEMENT);
92
+ i++;
93
+ continue;
94
+ }
95
+ if (b1 <= 223) {
96
+ if (i + 1 >= bytes.length) {
97
+ pushCodeUnit(parts, chunk, REPLACEMENT);
98
+ i++;
99
+ continue;
100
+ }
101
+ const b2 = bytes[i + 1];
102
+ if ((b2 & 192) !== 128) {
103
+ pushCodeUnit(parts, chunk, REPLACEMENT);
104
+ i++;
105
+ continue;
106
+ }
107
+ pushCodeUnit(parts, chunk, (b1 & 31) << 6 | b2 & 63);
108
+ i += 2;
109
+ continue;
110
+ }
111
+ if (b1 <= 239) {
112
+ if (i + 2 >= bytes.length) {
113
+ pushCodeUnit(parts, chunk, REPLACEMENT);
114
+ i++;
115
+ continue;
116
+ }
117
+ const b2 = bytes[i + 1];
118
+ const b3 = bytes[i + 2];
119
+ if (!((b2 & 192) === 128 && (b3 & 192) === 128 && !(b1 === 224 && b2 < 160) && !(b1 === 237 && b2 >= 160))) {
120
+ pushCodeUnit(parts, chunk, REPLACEMENT);
121
+ i++;
122
+ continue;
123
+ }
124
+ pushCodeUnit(parts, chunk, (b1 & 15) << 12 | (b2 & 63) << 6 | b3 & 63);
125
+ i += 3;
126
+ continue;
127
+ }
128
+ if (i + 3 >= bytes.length) {
129
+ pushCodeUnit(parts, chunk, REPLACEMENT);
130
+ i++;
131
+ continue;
132
+ }
133
+ const b2 = bytes[i + 1];
134
+ const b3 = bytes[i + 2];
135
+ const b4 = bytes[i + 3];
136
+ if (!((b2 & 192) === 128 && (b3 & 192) === 128 && (b4 & 192) === 128 && !(b1 === 240 && b2 < 144) && !(b1 === 244 && b2 > 143))) {
137
+ pushCodeUnit(parts, chunk, REPLACEMENT);
138
+ i++;
139
+ continue;
140
+ }
141
+ pushCodePoint(parts, chunk, (b1 & 7) << 18 | (b2 & 63) << 12 | (b3 & 63) << 6 | b4 & 63);
142
+ i += 4;
143
+ }
144
+ flushChunk(parts, chunk);
145
+ return parts.join("");
146
+ }
147
+ function decodeUTF16LE(bytes) {
148
+ const parts = [];
149
+ const chunk = [];
150
+ const len = bytes.length;
151
+ let i = 0;
152
+ while (i + 1 < len) {
153
+ const u1 = bytes[i] | bytes[i + 1] << 8;
154
+ i += 2;
155
+ if (u1 >= 55296 && u1 <= 56319) {
156
+ if (i + 1 < len) {
157
+ const u2 = bytes[i] | bytes[i + 1] << 8;
158
+ if (u2 >= 56320 && u2 <= 57343) {
159
+ pushCodeUnit(parts, chunk, u1);
160
+ pushCodeUnit(parts, chunk, u2);
161
+ i += 2;
162
+ } else pushCodeUnit(parts, chunk, REPLACEMENT);
163
+ } else pushCodeUnit(parts, chunk, REPLACEMENT);
164
+ continue;
165
+ }
166
+ if (u1 >= 56320 && u1 <= 57343) {
167
+ pushCodeUnit(parts, chunk, REPLACEMENT);
168
+ continue;
169
+ }
170
+ pushCodeUnit(parts, chunk, u1);
171
+ }
172
+ if (i < len) pushCodeUnit(parts, chunk, REPLACEMENT);
173
+ flushChunk(parts, chunk);
174
+ return parts.join("");
175
+ }
176
+ function decodeASCII(bytes) {
177
+ const parts = [];
178
+ for (let i = 0; i < bytes.length; i += CHUNK) {
179
+ const end = Math.min(bytes.length, i + CHUNK);
180
+ const codes = new Array(end - i);
181
+ for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j] & 127;
182
+ parts.push(String.fromCharCode.apply(null, codes));
183
+ }
184
+ return parts.join("");
185
+ }
186
+ function decodeLatin1(bytes) {
187
+ const parts = [];
188
+ for (let i = 0; i < bytes.length; i += CHUNK) {
189
+ const end = Math.min(bytes.length, i + CHUNK);
190
+ const codes = new Array(end - i);
191
+ for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j];
192
+ parts.push(String.fromCharCode.apply(null, codes));
193
+ }
194
+ return parts.join("");
195
+ }
196
+ function decodeWindows1252(bytes) {
197
+ const parts = [];
198
+ let out = "";
199
+ for (let i = 0; i < bytes.length; i++) {
200
+ const b = bytes[i];
201
+ const extra = b >= 128 && b <= 159 ? WINDOWS_1252_EXTRA[b] : void 0;
202
+ out += extra !== null && extra !== void 0 ? extra : String.fromCharCode(b);
203
+ if (out.length >= CHUNK) {
204
+ parts.push(out);
205
+ out = "";
206
+ }
207
+ }
208
+ if (out) parts.push(out);
209
+ return parts.join("");
210
+ }
211
+ //#endregion
212
+ //#region node_modules/token-types/lib/index.js
213
+ function dv(array) {
214
+ return new DataView(array.buffer, array.byteOffset);
215
+ }
216
+ const UINT8 = {
217
+ len: 1,
218
+ get(array, offset) {
219
+ return dv(array).getUint8(offset);
220
+ },
221
+ put(array, offset, value) {
222
+ dv(array).setUint8(offset, value);
223
+ return offset + 1;
224
+ }
225
+ };
226
+ /**
227
+ * 16-bit unsigned integer, Little Endian byte order
228
+ */
229
+ const UINT16_LE = {
230
+ len: 2,
231
+ get(array, offset) {
232
+ return dv(array).getUint16(offset, true);
233
+ },
234
+ put(array, offset, value) {
235
+ dv(array).setUint16(offset, value, true);
236
+ return offset + 2;
237
+ }
238
+ };
239
+ /**
240
+ * 16-bit unsigned integer, Big Endian byte order
241
+ */
242
+ const UINT16_BE = {
243
+ len: 2,
244
+ get(array, offset) {
245
+ return dv(array).getUint16(offset);
246
+ },
247
+ put(array, offset, value) {
248
+ dv(array).setUint16(offset, value);
249
+ return offset + 2;
250
+ }
251
+ };
252
+ /**
253
+ * 32-bit unsigned integer, Little Endian byte order
254
+ */
255
+ const UINT32_LE = {
256
+ len: 4,
257
+ get(array, offset) {
258
+ return dv(array).getUint32(offset, true);
259
+ },
260
+ put(array, offset, value) {
261
+ dv(array).setUint32(offset, value, true);
262
+ return offset + 4;
263
+ }
264
+ };
265
+ /**
266
+ * 32-bit unsigned integer, Big Endian byte order
267
+ */
268
+ const UINT32_BE = {
269
+ len: 4,
270
+ get(array, offset) {
271
+ return dv(array).getUint32(offset);
272
+ },
273
+ put(array, offset, value) {
274
+ dv(array).setUint32(offset, value);
275
+ return offset + 4;
276
+ }
277
+ };
278
+ /**
279
+ * 32-bit signed integer, Big Endian byte order
280
+ */
281
+ const INT32_BE = {
282
+ len: 4,
283
+ get(array, offset) {
284
+ return dv(array).getInt32(offset);
285
+ },
286
+ put(array, offset, value) {
287
+ dv(array).setInt32(offset, value);
288
+ return offset + 4;
289
+ }
290
+ };
291
+ /**
292
+ * 64-bit unsigned integer, Little Endian byte order
293
+ */
294
+ const UINT64_LE = {
295
+ len: 8,
296
+ get(array, offset) {
297
+ return dv(array).getBigUint64(offset, true);
298
+ },
299
+ put(array, offset, value) {
300
+ dv(array).setBigUint64(offset, value, true);
301
+ return offset + 8;
302
+ }
303
+ };
304
+ /**
305
+ * Consume a fixed number of bytes from the stream and return a string with a specified encoding.
306
+ * Supports all encodings supported by TextDecoder, plus 'windows-1252'.
307
+ */
308
+ var StringType = class {
309
+ constructor(len, encoding) {
310
+ this.len = len;
311
+ this.encoding = encoding;
312
+ }
313
+ get(data, offset = 0) {
314
+ return textDecode(data.subarray(offset, offset + this.len), this.encoding);
315
+ }
316
+ };
317
+ //#endregion
4
318
  //#region node_modules/strtok3/lib/stream/Errors.js
5
319
  const defaultMessages = "End-Of-Stream";
6
320
  /**
@@ -183,7 +497,7 @@ var AbstractTokenizer = class {
183
497
  * @protected
184
498
  */
185
499
  constructor(options) {
186
- this.numBuffer = new Uint8Array(8);
500
+ this.numBuffer = /* @__PURE__ */ new Uint8Array(8);
187
501
  /**
188
502
  * Tokenizer-stream position
189
503
  */
@@ -234,637 +548,271 @@ var AbstractTokenizer = class {
234
548
  return token.get(this.numBuffer, 0);
235
549
  }
236
550
  /**
237
- * Ignore number of bytes, advances the pointer in under tokenizer-stream.
238
- * @param length - Number of bytes to ignore
239
- * @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
240
- */
241
- async ignore(length) {
242
- if (this.fileInfo.size !== void 0) {
243
- const bytesLeft = this.fileInfo.size - this.position;
244
- if (length > bytesLeft) {
245
- this.position += bytesLeft;
246
- return bytesLeft;
247
- }
248
- }
249
- this.position += length;
250
- return length;
251
- }
252
- async close() {
253
- await this.abort();
254
- await this.onClose?.();
255
- }
256
- normalizeOptions(uint8Array, options) {
257
- if (!this.supportsRandomAccess() && options && options.position !== void 0 && options.position < this.position) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
258
- return {
259
- mayBeLess: false,
260
- offset: 0,
261
- length: uint8Array.length,
262
- position: this.position,
263
- ...options
264
- };
265
- }
266
- abort() {
267
- return Promise.resolve();
268
- }
269
- };
270
- //#endregion
271
- //#region node_modules/strtok3/lib/ReadStreamTokenizer.js
272
- const maxBufferSize = 256e3;
273
- var ReadStreamTokenizer = class extends AbstractTokenizer {
274
- /**
275
- * Constructor
276
- * @param streamReader stream-reader to read from
277
- * @param options Tokenizer options
278
- */
279
- constructor(streamReader, options) {
280
- super(options);
281
- this.streamReader = streamReader;
282
- this.fileInfo = options?.fileInfo ?? {};
283
- }
284
- /**
285
- * Read buffer from tokenizer
286
- * @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
287
- * @param options - Read behaviour options
288
- * @returns Promise with number of bytes read
289
- */
290
- async readBuffer(uint8Array, options) {
291
- const normOptions = this.normalizeOptions(uint8Array, options);
292
- const skipBytes = normOptions.position - this.position;
293
- if (skipBytes > 0) {
294
- await this.ignore(skipBytes);
295
- return this.readBuffer(uint8Array, options);
296
- }
297
- if (skipBytes < 0) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
298
- if (normOptions.length === 0) return 0;
299
- const bytesRead = await this.streamReader.read(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
300
- this.position += bytesRead;
301
- if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) throw new EndOfStreamError();
302
- return bytesRead;
303
- }
304
- /**
305
- * Peek (read ahead) buffer from tokenizer
306
- * @param uint8Array - Uint8Array (or Buffer) to write data to
307
- * @param options - Read behaviour options
308
- * @returns Promise with number of bytes peeked
309
- */
310
- async peekBuffer(uint8Array, options) {
311
- const normOptions = this.normalizeOptions(uint8Array, options);
312
- let bytesRead = 0;
313
- if (normOptions.position) {
314
- const skipBytes = normOptions.position - this.position;
315
- if (skipBytes > 0) {
316
- const skipBuffer = new Uint8Array(normOptions.length + skipBytes);
317
- bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess });
318
- uint8Array.set(skipBuffer.subarray(skipBytes));
319
- return bytesRead - skipBytes;
320
- }
321
- if (skipBytes < 0) throw new Error("Cannot peek from a negative offset in a stream");
322
- }
323
- if (normOptions.length > 0) {
324
- try {
325
- bytesRead = await this.streamReader.peek(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
326
- } catch (err) {
327
- if (options?.mayBeLess && err instanceof EndOfStreamError) return 0;
328
- throw err;
329
- }
330
- if (!normOptions.mayBeLess && bytesRead < normOptions.length) throw new EndOfStreamError();
331
- }
332
- return bytesRead;
333
- }
334
- async ignore(length) {
335
- const bufSize = Math.min(maxBufferSize, length);
336
- const buf = new Uint8Array(bufSize);
337
- let totBytesRead = 0;
338
- while (totBytesRead < length) {
339
- const remaining = length - totBytesRead;
340
- const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
341
- if (bytesRead < 0) return bytesRead;
342
- totBytesRead += bytesRead;
343
- }
344
- return totBytesRead;
345
- }
346
- abort() {
347
- return this.streamReader.abort();
348
- }
349
- async close() {
350
- return this.streamReader.close();
351
- }
352
- supportsRandomAccess() {
353
- return false;
354
- }
355
- };
356
- //#endregion
357
- //#region node_modules/strtok3/lib/BufferTokenizer.js
358
- var BufferTokenizer = class extends AbstractTokenizer {
359
- /**
360
- * Construct BufferTokenizer
361
- * @param uint8Array - Uint8Array to tokenize
362
- * @param options Tokenizer options
363
- */
364
- constructor(uint8Array, options) {
365
- super(options);
366
- this.uint8Array = uint8Array;
367
- this.fileInfo = {
368
- ...options?.fileInfo ?? {},
369
- size: uint8Array.length
370
- };
371
- }
372
- /**
373
- * Read buffer from tokenizer
374
- * @param uint8Array - Uint8Array to tokenize
375
- * @param options - Read behaviour options
376
- * @returns {Promise<number>}
377
- */
378
- async readBuffer(uint8Array, options) {
379
- if (options?.position) this.position = options.position;
380
- const bytesRead = await this.peekBuffer(uint8Array, options);
381
- this.position += bytesRead;
382
- return bytesRead;
383
- }
384
- /**
385
- * Peek (read ahead) buffer from tokenizer
386
- * @param uint8Array
387
- * @param options - Read behaviour options
388
- * @returns {Promise<number>}
389
- */
390
- async peekBuffer(uint8Array, options) {
391
- const normOptions = this.normalizeOptions(uint8Array, options);
392
- const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length);
393
- if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
394
- uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read));
395
- return bytes2read;
396
- }
397
- close() {
398
- return super.close();
399
- }
400
- supportsRandomAccess() {
401
- return true;
402
- }
403
- setPosition(position) {
404
- this.position = position;
405
- }
406
- };
407
- //#endregion
408
- //#region node_modules/strtok3/lib/BlobTokenizer.js
409
- var BlobTokenizer = class extends AbstractTokenizer {
410
- /**
411
- * Construct BufferTokenizer
412
- * @param blob - Uint8Array to tokenize
413
- * @param options Tokenizer options
414
- */
415
- constructor(blob, options) {
416
- super(options);
417
- this.blob = blob;
418
- this.fileInfo = {
419
- ...options?.fileInfo ?? {},
420
- size: blob.size,
421
- mimeType: blob.type
422
- };
423
- }
424
- /**
425
- * Read buffer from tokenizer
426
- * @param uint8Array - Uint8Array to tokenize
427
- * @param options - Read behaviour options
428
- * @returns {Promise<number>}
429
- */
430
- async readBuffer(uint8Array, options) {
431
- if (options?.position) this.position = options.position;
432
- const bytesRead = await this.peekBuffer(uint8Array, options);
433
- this.position += bytesRead;
434
- return bytesRead;
435
- }
436
- /**
437
- * Peek (read ahead) buffer from tokenizer
438
- * @param buffer
439
- * @param options - Read behaviour options
440
- * @returns {Promise<number>}
551
+ * Ignore number of bytes, advances the pointer in under tokenizer-stream.
552
+ * @param length - Number of bytes to ignore. Must be ≥ 0.
553
+ * @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
441
554
  */
442
- async peekBuffer(buffer, options) {
443
- const normOptions = this.normalizeOptions(buffer, options);
444
- const bytes2read = Math.min(this.blob.size - normOptions.position, normOptions.length);
445
- if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
446
- const arrayBuffer = await this.blob.slice(normOptions.position, normOptions.position + bytes2read).arrayBuffer();
447
- buffer.set(new Uint8Array(arrayBuffer));
448
- return bytes2read;
555
+ async ignore(length) {
556
+ if (length < 0) throw new RangeError("ignore length must be ≥ 0 bytes");
557
+ if (this.fileInfo.size !== void 0) {
558
+ const bytesLeft = this.fileInfo.size - this.position;
559
+ if (length > bytesLeft) {
560
+ this.position += bytesLeft;
561
+ return bytesLeft;
562
+ }
563
+ }
564
+ this.position += length;
565
+ return length;
449
566
  }
450
- close() {
451
- return super.close();
567
+ async close() {
568
+ await this.abort();
569
+ await this.onClose?.();
452
570
  }
453
- supportsRandomAccess() {
454
- return true;
571
+ normalizeOptions(uint8Array, options) {
572
+ if (!this.supportsRandomAccess() && options && options.position !== void 0 && options.position < this.position) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
573
+ return {
574
+ mayBeLess: false,
575
+ offset: 0,
576
+ length: uint8Array.length,
577
+ position: this.position,
578
+ ...options
579
+ };
455
580
  }
456
- setPosition(position) {
457
- this.position = position;
581
+ abort() {
582
+ return Promise.resolve();
458
583
  }
459
584
  };
460
585
  //#endregion
461
- //#region node_modules/strtok3/lib/core.js
462
- /**
463
- * Construct ReadStreamTokenizer from given ReadableStream (WebStream API).
464
- * Will set fileSize, if provided given Stream has set the .path property/
465
- * @param webStream - Read from Node.js Stream.Readable (must be a byte stream)
466
- * @param options - Tokenizer options
467
- * @returns ReadStreamTokenizer
468
- */
469
- function fromWebStream(webStream, options) {
470
- const webStreamReader = makeWebStreamReader(webStream);
471
- const _options = options ?? {};
472
- const chainedClose = _options.onClose;
473
- _options.onClose = async () => {
474
- await webStreamReader.close();
475
- if (chainedClose) return chainedClose();
476
- };
477
- return new ReadStreamTokenizer(webStreamReader, _options);
478
- }
479
- /**
480
- * Construct ReadStreamTokenizer from given Buffer.
481
- * @param uint8Array - Uint8Array to tokenize
482
- * @param options - Tokenizer options
483
- * @returns BufferTokenizer
484
- */
485
- function fromBuffer(uint8Array, options) {
486
- return new BufferTokenizer(uint8Array, options);
487
- }
488
- /**
489
- * Construct ReadStreamTokenizer from given Blob.
490
- * @param blob - Uint8Array to tokenize
491
- * @param options - Tokenizer options
492
- * @returns BufferTokenizer
493
- */
494
- function fromBlob(blob, options) {
495
- return new BlobTokenizer(blob, options);
496
- }
497
- (class FileTokenizer extends AbstractTokenizer {
586
+ //#region node_modules/strtok3/lib/ReadStreamTokenizer.js
587
+ const maxBufferSize = 256e3;
588
+ var ReadStreamTokenizer = class extends AbstractTokenizer {
498
589
  /**
499
- * Create tokenizer from provided file path
500
- * @param sourceFilePath File path
590
+ * Constructor
591
+ * @param streamReader stream-reader to read from
592
+ * @param options Tokenizer options
501
593
  */
502
- static async fromFile(sourceFilePath) {
503
- const fileHandle = await open(sourceFilePath, "r");
504
- return new FileTokenizer(fileHandle, { fileInfo: {
505
- path: sourceFilePath,
506
- size: (await fileHandle.stat()).size
507
- } });
508
- }
509
- constructor(fileHandle, options) {
594
+ constructor(streamReader, options) {
510
595
  super(options);
511
- this.fileHandle = fileHandle;
512
- this.fileInfo = options.fileInfo;
596
+ this.streamReader = streamReader;
597
+ this.fileInfo = options?.fileInfo ?? {};
513
598
  }
514
599
  /**
515
- * Read buffer from file
516
- * @param uint8Array - Uint8Array to write result to
600
+ * Read buffer from tokenizer
601
+ * @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
517
602
  * @param options - Read behaviour options
518
- * @returns Promise number of bytes read
603
+ * @returns Promise with number of bytes read
519
604
  */
520
605
  async readBuffer(uint8Array, options) {
521
606
  const normOptions = this.normalizeOptions(uint8Array, options);
522
- this.position = normOptions.position;
607
+ const skipBytes = normOptions.position - this.position;
608
+ if (skipBytes > 0) {
609
+ await this.ignore(skipBytes);
610
+ return this.readBuffer(uint8Array, options);
611
+ }
612
+ if (skipBytes < 0) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
523
613
  if (normOptions.length === 0) return 0;
524
- const res = await this.fileHandle.read(uint8Array, 0, normOptions.length, normOptions.position);
525
- this.position += res.bytesRead;
526
- if (res.bytesRead < normOptions.length && (!options || !options.mayBeLess)) throw new EndOfStreamError();
527
- return res.bytesRead;
614
+ const bytesRead = await this.streamReader.read(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
615
+ this.position += bytesRead;
616
+ if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) throw new EndOfStreamError();
617
+ return bytesRead;
528
618
  }
529
619
  /**
530
- * Peek buffer from file
620
+ * Peek (read ahead) buffer from tokenizer
531
621
  * @param uint8Array - Uint8Array (or Buffer) to write data to
532
622
  * @param options - Read behaviour options
533
- * @returns Promise number of bytes read
623
+ * @returns Promise with number of bytes peeked
534
624
  */
535
625
  async peekBuffer(uint8Array, options) {
536
626
  const normOptions = this.normalizeOptions(uint8Array, options);
537
- const res = await this.fileHandle.read(uint8Array, 0, normOptions.length, normOptions.position);
538
- if (!normOptions.mayBeLess && res.bytesRead < normOptions.length) throw new EndOfStreamError();
539
- return res.bytesRead;
540
- }
541
- async close() {
542
- await this.fileHandle.close();
543
- return super.close();
544
- }
545
- setPosition(position) {
546
- this.position = position;
547
- }
548
- supportsRandomAccess() {
549
- return true;
550
- }
551
- }).fromFile;
552
- //#endregion
553
- //#region node_modules/@borewit/text-codec/lib/index.js
554
- const WINDOWS_1252_EXTRA = {
555
- 128: "€",
556
- 130: "‚",
557
- 131: "ƒ",
558
- 132: "„",
559
- 133: "…",
560
- 134: "†",
561
- 135: "‡",
562
- 136: "ˆ",
563
- 137: "‰",
564
- 138: "Š",
565
- 139: "‹",
566
- 140: "Œ",
567
- 142: "Ž",
568
- 145: "‘",
569
- 146: "’",
570
- 147: "“",
571
- 148: "”",
572
- 149: "•",
573
- 150: "–",
574
- 151: "—",
575
- 152: "˜",
576
- 153: "™",
577
- 154: "š",
578
- 155: "›",
579
- 156: "œ",
580
- 158: "ž",
581
- 159: "Ÿ"
582
- };
583
- const WINDOWS_1252_REVERSE = {};
584
- for (const [code, char] of Object.entries(WINDOWS_1252_EXTRA)) WINDOWS_1252_REVERSE[char] = Number.parseInt(code, 10);
585
- let _utf8Decoder;
586
- function utf8Decoder() {
587
- if (typeof globalThis.TextDecoder === "undefined") return void 0;
588
- return _utf8Decoder !== null && _utf8Decoder !== void 0 ? _utf8Decoder : _utf8Decoder = new globalThis.TextDecoder("utf-8");
589
- }
590
- const CHUNK = 32 * 1024;
591
- const REPLACEMENT = 65533;
592
- /**
593
- * Decode text from binary data
594
- */
595
- function textDecode(bytes, encoding = "utf-8") {
596
- switch (encoding.toLowerCase()) {
597
- case "utf-8":
598
- case "utf8": {
599
- const dec = utf8Decoder();
600
- return dec ? dec.decode(bytes) : decodeUTF8(bytes);
601
- }
602
- case "utf-16le": return decodeUTF16LE(bytes);
603
- case "us-ascii":
604
- case "ascii": return decodeASCII(bytes);
605
- case "latin1":
606
- case "iso-8859-1": return decodeLatin1(bytes);
607
- case "windows-1252": return decodeWindows1252(bytes);
608
- default: throw new RangeError(`Encoding '${encoding}' not supported`);
609
- }
610
- }
611
- function flushChunk(parts, chunk) {
612
- if (chunk.length === 0) return;
613
- parts.push(String.fromCharCode.apply(null, chunk));
614
- chunk.length = 0;
615
- }
616
- function pushCodeUnit(parts, chunk, codeUnit) {
617
- chunk.push(codeUnit);
618
- if (chunk.length >= CHUNK) flushChunk(parts, chunk);
619
- }
620
- function pushCodePoint(parts, chunk, cp) {
621
- if (cp <= 65535) {
622
- pushCodeUnit(parts, chunk, cp);
623
- return;
624
- }
625
- cp -= 65536;
626
- pushCodeUnit(parts, chunk, 55296 + (cp >> 10));
627
- pushCodeUnit(parts, chunk, 56320 + (cp & 1023));
628
- }
629
- function decodeUTF8(bytes) {
630
- const parts = [];
631
- const chunk = [];
632
- let i = 0;
633
- if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) i = 3;
634
- while (i < bytes.length) {
635
- const b1 = bytes[i];
636
- if (b1 <= 127) {
637
- pushCodeUnit(parts, chunk, b1);
638
- i++;
639
- continue;
640
- }
641
- if (b1 < 194 || b1 > 244) {
642
- pushCodeUnit(parts, chunk, REPLACEMENT);
643
- i++;
644
- continue;
645
- }
646
- if (b1 <= 223) {
647
- if (i + 1 >= bytes.length) {
648
- pushCodeUnit(parts, chunk, REPLACEMENT);
649
- i++;
650
- continue;
651
- }
652
- const b2 = bytes[i + 1];
653
- if ((b2 & 192) !== 128) {
654
- pushCodeUnit(parts, chunk, REPLACEMENT);
655
- i++;
656
- continue;
657
- }
658
- pushCodeUnit(parts, chunk, (b1 & 31) << 6 | b2 & 63);
659
- i += 2;
660
- continue;
661
- }
662
- if (b1 <= 239) {
663
- if (i + 2 >= bytes.length) {
664
- pushCodeUnit(parts, chunk, REPLACEMENT);
665
- i++;
666
- continue;
667
- }
668
- const b2 = bytes[i + 1];
669
- const b3 = bytes[i + 2];
670
- if (!((b2 & 192) === 128 && (b3 & 192) === 128 && !(b1 === 224 && b2 < 160) && !(b1 === 237 && b2 >= 160))) {
671
- pushCodeUnit(parts, chunk, REPLACEMENT);
672
- i++;
673
- continue;
627
+ let bytesRead = 0;
628
+ if (normOptions.position) {
629
+ const skipBytes = normOptions.position - this.position;
630
+ if (skipBytes > 0) {
631
+ const skipBuffer = new Uint8Array(normOptions.length + skipBytes);
632
+ bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess });
633
+ uint8Array.set(skipBuffer.subarray(skipBytes));
634
+ return bytesRead - skipBytes;
674
635
  }
675
- pushCodeUnit(parts, chunk, (b1 & 15) << 12 | (b2 & 63) << 6 | b3 & 63);
676
- i += 3;
677
- continue;
678
- }
679
- if (i + 3 >= bytes.length) {
680
- pushCodeUnit(parts, chunk, REPLACEMENT);
681
- i++;
682
- continue;
636
+ if (skipBytes < 0) throw new Error("Cannot peek from a negative offset in a stream");
683
637
  }
684
- const b2 = bytes[i + 1];
685
- const b3 = bytes[i + 2];
686
- const b4 = bytes[i + 3];
687
- if (!((b2 & 192) === 128 && (b3 & 192) === 128 && (b4 & 192) === 128 && !(b1 === 240 && b2 < 144) && !(b1 === 244 && b2 > 143))) {
688
- pushCodeUnit(parts, chunk, REPLACEMENT);
689
- i++;
690
- continue;
638
+ if (normOptions.length > 0) {
639
+ try {
640
+ bytesRead = await this.streamReader.peek(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
641
+ } catch (err) {
642
+ if (options?.mayBeLess && err instanceof EndOfStreamError) return 0;
643
+ throw err;
644
+ }
645
+ if (!normOptions.mayBeLess && bytesRead < normOptions.length) throw new EndOfStreamError();
691
646
  }
692
- pushCodePoint(parts, chunk, (b1 & 7) << 18 | (b2 & 63) << 12 | (b3 & 63) << 6 | b4 & 63);
693
- i += 4;
647
+ return bytesRead;
694
648
  }
695
- flushChunk(parts, chunk);
696
- return parts.join("");
697
- }
698
- function decodeUTF16LE(bytes) {
699
- const parts = [];
700
- const chunk = [];
701
- const len = bytes.length;
702
- let i = 0;
703
- while (i + 1 < len) {
704
- const u1 = bytes[i] | bytes[i + 1] << 8;
705
- i += 2;
706
- if (u1 >= 55296 && u1 <= 56319) {
707
- if (i + 1 < len) {
708
- const u2 = bytes[i] | bytes[i + 1] << 8;
709
- if (u2 >= 56320 && u2 <= 57343) {
710
- pushCodeUnit(parts, chunk, u1);
711
- pushCodeUnit(parts, chunk, u2);
712
- i += 2;
713
- } else pushCodeUnit(parts, chunk, REPLACEMENT);
714
- } else pushCodeUnit(parts, chunk, REPLACEMENT);
715
- continue;
716
- }
717
- if (u1 >= 56320 && u1 <= 57343) {
718
- pushCodeUnit(parts, chunk, REPLACEMENT);
719
- continue;
649
+ /**
650
+ * @param length Number of bytes to ignore. Must be ≥ 0.
651
+ */
652
+ async ignore(length) {
653
+ if (length < 0) throw new RangeError("ignore length must be ≥ 0 bytes");
654
+ const bufSize = Math.min(maxBufferSize, length);
655
+ const buf = new Uint8Array(bufSize);
656
+ let totBytesRead = 0;
657
+ while (totBytesRead < length) {
658
+ const remaining = length - totBytesRead;
659
+ const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
660
+ if (bytesRead < 0) return bytesRead;
661
+ totBytesRead += bytesRead;
720
662
  }
721
- pushCodeUnit(parts, chunk, u1);
663
+ return totBytesRead;
722
664
  }
723
- if (i < len) pushCodeUnit(parts, chunk, REPLACEMENT);
724
- flushChunk(parts, chunk);
725
- return parts.join("");
726
- }
727
- function decodeASCII(bytes) {
728
- const parts = [];
729
- for (let i = 0; i < bytes.length; i += CHUNK) {
730
- const end = Math.min(bytes.length, i + CHUNK);
731
- const codes = new Array(end - i);
732
- for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j] & 127;
733
- parts.push(String.fromCharCode.apply(null, codes));
665
+ abort() {
666
+ return this.streamReader.abort();
734
667
  }
735
- return parts.join("");
736
- }
737
- function decodeLatin1(bytes) {
738
- const parts = [];
739
- for (let i = 0; i < bytes.length; i += CHUNK) {
740
- const end = Math.min(bytes.length, i + CHUNK);
741
- const codes = new Array(end - i);
742
- for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j];
743
- parts.push(String.fromCharCode.apply(null, codes));
668
+ async close() {
669
+ return this.streamReader.close();
744
670
  }
745
- return parts.join("");
746
- }
747
- function decodeWindows1252(bytes) {
748
- const parts = [];
749
- let out = "";
750
- for (let i = 0; i < bytes.length; i++) {
751
- const b = bytes[i];
752
- const extra = b >= 128 && b <= 159 ? WINDOWS_1252_EXTRA[b] : void 0;
753
- out += extra !== null && extra !== void 0 ? extra : String.fromCharCode(b);
754
- if (out.length >= CHUNK) {
755
- parts.push(out);
756
- out = "";
757
- }
671
+ supportsRandomAccess() {
672
+ return false;
758
673
  }
759
- if (out) parts.push(out);
760
- return parts.join("");
761
- }
674
+ };
762
675
  //#endregion
763
- //#region node_modules/token-types/lib/index.js
764
- function dv(array) {
765
- return new DataView(array.buffer, array.byteOffset);
766
- }
767
- const UINT8 = {
768
- len: 1,
769
- get(array, offset) {
770
- return dv(array).getUint8(offset);
771
- },
772
- put(array, offset, value) {
773
- dv(array).setUint8(offset, value);
774
- return offset + 1;
676
+ //#region node_modules/strtok3/lib/BufferTokenizer.js
677
+ var BufferTokenizer = class extends AbstractTokenizer {
678
+ /**
679
+ * Construct BufferTokenizer
680
+ * @param uint8Array - Uint8Array to tokenize
681
+ * @param options Tokenizer options
682
+ */
683
+ constructor(uint8Array, options) {
684
+ super(options);
685
+ this.uint8Array = uint8Array;
686
+ this.fileInfo = {
687
+ ...options?.fileInfo ?? {},
688
+ size: uint8Array.length
689
+ };
775
690
  }
776
- };
777
- /**
778
- * 16-bit unsigned integer, Little Endian byte order
779
- */
780
- const UINT16_LE = {
781
- len: 2,
782
- get(array, offset) {
783
- return dv(array).getUint16(offset, true);
784
- },
785
- put(array, offset, value) {
786
- dv(array).setUint16(offset, value, true);
787
- return offset + 2;
691
+ /**
692
+ * Read buffer from tokenizer
693
+ * @param uint8Array - Uint8Array to tokenize
694
+ * @param options - Read behaviour options
695
+ * @returns {Promise<number>}
696
+ */
697
+ async readBuffer(uint8Array, options) {
698
+ if (options?.position) this.position = options.position;
699
+ const bytesRead = await this.peekBuffer(uint8Array, options);
700
+ this.position += bytesRead;
701
+ return bytesRead;
788
702
  }
789
- };
790
- /**
791
- * 16-bit unsigned integer, Big Endian byte order
792
- */
793
- const UINT16_BE = {
794
- len: 2,
795
- get(array, offset) {
796
- return dv(array).getUint16(offset);
797
- },
798
- put(array, offset, value) {
799
- dv(array).setUint16(offset, value);
800
- return offset + 2;
703
+ /**
704
+ * Peek (read ahead) buffer from tokenizer
705
+ * @param uint8Array
706
+ * @param options - Read behaviour options
707
+ * @returns {Promise<number>}
708
+ */
709
+ async peekBuffer(uint8Array, options) {
710
+ const normOptions = this.normalizeOptions(uint8Array, options);
711
+ const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length);
712
+ if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
713
+ uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read));
714
+ return bytes2read;
801
715
  }
802
- };
803
- /**
804
- * 32-bit unsigned integer, Little Endian byte order
805
- */
806
- const UINT32_LE = {
807
- len: 4,
808
- get(array, offset) {
809
- return dv(array).getUint32(offset, true);
810
- },
811
- put(array, offset, value) {
812
- dv(array).setUint32(offset, value, true);
813
- return offset + 4;
716
+ close() {
717
+ return super.close();
814
718
  }
815
- };
816
- /**
817
- * 32-bit unsigned integer, Big Endian byte order
818
- */
819
- const UINT32_BE = {
820
- len: 4,
821
- get(array, offset) {
822
- return dv(array).getUint32(offset);
823
- },
824
- put(array, offset, value) {
825
- dv(array).setUint32(offset, value);
826
- return offset + 4;
719
+ supportsRandomAccess() {
720
+ return true;
721
+ }
722
+ setPosition(position) {
723
+ this.position = position;
827
724
  }
828
725
  };
829
- /**
830
- * 32-bit signed integer, Big Endian byte order
831
- */
832
- const INT32_BE = {
833
- len: 4,
834
- get(array, offset) {
835
- return dv(array).getInt32(offset);
836
- },
837
- put(array, offset, value) {
838
- dv(array).setInt32(offset, value);
839
- return offset + 4;
726
+ //#endregion
727
+ //#region node_modules/strtok3/lib/BlobTokenizer.js
728
+ var BlobTokenizer = class extends AbstractTokenizer {
729
+ /**
730
+ * Construct BufferTokenizer
731
+ * @param blob - Uint8Array to tokenize
732
+ * @param options Tokenizer options
733
+ */
734
+ constructor(blob, options) {
735
+ super(options);
736
+ this.blob = blob;
737
+ this.fileInfo = {
738
+ ...options?.fileInfo ?? {},
739
+ size: blob.size,
740
+ mimeType: blob.type
741
+ };
742
+ }
743
+ /**
744
+ * Read buffer from tokenizer
745
+ * @param uint8Array - Uint8Array to tokenize
746
+ * @param options - Read behaviour options
747
+ * @returns {Promise<number>}
748
+ */
749
+ async readBuffer(uint8Array, options) {
750
+ if (options?.position) this.position = options.position;
751
+ const bytesRead = await this.peekBuffer(uint8Array, options);
752
+ this.position += bytesRead;
753
+ return bytesRead;
754
+ }
755
+ /**
756
+ * Peek (read ahead) buffer from tokenizer
757
+ * @param buffer
758
+ * @param options - Read behaviour options
759
+ * @returns {Promise<number>}
760
+ */
761
+ async peekBuffer(buffer, options) {
762
+ const normOptions = this.normalizeOptions(buffer, options);
763
+ const bytes2read = Math.min(this.blob.size - normOptions.position, normOptions.length);
764
+ if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
765
+ const arrayBuffer = await this.blob.slice(normOptions.position, normOptions.position + bytes2read).arrayBuffer();
766
+ buffer.set(new Uint8Array(arrayBuffer));
767
+ return bytes2read;
768
+ }
769
+ close() {
770
+ return super.close();
771
+ }
772
+ supportsRandomAccess() {
773
+ return true;
774
+ }
775
+ setPosition(position) {
776
+ this.position = position;
840
777
  }
841
778
  };
779
+ //#endregion
780
+ //#region node_modules/strtok3/lib/core.js
842
781
  /**
843
- * 64-bit unsigned integer, Little Endian byte order
782
+ * Construct ReadStreamTokenizer from given ReadableStream (WebStream API).
783
+ * Will set fileSize, if provided given Stream has set the .path property/
784
+ * @param webStream - Read from Node.js Stream.Readable (must be a byte stream)
785
+ * @param options - Tokenizer options
786
+ * @returns ReadStreamTokenizer
844
787
  */
845
- const UINT64_LE = {
846
- len: 8,
847
- get(array, offset) {
848
- return dv(array).getBigUint64(offset, true);
849
- },
850
- put(array, offset, value) {
851
- dv(array).setBigUint64(offset, value, true);
852
- return offset + 8;
853
- }
854
- };
788
+ function fromWebStream(webStream, options) {
789
+ const webStreamReader = makeWebStreamReader(webStream);
790
+ const _options = options ?? {};
791
+ const chainedClose = _options.onClose;
792
+ _options.onClose = async () => {
793
+ await webStreamReader.close();
794
+ if (chainedClose) return chainedClose();
795
+ };
796
+ return new ReadStreamTokenizer(webStreamReader, _options);
797
+ }
855
798
  /**
856
- * Consume a fixed number of bytes from the stream and return a string with a specified encoding.
857
- * Supports all encodings supported by TextDecoder, plus 'windows-1252'.
799
+ * Construct ReadStreamTokenizer from given Buffer.
800
+ * @param uint8Array - Uint8Array to tokenize
801
+ * @param options - Tokenizer options
802
+ * @returns BufferTokenizer
858
803
  */
859
- var StringType = class {
860
- constructor(len, encoding) {
861
- this.len = len;
862
- this.encoding = encoding;
863
- }
864
- get(data, offset = 0) {
865
- return textDecode(data.subarray(offset, offset + this.len), this.encoding);
866
- }
867
- };
804
+ function fromBuffer(uint8Array, options) {
805
+ return new BufferTokenizer(uint8Array, options);
806
+ }
807
+ /**
808
+ * Construct ReadStreamTokenizer from given Blob.
809
+ * @param blob - Uint8Array to tokenize
810
+ * @param options - Tokenizer options
811
+ * @returns BufferTokenizer
812
+ */
813
+ function fromBlob(blob, options) {
814
+ return new BlobTokenizer(blob, options);
815
+ }
868
816
  //#endregion
869
817
  //#region node_modules/ms/index.js
870
818
  var require_ms = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -1123,15 +1071,16 @@ var require_common = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1123
1071
  let templateIndex = 0;
1124
1072
  let starIndex = -1;
1125
1073
  let matchIndex = 0;
1126
- while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) if (template[templateIndex] === "*") {
1127
- starIndex = templateIndex;
1128
- matchIndex = searchIndex;
1129
- templateIndex++;
1130
- } else {
1131
- searchIndex++;
1132
- templateIndex++;
1133
- }
1134
- else if (starIndex !== -1) {
1074
+ while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
1075
+ if (template[templateIndex] === "*") {
1076
+ starIndex = templateIndex;
1077
+ matchIndex = searchIndex;
1078
+ templateIndex++;
1079
+ } else {
1080
+ searchIndex++;
1081
+ templateIndex++;
1082
+ }
1083
+ } else if (starIndex !== -1) {
1135
1084
  templateIndex = starIndex + 1;
1136
1085
  matchIndex++;
1137
1086
  searchIndex = matchIndex;
@@ -1726,7 +1675,7 @@ function signatureToArray(signature) {
1726
1675
  return signatureBytes;
1727
1676
  }
1728
1677
  const debug = (0, import_src.default)("tokenizer:inflate");
1729
- const syncBufferSize = 256 * 1024;
1678
+ const syncBufferSize = 262144;
1730
1679
  const ddSignatureArray = signatureToArray(Signature.DataDescriptor);
1731
1680
  const eocdSignatureBytes = signatureToArray(Signature.EndOfCentralDirectory);
1732
1681
  var ZipHandler = class ZipHandler {
@@ -1742,7 +1691,7 @@ var ZipHandler = class ZipHandler {
1742
1691
  }
1743
1692
  async findEndOfCentralDirectoryLocator() {
1744
1693
  const randomReadTokenizer = this.tokenizer;
1745
- const chunkLength = Math.min(16 * 1024, randomReadTokenizer.fileInfo.size);
1694
+ const chunkLength = Math.min(16384, randomReadTokenizer.fileInfo.size);
1746
1695
  const buffer = this.syncBuffer.subarray(0, chunkLength);
1747
1696
  await this.tokenizer.readBuffer(buffer, { position: randomReadTokenizer.fileInfo.size - chunkLength });
1748
1697
  for (let i = buffer.length - 4; i >= 0; i--) if (buffer[i] === eocdSignatureBytes[0] && buffer[i + 1] === eocdSignatureBytes[1] && buffer[i + 2] === eocdSignatureBytes[2] && buffer[i + 3] === eocdSignatureBytes[3]) return randomReadTokenizer.fileInfo.size - chunkLength + i;
@@ -1900,7 +1849,7 @@ var GzipHandler = class {
1900
1849
  inflate() {
1901
1850
  const tokenizer = this.tokenizer;
1902
1851
  return new ReadableStream({ async pull(controller) {
1903
- const buffer = new Uint8Array(1024);
1852
+ const buffer = /* @__PURE__ */ new Uint8Array(1024);
1904
1853
  const size = await tokenizer.readBuffer(buffer, { mayBeLess: true });
1905
1854
  if (size === 0) {
1906
1855
  controller.close();
@@ -1910,6 +1859,33 @@ var GzipHandler = class {
1910
1859
  } }).pipeThrough(new DecompressionStream("gzip"));
1911
1860
  }
1912
1861
  };
1862
+ //#endregion
1863
+ //#region node_modules/uint8array-extras/index.js
1864
+ const objectToString = Object.prototype.toString;
1865
+ const uint8ArrayStringified = "[object Uint8Array]";
1866
+ function isType(value, typeConstructor, typeStringified) {
1867
+ if (!value) return false;
1868
+ if (value.constructor === typeConstructor) return true;
1869
+ return objectToString.call(value) === typeStringified;
1870
+ }
1871
+ function isUint8Array(value) {
1872
+ return isType(value, Uint8Array, uint8ArrayStringified);
1873
+ }
1874
+ function assertUint8Array(value) {
1875
+ if (!isUint8Array(value)) throw new TypeError(`Expected \`Uint8Array\`, got \`${typeof value}\``);
1876
+ }
1877
+ function concatUint8Arrays(arrays, totalLength) {
1878
+ if (arrays.length === 0) return /* @__PURE__ */ new Uint8Array(0);
1879
+ totalLength ??= arrays.reduce((accumulator, currentValue) => accumulator + currentValue.length, 0);
1880
+ const returnValue = new Uint8Array(totalLength);
1881
+ let offset = 0;
1882
+ for (const array of arrays) {
1883
+ assertUint8Array(array);
1884
+ returnValue.set(array, offset);
1885
+ offset += array.length;
1886
+ }
1887
+ return returnValue;
1888
+ }
1913
1889
  new globalThis.TextDecoder("utf8");
1914
1890
  new globalThis.TextEncoder();
1915
1891
  Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
@@ -1927,7 +1903,7 @@ function getUintBE(view) {
1927
1903
  if (byteLength === 1) return view.getUint8(0);
1928
1904
  }
1929
1905
  //#endregion
1930
- //#region node_modules/file-type/util.js
1906
+ //#region node_modules/file-type/source/tokens.js
1931
1907
  function stringToBytes(string, encoding) {
1932
1908
  if (encoding === "utf-16le") {
1933
1909
  const bytes = [];
@@ -1955,7 +1931,7 @@ Checks whether the TAR checksum is valid.
1955
1931
  @returns {boolean} `true` if the TAR checksum is valid, otherwise `false`.
1956
1932
  */
1957
1933
  function tarHeaderChecksumMatches(arrayBuffer, offset = 0) {
1958
- const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(/\0.*$/, "").trim(), 8);
1934
+ const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(new RegExp("\\0.*$", "v"), "").trim(), 8);
1959
1935
  if (Number.isNaN(readSum)) return false;
1960
1936
  let sum = 256;
1961
1937
  for (let index = offset; index < offset + 148; index++) sum += arrayBuffer[index];
@@ -1967,11 +1943,11 @@ ID3 UINT32 sync-safe tokenizer token.
1967
1943
  28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals".
1968
1944
  */
1969
1945
  const uint32SyncSafeToken = {
1970
- get: (buffer, offset) => buffer[offset + 3] & 127 | buffer[offset + 2] << 7 | buffer[offset + 1] << 14 | buffer[offset] << 21,
1946
+ get: (buffer, offset) => buffer[offset + 3] & 127 | (buffer[offset + 2] & 127) << 7 | (buffer[offset + 1] & 127) << 14 | (buffer[offset] & 127) << 21,
1971
1947
  len: 4
1972
1948
  };
1973
1949
  //#endregion
1974
- //#region node_modules/file-type/supported.js
1950
+ //#region node_modules/file-type/source/supported.js
1975
1951
  const extensions = [
1976
1952
  "jpg",
1977
1953
  "png",
@@ -2152,7 +2128,10 @@ const extensions = [
2152
2128
  "ppsx",
2153
2129
  "tar.gz",
2154
2130
  "reg",
2155
- "dat"
2131
+ "dat",
2132
+ "key",
2133
+ "numbers",
2134
+ "pages"
2156
2135
  ];
2157
2136
  const mimeTypes = [
2158
2137
  "image/jpeg",
@@ -2235,7 +2214,7 @@ const mimeTypes = [
2235
2214
  "application/x-unix-archive",
2236
2215
  "application/x-rpm",
2237
2216
  "application/x-compress",
2238
- "application/x-lzip",
2217
+ "application/lzip",
2239
2218
  "application/x-cfb",
2240
2219
  "application/x-mie",
2241
2220
  "application/mxf",
@@ -2264,8 +2243,8 @@ const mimeTypes = [
2264
2243
  "model/gltf-binary",
2265
2244
  "application/vnd.tcpdump.pcap",
2266
2245
  "audio/x-dsf",
2267
- "application/x.ms.shortcut",
2268
- "application/x.apple.alias",
2246
+ "application/x-ms-shortcut",
2247
+ "application/x-ft-apple.alias",
2269
2248
  "audio/x-voc",
2270
2249
  "audio/vnd.dolby.dd-raw",
2271
2250
  "audio/x-m4a",
@@ -2305,10 +2284,10 @@ const mimeTypes = [
2305
2284
  "application/x-ace-compressed",
2306
2285
  "application/avro",
2307
2286
  "application/vnd.iccprofile",
2308
- "application/x.autodesk.fbx",
2287
+ "application/x-ft-fbx",
2309
2288
  "application/vnd.visio",
2310
2289
  "application/vnd.android.package-archive",
2311
- "application/vnd.google.draco",
2290
+ "application/x-ft-draco",
2312
2291
  "application/x-lz4",
2313
2292
  "application/vnd.openxmlformats-officedocument.presentationml.template",
2314
2293
  "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
@@ -2329,48 +2308,14 @@ const mimeTypes = [
2329
2308
  "application/x-spss-sav",
2330
2309
  "application/x-ms-regedit",
2331
2310
  "application/x-ft-windows-registry-hive",
2332
- "application/x-jmp-data"
2311
+ "application/x-jmp-data",
2312
+ "application/vnd.apple.keynote",
2313
+ "application/vnd.apple.numbers",
2314
+ "application/vnd.apple.pages"
2333
2315
  ];
2334
2316
  //#endregion
2335
- //#region node_modules/file-type/core.js
2336
- /**
2337
- Primary entry point, Node.js specific entry point is index.js
2338
- */
2339
- const reasonableDetectionSizeInBytes = 4100;
2340
- const maximumMpegOffsetTolerance = reasonableDetectionSizeInBytes - 2;
2341
- const maximumZipEntrySizeInBytes = 1024 * 1024;
2342
- const maximumZipEntryCount = 1024;
2343
- const maximumZipBufferedReadSizeInBytes = 2 ** 31 - 1;
2344
- const maximumUntrustedSkipSizeInBytes = 16 * 1024 * 1024;
2345
- const maximumZipTextEntrySizeInBytes = maximumZipEntrySizeInBytes;
2346
- const maximumNestedGzipDetectionSizeInBytes = maximumUntrustedSkipSizeInBytes;
2347
- const maximumNestedGzipProbeDepth = 1;
2348
- const maximumId3HeaderSizeInBytes = maximumUntrustedSkipSizeInBytes;
2349
- const maximumEbmlDocumentTypeSizeInBytes = 64;
2350
- const maximumEbmlElementPayloadSizeInBytes = maximumUntrustedSkipSizeInBytes;
2351
- const maximumEbmlElementCount = 256;
2352
- const maximumPngChunkCount = 512;
2353
- const maximumAsfHeaderObjectCount = 512;
2354
- const maximumTiffTagCount = 512;
2355
- const maximumDetectionReentryCount = 256;
2356
- const maximumPngChunkSizeInBytes = maximumUntrustedSkipSizeInBytes;
2357
- const maximumTiffIfdOffsetInBytes = maximumUntrustedSkipSizeInBytes;
2358
- const recoverableZipErrorMessages = new Set([
2359
- "Unexpected signature",
2360
- "Encrypted ZIP",
2361
- "Expected Central-File-Header signature"
2362
- ]);
2363
- const recoverableZipErrorMessagePrefixes = [
2364
- "ZIP entry count exceeds ",
2365
- "Unsupported ZIP compression method:",
2366
- "ZIP entry compressed data exceeds ",
2367
- "ZIP entry decompressed data exceeds "
2368
- ];
2369
- const recoverableZipErrorCodes = new Set([
2370
- "Z_BUF_ERROR",
2371
- "Z_DATA_ERROR",
2372
- "ERR_INVALID_STATE"
2373
- ]);
2317
+ //#region node_modules/file-type/source/parser.js
2318
+ const maximumUntrustedSkipSizeInBytes = 16777216;
2374
2319
  var ParserHardLimitError = class extends Error {};
2375
2320
  function getSafeBound(value, maximum, reason) {
2376
2321
  if (!Number.isFinite(value) || value < 0 || value > maximum) throw new ParserHardLimitError(`${reason} has invalid size ${value} (maximum ${maximum} bytes)`);
@@ -2387,154 +2332,133 @@ async function safeReadBuffer(tokenizer, buffer, options, { maximumLength = buff
2387
2332
  length: safeLength
2388
2333
  });
2389
2334
  }
2390
- async function decompressDeflateRawWithLimit(data, { maximumLength = maximumZipEntrySizeInBytes } = {}) {
2391
- const reader = new ReadableStream({ start(controller) {
2392
- controller.enqueue(data);
2393
- controller.close();
2394
- } }).pipeThrough(new DecompressionStream("deflate-raw")).getReader();
2395
- const chunks = [];
2396
- let totalLength = 0;
2397
- try {
2398
- for (;;) {
2399
- const { done, value } = await reader.read();
2400
- if (done) break;
2401
- totalLength += value.length;
2402
- if (totalLength > maximumLength) {
2403
- await reader.cancel();
2404
- throw new Error(`ZIP entry decompressed data exceeds ${maximumLength} bytes`);
2405
- }
2406
- chunks.push(value);
2407
- }
2408
- } finally {
2409
- reader.releaseLock();
2410
- }
2411
- const uncompressedData = new Uint8Array(totalLength);
2412
- let offset = 0;
2413
- for (const chunk of chunks) {
2414
- uncompressedData.set(chunk, offset);
2415
- offset += chunk.length;
2416
- }
2417
- return uncompressedData;
2418
- }
2419
- const zipDataDescriptorSignature = 134695760;
2420
- const zipDataDescriptorLengthInBytes = 16;
2421
- const zipDataDescriptorOverlapLengthInBytes = zipDataDescriptorLengthInBytes - 1;
2422
- function findZipDataDescriptorOffset(buffer, bytesConsumed) {
2423
- if (buffer.length < zipDataDescriptorLengthInBytes) return -1;
2424
- const lastPossibleDescriptorOffset = buffer.length - zipDataDescriptorLengthInBytes;
2425
- for (let index = 0; index <= lastPossibleDescriptorOffset; index++) if (UINT32_LE.get(buffer, index) === zipDataDescriptorSignature && UINT32_LE.get(buffer, index + 8) === bytesConsumed + index) return index;
2426
- return -1;
2427
- }
2428
- function mergeByteChunks(chunks, totalLength) {
2429
- const merged = new Uint8Array(totalLength);
2430
- let offset = 0;
2431
- for (const chunk of chunks) {
2432
- merged.set(chunk, offset);
2433
- offset += chunk.length;
2434
- }
2435
- return merged;
2335
+ function checkBytes(buffer, headers, options) {
2336
+ options = {
2337
+ offset: 0,
2338
+ ...options
2339
+ };
2340
+ for (const [index, header] of headers.entries()) if (options.mask) {
2341
+ if (header !== (options.mask[index] & buffer[index + options.offset])) return false;
2342
+ } else if (header !== buffer[index + options.offset]) return false;
2343
+ return true;
2436
2344
  }
2437
- async function readZipDataDescriptorEntryWithLimit(zipHandler, { shouldBuffer, maximumLength = maximumZipEntrySizeInBytes } = {}) {
2438
- const { syncBuffer } = zipHandler;
2439
- const { length: syncBufferLength } = syncBuffer;
2440
- const chunks = [];
2441
- let bytesConsumed = 0;
2442
- for (;;) {
2443
- const length = await zipHandler.tokenizer.peekBuffer(syncBuffer, { mayBeLess: true });
2444
- const dataDescriptorOffset = findZipDataDescriptorOffset(syncBuffer.subarray(0, length), bytesConsumed);
2445
- const retainedLength = dataDescriptorOffset >= 0 ? 0 : length === syncBufferLength ? Math.min(zipDataDescriptorOverlapLengthInBytes, length - 1) : 0;
2446
- const chunkLength = dataDescriptorOffset >= 0 ? dataDescriptorOffset : length - retainedLength;
2447
- if (chunkLength === 0) break;
2448
- bytesConsumed += chunkLength;
2449
- if (bytesConsumed > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
2450
- if (shouldBuffer) {
2451
- const data = new Uint8Array(chunkLength);
2452
- await zipHandler.tokenizer.readBuffer(data);
2453
- chunks.push(data);
2454
- } else await zipHandler.tokenizer.ignore(chunkLength);
2455
- if (dataDescriptorOffset >= 0) break;
2456
- }
2457
- if (!shouldBuffer) return;
2458
- return mergeByteChunks(chunks, bytesConsumed);
2345
+ function hasUnknownFileSize(tokenizer) {
2346
+ const fileSize = tokenizer.fileInfo.size;
2347
+ return !Number.isFinite(fileSize) || fileSize === Number.MAX_SAFE_INTEGER;
2459
2348
  }
2460
- async function readZipEntryData(zipHandler, zipHeader, { shouldBuffer } = {}) {
2461
- if (zipHeader.dataDescriptor && zipHeader.compressedSize === 0) return readZipDataDescriptorEntryWithLimit(zipHandler, { shouldBuffer });
2462
- if (!shouldBuffer) {
2463
- await zipHandler.tokenizer.ignore(zipHeader.compressedSize);
2464
- return;
2465
- }
2466
- const maximumLength = getMaximumZipBufferedReadLength(zipHandler.tokenizer);
2467
- if (!Number.isFinite(zipHeader.compressedSize) || zipHeader.compressedSize < 0 || zipHeader.compressedSize > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
2468
- const fileData = new Uint8Array(zipHeader.compressedSize);
2469
- await zipHandler.tokenizer.readBuffer(fileData);
2470
- return fileData;
2349
+ function hasExceededUnknownSizeScanBudget(tokenizer, startOffset, maximumBytes) {
2350
+ return hasUnknownFileSize(tokenizer) && tokenizer.position - startOffset > maximumBytes;
2471
2351
  }
2472
- ZipHandler.prototype.inflate = async function(zipHeader, fileData, callback) {
2473
- if (zipHeader.compressedMethod === 0) return callback(fileData);
2474
- if (zipHeader.compressedMethod !== 8) throw new Error(`Unsupported ZIP compression method: ${zipHeader.compressedMethod}`);
2475
- return callback(await decompressDeflateRawWithLimit(fileData, { maximumLength: maximumZipEntrySizeInBytes }));
2476
- };
2477
- ZipHandler.prototype.unzip = async function(fileCallback) {
2478
- let stop = false;
2479
- let zipEntryCount = 0;
2480
- do {
2481
- const zipHeader = await this.readLocalFileHeader();
2482
- if (!zipHeader) break;
2483
- zipEntryCount++;
2484
- if (zipEntryCount > maximumZipEntryCount) throw new Error(`ZIP entry count exceeds ${maximumZipEntryCount}`);
2485
- const next = fileCallback(zipHeader);
2486
- stop = Boolean(next.stop);
2487
- await this.tokenizer.ignore(zipHeader.extraFieldLength);
2488
- const fileData = await readZipEntryData(this, zipHeader, { shouldBuffer: Boolean(next.handler) });
2489
- if (next.handler) await this.inflate(zipHeader, fileData, next.handler);
2490
- if (zipHeader.dataDescriptor) {
2491
- const dataDescriptor = new Uint8Array(zipDataDescriptorLengthInBytes);
2492
- await this.tokenizer.readBuffer(dataDescriptor);
2493
- if (UINT32_LE.get(dataDescriptor, 0) !== zipDataDescriptorSignature) throw new Error(`Expected data-descriptor-signature at position ${this.tokenizer.position - dataDescriptor.length}`);
2494
- }
2495
- } while (!stop);
2496
- };
2497
- function createByteLimitedReadableStream(stream, maximumBytes) {
2498
- const reader = stream.getReader();
2499
- let emittedBytes = 0;
2500
- let sourceDone = false;
2501
- let sourceCanceled = false;
2502
- const cancelSource = async (reason) => {
2503
- if (sourceDone || sourceCanceled) return;
2504
- sourceCanceled = true;
2505
- await reader.cancel(reason);
2506
- };
2507
- return new ReadableStream({
2508
- async pull(controller) {
2509
- if (emittedBytes >= maximumBytes) {
2510
- controller.close();
2511
- await cancelSource();
2512
- return;
2513
- }
2514
- const { done, value } = await reader.read();
2515
- if (done || !value) {
2516
- sourceDone = true;
2517
- controller.close();
2518
- return;
2519
- }
2520
- const remainingBytes = maximumBytes - emittedBytes;
2521
- if (value.length > remainingBytes) {
2522
- controller.enqueue(value.subarray(0, remainingBytes));
2523
- emittedBytes += remainingBytes;
2524
- controller.close();
2525
- await cancelSource();
2526
- return;
2352
+ //#endregion
2353
+ //#region node_modules/file-type/source/detectors/zip.js
2354
+ const maximumZipEntrySizeInBytes = 1048576;
2355
+ const maximumZipEntryCount = 1024;
2356
+ const maximumZipBufferedReadSizeInBytes = 2 ** 31 - 1;
2357
+ const maximumZipTextEntrySizeInBytes = maximumZipEntrySizeInBytes;
2358
+ const recoverableZipErrorMessages = /* @__PURE__ */ new Set([
2359
+ "Unexpected signature",
2360
+ "Encrypted ZIP",
2361
+ "Expected Central-File-Header signature"
2362
+ ]);
2363
+ const recoverableZipErrorMessagePrefixes = [
2364
+ "ZIP entry count exceeds ",
2365
+ "Unsupported ZIP compression method:",
2366
+ "ZIP entry compressed data exceeds ",
2367
+ "ZIP entry decompressed data exceeds ",
2368
+ "Expected data-descriptor-signature at position "
2369
+ ];
2370
+ const recoverableZipErrorCodes = /* @__PURE__ */ new Set([
2371
+ "Z_BUF_ERROR",
2372
+ "Z_DATA_ERROR",
2373
+ "ERR_INVALID_STATE"
2374
+ ]);
2375
+ async function decompressDeflateRawWithLimit(data, { maximumLength = maximumZipEntrySizeInBytes } = {}) {
2376
+ const reader = new ReadableStream({ start(controller) {
2377
+ controller.enqueue(data);
2378
+ controller.close();
2379
+ } }).pipeThrough(new DecompressionStream("deflate-raw")).getReader();
2380
+ const chunks = [];
2381
+ let totalLength = 0;
2382
+ try {
2383
+ for (;;) {
2384
+ const { done, value } = await reader.read();
2385
+ if (done) break;
2386
+ totalLength += value.length;
2387
+ if (totalLength > maximumLength) {
2388
+ await reader.cancel().catch(() => {});
2389
+ throw new Error(`ZIP entry decompressed data exceeds ${maximumLength} bytes`);
2527
2390
  }
2528
- controller.enqueue(value);
2529
- emittedBytes += value.length;
2530
- },
2531
- async cancel(reason) {
2532
- await cancelSource(reason);
2391
+ chunks.push(value);
2533
2392
  }
2534
- });
2393
+ } catch (error) {
2394
+ if (error.code !== "ERR_TRAILING_JUNK_AFTER_STREAM_END") throw error;
2395
+ } finally {
2396
+ reader.releaseLock();
2397
+ }
2398
+ const uncompressedData = new Uint8Array(totalLength);
2399
+ let offset = 0;
2400
+ for (const chunk of chunks) {
2401
+ uncompressedData.set(chunk, offset);
2402
+ offset += chunk.length;
2403
+ }
2404
+ return uncompressedData;
2535
2405
  }
2536
- async function fileTypeFromBlob(blob, options) {
2537
- return new FileTypeParser(options).fromBlob(blob);
2406
+ function mergeByteChunks(chunks, totalLength) {
2407
+ const merged = new Uint8Array(totalLength);
2408
+ let offset = 0;
2409
+ for (const chunk of chunks) {
2410
+ merged.set(chunk, offset);
2411
+ offset += chunk.length;
2412
+ }
2413
+ return merged;
2414
+ }
2415
+ function getMaximumZipBufferedReadLength(tokenizer) {
2416
+ const fileSize = tokenizer.fileInfo.size;
2417
+ const remainingBytes = Number.isFinite(fileSize) ? Math.max(0, fileSize - tokenizer.position) : Number.MAX_SAFE_INTEGER;
2418
+ return Math.min(remainingBytes, maximumZipBufferedReadSizeInBytes);
2419
+ }
2420
+ function isRecoverableZipError(error) {
2421
+ if (error instanceof EndOfStreamError) return true;
2422
+ if (error instanceof ParserHardLimitError) return true;
2423
+ if (!(error instanceof Error)) return false;
2424
+ if (recoverableZipErrorMessages.has(error.message)) return true;
2425
+ if (recoverableZipErrorCodes.has(error.code)) return true;
2426
+ for (const prefix of recoverableZipErrorMessagePrefixes) if (error.message.startsWith(prefix)) return true;
2427
+ return false;
2428
+ }
2429
+ function canReadZipEntryForDetection(zipHeader, maximumSize = maximumZipEntrySizeInBytes) {
2430
+ const sizes = [zipHeader.compressedSize, zipHeader.uncompressedSize];
2431
+ for (const size of sizes) if (!Number.isFinite(size) || size < 0 || size > maximumSize) return false;
2432
+ return true;
2433
+ }
2434
+ function createIWorkZipDetectionState() {
2435
+ return {
2436
+ hasDocumentEntry: false,
2437
+ hasMasterSlideEntry: false,
2438
+ hasTablesEntry: false,
2439
+ hasCalculationEngineEntry: false
2440
+ };
2441
+ }
2442
+ function updateIWorkZipDetectionStateFromFilename(iWorkState, filename) {
2443
+ if (filename === "Index/Document.iwa") iWorkState.hasDocumentEntry = true;
2444
+ if (filename.startsWith("Index/MasterSlide")) iWorkState.hasMasterSlideEntry = true;
2445
+ if (filename.startsWith("Index/Tables/")) iWorkState.hasTablesEntry = true;
2446
+ if (filename === "Index/CalculationEngine.iwa") iWorkState.hasCalculationEngineEntry = true;
2447
+ }
2448
+ function getIWorkFileTypeFromZipEntries(iWorkState) {
2449
+ if (!iWorkState.hasDocumentEntry) return;
2450
+ if (iWorkState.hasMasterSlideEntry) return {
2451
+ ext: "key",
2452
+ mime: "application/vnd.apple.keynote"
2453
+ };
2454
+ if (iWorkState.hasTablesEntry) return {
2455
+ ext: "numbers",
2456
+ mime: "application/vnd.apple.numbers"
2457
+ };
2458
+ return {
2459
+ ext: "pages",
2460
+ mime: "application/vnd.apple.pages"
2461
+ };
2538
2462
  }
2539
2463
  function getFileTypeFromMimeType(mimeType) {
2540
2464
  mimeType = mimeType.toLowerCase();
@@ -2639,19 +2563,495 @@ function getFileTypeFromMimeType(mimeType) {
2639
2563
  ext: "3mf",
2640
2564
  mime: "model/3mf"
2641
2565
  };
2642
- default:
2643
2566
  }
2644
- }
2645
- function _check(buffer, headers, options) {
2646
- options = {
2647
- offset: 0,
2648
- ...options
2567
+ }
2568
+ function createOpenXmlZipDetectionState() {
2569
+ return {
2570
+ hasContentTypesEntry: false,
2571
+ hasParsedContentTypesEntry: false,
2572
+ isParsingContentTypes: false,
2573
+ hasUnparseableContentTypes: false,
2574
+ hasWordDirectory: false,
2575
+ hasPresentationDirectory: false,
2576
+ hasSpreadsheetDirectory: false,
2577
+ hasThreeDimensionalModelEntry: false
2578
+ };
2579
+ }
2580
+ function updateOpenXmlZipDetectionStateFromFilename(openXmlState, filename) {
2581
+ if (filename.startsWith("word/")) openXmlState.hasWordDirectory = true;
2582
+ if (filename.startsWith("ppt/")) openXmlState.hasPresentationDirectory = true;
2583
+ if (filename.startsWith("xl/")) openXmlState.hasSpreadsheetDirectory = true;
2584
+ if (filename.startsWith("3D/") && filename.endsWith(".model")) openXmlState.hasThreeDimensionalModelEntry = true;
2585
+ }
2586
+ function getOpenXmlFileTypeFromDirectoryNames(openXmlState) {
2587
+ if (openXmlState.hasWordDirectory) return {
2588
+ ext: "docx",
2589
+ mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
2590
+ };
2591
+ if (openXmlState.hasPresentationDirectory) return {
2592
+ ext: "pptx",
2593
+ mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
2594
+ };
2595
+ if (openXmlState.hasSpreadsheetDirectory) return {
2596
+ ext: "xlsx",
2597
+ mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
2598
+ };
2599
+ if (openXmlState.hasThreeDimensionalModelEntry) return {
2600
+ ext: "3mf",
2601
+ mime: "model/3mf"
2602
+ };
2603
+ }
2604
+ function getOpenXmlFileTypeFromZipEntries(openXmlState) {
2605
+ if (!openXmlState.hasContentTypesEntry || openXmlState.hasUnparseableContentTypes || openXmlState.isParsingContentTypes || openXmlState.hasParsedContentTypesEntry) return;
2606
+ return getOpenXmlFileTypeFromDirectoryNames(openXmlState);
2607
+ }
2608
+ function getOpenXmlMimeTypeFromContentTypesXml(xmlContent) {
2609
+ const endPosition = xmlContent.indexOf(".main+xml\"");
2610
+ if (endPosition === -1) {
2611
+ const mimeType = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml";
2612
+ if (xmlContent.includes(`ContentType="${mimeType}"`)) return mimeType;
2613
+ return;
2614
+ }
2615
+ const truncatedContent = xmlContent.slice(0, endPosition);
2616
+ const firstQuotePosition = truncatedContent.lastIndexOf("\"");
2617
+ return truncatedContent.slice(firstQuotePosition + 1);
2618
+ }
2619
+ const zipDataDescriptorSignature = 134695760;
2620
+ const zipDataDescriptorLengthInBytes = 16;
2621
+ const zipDataDescriptorOverlapLengthInBytes = 15;
2622
+ function findZipDataDescriptorOffset(buffer, bytesConsumed) {
2623
+ if (buffer.length < zipDataDescriptorLengthInBytes) return -1;
2624
+ const lastPossibleDescriptorOffset = buffer.length - zipDataDescriptorLengthInBytes;
2625
+ for (let index = 0; index <= lastPossibleDescriptorOffset; index++) if (UINT32_LE.get(buffer, index) === zipDataDescriptorSignature && UINT32_LE.get(buffer, index + 8) === bytesConsumed + index) return index;
2626
+ return -1;
2627
+ }
2628
+ async function readZipDataDescriptorEntryWithLimit(zipHandler, { shouldBuffer, maximumLength = maximumZipEntrySizeInBytes } = {}) {
2629
+ const { syncBuffer } = zipHandler;
2630
+ const { length: syncBufferLength } = syncBuffer;
2631
+ const chunks = [];
2632
+ let bytesConsumed = 0;
2633
+ for (;;) {
2634
+ const length = await zipHandler.tokenizer.peekBuffer(syncBuffer, { mayBeLess: true });
2635
+ const dataDescriptorOffset = findZipDataDescriptorOffset(syncBuffer.subarray(0, length), bytesConsumed);
2636
+ const retainedLength = dataDescriptorOffset >= 0 ? 0 : length === syncBufferLength ? Math.min(zipDataDescriptorOverlapLengthInBytes, length - 1) : 0;
2637
+ const chunkLength = dataDescriptorOffset >= 0 ? dataDescriptorOffset : length - retainedLength;
2638
+ if (chunkLength === 0) break;
2639
+ bytesConsumed += chunkLength;
2640
+ if (bytesConsumed > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
2641
+ if (shouldBuffer) {
2642
+ const data = new Uint8Array(chunkLength);
2643
+ await zipHandler.tokenizer.readBuffer(data);
2644
+ chunks.push(data);
2645
+ } else await zipHandler.tokenizer.ignore(chunkLength);
2646
+ if (dataDescriptorOffset >= 0) break;
2647
+ }
2648
+ if (!hasUnknownFileSize(zipHandler.tokenizer)) zipHandler.knownSizeDescriptorScannedBytes += bytesConsumed;
2649
+ if (!shouldBuffer) return;
2650
+ return mergeByteChunks(chunks, bytesConsumed);
2651
+ }
2652
+ function getRemainingZipScanBudget(zipHandler, startOffset) {
2653
+ if (hasUnknownFileSize(zipHandler.tokenizer)) return Math.max(0, maximumUntrustedSkipSizeInBytes - (zipHandler.tokenizer.position - startOffset));
2654
+ return Math.max(0, maximumZipEntrySizeInBytes - zipHandler.knownSizeDescriptorScannedBytes);
2655
+ }
2656
+ async function readZipEntryData(zipHandler, zipHeader, { shouldBuffer, maximumDescriptorLength = maximumZipEntrySizeInBytes } = {}) {
2657
+ if (zipHeader.dataDescriptor && zipHeader.compressedSize === 0) return readZipDataDescriptorEntryWithLimit(zipHandler, {
2658
+ shouldBuffer,
2659
+ maximumLength: maximumDescriptorLength
2660
+ });
2661
+ if (!shouldBuffer) {
2662
+ await safeIgnore(zipHandler.tokenizer, zipHeader.compressedSize, {
2663
+ maximumLength: hasUnknownFileSize(zipHandler.tokenizer) ? maximumZipEntrySizeInBytes : zipHandler.tokenizer.fileInfo.size,
2664
+ reason: "ZIP entry compressed data"
2665
+ });
2666
+ return;
2667
+ }
2668
+ const maximumLength = getMaximumZipBufferedReadLength(zipHandler.tokenizer);
2669
+ if (!Number.isFinite(zipHeader.compressedSize) || zipHeader.compressedSize < 0 || zipHeader.compressedSize > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
2670
+ const fileData = new Uint8Array(zipHeader.compressedSize);
2671
+ await zipHandler.tokenizer.readBuffer(fileData);
2672
+ return fileData;
2673
+ }
2674
+ ZipHandler.prototype.inflate = async function(zipHeader, fileData, callback) {
2675
+ if (zipHeader.compressedMethod === 0) return callback(fileData);
2676
+ if (zipHeader.compressedMethod !== 8) throw new Error(`Unsupported ZIP compression method: ${zipHeader.compressedMethod}`);
2677
+ return callback(await decompressDeflateRawWithLimit(fileData, { maximumLength: maximumZipEntrySizeInBytes }));
2678
+ };
2679
+ ZipHandler.prototype.unzip = async function(fileCallback) {
2680
+ let stop = false;
2681
+ let zipEntryCount = 0;
2682
+ const zipScanStart = this.tokenizer.position;
2683
+ this.knownSizeDescriptorScannedBytes = 0;
2684
+ do {
2685
+ if (hasExceededUnknownSizeScanBudget(this.tokenizer, zipScanStart, 16777216)) throw new ParserHardLimitError(`ZIP stream probing exceeds ${maximumUntrustedSkipSizeInBytes} bytes`);
2686
+ const zipHeader = await this.readLocalFileHeader();
2687
+ if (!zipHeader) break;
2688
+ zipEntryCount++;
2689
+ if (zipEntryCount > maximumZipEntryCount) throw new Error(`ZIP entry count exceeds ${maximumZipEntryCount}`);
2690
+ const next = fileCallback(zipHeader);
2691
+ stop = Boolean(next.stop);
2692
+ await this.tokenizer.ignore(zipHeader.extraFieldLength);
2693
+ const fileData = await readZipEntryData(this, zipHeader, {
2694
+ shouldBuffer: Boolean(next.handler),
2695
+ maximumDescriptorLength: Math.min(maximumZipEntrySizeInBytes, getRemainingZipScanBudget(this, zipScanStart))
2696
+ });
2697
+ if (next.handler) await this.inflate(zipHeader, fileData, next.handler);
2698
+ if (zipHeader.dataDescriptor) {
2699
+ const dataDescriptor = new Uint8Array(zipDataDescriptorLengthInBytes);
2700
+ await this.tokenizer.readBuffer(dataDescriptor);
2701
+ if (UINT32_LE.get(dataDescriptor, 0) !== zipDataDescriptorSignature) throw new Error(`Expected data-descriptor-signature at position ${this.tokenizer.position - dataDescriptor.length}`);
2702
+ }
2703
+ if (hasExceededUnknownSizeScanBudget(this.tokenizer, zipScanStart, 16777216)) throw new ParserHardLimitError(`ZIP stream probing exceeds ${maximumUntrustedSkipSizeInBytes} bytes`);
2704
+ } while (!stop);
2705
+ };
2706
+ async function detectZip(tokenizer) {
2707
+ let fileType;
2708
+ const openXmlState = createOpenXmlZipDetectionState();
2709
+ const iWorkState = createIWorkZipDetectionState();
2710
+ try {
2711
+ await new ZipHandler(tokenizer).unzip((zipHeader) => {
2712
+ updateOpenXmlZipDetectionStateFromFilename(openXmlState, zipHeader.filename);
2713
+ updateIWorkZipDetectionStateFromFilename(iWorkState, zipHeader.filename);
2714
+ if (iWorkState.hasDocumentEntry && (iWorkState.hasMasterSlideEntry || iWorkState.hasTablesEntry)) {
2715
+ fileType = getIWorkFileTypeFromZipEntries(iWorkState);
2716
+ return { stop: true };
2717
+ }
2718
+ const isOpenXmlContentTypesEntry = zipHeader.filename === "[Content_Types].xml";
2719
+ const openXmlFileTypeFromEntries = getOpenXmlFileTypeFromZipEntries(openXmlState);
2720
+ if (!isOpenXmlContentTypesEntry && openXmlFileTypeFromEntries) {
2721
+ fileType = openXmlFileTypeFromEntries;
2722
+ return { stop: true };
2723
+ }
2724
+ switch (zipHeader.filename) {
2725
+ case "META-INF/mozilla.rsa":
2726
+ fileType = {
2727
+ ext: "xpi",
2728
+ mime: "application/x-xpinstall"
2729
+ };
2730
+ return { stop: true };
2731
+ case "META-INF/MANIFEST.MF":
2732
+ fileType = {
2733
+ ext: "jar",
2734
+ mime: "application/java-archive"
2735
+ };
2736
+ return { stop: true };
2737
+ case "mimetype":
2738
+ if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) return {};
2739
+ return {
2740
+ async handler(fileData) {
2741
+ fileType = getFileTypeFromMimeType(new TextDecoder("utf-8").decode(fileData).trim());
2742
+ },
2743
+ stop: true
2744
+ };
2745
+ case "[Content_Types].xml":
2746
+ openXmlState.hasContentTypesEntry = true;
2747
+ if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) {
2748
+ openXmlState.hasUnparseableContentTypes = true;
2749
+ return {};
2750
+ }
2751
+ openXmlState.isParsingContentTypes = true;
2752
+ return {
2753
+ async handler(fileData) {
2754
+ const mimeType = getOpenXmlMimeTypeFromContentTypesXml(new TextDecoder("utf-8").decode(fileData));
2755
+ if (mimeType) fileType = getFileTypeFromMimeType(mimeType);
2756
+ openXmlState.hasParsedContentTypesEntry = true;
2757
+ openXmlState.isParsingContentTypes = false;
2758
+ },
2759
+ stop: true
2760
+ };
2761
+ default:
2762
+ if (new RegExp("classes\\d*\\.dex", "v").test(zipHeader.filename)) {
2763
+ fileType = {
2764
+ ext: "apk",
2765
+ mime: "application/vnd.android.package-archive"
2766
+ };
2767
+ return { stop: true };
2768
+ }
2769
+ return {};
2770
+ }
2771
+ });
2772
+ } catch (error) {
2773
+ if (!isRecoverableZipError(error)) throw error;
2774
+ if (openXmlState.isParsingContentTypes) {
2775
+ openXmlState.isParsingContentTypes = false;
2776
+ openXmlState.hasUnparseableContentTypes = true;
2777
+ }
2778
+ if (!fileType && error instanceof EndOfStreamError && !openXmlState.hasContentTypesEntry) fileType = getOpenXmlFileTypeFromDirectoryNames(openXmlState);
2779
+ }
2780
+ const iWorkFileType = hasUnknownFileSize(tokenizer) && iWorkState.hasDocumentEntry && !iWorkState.hasMasterSlideEntry && !iWorkState.hasTablesEntry && !iWorkState.hasCalculationEngineEntry ? void 0 : getIWorkFileTypeFromZipEntries(iWorkState);
2781
+ return fileType ?? getOpenXmlFileTypeFromZipEntries(openXmlState) ?? iWorkFileType ?? {
2782
+ ext: "zip",
2783
+ mime: "application/zip"
2784
+ };
2785
+ }
2786
+ //#endregion
2787
+ //#region node_modules/file-type/source/detectors/ebml.js
2788
+ const maximumEbmlDocumentTypeSizeInBytes = 64;
2789
+ const maximumEbmlElementPayloadSizeInBytes = 1048576;
2790
+ const maximumEbmlElementCount = 256;
2791
+ async function detectEbml(tokenizer) {
2792
+ async function readField() {
2793
+ const msb = await tokenizer.peekNumber(UINT8);
2794
+ let mask = 128;
2795
+ let ic = 0;
2796
+ while ((msb & mask) === 0 && mask !== 0) {
2797
+ ++ic;
2798
+ mask >>= 1;
2799
+ }
2800
+ const id = new Uint8Array(ic + 1);
2801
+ await safeReadBuffer(tokenizer, id, void 0, {
2802
+ maximumLength: id.length,
2803
+ reason: "EBML field"
2804
+ });
2805
+ return id;
2806
+ }
2807
+ async function readElement() {
2808
+ const idField = await readField();
2809
+ const lengthField = await readField();
2810
+ lengthField[0] ^= 128 >> lengthField.length - 1;
2811
+ const nrLength = Math.min(6, lengthField.length);
2812
+ const idView = new DataView(idField.buffer);
2813
+ const lengthView = new DataView(lengthField.buffer, lengthField.length - nrLength, nrLength);
2814
+ return {
2815
+ id: getUintBE(idView),
2816
+ len: getUintBE(lengthView)
2817
+ };
2818
+ }
2819
+ async function readChildren(children) {
2820
+ let ebmlElementCount = 0;
2821
+ while (children > 0) {
2822
+ ebmlElementCount++;
2823
+ if (ebmlElementCount > maximumEbmlElementCount) return;
2824
+ if (hasExceededUnknownSizeScanBudget(tokenizer, ebmlScanStart, 16777216)) return;
2825
+ const previousPosition = tokenizer.position;
2826
+ const element = await readElement();
2827
+ if (element.id === 17026) {
2828
+ if (element.len > maximumEbmlDocumentTypeSizeInBytes) return;
2829
+ const documentTypeLength = getSafeBound(element.len, maximumEbmlDocumentTypeSizeInBytes, "EBML DocType");
2830
+ return (await tokenizer.readToken(new StringType(documentTypeLength))).replaceAll(new RegExp("\\0.*$", "gv"), "");
2831
+ }
2832
+ if (hasUnknownFileSize(tokenizer) && (!Number.isFinite(element.len) || element.len < 0 || element.len > maximumEbmlElementPayloadSizeInBytes)) return;
2833
+ await safeIgnore(tokenizer, element.len, {
2834
+ maximumLength: hasUnknownFileSize(tokenizer) ? maximumEbmlElementPayloadSizeInBytes : tokenizer.fileInfo.size,
2835
+ reason: "EBML payload"
2836
+ });
2837
+ --children;
2838
+ if (tokenizer.position <= previousPosition) return;
2839
+ }
2840
+ }
2841
+ const rootElement = await readElement();
2842
+ const ebmlScanStart = tokenizer.position;
2843
+ switch (await readChildren(rootElement.len)) {
2844
+ case "webm": return {
2845
+ ext: "webm",
2846
+ mime: "video/webm"
2847
+ };
2848
+ case "matroska": return {
2849
+ ext: "mkv",
2850
+ mime: "video/matroska"
2851
+ };
2852
+ }
2853
+ }
2854
+ //#endregion
2855
+ //#region node_modules/file-type/source/detectors/png.js
2856
+ const maximumPngChunkCount = 512;
2857
+ const maximumPngStreamScanBudgetInBytes = 16777216;
2858
+ const maximumPngChunkSizeInBytes = 1048576;
2859
+ function isPngAncillaryChunk(type) {
2860
+ return (type.codePointAt(0) & 32) !== 0;
2861
+ }
2862
+ async function detectPng(tokenizer) {
2863
+ const pngFileType = {
2864
+ ext: "png",
2865
+ mime: "image/png"
2866
+ };
2867
+ const apngFileType = {
2868
+ ext: "apng",
2869
+ mime: "image/apng"
2870
+ };
2871
+ await tokenizer.ignore(8);
2872
+ async function readChunkHeader() {
2873
+ return {
2874
+ length: await tokenizer.readToken(INT32_BE),
2875
+ type: await tokenizer.readToken(new StringType(4, "latin1"))
2876
+ };
2877
+ }
2878
+ const isUnknownPngStream = hasUnknownFileSize(tokenizer);
2879
+ const pngScanStart = tokenizer.position;
2880
+ let pngChunkCount = 0;
2881
+ let hasSeenImageHeader = false;
2882
+ do {
2883
+ pngChunkCount++;
2884
+ if (pngChunkCount > maximumPngChunkCount) break;
2885
+ if (hasExceededUnknownSizeScanBudget(tokenizer, pngScanStart, maximumPngStreamScanBudgetInBytes)) break;
2886
+ const previousPosition = tokenizer.position;
2887
+ const chunk = await readChunkHeader();
2888
+ if (chunk.length < 0) return;
2889
+ if (chunk.type === "IHDR") {
2890
+ if (chunk.length !== 13) return;
2891
+ hasSeenImageHeader = true;
2892
+ }
2893
+ switch (chunk.type) {
2894
+ case "IDAT": return pngFileType;
2895
+ case "acTL": return apngFileType;
2896
+ default:
2897
+ if (!hasSeenImageHeader && chunk.type !== "CgBI") return;
2898
+ if (isUnknownPngStream && chunk.length > maximumPngChunkSizeInBytes) return hasSeenImageHeader && isPngAncillaryChunk(chunk.type) ? pngFileType : void 0;
2899
+ try {
2900
+ await safeIgnore(tokenizer, chunk.length + 4, {
2901
+ maximumLength: isUnknownPngStream ? 1048580 : tokenizer.fileInfo.size,
2902
+ reason: "PNG chunk payload"
2903
+ });
2904
+ } catch (error) {
2905
+ if (!isUnknownPngStream && (error instanceof ParserHardLimitError || error instanceof EndOfStreamError)) return pngFileType;
2906
+ throw error;
2907
+ }
2908
+ }
2909
+ if (tokenizer.position <= previousPosition) break;
2910
+ } while (tokenizer.position + 8 < tokenizer.fileInfo.size);
2911
+ return pngFileType;
2912
+ }
2913
+ //#endregion
2914
+ //#region node_modules/file-type/source/detectors/asf.js
2915
+ const maximumAsfHeaderObjectCount = 512;
2916
+ const maximumAsfHeaderPayloadSizeInBytes = 1048576;
2917
+ async function detectAsf(tokenizer) {
2918
+ let isMalformedAsf = false;
2919
+ try {
2920
+ async function readHeader() {
2921
+ const guid = /* @__PURE__ */ new Uint8Array(16);
2922
+ await safeReadBuffer(tokenizer, guid, void 0, {
2923
+ maximumLength: guid.length,
2924
+ reason: "ASF header GUID"
2925
+ });
2926
+ return {
2927
+ id: guid,
2928
+ size: Number(await tokenizer.readToken(UINT64_LE))
2929
+ };
2930
+ }
2931
+ await safeIgnore(tokenizer, 30, {
2932
+ maximumLength: 30,
2933
+ reason: "ASF header prelude"
2934
+ });
2935
+ const isUnknownFileSize = hasUnknownFileSize(tokenizer);
2936
+ const asfHeaderScanStart = tokenizer.position;
2937
+ let asfHeaderObjectCount = 0;
2938
+ while (tokenizer.position + 24 < tokenizer.fileInfo.size) {
2939
+ asfHeaderObjectCount++;
2940
+ if (asfHeaderObjectCount > maximumAsfHeaderObjectCount) break;
2941
+ if (hasExceededUnknownSizeScanBudget(tokenizer, asfHeaderScanStart, 16777216)) break;
2942
+ const previousPosition = tokenizer.position;
2943
+ const header = await readHeader();
2944
+ let payload = header.size - 24;
2945
+ if (!Number.isFinite(payload) || payload < 0) {
2946
+ isMalformedAsf = true;
2947
+ break;
2948
+ }
2949
+ if (checkBytes(header.id, [
2950
+ 145,
2951
+ 7,
2952
+ 220,
2953
+ 183,
2954
+ 183,
2955
+ 169,
2956
+ 207,
2957
+ 17,
2958
+ 142,
2959
+ 230,
2960
+ 0,
2961
+ 192,
2962
+ 12,
2963
+ 32,
2964
+ 83,
2965
+ 101
2966
+ ])) {
2967
+ const typeId = /* @__PURE__ */ new Uint8Array(16);
2968
+ payload -= await safeReadBuffer(tokenizer, typeId, void 0, {
2969
+ maximumLength: typeId.length,
2970
+ reason: "ASF stream type GUID"
2971
+ });
2972
+ if (checkBytes(typeId, [
2973
+ 64,
2974
+ 158,
2975
+ 105,
2976
+ 248,
2977
+ 77,
2978
+ 91,
2979
+ 207,
2980
+ 17,
2981
+ 168,
2982
+ 253,
2983
+ 0,
2984
+ 128,
2985
+ 95,
2986
+ 92,
2987
+ 68,
2988
+ 43
2989
+ ])) return {
2990
+ ext: "asf",
2991
+ mime: "audio/x-ms-asf"
2992
+ };
2993
+ if (checkBytes(typeId, [
2994
+ 192,
2995
+ 239,
2996
+ 25,
2997
+ 188,
2998
+ 77,
2999
+ 91,
3000
+ 207,
3001
+ 17,
3002
+ 168,
3003
+ 253,
3004
+ 0,
3005
+ 128,
3006
+ 95,
3007
+ 92,
3008
+ 68,
3009
+ 43
3010
+ ])) return {
3011
+ ext: "asf",
3012
+ mime: "video/x-ms-asf"
3013
+ };
3014
+ break;
3015
+ }
3016
+ if (isUnknownFileSize && payload > maximumAsfHeaderPayloadSizeInBytes) {
3017
+ isMalformedAsf = true;
3018
+ break;
3019
+ }
3020
+ await safeIgnore(tokenizer, payload, {
3021
+ maximumLength: isUnknownFileSize ? maximumAsfHeaderPayloadSizeInBytes : tokenizer.fileInfo.size,
3022
+ reason: "ASF header payload"
3023
+ });
3024
+ if (tokenizer.position <= previousPosition) {
3025
+ isMalformedAsf = true;
3026
+ break;
3027
+ }
3028
+ }
3029
+ } catch (error) {
3030
+ if (error instanceof EndOfStreamError || error instanceof ParserHardLimitError) {
3031
+ if (hasUnknownFileSize(tokenizer)) isMalformedAsf = true;
3032
+ } else throw error;
3033
+ }
3034
+ if (isMalformedAsf) return;
3035
+ return {
3036
+ ext: "asf",
3037
+ mime: "application/vnd.ms-asf"
2649
3038
  };
2650
- for (const [index, header] of headers.entries()) if (options.mask) {
2651
- if (header !== (options.mask[index] & buffer[index + options.offset])) return false;
2652
- } else if (header !== buffer[index + options.offset]) return false;
2653
- return true;
2654
3039
  }
3040
+ //#endregion
3041
+ //#region node_modules/file-type/source/index.js
3042
+ /**
3043
+ Primary entry point, Node.js specific entry point is index.js
3044
+ */
3045
+ const reasonableDetectionSizeInBytes = 4100;
3046
+ const maximumMpegOffsetTolerance = 4096;
3047
+ const maximumNestedGzipDetectionSizeInBytes = maximumUntrustedSkipSizeInBytes;
3048
+ const maximumNestedGzipProbeDepth = 1;
3049
+ const unknownSizeGzipProbeTimeoutInMilliseconds = 100;
3050
+ const maximumId3HeaderSizeInBytes = maximumUntrustedSkipSizeInBytes;
3051
+ const maximumTiffTagCount = 512;
3052
+ const maximumDetectionReentryCount = 256;
3053
+ const maximumTiffStreamIfdOffsetInBytes = 1048576;
3054
+ const maximumTiffIfdOffsetInBytes = maximumUntrustedSkipSizeInBytes;
2655
3055
  function normalizeSampleSize(sampleSize) {
2656
3056
  if (!Number.isFinite(sampleSize)) return reasonableDetectionSizeInBytes;
2657
3057
  return Math.max(1, Math.trunc(sampleSize));
@@ -2664,81 +3064,65 @@ function getKnownFileSizeOrMaximum(fileSize) {
2664
3064
  if (!Number.isFinite(fileSize)) return Number.MAX_SAFE_INTEGER;
2665
3065
  return Math.max(0, fileSize);
2666
3066
  }
2667
- function hasUnknownFileSize(tokenizer) {
2668
- const fileSize = tokenizer.fileInfo.size;
2669
- return !Number.isFinite(fileSize) || fileSize === Number.MAX_SAFE_INTEGER;
2670
- }
2671
- function hasExceededUnknownSizeScanBudget(tokenizer, startOffset, maximumBytes) {
2672
- return hasUnknownFileSize(tokenizer) && tokenizer.position - startOffset > maximumBytes;
2673
- }
2674
- function getMaximumZipBufferedReadLength(tokenizer) {
2675
- const fileSize = tokenizer.fileInfo.size;
2676
- const remainingBytes = Number.isFinite(fileSize) ? Math.max(0, fileSize - tokenizer.position) : Number.MAX_SAFE_INTEGER;
2677
- return Math.min(remainingBytes, maximumZipBufferedReadSizeInBytes);
2678
- }
2679
- function isRecoverableZipError(error) {
2680
- if (error instanceof EndOfStreamError) return true;
2681
- if (error instanceof ParserHardLimitError) return true;
2682
- if (!(error instanceof Error)) return false;
2683
- if (recoverableZipErrorMessages.has(error.message)) return true;
2684
- if (recoverableZipErrorCodes.has(error.code)) return true;
2685
- for (const prefix of recoverableZipErrorMessagePrefixes) if (error.message.startsWith(prefix)) return true;
2686
- return false;
2687
- }
2688
- function canReadZipEntryForDetection(zipHeader, maximumSize = maximumZipEntrySizeInBytes) {
2689
- const sizes = [zipHeader.compressedSize, zipHeader.uncompressedSize];
2690
- for (const size of sizes) if (!Number.isFinite(size) || size < 0 || size > maximumSize) return false;
2691
- return true;
3067
+ function importAtRuntime(specifier) {
3068
+ return import(specifier);
2692
3069
  }
2693
- function createOpenXmlZipDetectionState() {
2694
- return {
2695
- hasContentTypesEntry: false,
2696
- hasParsedContentTypesEntry: false,
2697
- isParsingContentTypes: false,
2698
- hasUnparseableContentTypes: false,
2699
- hasWordDirectory: false,
2700
- hasPresentationDirectory: false,
2701
- hasSpreadsheetDirectory: false,
2702
- hasThreeDimensionalModelEntry: false
2703
- };
3070
+ function toDefaultStream(stream) {
3071
+ return stream.pipeThrough(new TransformStream());
2704
3072
  }
2705
- function updateOpenXmlZipDetectionStateFromFilename(openXmlState, filename) {
2706
- if (filename.startsWith("word/")) openXmlState.hasWordDirectory = true;
2707
- if (filename.startsWith("ppt/")) openXmlState.hasPresentationDirectory = true;
2708
- if (filename.startsWith("xl/")) openXmlState.hasSpreadsheetDirectory = true;
2709
- if (filename.startsWith("3D/") && filename.endsWith(".model")) openXmlState.hasThreeDimensionalModelEntry = true;
3073
+ function readWithSignal(reader, signal) {
3074
+ if (signal === void 0) return reader.read();
3075
+ signal.throwIfAborted();
3076
+ return Promise.race([reader.read(), new Promise((_resolve, reject) => {
3077
+ signal.addEventListener("abort", () => {
3078
+ reject(signal.reason);
3079
+ reader.cancel(signal.reason).catch(() => {});
3080
+ }, { once: true });
3081
+ })]);
2710
3082
  }
2711
- function getOpenXmlFileTypeFromZipEntries(openXmlState) {
2712
- if (!openXmlState.hasContentTypesEntry || openXmlState.hasUnparseableContentTypes || openXmlState.isParsingContentTypes || openXmlState.hasParsedContentTypesEntry) return;
2713
- if (openXmlState.hasWordDirectory) return {
2714
- ext: "docx",
2715
- mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
2716
- };
2717
- if (openXmlState.hasPresentationDirectory) return {
2718
- ext: "pptx",
2719
- mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
2720
- };
2721
- if (openXmlState.hasSpreadsheetDirectory) return {
2722
- ext: "xlsx",
2723
- mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
2724
- };
2725
- if (openXmlState.hasThreeDimensionalModelEntry) return {
2726
- ext: "3mf",
2727
- mime: "model/3mf"
3083
+ function createByteLimitedReadableStream(stream, maximumBytes) {
3084
+ const reader = stream.getReader();
3085
+ let emittedBytes = 0;
3086
+ let sourceDone = false;
3087
+ let sourceCanceled = false;
3088
+ const cancelSource = async (reason) => {
3089
+ if (sourceDone || sourceCanceled) return;
3090
+ sourceCanceled = true;
3091
+ await reader.cancel(reason);
2728
3092
  };
3093
+ return new ReadableStream({
3094
+ async pull(controller) {
3095
+ if (emittedBytes >= maximumBytes) {
3096
+ controller.close();
3097
+ await cancelSource();
3098
+ return;
3099
+ }
3100
+ const { done, value } = await reader.read();
3101
+ if (done || !value) {
3102
+ sourceDone = true;
3103
+ controller.close();
3104
+ return;
3105
+ }
3106
+ const remainingBytes = maximumBytes - emittedBytes;
3107
+ if (value.length > remainingBytes) {
3108
+ controller.enqueue(value.subarray(0, remainingBytes));
3109
+ emittedBytes += remainingBytes;
3110
+ controller.close();
3111
+ await cancelSource();
3112
+ return;
3113
+ }
3114
+ controller.enqueue(value);
3115
+ emittedBytes += value.length;
3116
+ },
3117
+ async cancel(reason) {
3118
+ await cancelSource(reason);
3119
+ }
3120
+ });
2729
3121
  }
2730
- function getOpenXmlMimeTypeFromContentTypesXml(xmlContent) {
2731
- const endPosition = xmlContent.indexOf(".main+xml\"");
2732
- if (endPosition === -1) {
2733
- const mimeType = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml";
2734
- if (xmlContent.includes(`ContentType="${mimeType}"`)) return mimeType;
2735
- return;
2736
- }
2737
- const truncatedContent = xmlContent.slice(0, endPosition);
2738
- const firstQuotePosition = truncatedContent.lastIndexOf("\"");
2739
- return truncatedContent.slice(firstQuotePosition + 1);
3122
+ async function fileTypeFromBlob(blob, options) {
3123
+ return new FileTypeParser(options).fromBlob(blob);
2740
3124
  }
2741
- var FileTypeParser = class {
3125
+ var FileTypeParser = class FileTypeParser {
2742
3126
  constructor(options) {
2743
3127
  const normalizedMpegOffsetTolerance = normalizeMpegOffsetTolerance(options?.mpegOffsetTolerance);
2744
3128
  this.options = {
@@ -2762,7 +3146,10 @@ var FileTypeParser = class {
2762
3146
  getTokenizerOptions() {
2763
3147
  return { ...this.tokenizerOptions };
2764
3148
  }
2765
- async fromTokenizer(tokenizer, detectionReentryCount = 0) {
3149
+ createTokenizerFromWebStream(stream) {
3150
+ return fromWebStream(toDefaultStream(stream), this.getTokenizerOptions());
3151
+ }
3152
+ async parseTokenizer(tokenizer, detectionReentryCount = 0) {
2766
3153
  this.detectionReentryCount = detectionReentryCount;
2767
3154
  const initialPosition = tokenizer.position;
2768
3155
  for (const detector of this.detectors) {
@@ -2778,6 +3165,13 @@ var FileTypeParser = class {
2778
3165
  if (initialPosition !== tokenizer.position) return;
2779
3166
  }
2780
3167
  }
3168
+ async fromTokenizer(tokenizer) {
3169
+ try {
3170
+ return await this.parseTokenizer(tokenizer);
3171
+ } finally {
3172
+ await tokenizer.close();
3173
+ }
3174
+ }
2781
3175
  async fromBuffer(input) {
2782
3176
  if (!(input instanceof Uint8Array || input instanceof ArrayBuffer)) throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`ArrayBuffer\`, got \`${typeof input}\``);
2783
3177
  const buffer = input instanceof Uint8Array ? input : new Uint8Array(input);
@@ -2785,42 +3179,78 @@ var FileTypeParser = class {
2785
3179
  return this.fromTokenizer(fromBuffer(buffer, this.getTokenizerOptions()));
2786
3180
  }
2787
3181
  async fromBlob(blob) {
3182
+ this.options.signal?.throwIfAborted();
2788
3183
  const tokenizer = fromBlob(blob, this.getTokenizerOptions());
2789
- try {
2790
- return await this.fromTokenizer(tokenizer);
2791
- } finally {
2792
- await tokenizer.close();
2793
- }
3184
+ return this.fromTokenizer(tokenizer);
2794
3185
  }
2795
3186
  async fromStream(stream) {
2796
- const tokenizer = fromWebStream(stream, this.getTokenizerOptions());
2797
- try {
2798
- return await this.fromTokenizer(tokenizer);
2799
- } finally {
2800
- await tokenizer.close();
3187
+ this.options.signal?.throwIfAborted();
3188
+ const tokenizer = this.createTokenizerFromWebStream(stream);
3189
+ return this.fromTokenizer(tokenizer);
3190
+ }
3191
+ async fromFile(path) {
3192
+ this.options.signal?.throwIfAborted();
3193
+ const [{ default: fsPromises }, { FileTokenizer }] = await Promise.all([importAtRuntime("node:fs/promises"), importAtRuntime("strtok3")]);
3194
+ const fileHandle = await fsPromises.open(path, fsPromises.constants.O_RDONLY | fsPromises.constants.O_NONBLOCK);
3195
+ const fileStat = await fileHandle.stat();
3196
+ if (!fileStat.isFile()) {
3197
+ await fileHandle.close();
3198
+ return;
2801
3199
  }
3200
+ const tokenizer = new FileTokenizer(fileHandle, {
3201
+ ...this.getTokenizerOptions(),
3202
+ fileInfo: {
3203
+ path,
3204
+ size: fileStat.size
3205
+ }
3206
+ });
3207
+ return this.fromTokenizer(tokenizer);
2802
3208
  }
2803
3209
  async toDetectionStream(stream, options) {
3210
+ this.options.signal?.throwIfAborted();
2804
3211
  const sampleSize = normalizeSampleSize(options?.sampleSize ?? 4100);
2805
3212
  let detectedFileType;
2806
- let firstChunk;
2807
- const reader = stream.getReader({ mode: "byob" });
3213
+ let streamEnded = false;
3214
+ const reader = stream.getReader();
3215
+ const chunks = [];
3216
+ let totalSize = 0;
2808
3217
  try {
2809
- const { value: chunk, done } = await reader.read(new Uint8Array(sampleSize));
2810
- firstChunk = chunk;
2811
- if (!done && chunk) try {
2812
- detectedFileType = await this.fromBuffer(chunk.subarray(0, sampleSize));
3218
+ while (totalSize < sampleSize) {
3219
+ const { value, done } = await readWithSignal(reader, this.options.signal);
3220
+ if (done || !value) {
3221
+ streamEnded = true;
3222
+ break;
3223
+ }
3224
+ chunks.push(value);
3225
+ totalSize += value.length;
3226
+ }
3227
+ if (!streamEnded && totalSize === sampleSize) {
3228
+ const { value, done } = await readWithSignal(reader, this.options.signal);
3229
+ if (done || !value) streamEnded = true;
3230
+ else {
3231
+ chunks.push(value);
3232
+ totalSize += value.length;
3233
+ }
3234
+ }
3235
+ } finally {
3236
+ reader.releaseLock();
3237
+ }
3238
+ if (totalSize > 0) {
3239
+ const sample = chunks.length === 1 ? chunks[0] : concatUint8Arrays(chunks);
3240
+ try {
3241
+ detectedFileType = await this.fromBuffer(sample.subarray(0, sampleSize));
2813
3242
  } catch (error) {
2814
3243
  if (!(error instanceof EndOfStreamError)) throw error;
2815
3244
  detectedFileType = void 0;
2816
3245
  }
2817
- firstChunk = chunk;
2818
- } finally {
2819
- reader.releaseLock();
3246
+ if (!streamEnded && detectedFileType?.ext === "pages") detectedFileType = {
3247
+ ext: "zip",
3248
+ mime: "application/zip"
3249
+ };
2820
3250
  }
2821
3251
  const transformStream = new TransformStream({
2822
- async start(controller) {
2823
- controller.enqueue(firstChunk);
3252
+ start(controller) {
3253
+ for (const chunk of chunks) controller.enqueue(chunk);
2824
3254
  },
2825
3255
  transform(chunk, controller) {
2826
3256
  controller.enqueue(chunk);
@@ -2830,8 +3260,48 @@ var FileTypeParser = class {
2830
3260
  newStream.fileType = detectedFileType;
2831
3261
  return newStream;
2832
3262
  }
3263
+ async detectGzip(tokenizer) {
3264
+ if (this.gzipProbeDepth >= maximumNestedGzipProbeDepth) return {
3265
+ ext: "gz",
3266
+ mime: "application/gzip"
3267
+ };
3268
+ const limitedInflatedStream = createByteLimitedReadableStream(new GzipHandler(tokenizer).inflate(), maximumNestedGzipDetectionSizeInBytes);
3269
+ const hasUnknownSize = hasUnknownFileSize(tokenizer);
3270
+ let timeout;
3271
+ let probeSignal;
3272
+ let probeParser;
3273
+ let compressedFileType;
3274
+ if (hasUnknownSize) {
3275
+ const timeoutController = new AbortController();
3276
+ timeout = setTimeout(() => {
3277
+ timeoutController.abort(new DOMException(`Operation timed out after ${unknownSizeGzipProbeTimeoutInMilliseconds} ms`, "TimeoutError"));
3278
+ }, unknownSizeGzipProbeTimeoutInMilliseconds);
3279
+ probeSignal = this.options.signal === void 0 ? timeoutController.signal : AbortSignal.any([this.options.signal, timeoutController.signal]);
3280
+ probeParser = new FileTypeParser({
3281
+ ...this.options,
3282
+ signal: probeSignal
3283
+ });
3284
+ probeParser.gzipProbeDepth = this.gzipProbeDepth + 1;
3285
+ } else this.gzipProbeDepth++;
3286
+ try {
3287
+ compressedFileType = await (probeParser ?? this).fromStream(limitedInflatedStream);
3288
+ } catch (error) {
3289
+ if (error?.name === "AbortError" && probeSignal?.reason?.name !== "TimeoutError") throw error;
3290
+ } finally {
3291
+ clearTimeout(timeout);
3292
+ if (!hasUnknownSize) this.gzipProbeDepth--;
3293
+ }
3294
+ if (compressedFileType?.ext === "tar") return {
3295
+ ext: "tar.gz",
3296
+ mime: "application/gzip"
3297
+ };
3298
+ return {
3299
+ ext: "gz",
3300
+ mime: "application/gzip"
3301
+ };
3302
+ }
2833
3303
  check(header, options) {
2834
- return _check(this.buffer, header, options);
3304
+ return checkBytes(this.buffer, header, options);
2835
3305
  }
2836
3306
  checkString(header, options) {
2837
3307
  return this.check(stringToBytes(header, options?.encoding), options);
@@ -2840,6 +3310,17 @@ var FileTypeParser = class {
2840
3310
  this.buffer = new Uint8Array(reasonableDetectionSizeInBytes);
2841
3311
  if (tokenizer.fileInfo.size === void 0) tokenizer.fileInfo.size = Number.MAX_SAFE_INTEGER;
2842
3312
  this.tokenizer = tokenizer;
3313
+ if (hasUnknownFileSize(tokenizer)) {
3314
+ await tokenizer.peekBuffer(this.buffer, {
3315
+ length: 3,
3316
+ mayBeLess: true
3317
+ });
3318
+ if (this.check([
3319
+ 31,
3320
+ 139,
3321
+ 8
3322
+ ])) return this.detectGzip(tokenizer);
3323
+ }
2843
3324
  await tokenizer.peekBuffer(this.buffer, {
2844
3325
  length: 32,
2845
3326
  mayBeLess: true
@@ -2916,30 +3397,7 @@ var FileTypeParser = class {
2916
3397
  31,
2917
3398
  139,
2918
3399
  8
2919
- ])) {
2920
- if (this.gzipProbeDepth >= maximumNestedGzipProbeDepth) return {
2921
- ext: "gz",
2922
- mime: "application/gzip"
2923
- };
2924
- const limitedInflatedStream = createByteLimitedReadableStream(new GzipHandler(tokenizer).inflate(), maximumNestedGzipDetectionSizeInBytes);
2925
- let compressedFileType;
2926
- try {
2927
- this.gzipProbeDepth++;
2928
- compressedFileType = await this.fromStream(limitedInflatedStream);
2929
- } catch (error) {
2930
- if (error?.name === "AbortError") throw error;
2931
- } finally {
2932
- this.gzipProbeDepth--;
2933
- }
2934
- if (compressedFileType?.ext === "tar") return {
2935
- ext: "tar.gz",
2936
- mime: "application/gzip"
2937
- };
2938
- return {
2939
- ext: "gz",
2940
- mime: "application/gzip"
2941
- };
2942
- }
3400
+ ])) return this.detectGzip(tokenizer);
2943
3401
  if (this.check([
2944
3402
  66,
2945
3403
  90,
@@ -2955,7 +3413,7 @@ var FileTypeParser = class {
2955
3413
  });
2956
3414
  const id3HeaderLength = await tokenizer.readToken(uint32SyncSafeToken);
2957
3415
  const isUnknownFileSize = hasUnknownFileSize(tokenizer);
2958
- if (!Number.isFinite(id3HeaderLength) || id3HeaderLength < 0 || isUnknownFileSize && id3HeaderLength > maximumId3HeaderSizeInBytes) return;
3416
+ if (!Number.isFinite(id3HeaderLength) || id3HeaderLength < 0 || isUnknownFileSize && (id3HeaderLength > maximumId3HeaderSizeInBytes || tokenizer.position + id3HeaderLength > maximumId3HeaderSizeInBytes)) return;
2959
3417
  if (tokenizer.position + id3HeaderLength > tokenizer.fileInfo.size) {
2960
3418
  if (isUnknownFileSize) return;
2961
3419
  return {
@@ -2974,7 +3432,7 @@ var FileTypeParser = class {
2974
3432
  }
2975
3433
  if (this.detectionReentryCount >= maximumDetectionReentryCount) return;
2976
3434
  this.detectionReentryCount++;
2977
- return this.fromTokenizer(tokenizer, this.detectionReentryCount);
3435
+ return this.parseTokenizer(tokenizer, this.detectionReentryCount);
2978
3436
  }
2979
3437
  if (this.checkString("MP+")) return {
2980
3438
  ext: "mpc",
@@ -3032,83 +3490,12 @@ var FileTypeParser = class {
3032
3490
  75,
3033
3491
  3,
3034
3492
  4
3035
- ])) {
3036
- let fileType;
3037
- const openXmlState = createOpenXmlZipDetectionState();
3038
- try {
3039
- await new ZipHandler(tokenizer).unzip((zipHeader) => {
3040
- updateOpenXmlZipDetectionStateFromFilename(openXmlState, zipHeader.filename);
3041
- const isOpenXmlContentTypesEntry = zipHeader.filename === "[Content_Types].xml";
3042
- const openXmlFileTypeFromEntries = getOpenXmlFileTypeFromZipEntries(openXmlState);
3043
- if (!isOpenXmlContentTypesEntry && openXmlFileTypeFromEntries) {
3044
- fileType = openXmlFileTypeFromEntries;
3045
- return { stop: true };
3046
- }
3047
- switch (zipHeader.filename) {
3048
- case "META-INF/mozilla.rsa":
3049
- fileType = {
3050
- ext: "xpi",
3051
- mime: "application/x-xpinstall"
3052
- };
3053
- return { stop: true };
3054
- case "META-INF/MANIFEST.MF":
3055
- fileType = {
3056
- ext: "jar",
3057
- mime: "application/java-archive"
3058
- };
3059
- return { stop: true };
3060
- case "mimetype":
3061
- if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) return {};
3062
- return {
3063
- async handler(fileData) {
3064
- fileType = getFileTypeFromMimeType(new TextDecoder("utf-8").decode(fileData).trim());
3065
- },
3066
- stop: true
3067
- };
3068
- case "[Content_Types].xml":
3069
- openXmlState.hasContentTypesEntry = true;
3070
- if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) {
3071
- openXmlState.hasUnparseableContentTypes = true;
3072
- return {};
3073
- }
3074
- openXmlState.isParsingContentTypes = true;
3075
- return {
3076
- async handler(fileData) {
3077
- const mimeType = getOpenXmlMimeTypeFromContentTypesXml(new TextDecoder("utf-8").decode(fileData));
3078
- if (mimeType) fileType = getFileTypeFromMimeType(mimeType);
3079
- openXmlState.hasParsedContentTypesEntry = true;
3080
- openXmlState.isParsingContentTypes = false;
3081
- },
3082
- stop: true
3083
- };
3084
- default:
3085
- if (/classes\d*\.dex/.test(zipHeader.filename)) {
3086
- fileType = {
3087
- ext: "apk",
3088
- mime: "application/vnd.android.package-archive"
3089
- };
3090
- return { stop: true };
3091
- }
3092
- return {};
3093
- }
3094
- });
3095
- } catch (error) {
3096
- if (!isRecoverableZipError(error)) throw error;
3097
- if (openXmlState.isParsingContentTypes) {
3098
- openXmlState.isParsingContentTypes = false;
3099
- openXmlState.hasUnparseableContentTypes = true;
3100
- }
3101
- }
3102
- return fileType ?? getOpenXmlFileTypeFromZipEntries(openXmlState) ?? {
3103
- ext: "zip",
3104
- mime: "application/zip"
3105
- };
3106
- }
3493
+ ])) return detectZip(tokenizer);
3107
3494
  if (this.checkString("OggS")) {
3108
3495
  await tokenizer.ignore(28);
3109
- const type = new Uint8Array(8);
3496
+ const type = /* @__PURE__ */ new Uint8Array(8);
3110
3497
  await tokenizer.readBuffer(type);
3111
- if (_check(type, [
3498
+ if (checkBytes(type, [
3112
3499
  79,
3113
3500
  112,
3114
3501
  117,
@@ -3121,7 +3508,7 @@ var FileTypeParser = class {
3121
3508
  ext: "opus",
3122
3509
  mime: "audio/ogg; codecs=opus"
3123
3510
  };
3124
- if (_check(type, [
3511
+ if (checkBytes(type, [
3125
3512
  128,
3126
3513
  116,
3127
3514
  104,
@@ -3133,7 +3520,7 @@ var FileTypeParser = class {
3133
3520
  ext: "ogv",
3134
3521
  mime: "video/ogg"
3135
3522
  };
3136
- if (_check(type, [
3523
+ if (checkBytes(type, [
3137
3524
  1,
3138
3525
  118,
3139
3526
  105,
@@ -3145,7 +3532,7 @@ var FileTypeParser = class {
3145
3532
  ext: "ogm",
3146
3533
  mime: "video/ogg"
3147
3534
  };
3148
- if (_check(type, [
3535
+ if (checkBytes(type, [
3149
3536
  127,
3150
3537
  70,
3151
3538
  76,
@@ -3155,7 +3542,7 @@ var FileTypeParser = class {
3155
3542
  ext: "oga",
3156
3543
  mime: "audio/ogg"
3157
3544
  };
3158
- if (_check(type, [
3545
+ if (checkBytes(type, [
3159
3546
  83,
3160
3547
  112,
3161
3548
  101,
@@ -3167,7 +3554,7 @@ var FileTypeParser = class {
3167
3554
  ext: "spx",
3168
3555
  mime: "audio/ogg"
3169
3556
  };
3170
- if (_check(type, [
3557
+ if (checkBytes(type, [
3171
3558
  1,
3172
3559
  118,
3173
3560
  111,
@@ -3230,7 +3617,7 @@ var FileTypeParser = class {
3230
3617
  };
3231
3618
  if (this.checkString("LZIP")) return {
3232
3619
  ext: "lz",
3233
- mime: "application/x-lzip"
3620
+ mime: "application/lzip"
3234
3621
  };
3235
3622
  if (this.checkString("fLaC")) return {
3236
3623
  ext: "flac",
@@ -3279,67 +3666,7 @@ var FileTypeParser = class {
3279
3666
  69,
3280
3667
  223,
3281
3668
  163
3282
- ])) {
3283
- async function readField() {
3284
- const msb = await tokenizer.peekNumber(UINT8);
3285
- let mask = 128;
3286
- let ic = 0;
3287
- while ((msb & mask) === 0 && mask !== 0) {
3288
- ++ic;
3289
- mask >>= 1;
3290
- }
3291
- const id = new Uint8Array(ic + 1);
3292
- await safeReadBuffer(tokenizer, id, void 0, {
3293
- maximumLength: id.length,
3294
- reason: "EBML field"
3295
- });
3296
- return id;
3297
- }
3298
- async function readElement() {
3299
- const idField = await readField();
3300
- const lengthField = await readField();
3301
- lengthField[0] ^= 128 >> lengthField.length - 1;
3302
- const nrLength = Math.min(6, lengthField.length);
3303
- const idView = new DataView(idField.buffer);
3304
- const lengthView = new DataView(lengthField.buffer, lengthField.length - nrLength, nrLength);
3305
- return {
3306
- id: getUintBE(idView),
3307
- len: getUintBE(lengthView)
3308
- };
3309
- }
3310
- async function readChildren(children) {
3311
- let ebmlElementCount = 0;
3312
- while (children > 0) {
3313
- ebmlElementCount++;
3314
- if (ebmlElementCount > maximumEbmlElementCount) return;
3315
- const previousPosition = tokenizer.position;
3316
- const element = await readElement();
3317
- if (element.id === 17026) {
3318
- if (element.len > maximumEbmlDocumentTypeSizeInBytes) return;
3319
- const documentTypeLength = getSafeBound(element.len, maximumEbmlDocumentTypeSizeInBytes, "EBML DocType");
3320
- return (await tokenizer.readToken(new StringType(documentTypeLength))).replaceAll(/\00.*$/g, "");
3321
- }
3322
- if (hasUnknownFileSize(tokenizer) && (!Number.isFinite(element.len) || element.len < 0 || element.len > maximumEbmlElementPayloadSizeInBytes)) return;
3323
- await safeIgnore(tokenizer, element.len, {
3324
- maximumLength: hasUnknownFileSize(tokenizer) ? maximumEbmlElementPayloadSizeInBytes : tokenizer.fileInfo.size,
3325
- reason: "EBML payload"
3326
- });
3327
- --children;
3328
- if (tokenizer.position <= previousPosition) return;
3329
- }
3330
- }
3331
- switch (await readChildren((await readElement()).len)) {
3332
- case "webm": return {
3333
- ext: "webm",
3334
- mime: "video/webm"
3335
- };
3336
- case "matroska": return {
3337
- ext: "mkv",
3338
- mime: "video/matroska"
3339
- };
3340
- default: return;
3341
- }
3342
- }
3669
+ ])) return detectEbml(tokenizer);
3343
3670
  if (this.checkString("SQLi")) return {
3344
3671
  ext: "sqlite",
3345
3672
  mime: "application/x-sqlite3"
@@ -3469,7 +3796,7 @@ var FileTypeParser = class {
3469
3796
  ext: "amr",
3470
3797
  mime: "audio/amr"
3471
3798
  };
3472
- if (this.checkString("{\\rtf")) return {
3799
+ if (this.checkString(String.raw`{\rtf`)) return {
3473
3800
  ext: "rtf",
3474
3801
  mime: "application/rtf"
3475
3802
  };
@@ -3538,7 +3865,7 @@ var FileTypeParser = class {
3538
3865
  };
3539
3866
  if (this.checkString("DRACO")) return {
3540
3867
  ext: "drc",
3541
- mime: "application/vnd.google.draco"
3868
+ mime: "application/x-ft-draco"
3542
3869
  };
3543
3870
  if (this.check([
3544
3871
  253,
@@ -3583,7 +3910,7 @@ var FileTypeParser = class {
3583
3910
  };
3584
3911
  if (this.checkString("AC")) {
3585
3912
  const version = new StringType(4, "latin1").get(this.buffer, 2);
3586
- if (version.match("^d*") && version >= 1e3 && version <= 1050) return {
3913
+ if (new RegExp("^\\d+$", "v").test(version) && version >= 1e3 && version <= 1050) return {
3587
3914
  ext: "dwg",
3588
3915
  mime: "image/vnd.dwg"
3589
3916
  };
@@ -3626,51 +3953,7 @@ var FileTypeParser = class {
3626
3953
  10,
3627
3954
  26,
3628
3955
  10
3629
- ])) {
3630
- const pngFileType = {
3631
- ext: "png",
3632
- mime: "image/png"
3633
- };
3634
- const apngFileType = {
3635
- ext: "apng",
3636
- mime: "image/apng"
3637
- };
3638
- await tokenizer.ignore(8);
3639
- async function readChunkHeader() {
3640
- return {
3641
- length: await tokenizer.readToken(INT32_BE),
3642
- type: await tokenizer.readToken(new StringType(4, "latin1"))
3643
- };
3644
- }
3645
- const isUnknownPngStream = hasUnknownFileSize(tokenizer);
3646
- const pngScanStart = tokenizer.position;
3647
- let pngChunkCount = 0;
3648
- do {
3649
- pngChunkCount++;
3650
- if (pngChunkCount > maximumPngChunkCount) break;
3651
- if (hasExceededUnknownSizeScanBudget(tokenizer, pngScanStart, maximumPngChunkSizeInBytes)) break;
3652
- const previousPosition = tokenizer.position;
3653
- const chunk = await readChunkHeader();
3654
- if (chunk.length < 0) return;
3655
- switch (chunk.type) {
3656
- case "IDAT": return pngFileType;
3657
- case "acTL": return apngFileType;
3658
- default:
3659
- if (isUnknownPngStream && chunk.length > maximumPngChunkSizeInBytes) return;
3660
- try {
3661
- await safeIgnore(tokenizer, chunk.length + 4, {
3662
- maximumLength: isUnknownPngStream ? 16777220 : tokenizer.fileInfo.size,
3663
- reason: "PNG chunk payload"
3664
- });
3665
- } catch (error) {
3666
- if (!isUnknownPngStream && (error instanceof ParserHardLimitError || error instanceof EndOfStreamError)) return pngFileType;
3667
- throw error;
3668
- }
3669
- }
3670
- if (tokenizer.position <= previousPosition) break;
3671
- } while (tokenizer.position + 8 < tokenizer.fileInfo.size);
3672
- return pngFileType;
3673
- }
3956
+ ])) return detectPng(tokenizer);
3674
3957
  if (this.check([
3675
3958
  65,
3676
3959
  82,
@@ -3893,125 +4176,7 @@ var FileTypeParser = class {
3893
4176
  17,
3894
4177
  166,
3895
4178
  217
3896
- ])) {
3897
- let isMalformedAsf = false;
3898
- try {
3899
- async function readHeader() {
3900
- const guid = new Uint8Array(16);
3901
- await safeReadBuffer(tokenizer, guid, void 0, {
3902
- maximumLength: guid.length,
3903
- reason: "ASF header GUID"
3904
- });
3905
- return {
3906
- id: guid,
3907
- size: Number(await tokenizer.readToken(UINT64_LE))
3908
- };
3909
- }
3910
- await safeIgnore(tokenizer, 30, {
3911
- maximumLength: 30,
3912
- reason: "ASF header prelude"
3913
- });
3914
- const isUnknownFileSize = hasUnknownFileSize(tokenizer);
3915
- const asfHeaderScanStart = tokenizer.position;
3916
- let asfHeaderObjectCount = 0;
3917
- while (tokenizer.position + 24 < tokenizer.fileInfo.size) {
3918
- asfHeaderObjectCount++;
3919
- if (asfHeaderObjectCount > maximumAsfHeaderObjectCount) break;
3920
- if (hasExceededUnknownSizeScanBudget(tokenizer, asfHeaderScanStart, maximumUntrustedSkipSizeInBytes)) break;
3921
- const previousPosition = tokenizer.position;
3922
- const header = await readHeader();
3923
- let payload = header.size - 24;
3924
- if (!Number.isFinite(payload) || payload < 0) {
3925
- isMalformedAsf = true;
3926
- break;
3927
- }
3928
- if (_check(header.id, [
3929
- 145,
3930
- 7,
3931
- 220,
3932
- 183,
3933
- 183,
3934
- 169,
3935
- 207,
3936
- 17,
3937
- 142,
3938
- 230,
3939
- 0,
3940
- 192,
3941
- 12,
3942
- 32,
3943
- 83,
3944
- 101
3945
- ])) {
3946
- const typeId = new Uint8Array(16);
3947
- payload -= await safeReadBuffer(tokenizer, typeId, void 0, {
3948
- maximumLength: typeId.length,
3949
- reason: "ASF stream type GUID"
3950
- });
3951
- if (_check(typeId, [
3952
- 64,
3953
- 158,
3954
- 105,
3955
- 248,
3956
- 77,
3957
- 91,
3958
- 207,
3959
- 17,
3960
- 168,
3961
- 253,
3962
- 0,
3963
- 128,
3964
- 95,
3965
- 92,
3966
- 68,
3967
- 43
3968
- ])) return {
3969
- ext: "asf",
3970
- mime: "audio/x-ms-asf"
3971
- };
3972
- if (_check(typeId, [
3973
- 192,
3974
- 239,
3975
- 25,
3976
- 188,
3977
- 77,
3978
- 91,
3979
- 207,
3980
- 17,
3981
- 168,
3982
- 253,
3983
- 0,
3984
- 128,
3985
- 95,
3986
- 92,
3987
- 68,
3988
- 43
3989
- ])) return {
3990
- ext: "asf",
3991
- mime: "video/x-ms-asf"
3992
- };
3993
- break;
3994
- }
3995
- await safeIgnore(tokenizer, payload, {
3996
- maximumLength: isUnknownFileSize ? maximumUntrustedSkipSizeInBytes : tokenizer.fileInfo.size,
3997
- reason: "ASF header payload"
3998
- });
3999
- if (tokenizer.position <= previousPosition) {
4000
- isMalformedAsf = true;
4001
- break;
4002
- }
4003
- }
4004
- } catch (error) {
4005
- if (error instanceof EndOfStreamError || error instanceof ParserHardLimitError) {
4006
- if (hasUnknownFileSize(tokenizer)) isMalformedAsf = true;
4007
- } else throw error;
4008
- }
4009
- if (isMalformedAsf) return;
4010
- return {
4011
- ext: "asf",
4012
- mime: "application/vnd.ms-asf"
4013
- };
4014
- }
4179
+ ])) return detectAsf(tokenizer);
4015
4180
  if (this.check([
4016
4181
  171,
4017
4182
  75,
@@ -4277,7 +4442,7 @@ var FileTypeParser = class {
4277
4442
  70
4278
4443
  ])) return {
4279
4444
  ext: "lnk",
4280
- mime: "application/x.ms.shortcut"
4445
+ mime: "application/x-ms-shortcut"
4281
4446
  };
4282
4447
  if (this.check([
4283
4448
  98,
@@ -4298,11 +4463,11 @@ var FileTypeParser = class {
4298
4463
  0
4299
4464
  ])) return {
4300
4465
  ext: "alias",
4301
- mime: "application/x.apple.alias"
4466
+ mime: "application/x-ft-apple.alias"
4302
4467
  };
4303
4468
  if (this.checkString("Kaydara FBX Binary \0")) return {
4304
4469
  ext: "fbx",
4305
- mime: "application/x.autodesk.fbx"
4470
+ mime: "application/x-ft-fbx"
4306
4471
  };
4307
4472
  if (this.check([76, 80], { offset: 34 }) && (this.check([
4308
4473
  0,
@@ -4474,10 +4639,10 @@ var FileTypeParser = class {
4474
4639
  mime: "image/x-icon"
4475
4640
  };
4476
4641
  await tokenizer.peekBuffer(this.buffer, {
4477
- length: Math.min(2 + this.options.mpegOffsetTolerance, fileSize),
4642
+ length: Math.min(4 + this.options.mpegOffsetTolerance, fileSize),
4478
4643
  mayBeLess: true
4479
4644
  });
4480
- if (this.buffer.length >= 2 + this.options.mpegOffsetTolerance) for (let depth = 0; depth <= this.options.mpegOffsetTolerance; ++depth) {
4645
+ if (this.buffer.length >= 4 + this.options.mpegOffsetTolerance) for (let depth = 0; depth <= this.options.mpegOffsetTolerance; ++depth) {
4481
4646
  const type = this.scanMpeg(depth);
4482
4647
  if (type) return type;
4483
4648
  }
@@ -4494,7 +4659,6 @@ var FileTypeParser = class {
4494
4659
  ext: "dng",
4495
4660
  mime: "image/x-adobe-dng"
4496
4661
  };
4497
- default:
4498
4662
  }
4499
4663
  }
4500
4664
  async readTiffIFD(bigEndian) {
@@ -4528,6 +4692,7 @@ var FileTypeParser = class {
4528
4692
  };
4529
4693
  }
4530
4694
  }
4695
+ if (hasUnknownFileSize(this.tokenizer) && ifdOffset > maximumTiffStreamIfdOffsetInBytes) return tiffFileType;
4531
4696
  const maximumTiffOffset = hasUnknownFileSize(this.tokenizer) ? maximumTiffIfdOffsetInBytes : this.tokenizer.fileInfo.size;
4532
4697
  try {
4533
4698
  await safeIgnore(this.tokenizer, ifdOffset, {
@@ -4563,19 +4728,23 @@ var FileTypeParser = class {
4563
4728
  if (this.check([16], {
4564
4729
  offset: offset + 1,
4565
4730
  mask: [22]
4566
- })) {
4567
- if (this.check([8], {
4568
- offset: offset + 1,
4569
- mask: [8]
4570
- })) return {
4571
- ext: "aac",
4572
- mime: "audio/aac"
4573
- };
4574
- return {
4575
- ext: "aac",
4576
- mime: "audio/aac"
4577
- };
4578
- }
4731
+ })) return {
4732
+ ext: "aac",
4733
+ mime: "audio/aac"
4734
+ };
4735
+ if (this.check([255, 254], { offset })) return;
4736
+ if (this.check([8], {
4737
+ offset: offset + 1,
4738
+ mask: [24]
4739
+ })) return;
4740
+ if (this.check([240], {
4741
+ offset: offset + 2,
4742
+ mask: [240]
4743
+ })) return;
4744
+ if (this.check([12], {
4745
+ offset: offset + 2,
4746
+ mask: [12]
4747
+ })) return;
4579
4748
  if (this.check([2], {
4580
4749
  offset: offset + 1,
4581
4750
  mask: [6]
@@ -4605,4 +4774,4 @@ new Set(mimeTypes);
4605
4774
  //#endregion
4606
4775
  export { fileTypeFromBlob };
4607
4776
 
4608
- //# sourceMappingURL=file-type-BwbWtW7C.mjs.map
4777
+ //# sourceMappingURL=source-BpNO27ea.mjs.map