@poe-platform/safe-bash 0.1.532 → 0.1.534

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.
Files changed (39) hide show
  1. package/dist/safe-bash/commands/archive/index.d.ts +2 -0
  2. package/dist/safe-bash/commands/archive/index.d.ts.map +1 -1
  3. package/dist/safe-bash/commands/archive/index.js +11 -3
  4. package/dist/safe-bash/commands/archive/index.js.map +1 -1
  5. package/dist/safe-bash/commands/archive/unzip/arguments.d.ts +32 -0
  6. package/dist/safe-bash/commands/archive/unzip/arguments.d.ts.map +1 -0
  7. package/dist/safe-bash/commands/archive/unzip/arguments.js +214 -0
  8. package/dist/safe-bash/commands/archive/unzip/arguments.js.map +1 -0
  9. package/dist/safe-bash/commands/archive/unzip/safety.d.ts +28 -0
  10. package/dist/safe-bash/commands/archive/unzip/safety.d.ts.map +1 -0
  11. package/dist/safe-bash/commands/archive/unzip/safety.js +288 -0
  12. package/dist/safe-bash/commands/archive/unzip/safety.js.map +1 -0
  13. package/dist/safe-bash/commands/archive/unzip.d.ts +4 -0
  14. package/dist/safe-bash/commands/archive/unzip.d.ts.map +1 -0
  15. package/dist/safe-bash/commands/archive/unzip.js +264 -0
  16. package/dist/safe-bash/commands/archive/unzip.js.map +1 -0
  17. package/dist/safe-bash/commands/archive/zip/safety.d.ts +28 -0
  18. package/dist/safe-bash/commands/archive/zip/safety.d.ts.map +1 -0
  19. package/dist/safe-bash/commands/archive/zip/safety.js +228 -0
  20. package/dist/safe-bash/commands/archive/zip/safety.js.map +1 -0
  21. package/dist/safe-bash/commands/archive/zip-format.d.ts +39 -0
  22. package/dist/safe-bash/commands/archive/zip-format.d.ts.map +1 -0
  23. package/dist/safe-bash/commands/archive/zip-format.js +509 -0
  24. package/dist/safe-bash/commands/archive/zip-format.js.map +1 -0
  25. package/dist/safe-bash/commands/archive/zip.d.ts +4 -0
  26. package/dist/safe-bash/commands/archive/zip.d.ts.map +1 -0
  27. package/dist/safe-bash/commands/archive/zip.js +290 -0
  28. package/dist/safe-bash/commands/archive/zip.js.map +1 -0
  29. package/dist/safe-bash/commands/bytes/compression/codec.d.ts +1 -1
  30. package/dist/safe-bash/commands/bytes/compression/codec.d.ts.map +1 -1
  31. package/dist/safe-bash/commands/bytes/compression/codec.js +2 -2
  32. package/dist/safe-bash/commands/bytes/compression/codec.js.map +1 -1
  33. package/dist/safe-bash/core.browser.js +1937 -389
  34. package/dist/safe-bash/core.browser.js.map +4 -4
  35. package/dist/safe-bash/shell/runtime.d.ts +1 -0
  36. package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
  37. package/dist/safe-bash/shell/runtime.js +4 -1
  38. package/dist/safe-bash/shell/runtime.js.map +1 -1
  39. package/package.json +2 -2
@@ -841,7 +841,7 @@ var Parser = class {
841
841
  return { minimum: 0, maximum: 1 };
842
842
  }
843
843
  this.position += 2;
844
- const number5 = () => {
844
+ const number6 = () => {
845
845
  let value2 = 0, count2 = 0;
846
846
  while (this.tokens[this.position] >= "0" && this.tokens[this.position] <= "9") {
847
847
  this.work.charge();
@@ -850,12 +850,12 @@ var Parser = class {
850
850
  }
851
851
  return count2 ? value2 : void 0;
852
852
  };
853
- const minimum = number5();
853
+ const minimum = number6();
854
854
  if (minimum === void 0) syntax("Invalid content of \\{\\}");
855
855
  let maximum = minimum;
856
856
  if (this.at(",")) {
857
857
  this.position++;
858
- maximum = number5() ?? Infinity;
858
+ maximum = number6() ?? Infinity;
859
859
  }
860
860
  if (!this.escaped("}")) syntax("Unmatched \\{");
861
861
  this.position += 2;
@@ -1111,15 +1111,15 @@ function* matchExprSteps(descriptor2, subject, options3 = {}) {
1111
1111
  if (start < 0 || end < start || end - start > input3.values.length - state.position) break;
1112
1112
  work.charge(end - start);
1113
1113
  if (work.checkpoint()) yield;
1114
- let equal = true;
1114
+ let equal2 = true;
1115
1115
  for (let offset = 0; offset < end - start; offset++) {
1116
1116
  if (input3.values[start + offset] !== input3.values[state.position + offset]) {
1117
- equal = false;
1117
+ equal2 = false;
1118
1118
  break;
1119
1119
  }
1120
1120
  if ((offset + 1) % 256 === 0) yield;
1121
1121
  }
1122
- if (!equal) break;
1122
+ if (!equal2) break;
1123
1123
  state.position += end - start;
1124
1124
  if (end > start) {
1125
1125
  work.allocate(1);
@@ -2449,34 +2449,34 @@ async function formatPrintf(context2) {
2449
2449
  const arguments_ = incoming.args[0] === "--" ? incoming.slice(1) : incoming;
2450
2450
  const args = arguments_.args;
2451
2451
  requireOperands(args);
2452
- const format2 = args[0];
2453
- if (format2.startsWith("-") && incoming.args[0] !== "--") throw new UsageError(`invalid option '${format2}'`);
2452
+ const format3 = args[0];
2453
+ if (format3.startsWith("-") && incoming.args[0] !== "--") throw new UsageError(`invalid option '${format3}'`);
2454
2454
  const rawFormat = typeof arguments_.values[0] === "string" ? void 0 : arguments_.bytes(0);
2455
- const formatLength = rawFormat?.length ?? format2.length;
2455
+ const formatLength = rawFormat?.length ?? format3.length;
2456
2456
  let argument2 = 1;
2457
2457
  let exitCode = 0;
2458
2458
  let stopped = false;
2459
2459
  do {
2460
2460
  const before = argument2;
2461
2461
  for (let offset = 0; offset < formatLength && !stopped; ) {
2462
- if (rawFormat ? rawFormat[offset] !== 37 : format2[offset] !== "%") {
2463
- const end = rawFormat ? rawFormat.indexOf(37, offset) : format2.indexOf("%", offset);
2462
+ if (rawFormat ? rawFormat[offset] !== 37 : format3[offset] !== "%") {
2463
+ const end = rawFormat ? rawFormat.indexOf(37, offset) : format3.indexOf("%", offset);
2464
2464
  const limit = end < 0 ? formatLength : end;
2465
- const literal = rawFormat ? rawFormat.subarray(offset, limit) : format2.slice(offset, limit);
2465
+ const literal = rawFormat ? rawFormat.subarray(offset, limit) : format3.slice(offset, limit);
2466
2466
  const escaped3 = escapeBytes(literal);
2467
2467
  await output(context2, escaped3.bytes);
2468
2468
  stopped = escaped3.stop;
2469
2469
  offset += literal.length;
2470
2470
  continue;
2471
2471
  }
2472
- if (rawFormat ? rawFormat[offset + 1] === 37 : format2[offset + 1] === "%") {
2472
+ if (rawFormat ? rawFormat[offset + 1] === 37 : format3[offset + 1] === "%") {
2473
2473
  await output(context2, "%");
2474
2474
  offset += 2;
2475
2475
  continue;
2476
2476
  }
2477
2477
  let tokenEnd = offset + 1;
2478
2478
  if (rawFormat) while (tokenEnd < rawFormat.length && (rawFormat[tokenEnd] >= 48 && rawFormat[tokenEnd] <= 57 || [32, 35, 43, 45, 46].includes(rawFormat[tokenEnd]))) tokenEnd++;
2479
- const fragment = rawFormat ? decoder.decode(rawFormat.subarray(offset, tokenEnd + 1)) : format2.slice(offset);
2479
+ const fragment = rawFormat ? decoder.decode(rawFormat.subarray(offset, tokenEnd + 1)) : format3.slice(offset);
2480
2480
  const match = /^%([-+ #0]*)(\d+)?(?:\.(\d+))?([sbqcdiouxXfFeEgG])/u.exec(fragment);
2481
2481
  if (!match) throw new UsageError(`invalid format near '${fragment}'`);
2482
2482
  offset += match[0].length;
@@ -2504,30 +2504,30 @@ async function formatPrintf(context2) {
2504
2504
  if (specifier === "q") text3 = supplied === "" ? "''" : supplied.replace(/[^a-zA-Z0-9_./-]/gu, (character) => character === "\n" ? "$'\\n'" : `\\${character}`);
2505
2505
  else if (specifier === "c") text3 = supplied ? String.fromCodePoint(supplied.codePointAt(0)) : "\0";
2506
2506
  else {
2507
- let number5 = supplied === "" ? 0 : /^["']/u.test(supplied) ? supplied.codePointAt(1) ?? 0 : Number(supplied);
2507
+ let number6 = supplied === "" ? 0 : /^["']/u.test(supplied) ? supplied.codePointAt(1) ?? 0 : Number(supplied);
2508
2508
  if (/^[+-]0[xX][0-9a-fA-F]+$/u.test(supplied.trim())) {
2509
- number5 = Number(supplied.trim().slice(1)) * (supplied.trim().startsWith("-") ? -1 : 1);
2509
+ number6 = Number(supplied.trim().slice(1)) * (supplied.trim().startsWith("-") ? -1 : 1);
2510
2510
  }
2511
2511
  if (/^[+-]?0[0-9]+$/u.test(supplied) && !/[fFeEgG]/u.test(specifier)) {
2512
- if (/[89]/u.test(supplied)) number5 = NaN;
2513
- else number5 = parseInt(supplied.replace(/^[+-]?0/u, ""), 8) * (supplied.startsWith("-") ? -1 : 1);
2512
+ if (/[89]/u.test(supplied)) number6 = NaN;
2513
+ else number6 = parseInt(supplied.replace(/^[+-]?0/u, ""), 8) * (supplied.startsWith("-") ? -1 : 1);
2514
2514
  }
2515
- if (!Number.isFinite(number5)) {
2515
+ if (!Number.isFinite(number6)) {
2516
2516
  await writeDiagnostic(context2.stderr, `printf: '${supplied}': invalid number
2517
2517
  `, context2.signal);
2518
2518
  exitCode = 1;
2519
- number5 = 0;
2519
+ number6 = 0;
2520
2520
  }
2521
- if (/[fF]/u.test(specifier)) text3 = number5.toFixed(precision ?? 6);
2522
- else if (/[eE]/u.test(specifier)) text3 = number5.toExponential(precision ?? 6).replace(/e([+-])(\d)$/u, "e$10$2");
2523
- else if (/[gG]/u.test(specifier)) text3 = Number(number5.toPrecision(Math.max(1, precision ?? 6))).toString();
2521
+ if (/[fF]/u.test(specifier)) text3 = number6.toFixed(precision ?? 6);
2522
+ else if (/[eE]/u.test(specifier)) text3 = number6.toExponential(precision ?? 6).replace(/e([+-])(\d)$/u, "e$10$2");
2523
+ else if (/[gG]/u.test(specifier)) text3 = Number(number6.toPrecision(Math.max(1, precision ?? 6))).toString();
2524
2524
  else {
2525
2525
  const radix = /[xX]/u.test(specifier) ? 16 : specifier === "o" ? 8 : 10;
2526
2526
  const unsigned = /[uoxX]/u.test(specifier);
2527
2527
  let integral;
2528
2528
  try {
2529
2529
  const token = supplied.trim();
2530
- if (!token || /^["']/u.test(token)) integral = BigInt(Math.trunc(number5));
2530
+ if (!token || /^["']/u.test(token)) integral = BigInt(Math.trunc(number6));
2531
2531
  else {
2532
2532
  const magnitude = token.replace(/^[+-]/u, "");
2533
2533
  if (!/^(?:0[xX][0-9a-fA-F]+|0[0-7]*|[1-9][0-9]*)$/u.test(magnitude)) throw new Error("invalid integer");
@@ -2548,7 +2548,7 @@ async function formatPrintf(context2) {
2548
2548
  }
2549
2549
  }
2550
2550
  if (/[XFEG]/u.test(specifier)) text3 = text3.toUpperCase();
2551
- if (number5 >= 0 && /[difFeEgG]/u.test(specifier)) text3 = (flags3.includes("+") ? "+" : flags3.includes(" ") ? " " : "") + text3;
2551
+ if (number6 >= 0 && /[difFeEgG]/u.test(specifier)) text3 = (flags3.includes("+") ? "+" : flags3.includes(" ") ? " " : "") + text3;
2552
2552
  }
2553
2553
  if (flags3.includes("-")) text3 = text3.padEnd(width, " ");
2554
2554
  else if (flags3.includes("0") && /[diouxXfFeEgG]/u.test(specifier) && (precision === void 0 || /[fFeEgG]/u.test(specifier))) {
@@ -3384,14 +3384,14 @@ function filesystemCommands(maxDirectoryEntries) {
3384
3384
  else if (parsed.flags.has("F") && stat.type === "file" && stat.mode & 73) suffix2 = "*";
3385
3385
  if (parsed.flags.has("l")) {
3386
3386
  const size = parsed.flags.has("h") ? humanSize(stat.size, path) : String(stat.size);
3387
- const date = new Date(stat.mtimeMs).toISOString().slice(0, 16).replace("T", " ");
3387
+ const date2 = new Date(stat.mtimeMs).toISOString().slice(0, 16).replace("T", " ");
3388
3388
  let target = "";
3389
3389
  if (stat.type === "symlink") {
3390
3390
  await admitFilesystemModes(context2, "ls", ["link"], [path]);
3391
3391
  needCapability(context2, "readlink");
3392
3392
  target = ` -> ${escapeText(await context2.fs.readlink(path, { signal: context2.signal }), "display")}`;
3393
3393
  }
3394
- await output(context2, `${modeText(stat)} ${stat.nlink ?? 1} ${stat.uid ?? 0} ${stat.gid ?? 0} ${size} ${date} ${escapeText(display2, "display")}${suffix2}${target}
3394
+ await output(context2, `${modeText(stat)} ${stat.nlink ?? 1} ${stat.uid ?? 0} ${stat.gid ?? 0} ${size} ${date2} ${escapeText(display2, "display")}${suffix2}${target}
3395
3395
  `);
3396
3396
  } else await output(context2, `${escapeText(display2, "display")}${suffix2}
3397
3397
  `);
@@ -4152,7 +4152,7 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
4152
4152
  }
4153
4153
  let lineStart = true;
4154
4154
  let blankCount = 0;
4155
- let number5 = 1;
4155
+ let number6 = 1;
4156
4156
  for await (const chunk of source2) {
4157
4157
  const transformed = [];
4158
4158
  const append = (text3) => {
@@ -4160,7 +4160,7 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
4160
4160
  };
4161
4161
  for (const byte of chunk) {
4162
4162
  if (lineStart && byte === 10 && parsed.flags.has("s") && blankCount > 0) continue;
4163
- if (lineStart && (parsed.flags.has("b") ? byte !== 10 : parsed.flags.has("n"))) append(`${String(number5++).padStart(6)} `);
4163
+ if (lineStart && (parsed.flags.has("b") ? byte !== 10 : parsed.flags.has("n"))) append(`${String(number6++).padStart(6)} `);
4164
4164
  if (byte === 10) {
4165
4165
  if (parsed.flags.has("E")) transformed.push(36);
4166
4166
  transformed.push(10);
@@ -4654,7 +4654,7 @@ async function emitRecords(context2, records5, destination2) {
4654
4654
  }
4655
4655
  async function collectSortRecords(source2, delimiter, budget, signal, accept) {
4656
4656
  const pending = new RecordBuffer(bufferLimit);
4657
- const admit2 = (length) => {
4657
+ const admit3 = (length) => {
4658
4658
  signal.throwIfAborted();
4659
4659
  budget.admit(length);
4660
4660
  };
@@ -4663,13 +4663,13 @@ async function collectSortRecords(source2, delimiter, budget, signal, accept) {
4663
4663
  let start = 0;
4664
4664
  for (let offset = 0; offset < chunk.length; offset++) {
4665
4665
  if (chunk[offset] !== delimiter) continue;
4666
- const accepted = accept(pending.finish(admit2, chunk, start, offset));
4666
+ const accepted = accept(pending.finish(admit3, chunk, start, offset));
4667
4667
  if ((accepted instanceof Promise ? await accepted : accepted) === false) return false;
4668
4668
  start = offset + 1;
4669
4669
  }
4670
4670
  pending.append(chunk, start);
4671
4671
  }
4672
- if (pending.size) return await accept(pending.finish(admit2)) !== false;
4672
+ if (pending.size) return await accept(pending.finish(admit3)) !== false;
4673
4673
  return true;
4674
4674
  } finally {
4675
4675
  pending.clear();
@@ -5017,7 +5017,7 @@ function predicateCommands() {
5017
5017
  const unary2 = /* @__PURE__ */ new Set(["-n", "-z", "-e", "-a", "-f", "-c", "-d", "-L", "-h", "-s", "-r", "-w", "-x"]);
5018
5018
  const binary3 = /* @__PURE__ */ new Set(["=", "==", "!=", "<", ">", "-eq", "-ne", "-lt", "-le", "-gt", "-ge", "-nt", "-ot", "-ef"]);
5019
5019
  let offset = 0;
5020
- const number5 = (text3) => {
5020
+ const number6 = (text3) => {
5021
5021
  if (!/^[ \t]*[+-]?[0-9]+[ \t]*$/u.test(text3)) throw new UsageError(`integer expression expected: '${text3}'`);
5022
5022
  return BigInt(text3.trim());
5023
5023
  };
@@ -5053,8 +5053,8 @@ function predicateCommands() {
5053
5053
  if (identity2 !== "unknown") return identity2 === "same";
5054
5054
  return leftStat?.ino !== void 0 && rightStat?.ino !== void 0 && leftStat.type === rightStat.type && leftStat.ino === rightStat.ino && leftStat.dev === rightStat.dev;
5055
5055
  }
5056
- const leftNumber = number5(token);
5057
- const rightNumber = number5(right);
5056
+ const leftNumber = number6(token);
5057
+ const rightNumber = number6(right);
5058
5058
  if (operator === "-eq") return leftNumber === rightNumber;
5059
5059
  if (operator === "-ne") return leftNumber !== rightNumber;
5060
5060
  if (operator === "-lt") return leftNumber < rightNumber;
@@ -5449,7 +5449,7 @@ async function* argumentsFrom(source2, signal, delimiter, replacement = false) {
5449
5449
  let active = false;
5450
5450
  let escaped3 = false;
5451
5451
  let quote5 = "";
5452
- const parse18 = function* (text3) {
5452
+ const parse19 = function* (text3) {
5453
5453
  for (const character of text3) {
5454
5454
  if (delimiter !== void 0) {
5455
5455
  if (character === delimiter) {
@@ -5490,9 +5490,9 @@ async function* argumentsFrom(source2, signal, delimiter, replacement = false) {
5490
5490
  };
5491
5491
  for await (const chunk of readBytes(source2, signal)) {
5492
5492
  signal.throwIfAborted();
5493
- yield* parse18(utf82.decode(chunk, { stream: true }));
5493
+ yield* parse19(utf82.decode(chunk, { stream: true }));
5494
5494
  }
5495
- yield* parse18(utf82.decode());
5495
+ yield* parse19(utf82.decode());
5496
5496
  if (quote5 || escaped3) throw new UsageError(quote5 ? "unmatched quote in input" : "trailing backslash in input");
5497
5497
  if (active) yield current;
5498
5498
  }
@@ -6123,9 +6123,9 @@ function findCommands(execute5, maxDirectoryEntries) {
6123
6123
  index++;
6124
6124
  } else if (args[index] === "-maxdepth" || args[index] === "-mindepth") {
6125
6125
  if (args[index + 1] === void 0) throw new UsageError(`${args[index]} requires a number`);
6126
- const number5 = integer(args[index + 1]);
6127
- if (args[index] === "-maxdepth") maxDepth = number5;
6128
- else minDepth = number5;
6126
+ const number6 = integer(args[index + 1]);
6127
+ if (args[index] === "-maxdepth") maxDepth = number6;
6128
+ else minDepth = number6;
6129
6129
  args.splice(index, 2);
6130
6130
  values.splice(index, 2);
6131
6131
  } else if (args[index] === "-depth") {
@@ -6321,7 +6321,7 @@ function findCommands(execute5, maxDirectoryEntries) {
6321
6321
  };
6322
6322
  const evaluate = args.length ? disjunction() : async () => true;
6323
6323
  if (offset !== args.length) throw new UsageError(`unexpected expression '${args[offset]}'`);
6324
- for (const prepare of formats2) await prepare();
6324
+ for (const prepare2 of formats2) await prepare2();
6325
6325
  if (deletes && prunes && !explicitDepth) throw new PublicDiagnostic("-delete implies -depth; -prune is ineffective unless -depth is explicitly supplied");
6326
6326
  for (const reference of references.keys()) {
6327
6327
  context2.signal.throwIfAborted();
@@ -6958,15 +6958,15 @@ function widthValue(text3, maximum, unicode) {
6958
6958
  while (text3.charCodeAt(offset) === 32 || text3.charCodeAt(offset) >= 9 && text3.charCodeAt(offset) <= 13) offset++;
6959
6959
  if (text3[offset] === "+") offset++;
6960
6960
  const start = offset;
6961
- let number5 = 0;
6961
+ let number6 = 0;
6962
6962
  while (text3.charCodeAt(offset) >= 48 && text3.charCodeAt(offset) <= 57) {
6963
- number5 = Math.min(1073741824, number5 * 10 + text3.charCodeAt(offset++) - 48);
6963
+ number6 = Math.min(1073741824, number6 * 10 + text3.charCodeAt(offset++) - 48);
6964
6964
  }
6965
- if (offset === start || offset !== text3.length || number5 > maximum) {
6966
- const range3 = offset === text3.length && offset !== start && number5 > maximum;
6967
- throw new PublicDiagnostic(`invalid width: ${quote(Uint8Array.from(text3, (unit2) => unit2.charCodeAt(0)), false, unicode)}${range3 ? number5 > 1073741823 ? ": Value too large for defined data type" : ": Numerical result out of range" : ""}`);
6965
+ if (offset === start || offset !== text3.length || number6 > maximum) {
6966
+ const range3 = offset === text3.length && offset !== start && number6 > maximum;
6967
+ throw new PublicDiagnostic(`invalid width: ${quote(Uint8Array.from(text3, (unit2) => unit2.charCodeAt(0)), false, unicode)}${range3 ? number6 > 1073741823 ? ": Value too large for defined data type" : ": Numerical result out of range" : ""}`);
6968
6968
  }
6969
- return number5;
6969
+ return number6;
6970
6970
  }
6971
6971
  function parse3(context2) {
6972
6972
  const settings17 = { width: 75, goal: 70, crown: false, tagged: false, split: false, uniform: false, prefix: new Uint8Array(), leading: 0, fullPrefix: 0, files: [] };
@@ -10291,8 +10291,8 @@ function parse4(context2) {
10291
10291
  else if (key === "z") settings17.separator = 0;
10292
10292
  else if (key === "help" || key === "version") settings17.information = key;
10293
10293
  else if (key === "n") {
10294
- const number5 = decimal(value2, true, unicode);
10295
- if (number5 < settings17.count) settings17.count = number5;
10294
+ const number6 = decimal(value2, true, unicode);
10295
+ if (number6 < settings17.count) settings17.count = number6;
10296
10296
  } else if (key === "i") {
10297
10297
  if (settings17.range) throw new ShufDiagnostic("multiple -i options specified");
10298
10298
  const dash = value2.indexOf("-");
@@ -13763,10 +13763,10 @@ function parse6(source2, extended, separator, maxProgramInstructions) {
13763
13763
  };
13764
13764
  const address = () => {
13765
13765
  horizontal();
13766
- const number5 = /^[0-9]+/u.exec(source2.slice(offset));
13767
- if (number5) {
13768
- offset += number5[0].length;
13769
- const value2 = Number(number5[0]);
13766
+ const number6 = /^[0-9]+/u.exec(source2.slice(offset));
13767
+ if (number6) {
13768
+ offset += number6[0].length;
13769
+ const value2 = Number(number6[0]);
13770
13770
  if (!Number.isSafeInteger(value2) || value2 < 1) throw new ProgramError("sed line addresses must be positive integers");
13771
13771
  return { kind: "number", number: value2 };
13772
13772
  }
@@ -13966,7 +13966,7 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
13966
13966
  const next = await peekNext();
13967
13967
  return !next.done && next.value.fileIndex !== record4.fileIndex ? { ...record4, terminated: true } : record4;
13968
13968
  };
13969
- let number5 = 0;
13969
+ let number6 = 0;
13970
13970
  let hold = "";
13971
13971
  let holdTerminated = true;
13972
13972
  const joinSpace = (left, right) => {
@@ -13987,7 +13987,7 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
13987
13987
  try {
13988
13988
  while (!current.done) {
13989
13989
  budget.step();
13990
- number5++;
13990
+ number6++;
13991
13991
  let record4 = await prepareRecord(current.value);
13992
13992
  let pattern = record4.text;
13993
13993
  const appended = [];
@@ -14038,7 +14038,7 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
14038
14038
  if (terminated) outputState.unterminatedFiles.delete(path);
14039
14039
  else outputState.unterminatedFiles.add(path);
14040
14040
  };
14041
- const matches3 = async (address) => address.kind === "number" ? number5 === address.number : address.kind === "last" ? (await peekNext()).done === true : await getPattern(address.pattern).find(pattern, budget) !== void 0;
14041
+ const matches3 = async (address) => address.kind === "number" ? number6 === address.number : address.kind === "last" ? (await peekNext()).done === true : await getPattern(address.pattern).find(pattern, budget) !== void 0;
14042
14042
  for (let pc = 0; pc < program.length; ) {
14043
14043
  budget.step();
14044
14044
  await budget.checkpoint();
@@ -14048,13 +14048,13 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
14048
14048
  if (instruction.first) {
14049
14049
  if (instruction.second) {
14050
14050
  if (active.has(pc)) {
14051
- if (instruction.second.kind === "number" && number5 > instruction.second.number) selected = false;
14052
- ending = instruction.second.kind === "number" ? number5 >= instruction.second.number : await matches3(instruction.second);
14051
+ if (instruction.second.kind === "number" && number6 > instruction.second.number) selected = false;
14052
+ ending = instruction.second.kind === "number" ? number6 >= instruction.second.number : await matches3(instruction.second);
14053
14053
  if (ending) active.delete(pc);
14054
14054
  } else {
14055
14055
  selected = await matches3(instruction.first);
14056
14056
  if (selected) {
14057
- ending = instruction.second.kind === "number" && number5 >= instruction.second.number || instruction.second.kind === "last" && (await peekNext()).done === true;
14057
+ ending = instruction.second.kind === "number" && number6 >= instruction.second.number || instruction.second.kind === "last" && (await peekNext()).done === true;
14058
14058
  if (!ending) active.add(pc);
14059
14059
  }
14060
14060
  }
@@ -14075,7 +14075,7 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
14075
14075
  break;
14076
14076
  }
14077
14077
  case "=":
14078
- await emit2(`${number5}${separator}`);
14078
+ await emit2(`${number6}${separator}`);
14079
14079
  break;
14080
14080
  case "l": {
14081
14081
  const escapes = { "\x07": "\\a", "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", " ": "\\t", "\v": "\\v", "\\": "\\\\" };
@@ -14203,7 +14203,7 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
14203
14203
  return { status: 0, quit: false };
14204
14204
  }
14205
14205
  record4 = await prepareRecord(next.value);
14206
- number5++;
14206
+ number6++;
14207
14207
  pattern = instruction.kind === "N" ? joinSpace(pattern, record4.text) : record4.text;
14208
14208
  substituted = false;
14209
14209
  break;
@@ -14338,7 +14338,7 @@ var AwkArray = class {
14338
14338
  entries = /* @__PURE__ */ new Map();
14339
14339
  };
14340
14340
  var unset = Object.freeze({ kind: "unset" });
14341
- var numeric = (number5) => ({ kind: "number", number: number5 });
14341
+ var numeric = (number6) => ({ kind: "number", number: number6 });
14342
14342
  var string = (text3) => ({ kind: "string", text: text3 });
14343
14343
  function inputValue(text3) {
14344
14344
  return /^[ \t\r\n]*[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?[ \t\r\n]*$/u.test(text3) ? { kind: "numeric", text: text3, number: Number(text3) } : string(text3);
@@ -14366,28 +14366,28 @@ function general2(value2, precision, alternate) {
14366
14366
  return result2;
14367
14367
  }
14368
14368
  var formatPattern = /^%([-+ #0]*)(\*|[0-9]+)?(?:\.(\*|[0-9]*))?([csdiuoxXfFeEgG])/u;
14369
- function validateFormat(format2) {
14370
- for (let offset = 0; offset < format2.length; ) {
14371
- if (format2[offset] !== "%") {
14369
+ function validateFormat(format3) {
14370
+ for (let offset = 0; offset < format3.length; ) {
14371
+ if (format3[offset] !== "%") {
14372
14372
  offset++;
14373
14373
  continue;
14374
14374
  }
14375
- if (format2[offset + 1] === "%") {
14375
+ if (format3[offset + 1] === "%") {
14376
14376
  offset += 2;
14377
14377
  continue;
14378
14378
  }
14379
- const match = formatPattern.exec(format2.slice(offset));
14380
- if (!match) throw new ProgramError(`unsupported format near '${format2.slice(offset)}'`);
14379
+ const match = formatPattern.exec(format3.slice(offset));
14380
+ if (!match) throw new ProgramError(`unsupported format near '${format3.slice(offset)}'`);
14381
14381
  offset += match[0].length;
14382
14382
  if (match[2] !== "*" && Number(match[2] ?? 0) > 1e6 || match[3] !== "*" && Number(match[3] ?? 0) > (/[fFeEgG]/u.test(match[4]) ? 100 : 1e6)) throw new ProgramError("excessive format width or precision");
14383
14383
  }
14384
14384
  }
14385
- function formatted(format2, values, text3, budget) {
14386
- budget?.step(format2.length);
14385
+ function formatted(format3, values, text3, budget) {
14386
+ budget?.step(format3.length);
14387
14387
  let result2 = "";
14388
14388
  let argument2 = 0;
14389
14389
  const limit = Math.min(budget?.maxBufferBytes ?? 32 * 1024 * 1024, 32 * 1024 * 1024);
14390
- const admit2 = (length) => {
14390
+ const admit3 = (length) => {
14391
14391
  budget?.step(0);
14392
14392
  if (length > limit - result2.length) throw new ProgramError(budget && budget.maxBufferBytes < 32 * 1024 * 1024 ? "text buffer limit exceeded" : "formatted output exceeds buffer limit");
14393
14393
  budget?.step(length);
@@ -14401,20 +14401,20 @@ function formatted(format2, values, text3, budget) {
14401
14401
  if (value2 === void 0) throw new ProgramError("not enough arguments for format");
14402
14402
  return value2;
14403
14403
  };
14404
- for (let offset = 0; offset < format2.length; ) {
14405
- if (format2[offset] !== "%") {
14406
- admit2(1);
14407
- result2 += format2[offset++];
14404
+ for (let offset = 0; offset < format3.length; ) {
14405
+ if (format3[offset] !== "%") {
14406
+ admit3(1);
14407
+ result2 += format3[offset++];
14408
14408
  continue;
14409
14409
  }
14410
- if (format2[offset + 1] === "%") {
14411
- admit2(1);
14410
+ if (format3[offset + 1] === "%") {
14411
+ admit3(1);
14412
14412
  result2 += "%";
14413
14413
  offset += 2;
14414
14414
  continue;
14415
14415
  }
14416
- const match = formatPattern.exec(format2.slice(offset));
14417
- if (!match) throw new ProgramError(`unsupported format near '${format2.slice(offset)}'`);
14416
+ const match = formatPattern.exec(format3.slice(offset));
14417
+ if (!match) throw new ProgramError(`unsupported format near '${format3.slice(offset)}'`);
14418
14418
  offset += match[0].length;
14419
14419
  let flags3 = match[1];
14420
14420
  let width = match[2] === "*" ? Math.trunc(amountOf(take())) : Number(match[2] ?? 0);
@@ -14430,10 +14430,10 @@ function formatted(format2, values, text3, budget) {
14430
14430
  let part;
14431
14431
  if (conversion === "s") {
14432
14432
  const source2 = text3(value2);
14433
- admit2(Math.min(source2.length, precision ?? source2.length));
14433
+ admit3(Math.min(source2.length, precision ?? source2.length));
14434
14434
  part = source2.slice(0, precision);
14435
14435
  } else if (conversion === "c") {
14436
- admit2(1);
14436
+ admit3(1);
14437
14437
  part = value2.kind === "string" ? value2.text[0] ?? "\0" : String.fromCharCode(Math.trunc(amountOf(value2)) & 255);
14438
14438
  } else {
14439
14439
  const amount = amountOf(value2);
@@ -14448,46 +14448,46 @@ function formatted(format2, values, text3, budget) {
14448
14448
  part = (/[uoxX]/u.test(conversion) ? BigInt.asUintN(32, integer10) : integer10).toString(radix);
14449
14449
  if (precision !== void 0) {
14450
14450
  const negative = part.startsWith("-");
14451
- admit2(amount === 0 && precision === 0 ? 0 : Math.max(part.length, precision + Number(negative)));
14451
+ admit3(amount === 0 && precision === 0 ? 0 : Math.max(part.length, precision + Number(negative)));
14452
14452
  part = amount === 0 && precision === 0 ? "" : negative ? `-${part.slice(1).padStart(precision, "0")}` : part.padStart(precision, "0");
14453
14453
  }
14454
14454
  if (flags3.includes("#") && amount !== 0) {
14455
14455
  const prefix3 = radix === 16 ? "0x" : radix === 8 ? "0" : "";
14456
- admit2(prefix3.length + part.length);
14456
+ admit3(prefix3.length + part.length);
14457
14457
  part = prefix3 + part;
14458
14458
  }
14459
14459
  }
14460
- admit2(part.length);
14460
+ admit3(part.length);
14461
14461
  part = part.replace(/e([+-])([0-9])$/u, "e$10$2");
14462
14462
  if (/[XFEG]/u.test(conversion)) {
14463
- admit2(part.length);
14463
+ admit3(part.length);
14464
14464
  part = part.toUpperCase();
14465
14465
  }
14466
14466
  if (amount >= 0 && !/[uoxX]/u.test(conversion)) {
14467
14467
  const prefix3 = flags3.includes("+") ? "+" : flags3.includes(" ") ? " " : "";
14468
- admit2(prefix3.length + part.length);
14468
+ admit3(prefix3.length + part.length);
14469
14469
  part = prefix3 + part;
14470
14470
  }
14471
14471
  if (flags3.includes("#") && /[fFeE]/u.test(conversion)) {
14472
14472
  budget?.step(part.length);
14473
14473
  if (!part.includes(".")) {
14474
- admit2(part.length + 1);
14474
+ admit3(part.length + 1);
14475
14475
  part = part.replace(/([eE]|$)/u, ".$1");
14476
14476
  }
14477
14477
  }
14478
14478
  }
14479
- admit2(Math.max(part.length, width));
14479
+ admit3(Math.max(part.length, width));
14480
14480
  if (flags3.includes("-")) part = part.padEnd(width, " ");
14481
14481
  else if (flags3.includes("0") && /[diuoxXfFeEgG]/u.test(conversion) && (precision === void 0 || /[fFeEgG]/u.test(conversion))) {
14482
14482
  const prefix3 = /^(?:[+ -]|0[xX])/u.exec(part)?.[0] ?? "";
14483
14483
  part = prefix3 + part.slice(prefix3.length).padStart(Math.max(0, width - prefix3.length), "0");
14484
14484
  } else part = part.padStart(width, " ");
14485
- admit2(part.length);
14485
+ admit3(part.length);
14486
14486
  result2 += part;
14487
14487
  }
14488
14488
  return result2;
14489
14489
  }
14490
- function text(value2, format2 = "%.6g", budget) {
14490
+ function text(value2, format3 = "%.6g", budget) {
14491
14491
  if (value2.kind === "unset") return "";
14492
14492
  if (value2.kind !== "number") return value2.text;
14493
14493
  if (Number.isInteger(value2.number) && Math.abs(value2.number) < 1e21) {
@@ -14497,16 +14497,16 @@ function text(value2, format2 = "%.6g", budget) {
14497
14497
  budget?.step(result2.length);
14498
14498
  return result2;
14499
14499
  }
14500
- return formatted(format2, [value2], (argument2) => String(number(argument2)), budget);
14500
+ return formatted(format3, [value2], (argument2) => String(number(argument2)), budget);
14501
14501
  }
14502
- function compare3(left, right, format2, budget) {
14502
+ function compare3(left, right, format3, budget) {
14503
14503
  if (left.kind !== "string" && right.kind !== "string") {
14504
14504
  const first2 = number(left);
14505
14505
  const second2 = number(right);
14506
14506
  return first2 < second2 ? -1 : first2 > second2 ? 1 : 0;
14507
14507
  }
14508
- const first = text(left, format2, budget);
14509
- const second = text(right, format2, budget);
14508
+ const first = text(left, format3, budget);
14509
+ const second = text(right, format3, budget);
14510
14510
  return first < second ? -1 : first > second ? 1 : 0;
14511
14511
  }
14512
14512
 
@@ -14563,11 +14563,11 @@ var Lexer = class {
14563
14563
  this.offset += name2.length;
14564
14564
  return { kind: "name", text: name2, offset };
14565
14565
  }
14566
- const number5 = /^(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?/u.exec(rest)?.[0];
14567
- if (number5) {
14568
- if (!Number.isFinite(Number(number5))) throw new ProgramError("non-finite numeric literal");
14569
- this.offset += number5.length;
14570
- return { kind: "number", text: number5, offset };
14566
+ const number6 = /^(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?/u.exec(rest)?.[0];
14567
+ if (number6) {
14568
+ if (!Number.isFinite(Number(number6))) throw new ProgramError("non-finite numeric literal");
14569
+ this.offset += number6.length;
14570
+ return { kind: "number", text: number6, offset };
14571
14571
  }
14572
14572
  if (rest[0] === '"') {
14573
14573
  this.offset++;
@@ -16923,7 +16923,7 @@ async function diagnostic2(context2, error) {
16923
16923
  async function* lines2(source2, limits, state, binary3, nullData) {
16924
16924
  let pending = import_buffer.Buffer.alloc(0);
16925
16925
  let offset = 0;
16926
- let number5 = 0;
16926
+ let number6 = 0;
16927
16927
  const delimiter = nullData ? 0 : 10;
16928
16928
  for await (const data2 of readBytes(source2, limits.signal)) {
16929
16929
  await limits.tick();
@@ -16943,7 +16943,7 @@ async function* lines2(source2, limits, state, binary3, nullData) {
16943
16943
  const content = import_buffer.Buffer.concat([pending, chunk.subarray(start, end)]);
16944
16944
  const bytes3 = import_buffer.Buffer.concat([content, import_buffer.Buffer.from([delimiter])]);
16945
16945
  state.bytesSearched = offset + bytes3.length;
16946
- yield { content, bytes: bytes3, number: ++number5, offset };
16946
+ yield { content, bytes: bytes3, number: ++number6, offset };
16947
16947
  offset += bytes3.length;
16948
16948
  pending = import_buffer.Buffer.alloc(0);
16949
16949
  start = end + 1;
@@ -16953,7 +16953,7 @@ async function* lines2(source2, limits, state, binary3, nullData) {
16953
16953
  }
16954
16954
  if (pending.length) {
16955
16955
  state.bytesSearched = offset + pending.length;
16956
- yield { bytes: pending, content: pending, number: ++number5, offset };
16956
+ yield { bytes: pending, content: pending, number: ++number6, offset };
16957
16957
  }
16958
16958
  }
16959
16959
 
@@ -17499,7 +17499,7 @@ function createGrepCommands(executor) {
17499
17499
  const patterns2 = [];
17500
17500
  let patternCount = 0;
17501
17501
  let patternBytes = 0;
17502
- const admit2 = (chunk, atStart) => {
17502
+ const admit3 = (chunk, atStart) => {
17503
17503
  context2.signal.throwIfAborted();
17504
17504
  const size = typeof chunk === "string" ? import_buffer.Buffer.byteLength(chunk) : chunk.length;
17505
17505
  if (size > bufferLimit - patternBytes) throw new UsageError(`pattern byte limit exceeded (${bufferLimit} bytes)`);
@@ -17514,7 +17514,7 @@ function createGrepCommands(executor) {
17514
17514
  return atStart;
17515
17515
  };
17516
17516
  const addArgument = async (pattern) => {
17517
- admit2(pattern, true);
17517
+ admit3(pattern, true);
17518
17518
  if (pattern === "") {
17519
17519
  if (++patternCount > maxPatternCount) throw new UsageError(`pattern count limit exceeded (${maxPatternCount})`);
17520
17520
  patterns2.push("");
@@ -17525,7 +17525,7 @@ function createGrepCommands(executor) {
17525
17525
  async function* admitted(source2) {
17526
17526
  let atStart = true;
17527
17527
  for await (const chunk of source2) {
17528
- atStart = admit2(chunk, atStart);
17528
+ atStart = admit3(chunk, atStart);
17529
17529
  yield chunk;
17530
17530
  }
17531
17531
  }
@@ -17554,9 +17554,9 @@ function createGrepCommands(executor) {
17554
17554
  let failed = false;
17555
17555
  for (const name2 of names) {
17556
17556
  let count2 = 0;
17557
- let number5 = 0;
17557
+ let number6 = 0;
17558
17558
  const named2 = name2 === "-" ? "(standard input)" : name2;
17559
- const prefix3 = (lineNumber = false) => `${!parsed.flags.has("h") && (parsed.flags.has("H") || names.length > 1) ? `${named2}:` : ""}${lineNumber && parsed.flags.has("n") ? `${number5}:` : ""}`;
17559
+ const prefix3 = (lineNumber = false) => `${!parsed.flags.has("h") && (parsed.flags.has("H") || names.length > 1) ? `${named2}:` : ""}${lineNumber && parsed.flags.has("n") ? `${number6}:` : ""}`;
17560
17560
  try {
17561
17561
  const available2 = new AvailableRecords(parsed.flags.has("z") ? 0 : 10, bufferLimit);
17562
17562
  const source2 = name2 === "-" ? input(context2) : requiredFileInput(context2, grepRequirements, "file", name2, bufferLimit);
@@ -17565,7 +17565,7 @@ function createGrepCommands(executor) {
17565
17565
  for (let index = 0; index < batch.length; index++) {
17566
17566
  const line = batch[index];
17567
17567
  context2.signal.throwIfAborted();
17568
- number5++;
17568
+ number6++;
17569
17569
  const found = results[index];
17570
17570
  if (found.length > 0 === parsed.flags.has("v")) continue;
17571
17571
  count2++;
@@ -17625,9 +17625,9 @@ init_platform();
17625
17625
  // packages/safe-bash/src/commands/bytes/encoding/shared.ts
17626
17626
  init_platform();
17627
17627
  var blockSize = 8192;
17628
- function validatedOption(parsed, key, parse18, fallback) {
17628
+ function validatedOption(parsed, key, parse19, fallback) {
17629
17629
  let result2 = fallback;
17630
- for (const text3 of parsed.values.get(key) ?? []) result2 = parse18(text3);
17630
+ for (const text3 of parsed.values.get(key) ?? []) result2 = parse19(text3);
17631
17631
  return result2;
17632
17632
  }
17633
17633
  async function* sources(context2, operands, maxInputBytes) {
@@ -17769,7 +17769,7 @@ function decodeQuantum(quantum, alphabet) {
17769
17769
  }
17770
17770
  carry &= (1 << bits) - 1;
17771
17771
  }
17772
- return { bytes: decoded, valid: quantum.length === alphabet.quantum && alphabet.lengths.includes(length) && quantum.slice(length).every((number5) => number5 === -1) && carry === 0 };
17772
+ return { bytes: decoded, valid: quantum.length === alphabet.quantum && alphabet.lengths.includes(length) && quantum.slice(length).every((number6) => number6 === -1) && carry === 0 };
17773
17773
  }
17774
17774
  async function decode(context2, files, alphabet, ignore, maxInputBytes) {
17775
17775
  const lookup = new Int16Array(256).fill(-2);
@@ -17831,27 +17831,27 @@ function formats(text3) {
17831
17831
  if (!result2.length) throw new UsageError("empty output type");
17832
17832
  return result2;
17833
17833
  }
17834
- function formatRow(row, format2, bigEndian) {
17834
+ function formatRow(row, format3, bigEndian) {
17835
17835
  let text3 = "";
17836
17836
  const escapes = { 0: "\\0", 7: "\\a", 8: "\\b", 9: "\\t", 10: "\\n", 11: "\\v", 12: "\\f", 13: "\\r" };
17837
- for (let offset = 0; offset < row.length; offset += format2.size) {
17838
- if (format2.kind === "c") {
17837
+ for (let offset = 0; offset < row.length; offset += format3.size) {
17838
+ if (format3.kind === "c") {
17839
17839
  const byte = row[offset];
17840
17840
  const character = escapes[byte] ?? (byte >= 32 && byte <= 126 ? String.fromCharCode(byte) : byte.toString(8).padStart(3, "0"));
17841
17841
  text3 += ` ${character.padStart(3)}`;
17842
17842
  continue;
17843
17843
  }
17844
- let number5 = 0n;
17845
- for (let index = 0; index < format2.size; index++) {
17844
+ let number6 = 0n;
17845
+ for (let index = 0; index < format3.size; index++) {
17846
17846
  const byte = row[offset + index] ?? 0;
17847
- const shift = bigEndian ? format2.size - index - 1 : index;
17848
- number5 |= BigInt(byte) << BigInt(shift * 8);
17847
+ const shift = bigEndian ? format3.size - index - 1 : index;
17848
+ number6 |= BigInt(byte) << BigInt(shift * 8);
17849
17849
  }
17850
- const bits = format2.size * 8;
17851
- if (format2.kind === "d" && number5 >= 1n << BigInt(bits - 1)) number5 -= 1n << BigInt(bits);
17852
- const base = format2.kind === "o" ? 8 : format2.kind === "x" ? 16 : 10;
17853
- const width = format2.kind === "o" ? Math.ceil(bits / 3) : format2.kind === "x" ? bits / 4 : format2.kind === "d" ? (1n << BigInt(bits - 1)).toString().length + 1 : ((1n << BigInt(bits)) - 1n).toString().length;
17854
- text3 += ` ${number5.toString(base).padStart(width, base === 10 ? " " : "0")}`;
17850
+ const bits = format3.size * 8;
17851
+ if (format3.kind === "d" && number6 >= 1n << BigInt(bits - 1)) number6 -= 1n << BigInt(bits);
17852
+ const base = format3.kind === "o" ? 8 : format3.kind === "x" ? 16 : 10;
17853
+ const width = format3.kind === "o" ? Math.ceil(bits / 3) : format3.kind === "x" ? bits / 4 : format3.kind === "d" ? (1n << BigInt(bits - 1)).toString().length + 1 : ((1n << BigInt(bits)) - 1n).toString().length;
17854
+ text3 += ` ${number6.toString(base).padStart(width, base === 10 ? " " : "0")}`;
17855
17855
  }
17856
17856
  return text3;
17857
17857
  }
@@ -17904,9 +17904,9 @@ function createOdCommand(maxInputBytes) {
17904
17904
  const selected = (parsed.values.get("t") ?? ["o2"]).flatMap(formats);
17905
17905
  if (selected.length > 16) throw new UsageError("at most 16 output types are supported");
17906
17906
  const width = validatedOption(parsed, "w", (text3) => {
17907
- const number5 = numeric2(text3);
17908
- if (number5 < 1 || number5 > 4096 || selected.some((format2) => number5 % format2.size !== 0)) throw new UsageError("width must be 1..4096 and a multiple of each output type size");
17909
- return number5;
17907
+ const number6 = numeric2(text3);
17908
+ if (number6 < 1 || number6 > 4096 || selected.some((format3) => number6 % format3.size !== 0)) throw new UsageError("width must be 1..4096 and a multiple of each output type size");
17909
+ return number6;
17910
17910
  }, 16);
17911
17911
  const skip = validatedOption(parsed, "j", (text3) => numeric2(text3, true), 0);
17912
17912
  const count2 = validatedOption(parsed, "N", (text3) => numeric2(text3, true), Infinity);
@@ -18016,14 +18016,14 @@ function createXxdCommand(maxInputBytes) {
18016
18016
  const plain = parsed.flags.has("p");
18017
18017
  const reverse = parsed.flags.has("r");
18018
18018
  const columns = validatedOption(parsed, "c", (text3) => {
18019
- const number5 = numeric2(text3);
18020
- if (!plain && (number5 < 1 || number5 > 256) || plain && number5 > 4096) throw new UsageError("columns must be 1..256 (plain: 0..4096)");
18021
- return number5;
18019
+ const number6 = numeric2(text3);
18020
+ if (!plain && (number6 < 1 || number6 > 256) || plain && number6 > 4096) throw new UsageError("columns must be 1..256 (plain: 0..4096)");
18021
+ return number6;
18022
18022
  }, plain ? 30 : 16);
18023
18023
  const group = validatedOption(parsed, "g", (text3) => {
18024
- const number5 = numeric2(text3);
18025
- if (number5 > 256) throw new UsageError("group size must be 0..256");
18026
- return number5;
18024
+ const number6 = numeric2(text3);
18025
+ if (number6 > 256) throw new UsageError("group size must be 0..256");
18026
+ return number6;
18027
18027
  }, 2);
18028
18028
  const skip = validatedOption(parsed, "s", numeric2, 0);
18029
18029
  const count2 = validatedOption(parsed, "l", numeric2, Infinity);
@@ -22322,9 +22322,9 @@ async function* codec(input3, options3, signal) {
22322
22322
  if (!Number.isSafeInteger(requestedSize) || requestedSize <= 0) throw new RangeError("invalid codec chunk size");
22323
22323
  const chunkSize2 = Math.min(requestedSize, 64 * 1024);
22324
22324
  let output2 = new Uint8Array(chunkSize2);
22325
- const encoding = options3.mode === "gzip";
22325
+ const encoding = options3.mode === "gzip" || options3.mode === "deflate-raw";
22326
22326
  const stream = new ZStream();
22327
- const initialized = encoding ? deflateInit2(stream, options3.level ?? 6, 8, 31, 8, 0, true) : inflateInit2(stream, options3.mode === "inflate-raw" ? -15 : 31);
22327
+ const initialized = encoding ? deflateInit2(stream, options3.level ?? 6, 8, options3.mode === "deflate-raw" ? -15 : 31, 8, 0, true) : inflateInit2(stream, options3.mode === "inflate-raw" ? -15 : 31);
22328
22328
  if (initialized !== Z_OK) {
22329
22329
  if (encoding) deflateEnd(stream);
22330
22330
  else inflateEnd(stream);
@@ -23240,9 +23240,9 @@ async function contextSide(changes, start, end, kind, budget, append) {
23240
23240
  }
23241
23241
  }
23242
23242
  }
23243
- async function contextual(changes, format2, oldLabel, newLabel, context2, budget, append) {
23243
+ async function contextual(changes, format3, oldLabel, newLabel, context2, budget, append) {
23244
23244
  context2 = Math.min(context2, changes.length);
23245
- append(format2 === "unified" ? `--- ${oldLabel}
23245
+ append(format3 === "unified" ? `--- ${oldLabel}
23246
23246
  +++ ${newLabel}
23247
23247
  ` : `*** ${oldLabel}
23248
23248
  --- ${newLabel}
@@ -23288,7 +23288,7 @@ async function contextual(changes, format2, oldLabel, newLabel, context2, budget
23288
23288
  await budget.checkpoint();
23289
23289
  }
23290
23290
  budget.hunk();
23291
- if (format2 === "unified") {
23291
+ if (format3 === "unified") {
23292
23292
  append(`@@ -${unifiedRange(oldPosition, oldCount)} +${unifiedRange(newPosition, newCount)} @@
23293
23293
  `);
23294
23294
  for (let index = start; index < end; index++) {
@@ -23322,15 +23322,15 @@ function contextLength(value2) {
23322
23322
  function flags(args) {
23323
23323
  const result2 = { format: "normal", whitespace: "exact", context: 0, brief: false, recursive: false, newFile: false, labels: [], files: [] };
23324
23324
  let selectedFormat;
23325
- const selectFormat = (format2) => {
23326
- if (selectedFormat !== void 0 && selectedFormat !== format2) throw new ToolError("conflicting output format options");
23327
- selectedFormat = result2.format = format2;
23325
+ const selectFormat = (format3) => {
23326
+ if (selectedFormat !== void 0 && selectedFormat !== format3) throw new ToolError("conflicting output format options");
23327
+ selectedFormat = result2.format = format3;
23328
23328
  };
23329
23329
  let explicitContext = false;
23330
23330
  let legacyContext = -1;
23331
23331
  let previousDigit = false;
23332
- const selectContext = (format2, width, explicit) => {
23333
- selectFormat(format2);
23332
+ const selectContext = (format3, width, explicit) => {
23333
+ selectFormat(format3);
23334
23334
  result2.context = Math.max(result2.context, width);
23335
23335
  explicitContext ||= explicit;
23336
23336
  };
@@ -24085,7 +24085,7 @@ async function context(reader) {
24085
24085
  }
24086
24086
  return output2.join("");
24087
24087
  }
24088
- async function parsePatch(text3, budget, format2, target, progress) {
24088
+ async function parsePatch(text3, budget, format3, target, progress) {
24089
24089
  if (text3 && !text3.endsWith("\n")) throw new ToolError("patch is truncated: missing final LF");
24090
24090
  const reader = new Reader2(text3, budget);
24091
24091
  const patches = [];
@@ -24112,7 +24112,7 @@ async function parsePatch(text3, budget, format2, target, progress) {
24112
24112
  while (/^diff /u.test(reader.peek() ?? "")) await reader.take();
24113
24113
  const first = reader.peek() ?? "";
24114
24114
  const detected = first.startsWith("*** ") ? "context" : /^\d/u.test(first) ? "normal" : "unified";
24115
- if (format2 && detected !== format2) throw new ToolError(`patch format is ${detected}, not requested ${format2}`);
24115
+ if (format3 && detected !== format3) throw new ToolError(`patch format is ${detected}, not requested ${format3}`);
24116
24116
  if (detected === "unified") {
24117
24117
  reader.index = start;
24118
24118
  patches.push(...(await parseUnifiedSection(reader, budget)).map((patch) => ({ ...patch, ...indexPath === void 0 ? {} : { indexPath } })));
@@ -24208,8 +24208,8 @@ async function backupName(path, budget) {
24208
24208
  const version = entry.name.slice(prefix3.length, -1);
24209
24209
  if (version.length > 4096) throw new ToolError("backup version length limit exceeded");
24210
24210
  if (!/^[1-9]\d*$/u.test(version)) continue;
24211
- const number5 = BigInt(version);
24212
- if (number5 > maximum) maximum = number5;
24211
+ const number6 = BigInt(version);
24212
+ if (number6 > maximum) maximum = number6;
24213
24213
  }
24214
24214
  return maximum ? `${path}.~${maximum + 1n}~` : `${path}.orig`;
24215
24215
  }
@@ -24404,8 +24404,8 @@ ${context2 ? "---" : "+++"} ${names[1]}${times[1]}
24404
24404
  function flags2(args) {
24405
24405
  const result2 = { input: "-", reverse: false, dryRun: false, atomic: false, quiet: false, force: false, backup: true, fuzz: 2, ignoreWhitespace: false, removeEmpty: false };
24406
24406
  const operands = [];
24407
- const select = (format2) => {
24408
- result2.format = format2;
24407
+ const select = (format3) => {
24408
+ result2.format = format3;
24409
24409
  };
24410
24410
  let literal = false;
24411
24411
  for (let index = 0; index < args.length; index++) {
@@ -24918,7 +24918,7 @@ function createChmodCommand(configuration = {}) {
24918
24918
  init_platform();
24919
24919
  function parse9(args) {
24920
24920
  let follow = false;
24921
- let format2;
24921
+ let format3;
24922
24922
  let printf = false;
24923
24923
  let literal = false;
24924
24924
  const paths = [];
@@ -24929,14 +24929,14 @@ function parse9(args) {
24929
24929
  else if (argument2 === "--dereference") follow = true;
24930
24930
  else if (argument2 === "--format" || argument2.startsWith("--format=") || argument2 === "--printf" || argument2.startsWith("--printf=")) {
24931
24931
  printf = argument2.startsWith("--printf");
24932
- format2 = argument2.includes("=") ? argument2.slice(argument2.indexOf("=") + 1) : args[++index];
24933
- if (format2 === void 0) throw new UsageError(`missing format for '${argument2}'`);
24932
+ format3 = argument2.includes("=") ? argument2.slice(argument2.indexOf("=") + 1) : args[++index];
24933
+ if (format3 === void 0) throw new UsageError(`missing format for '${argument2}'`);
24934
24934
  } else if (!argument2.startsWith("--")) {
24935
24935
  for (let offset = 1; offset < argument2.length; offset++) {
24936
24936
  if (argument2[offset] === "L") follow = true;
24937
24937
  else if (argument2[offset] === "c") {
24938
- format2 = argument2.slice(offset + 1) || args[++index];
24939
- if (format2 === void 0) throw new UsageError("missing format for '-c'");
24938
+ format3 = argument2.slice(offset + 1) || args[++index];
24939
+ if (format3 === void 0) throw new UsageError("missing format for '-c'");
24940
24940
  printf = false;
24941
24941
  break;
24942
24942
  } else throw new UsageError(`unrecognized option '${argument2}'`);
@@ -24944,7 +24944,7 @@ function parse9(args) {
24944
24944
  } else throw new UsageError(`unrecognized option '${argument2}'`);
24945
24945
  }
24946
24946
  requireOperands(paths);
24947
- return { follow, format: format2, printf, paths };
24947
+ return { follow, format: format3, printf, paths };
24948
24948
  }
24949
24949
  function quoted(text3, style2) {
24950
24950
  if (style2 === "literal") return text3;
@@ -24977,9 +24977,9 @@ function timestamp2(milliseconds) {
24977
24977
  const nanoseconds = value2 < 0 ? -magnitude : magnitude;
24978
24978
  const remainder = (nanoseconds % 1000000000n + 1000000000n) % 1000000000n;
24979
24979
  const seconds = (nanoseconds - remainder) / 1000000000n;
24980
- const date = new Date(Number(seconds * 1000n));
24981
- if (Number.isNaN(date.getTime())) throw new FsError("EIO", { message: "invalid filesystem timestamp" });
24982
- return `${date.toISOString().replace("T", " ").replace(/\.\d{3}Z$/u, `.${remainder.toString().padStart(9, "0")}`)} +0000`;
24980
+ const date2 = new Date(Number(seconds * 1000n));
24981
+ if (Number.isNaN(date2.getTime())) throw new FsError("EIO", { message: "invalid filesystem timestamp" });
24982
+ return `${date2.toISOString().replace("T", " ").replace(/\.\d{3}Z$/u, `.${remainder.toString().padStart(9, "0")}`)} +0000`;
24983
24983
  }
24984
24984
  function epoch(milliseconds, precision) {
24985
24985
  if (precision > 3) throw new FsError("ENOTSUP", { message: "stat timestamps support at most millisecond precision" });
@@ -24990,21 +24990,21 @@ function epoch(milliseconds, precision) {
24990
24990
  const seconds = value2 < 0 && fraction === 0 ? -Math.floor(value2 / 1e3) : Math.floor(absolute2 / scale);
24991
24991
  return `${value2 < 0 ? "-" : ""}${seconds}${precision ? "." + fraction.toString().padStart(precision, "0") : ""}`;
24992
24992
  }
24993
- function directive(format2, start) {
24993
+ function directive(format3, start) {
24994
24994
  let index = start + 1;
24995
24995
  const flagsStart = index;
24996
- while (index < format2.length && "-+ #0".includes(format2[index])) index++;
24997
- const flags3 = format2.slice(flagsStart, index);
24996
+ while (index < format3.length && "-+ #0".includes(format3[index])) index++;
24997
+ const flags3 = format3.slice(flagsStart, index);
24998
24998
  const widthStart = index;
24999
- while (index < format2.length && format2[index] >= "0" && format2[index] <= "9") index++;
25000
- const width = format2.slice(widthStart, index);
24999
+ while (index < format3.length && format3[index] >= "0" && format3[index] <= "9") index++;
25000
+ const width = format3.slice(widthStart, index);
25001
25001
  let precision;
25002
- if (format2[index] === ".") {
25002
+ if (format3[index] === ".") {
25003
25003
  const precisionStart = ++index;
25004
- while (index < format2.length && format2[index] >= "0" && format2[index] <= "9") index++;
25005
- precision = format2.slice(precisionStart, index);
25004
+ while (index < format3.length && format3[index] >= "0" && format3[index] <= "9") index++;
25005
+ precision = format3.slice(precisionStart, index);
25006
25006
  }
25007
- const code = format2[index];
25007
+ const code = format3[index];
25008
25008
  if (code === void 0) throw new UsageError("invalid stat format directive");
25009
25009
  const codePoint = code.charCodeAt(0);
25010
25010
  if (code !== "%" && !(codePoint >= 65 && codePoint <= 90) && !(codePoint >= 97 && codePoint <= 122)) {
@@ -25036,7 +25036,7 @@ function formatField(text3, code, flags3, width, precision, numeric4, epoch2) {
25036
25036
  }
25037
25037
  return import_buffer.Buffer.concat([import_buffer.Buffer.alloc(padding, 32), bytes3]);
25038
25038
  }
25039
- async function render(context2, path, name2, stat, format2, escapes, limit) {
25039
+ async function render(context2, path, name2, stat, format3, escapes, limit) {
25040
25040
  const chunks = [];
25041
25041
  let bytes3 = 0;
25042
25042
  const append = (text3) => {
@@ -25045,11 +25045,11 @@ async function render(context2, path, name2, stat, format2, escapes, limit) {
25045
25045
  if (bytes3 > limit) throw new FsError("EFBIG", { message: "stat format output limit exceeded" });
25046
25046
  chunks.push(chunk);
25047
25047
  };
25048
- for (let index = 0; index < format2.length; ) {
25048
+ for (let index = 0; index < format3.length; ) {
25049
25049
  context2.signal.throwIfAborted();
25050
- if (escapes && format2[index] === "\\") {
25050
+ if (escapes && format3[index] === "\\") {
25051
25051
  const named2 = { a: "\x07", b: "\b", e: "\x1B", f: "\f", n: "\n", r: "\r", t: " ", v: "\v", "\\": "\\" };
25052
- const code2 = format2[index + 1] ?? "";
25052
+ const code2 = format3[index + 1] ?? "";
25053
25053
  if (Object.hasOwn(named2, code2)) {
25054
25054
  append(named2[code2]);
25055
25055
  index += 2;
@@ -25057,30 +25057,30 @@ async function render(context2, path, name2, stat, format2, escapes, limit) {
25057
25057
  }
25058
25058
  const radix = code2 === "x" ? 16 : 8;
25059
25059
  const start = index + (radix === 16 ? 2 : 1);
25060
- const end = Math.min(format2.length, start + (radix === 16 ? 2 : 3));
25060
+ const end = Math.min(format3.length, start + (radix === 16 ? 2 : 3));
25061
25061
  let offset = start;
25062
25062
  let value2 = 0;
25063
25063
  while (offset < end) {
25064
- const digit3 = "0123456789abcdef".indexOf(format2[offset].toLowerCase());
25064
+ const digit3 = "0123456789abcdef".indexOf(format3[offset].toLowerCase());
25065
25065
  if (digit3 < 0 || digit3 >= radix) break;
25066
25066
  value2 = value2 * radix + digit3;
25067
25067
  offset++;
25068
25068
  }
25069
25069
  if (offset === start) {
25070
- append(format2[index++]);
25070
+ append(format3[index++]);
25071
25071
  continue;
25072
25072
  }
25073
25073
  append(Uint8Array.of(value2));
25074
25074
  index = offset;
25075
25075
  continue;
25076
25076
  }
25077
- if (format2[index] !== "%") {
25078
- const point = String.fromCodePoint(format2.codePointAt(index));
25077
+ if (format3[index] !== "%") {
25078
+ const point = String.fromCodePoint(format3.codePointAt(index));
25079
25079
  append(point);
25080
25080
  index += point.length;
25081
25081
  continue;
25082
25082
  }
25083
- const parsed = directive(format2, index);
25083
+ const parsed = directive(format3, index);
25084
25084
  index += parsed.length;
25085
25085
  const { code, flags: flags3 } = parsed;
25086
25086
  const width = Number(parsed.width || 0);
@@ -25136,8 +25136,8 @@ function createStatCommand(configuration = {}) {
25136
25136
  try {
25137
25137
  const path = pathOf(context2, name2);
25138
25138
  const stat = await context2.fs[parsed.follow ? "stat" : "lstat"](path, { signal: context2.signal });
25139
- const format2 = parsed.format ?? " File: %N\n Size: %s Type: %F\n Mode: %a (%A)\nAccess: %x\nModify: %y\nChange: %z\n Birth: %w";
25140
- const text3 = await render(context2, path, name2, stat, format2, parsed.printf, configured.limits.maxOutputBytes);
25139
+ const format3 = parsed.format ?? " File: %N\n Size: %s Type: %F\n Mode: %a (%A)\nAccess: %x\nModify: %y\nChange: %z\n Birth: %w";
25140
+ const text3 = await render(context2, path, name2, stat, format3, parsed.printf, configured.limits.maxOutputBytes);
25141
25141
  await budget.output(parsed.printf ? text3 : import_buffer.Buffer.concat([text3, Uint8Array.of(10)]));
25142
25142
  } catch (error) {
25143
25143
  context2.signal.throwIfAborted();
@@ -26896,12 +26896,12 @@ function truncateCommand(options3 = {}) {
26896
26896
  }
26897
26897
  }
26898
26898
  outputBytes += length;
26899
- const encoder4 = new TextEncoder();
26899
+ const encoder5 = new TextEncoder();
26900
26900
  for (let offset = 0; offset < text3.length; ) {
26901
26901
  let end = Math.min(text3.length, offset + (utf82 ? 16384 : 65536));
26902
26902
  if (utf82 && end < text3.length && text3.charCodeAt(end - 1) >= 55296 && text3.charCodeAt(end - 1) <= 56319) end--;
26903
26903
  const chunk = text3.slice(offset, end);
26904
- await writeBytes(error ? stderr.output : stdout.output, utf82 ? encoder4.encode(chunk) : Uint8Array.from(chunk, (character) => character.charCodeAt(0)), signal);
26904
+ await writeBytes(error ? stderr.output : stdout.output, utf82 ? encoder5.encode(chunk) : Uint8Array.from(chunk, (character) => character.charCodeAt(0)), signal);
26905
26905
  offset = end;
26906
26906
  }
26907
26907
  };
@@ -27476,7 +27476,7 @@ async function parseOptions2(context2, limits) {
27476
27476
  let gzip = false;
27477
27477
  let verbose2 = false;
27478
27478
  let strip = 0;
27479
- let format2 = "pax";
27479
+ let format3 = "pax";
27480
27480
  let cwd = context2.cwd;
27481
27481
  let nullFiles = false;
27482
27482
  let verbatim = false;
@@ -27545,7 +27545,7 @@ async function parseOptions2(context2, limits) {
27545
27545
  strip = Number(value2);
27546
27546
  } else if (flag === "format") {
27547
27547
  if (value2 !== "ustar" && value2 !== "pax" && value2 !== "posix") fail2(`unsupported archive format: ${value2}`);
27548
- format2 = value2 === "ustar" ? "ustar" : "pax";
27548
+ format3 = value2 === "ustar" ? "ustar" : "pax";
27549
27549
  } else if (flag === "null") {
27550
27550
  nullFiles = true;
27551
27551
  verbatim = true;
@@ -27593,7 +27593,7 @@ async function parseOptions2(context2, limits) {
27593
27593
  if (mode === "c" && lateExclude) fail2("--exclude after source operands is unsupported; place exclusions before operands");
27594
27594
  if (mode === "c" && !operands.length && !filesFrom) fail2("refusing to create an empty archive without -T");
27595
27595
  if (archive !== "-") checkPath(archive, limits);
27596
- return { mode, archive, gzip, verbose: verbose2, strip, format: format2, cwd, operands, excludes };
27596
+ return { mode, archive, gzip, verbose: verbose2, strip, format: format3, cwd, operands, excludes };
27597
27597
  }
27598
27598
  function tokenize(pattern) {
27599
27599
  const characters = Array.from(pattern);
@@ -28176,6 +28176,1545 @@ async function readArchive(context2, source2, options3, budget) {
28176
28176
  }
28177
28177
  }
28178
28178
 
28179
+ // packages/safe-bash/src/commands/archive/zip.ts
28180
+ init_platform();
28181
+
28182
+ // packages/safe-bash/src/commands/archive/zip-format.ts
28183
+ init_platform();
28184
+ var encoder2 = new TextEncoder();
28185
+ var cp437 = "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0";
28186
+ var crcTable4 = Uint32Array.from({ length: 256 }, (_, index) => {
28187
+ let value2 = index;
28188
+ for (let bit = 0; bit < 8; bit++) value2 = value2 >>> 1 ^ (value2 & 1 ? 3988292384 : 0);
28189
+ return value2 >>> 0;
28190
+ });
28191
+ function crc322(bytes3, previous = 0) {
28192
+ let value2 = previous ^ 4294967295;
28193
+ for (const byte of bytes3) value2 = value2 >>> 8 ^ crcTable4[(value2 ^ byte) & 255];
28194
+ return (value2 ^ 4294967295) >>> 0;
28195
+ }
28196
+ function number3(value2, maximum, label) {
28197
+ if (!Number.isSafeInteger(value2) || value2 < 0 || value2 > maximum) fail2(`ZIP ${label} limit exceeded or invalid value`);
28198
+ }
28199
+ function admit2(limits, signal) {
28200
+ signal.throwIfAborted();
28201
+ for (const key of ["maxArchiveBytes", "maxEntryBytes", "maxTotalBytes", "maxMembers", "maxPathBytes", "maxDepth", "maxPaxBytes", "maxTextBytes", "chunkSize"]) {
28202
+ number3(limits[key], Number.MAX_SAFE_INTEGER, key);
28203
+ }
28204
+ if (limits.chunkSize < 512 || limits.chunkSize > 1024 * 1024) fail2("ZIP chunk size must be between 512 and 1048576");
28205
+ return Math.min(limits.chunkSize, 64 * 1024);
28206
+ }
28207
+ function pathBytes(name2, limits) {
28208
+ if (name2.length > Math.min(limits.maxPathBytes, 65535)) fail2("ZIP path byte limit exceeded");
28209
+ const bytes3 = encoder2.encode(name2);
28210
+ if (!name2 || text2(bytes3) !== name2 || name2.includes("\0")) fail2("ZIP invalid or unsafe path");
28211
+ number3(bytes3.length, Math.min(limits.maxPathBytes, 65535), "path byte");
28212
+ const parts = name2.split("/");
28213
+ if (parts.at(-1) === "") parts.pop();
28214
+ if (parts.some((part) => !part || part === "." || part === "..")) fail2("ZIP unsafe traversal or absolute path");
28215
+ number3(parts.length, limits.maxDepth, "path depth");
28216
+ return bytes3;
28217
+ }
28218
+ function equal(first, second) {
28219
+ return first.length === second.length && first.every((byte, index) => byte === second[index]);
28220
+ }
28221
+ function legacyName(bytes3) {
28222
+ let name2 = "";
28223
+ for (const byte of bytes3) name2 += byte < 128 ? String.fromCharCode(byte) : cp437[byte - 128];
28224
+ return name2;
28225
+ }
28226
+ function extras(bytes3, rawName, comment2, central, limits) {
28227
+ number3(bytes3.length, Math.min(limits.maxPaxBytes, 65535), "extra field");
28228
+ const result2 = {};
28229
+ const view = new DataView(bytes3.buffer, bytes3.byteOffset, bytes3.byteLength);
28230
+ const seen = /* @__PURE__ */ new Set();
28231
+ let offset = 0;
28232
+ while (offset < bytes3.length) {
28233
+ if (offset + 4 > bytes3.length) fail2("ZIP truncated extra field");
28234
+ const identifier = view.getUint16(offset, true);
28235
+ const length = view.getUint16(offset + 2, true);
28236
+ offset += 4;
28237
+ if (offset + length > bytes3.length) fail2("ZIP truncated extra field payload");
28238
+ if (seen.has(identifier)) fail2("ZIP duplicate extra field");
28239
+ seen.add(identifier);
28240
+ if (identifier === 1) fail2("ZIP64 is unsupported");
28241
+ if (identifier === 39169 || identifier === 23 || identifier === 24 || identifier === 25) fail2("ZIP encryption is unsupported");
28242
+ if (identifier === 28789 || identifier === 25461) {
28243
+ if (length < 5 || bytes3[offset] !== 1) fail2("ZIP unsupported or truncated Unicode extra field");
28244
+ const original = identifier === 28789 ? rawName : comment2;
28245
+ if (view.getUint32(offset + 1, true) !== crc322(original)) fail2("ZIP Unicode extra field CRC mismatch");
28246
+ const decoded = text2(bytes3.subarray(offset + 5, offset + length));
28247
+ if (identifier === 28789) {
28248
+ pathBytes(decoded, limits);
28249
+ result2.name = decoded;
28250
+ } else number3(length - 5, limits.maxTextBytes, "Unicode comment");
28251
+ }
28252
+ if (identifier === 21589) {
28253
+ if (!length) fail2("ZIP truncated timestamp extra field");
28254
+ const flags3 = bytes3[offset];
28255
+ if (flags3 & ~7) fail2("ZIP unsupported timestamp flags");
28256
+ const count2 = (flags3 & 1) + (central ? 0 : (flags3 >>> 1 & 1) + (flags3 >>> 2 & 1));
28257
+ if (length !== 1 + count2 * 4) fail2("ZIP truncated or inconsistent timestamp extra field");
28258
+ if (flags3 & 1) result2.modified = view.getInt32(offset + 1, true) * 1e3;
28259
+ }
28260
+ offset += length;
28261
+ }
28262
+ return result2;
28263
+ }
28264
+ function nameFrom(rawName, flags3, metadata3, limits) {
28265
+ number3(rawName.length, Math.min(limits.maxPathBytes, 65535), "raw path byte");
28266
+ const raw = flags3 & 2048 ? text2(rawName) : legacyName(rawName);
28267
+ pathBytes(raw, limits);
28268
+ if (flags3 & 2048 && metadata3.name !== void 0 && metadata3.name !== raw) fail2("ZIP conflicting UTF-8 and Unicode extra names");
28269
+ return metadata3.name ?? raw;
28270
+ }
28271
+ function format(method, flags3, version) {
28272
+ number3(flags3, 65535, "general purpose flags");
28273
+ if (flags3 & (1 | 64 | 8192)) fail2("ZIP encryption is unsupported");
28274
+ if (flags3 & ~2062 || method === 0 && flags3 & 6) fail2("ZIP unsupported general purpose flags");
28275
+ if (method !== 0 && method !== 8) fail2("ZIP unsupported compression method");
28276
+ if (version < (method === 8 || flags3 & 8 ? 20 : 10) || version > 20) fail2("ZIP unsupported extraction version (including ZIP64)");
28277
+ }
28278
+ function dosModified(date2, time) {
28279
+ if (!date2 && !time) return new Date(1980, 0, 1);
28280
+ const year = 1980 + (date2 >>> 9);
28281
+ const month = (date2 >>> 5 & 15) - 1;
28282
+ const day = date2 & 31;
28283
+ const hours = time >>> 11;
28284
+ const minutes = time >>> 5 & 63;
28285
+ const seconds = (time & 31) * 2;
28286
+ const result2 = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
28287
+ if (result2.getUTCFullYear() !== year || result2.getUTCMonth() !== month || result2.getUTCDate() !== day || hours > 23 || minutes > 59 || seconds > 59) fail2("ZIP invalid DOS timestamp");
28288
+ return new Date(year, month, day, hours, minutes, seconds);
28289
+ }
28290
+ function entryBounds(entry, limits) {
28291
+ pathBytes(entry.name, limits);
28292
+ number3(entry.size, Math.min(limits.maxEntryBytes, limits.maxTotalBytes, 4294967294), "entry byte");
28293
+ number3(entry.data.length, Math.min(limits.maxArchiveBytes, 4294967294), "compressed byte");
28294
+ number3(entry.crc32, 4294967295, "CRC32");
28295
+ number3(entry.mode, 65535, "mode");
28296
+ format(entry.method, entry.flags ?? 2048, entry.method === 8 || (entry.flags ?? 0) & 8 ? 20 : 10);
28297
+ if (entry.directory !== entry.name.endsWith("/") || entry.directory && (entry.symlink || entry.size !== 0)) fail2("ZIP inconsistent directory metadata");
28298
+ const type = entry.mode & 61440;
28299
+ if (type !== 0 && type !== (entry.directory ? 16384 : entry.symlink ? 40960 : 32768)) fail2("ZIP unsupported or conflicting file type");
28300
+ if (!Number.isFinite(entry.modified.getTime())) fail2("ZIP invalid modification time");
28301
+ }
28302
+ async function copyBytes(source2, destination2, start, chunkSize2, signal) {
28303
+ for (let offset = 0; offset < source2.length; offset += chunkSize2) {
28304
+ signal.throwIfAborted();
28305
+ destination2.set(source2.subarray(offset, offset + chunkSize2), start + offset);
28306
+ if (offset + chunkSize2 < source2.length) await yieldTurn(signal);
28307
+ }
28308
+ }
28309
+ async function readZipArchive(bytes3, limits, signal) {
28310
+ const chunkSize2 = admit2(limits, signal);
28311
+ number3(bytes3.length, Math.min(limits.maxArchiveBytes, 4294967294), "archive byte");
28312
+ const view = new DataView(bytes3.buffer, bytes3.byteOffset, bytes3.byteLength);
28313
+ let end = -1;
28314
+ const lower = Math.max(0, bytes3.length - 22 - 65535);
28315
+ for (let offset2 = bytes3.length - 22; offset2 >= lower; offset2--) {
28316
+ if ((bytes3.length - offset2) % 4096 === 0) await yieldTurn(signal);
28317
+ if (view.getUint32(offset2, true) === 101010256 && offset2 + 22 + view.getUint16(offset2 + 20, true) === bytes3.length) {
28318
+ const size = view.getUint32(offset2 + 12, true);
28319
+ const start = view.getUint32(offset2 + 16, true);
28320
+ const zip64 = size === 4294967295 || start === 4294967295 || view.getUint16(offset2 + 10, true) === 65535 || offset2 >= 20 && view.getUint32(offset2 - 20, true) === 117853008;
28321
+ if (!zip64 && start + size !== offset2) continue;
28322
+ if (end !== -1) fail2("ZIP ambiguous end records");
28323
+ end = offset2;
28324
+ }
28325
+ }
28326
+ if (end === -1) fail2("ZIP truncated or missing end of central directory");
28327
+ const members = view.getUint16(end + 10, true);
28328
+ const centralSize = view.getUint32(end + 12, true);
28329
+ const centralStart = view.getUint32(end + 16, true);
28330
+ if (members === 65535 || centralSize === 4294967295 || centralStart === 4294967295) fail2("ZIP64 is unsupported");
28331
+ if (view.getUint16(end + 4, true) || view.getUint16(end + 6, true) || view.getUint16(end + 8, true) !== members) fail2("ZIP multi-disk or inconsistent member count is unsupported");
28332
+ if (centralStart + centralSize !== end) fail2("ZIP invalid central directory span or unsupported ZIP64/trailing records");
28333
+ number3(members, limits.maxMembers, "member");
28334
+ number3(bytes3.length - end - 22, limits.maxTextBytes, "archive comment");
28335
+ const entries2 = [];
28336
+ const spans = [];
28337
+ let offset = centralStart;
28338
+ let total = 0;
28339
+ for (let index = 0; index < members; index++) {
28340
+ await yieldTurn(signal);
28341
+ if (offset + 46 > end || view.getUint32(offset, true) !== 33639248) fail2("ZIP truncated or invalid central header");
28342
+ const versionMadeBy = view.getUint16(offset + 4, true);
28343
+ const version = view.getUint16(offset + 6, true);
28344
+ const flags3 = view.getUint16(offset + 8, true);
28345
+ const method = view.getUint16(offset + 10, true);
28346
+ format(method, flags3, version);
28347
+ const dosTime = view.getUint16(offset + 12, true);
28348
+ const dosDate = view.getUint16(offset + 14, true);
28349
+ const checksum = view.getUint32(offset + 16, true);
28350
+ const compressedSize = view.getUint32(offset + 20, true);
28351
+ const size = view.getUint32(offset + 24, true);
28352
+ const nameLength = view.getUint16(offset + 28, true);
28353
+ const extraLength = view.getUint16(offset + 30, true);
28354
+ const commentLength = view.getUint16(offset + 32, true);
28355
+ const internalAttributes = view.getUint16(offset + 36, true);
28356
+ if (internalAttributes & ~1) fail2("ZIP unsupported internal attributes");
28357
+ const externalAttributes = view.getUint32(offset + 38, true);
28358
+ const local = view.getUint32(offset + 42, true);
28359
+ if (view.getUint16(offset + 34, true)) fail2("ZIP multi-disk member is unsupported");
28360
+ if (compressedSize === 4294967295 || size === 4294967295 || local === 4294967295) fail2("ZIP64 is unsupported");
28361
+ number3(size, limits.maxEntryBytes, "entry byte");
28362
+ if (method === 0 && compressedSize !== size) fail2("ZIP stored size mismatch");
28363
+ total += size;
28364
+ number3(total, limits.maxTotalBytes, "total byte");
28365
+ const next = offset + 46 + nameLength + extraLength + commentLength;
28366
+ if (next > end) fail2("ZIP truncated central metadata");
28367
+ number3(commentLength, limits.maxTextBytes, "entry comment");
28368
+ const rawName = bytes3.subarray(offset + 46, offset + 46 + nameLength);
28369
+ const centralExtra = bytes3.subarray(offset + 46 + nameLength, next - commentLength);
28370
+ const comment2 = bytes3.subarray(next - commentLength, next);
28371
+ if (flags3 & 2048) text2(comment2);
28372
+ const centralMetadata = extras(centralExtra, rawName, comment2, true, limits);
28373
+ const name2 = nameFrom(rawName, flags3, centralMetadata, limits);
28374
+ if (local + 30 > centralStart || view.getUint32(local, true) !== 67324752) fail2("ZIP invalid local header span");
28375
+ if (view.getUint16(local + 4, true) !== version || view.getUint16(local + 6, true) !== flags3 || view.getUint16(local + 8, true) !== method || view.getUint16(local + 10, true) !== dosTime || view.getUint16(local + 12, true) !== dosDate) fail2("ZIP central/local metadata mismatch");
28376
+ const localNameLength = view.getUint16(local + 26, true);
28377
+ const localExtraLength = view.getUint16(local + 28, true);
28378
+ const payloadStart = local + 30 + localNameLength + localExtraLength;
28379
+ let payloadEnd = payloadStart + compressedSize;
28380
+ if (payloadEnd > centralStart) fail2("ZIP truncated or overlapping local payload");
28381
+ const localName = bytes3.subarray(local + 30, local + 30 + localNameLength);
28382
+ if (!equal(rawName, localName)) fail2("ZIP central/local filename mismatch");
28383
+ const localExtra = bytes3.subarray(local + 30 + localNameLength, payloadStart);
28384
+ const localMetadata = extras(localExtra, localName, comment2, false, limits);
28385
+ const localEffective = nameFrom(localName, flags3, localMetadata, limits);
28386
+ if (localMetadata.name !== void 0 && localEffective !== name2) fail2("ZIP central/local Unicode name mismatch");
28387
+ if (centralMetadata.modified !== void 0 && localMetadata.modified !== void 0 && centralMetadata.modified !== localMetadata.modified) fail2("ZIP central/local timestamp mismatch");
28388
+ for (const [position, expected] of [[14, checksum], [18, compressedSize], [22, size]]) {
28389
+ const actual = view.getUint32(local + position, true);
28390
+ if (actual !== expected && (!(flags3 & 8) || actual !== 0)) fail2("ZIP central/local size or CRC mismatch");
28391
+ }
28392
+ if (flags3 & 8) {
28393
+ const matches3 = [];
28394
+ for (const signed2 of [false, true]) {
28395
+ const descriptor2 = payloadEnd + (signed2 ? 4 : 0);
28396
+ if (descriptor2 + 12 <= centralStart && (!signed2 || view.getUint32(payloadEnd, true) === 134695760) && view.getUint32(descriptor2, true) === checksum && view.getUint32(descriptor2 + 4, true) === compressedSize && view.getUint32(descriptor2 + 8, true) === size) matches3.push(descriptor2 + 12);
28397
+ }
28398
+ if (matches3.length !== 1) fail2("ZIP truncated, ambiguous or mismatched data descriptor");
28399
+ payloadEnd = matches3[0];
28400
+ }
28401
+ const host2 = versionMadeBy >>> 8;
28402
+ const unixMode = host2 === 3 || host2 === 19 ? externalAttributes >>> 16 : 0;
28403
+ const directory2 = name2.endsWith("/");
28404
+ if (Boolean(externalAttributes & 16) && !directory2) fail2("ZIP conflicting directory attributes");
28405
+ const mode = unixMode || (directory2 ? 16877 : 33188);
28406
+ const symlink = (mode & 61440) === 40960;
28407
+ const modified = dosModified(dosDate, dosTime);
28408
+ const timestamp3 = centralMetadata.modified ?? localMetadata.modified;
28409
+ if (timestamp3 !== void 0) modified.setTime(timestamp3);
28410
+ const entry = { name: name2, data: bytes3.subarray(payloadStart, payloadStart + compressedSize), size, method, crc32: checksum, modified, mode, directory: directory2, symlink, rawName, localName, comment: comment2, localExtra, centralExtra, flags: flags3, versionMadeBy, internalAttributes, externalAttributes, dosTime, dosDate };
28411
+ entryBounds(entry, limits);
28412
+ entries2.push(entry);
28413
+ spans.push({ start: local, end: payloadEnd });
28414
+ offset = next;
28415
+ }
28416
+ if (offset !== end) fail2("ZIP central directory size or member count mismatch");
28417
+ spans.sort((first, second) => first.start - second.start);
28418
+ let covered = 0;
28419
+ for (const span of spans) {
28420
+ if (span.start !== covered) fail2("ZIP overlapping spans, gaps or self-extracting prefix are unsupported");
28421
+ covered = span.end;
28422
+ }
28423
+ if (covered !== centralStart) fail2("ZIP unreferenced local data is unsupported");
28424
+ for (const entry of entries2) {
28425
+ const data2 = new Uint8Array(entry.data.length);
28426
+ await copyBytes(entry.data, data2, 0, chunkSize2, signal);
28427
+ entry.data = data2;
28428
+ entry.rawName = new Uint8Array(entry.rawName);
28429
+ entry.localName = new Uint8Array(entry.localName);
28430
+ entry.comment = new Uint8Array(entry.comment);
28431
+ entry.localExtra = new Uint8Array(entry.localExtra);
28432
+ entry.centralExtra = new Uint8Array(entry.centralExtra);
28433
+ await yieldTurn(signal);
28434
+ }
28435
+ return { entries: entries2, comment: new Uint8Array(bytes3.subarray(end + 22)) };
28436
+ }
28437
+ async function* decodeZipEntry(entry, limits, signal) {
28438
+ const chunkSize2 = admit2(limits, signal);
28439
+ entryBounds(entry, limits);
28440
+ const reader = new CodecReader((async function* () {
28441
+ yield entry.data;
28442
+ })(), signal);
28443
+ let length = 0;
28444
+ let checksum = 0;
28445
+ const source2 = entry.method === 8 ? codec(reader, { mode: "inflate-raw", chunkSize: chunkSize2 }, signal) : (async function* () {
28446
+ for (let offset = 0; offset < entry.data.length; offset += chunkSize2) {
28447
+ yield new Uint8Array(entry.data.subarray(offset, offset + chunkSize2));
28448
+ await yieldTurn(signal);
28449
+ }
28450
+ })();
28451
+ try {
28452
+ for await (const chunk of source2) {
28453
+ signal.throwIfAborted();
28454
+ length += chunk.length;
28455
+ number3(length, Math.min(limits.maxEntryBytes, limits.maxTotalBytes), "decoded byte");
28456
+ checksum = crc322(chunk, checksum);
28457
+ yield chunk;
28458
+ }
28459
+ if (entry.method === 8 && await reader.chunk() !== void 0) fail2("ZIP trailing compressed data");
28460
+ if (length !== entry.size) fail2("ZIP uncompressed size mismatch");
28461
+ if (checksum !== entry.crc32) fail2("ZIP CRC32 mismatch");
28462
+ } finally {
28463
+ await reader.close();
28464
+ }
28465
+ }
28466
+ async function makeZipEntry(name2, bytes3, attributes, limits, signal) {
28467
+ const chunkSize2 = admit2(limits, signal);
28468
+ const entry = { name: name2, data: bytes3, size: bytes3.length, method: 0, crc32: 0, ...attributes, modified: new Date(attributes.modified.getTime()) };
28469
+ entryBounds(entry, limits);
28470
+ for (let offset = 0; offset < bytes3.length; offset += chunkSize2) {
28471
+ entry.crc32 = crc322(bytes3.subarray(offset, offset + chunkSize2), entry.crc32);
28472
+ await yieldTurn(signal);
28473
+ }
28474
+ const reader = new CodecReader((async function* () {
28475
+ yield bytes3;
28476
+ })(), signal);
28477
+ try {
28478
+ if (bytes3.length && !entry.directory && !entry.symlink) {
28479
+ const chunks = [];
28480
+ let length = 0;
28481
+ for await (const chunk of codec(reader, { mode: "deflate-raw", chunkSize: chunkSize2 }, signal)) {
28482
+ length += chunk.length;
28483
+ if (length >= bytes3.length) break;
28484
+ chunks.push(new Uint8Array(chunk));
28485
+ }
28486
+ if (length < bytes3.length) {
28487
+ entry.data = new Uint8Array(length);
28488
+ let offset = 0;
28489
+ for (const chunk of chunks) {
28490
+ entry.data.set(chunk, offset);
28491
+ offset += chunk.length;
28492
+ await yieldTurn(signal);
28493
+ }
28494
+ entry.method = 8;
28495
+ return entry;
28496
+ }
28497
+ }
28498
+ entry.data = new Uint8Array(bytes3.length);
28499
+ await copyBytes(bytes3, entry.data, 0, chunkSize2, signal);
28500
+ return entry;
28501
+ } finally {
28502
+ await reader.close();
28503
+ }
28504
+ }
28505
+ function timestampExtra(modified) {
28506
+ const seconds = Math.floor(modified.getTime() / 1e3);
28507
+ if (seconds < -2147483648 || seconds > 2147483647) return new Uint8Array();
28508
+ const bytes3 = new Uint8Array(9);
28509
+ const view = new DataView(bytes3.buffer);
28510
+ view.setUint16(0, 21589, true);
28511
+ view.setUint16(2, 5, true);
28512
+ bytes3[4] = 1;
28513
+ view.setInt32(5, seconds, true);
28514
+ return bytes3;
28515
+ }
28516
+ async function writeZipArchive(archive, limits, signal) {
28517
+ const chunkSize2 = admit2(limits, signal);
28518
+ number3(archive.entries.length, Math.min(limits.maxMembers, 65534), "member");
28519
+ number3(archive.comment.length, Math.min(limits.maxTextBytes, 65535), "archive comment");
28520
+ let length = 22 + archive.comment.length;
28521
+ let localLength = 0;
28522
+ let total = 0;
28523
+ const encoded2 = [];
28524
+ for (const entry of archive.entries) {
28525
+ await yieldTurn(signal);
28526
+ entryBounds(entry, limits);
28527
+ if (entry.method === 0 && entry.data.length !== entry.size) fail2("ZIP stored size mismatch");
28528
+ total += entry.size;
28529
+ number3(total, limits.maxTotalBytes, "total byte");
28530
+ const rawName = entry.rawName ?? pathBytes(entry.name, limits);
28531
+ const flags3 = (entry.flags ?? 2048) & ~8;
28532
+ const comment2 = entry.comment ?? new Uint8Array();
28533
+ number3(comment2.length, Math.min(limits.maxTextBytes, 65535), "entry comment");
28534
+ if (flags3 & 2048) text2(comment2);
28535
+ const localExtra = entry.localExtra ?? timestampExtra(entry.modified);
28536
+ const centralExtra = entry.centralExtra ?? timestampExtra(entry.modified);
28537
+ const localMetadata = extras(localExtra, rawName, comment2, false, limits);
28538
+ const centralMetadata = extras(centralExtra, rawName, comment2, true, limits);
28539
+ if (nameFrom(rawName, flags3, centralMetadata, limits) !== entry.name || localMetadata.name !== void 0 && nameFrom(rawName, flags3, localMetadata, limits) !== entry.name || entry.localName && !equal(rawName, entry.localName)) fail2("ZIP retained filename metadata mismatch");
28540
+ if (localMetadata.modified !== void 0 && centralMetadata.modified !== void 0 && localMetadata.modified !== centralMetadata.modified) fail2("ZIP retained timestamp metadata mismatch");
28541
+ const rounded2 = new Date(Math.ceil(Math.floor(entry.modified.getTime() / 1e3) / 2) * 2e3);
28542
+ const year = Math.max(1980, Math.min(2107, rounded2.getFullYear()));
28543
+ const date2 = entry.dosDate ?? year - 1980 << 9 | rounded2.getMonth() + 1 << 5 | rounded2.getDate();
28544
+ const time = entry.dosTime ?? rounded2.getHours() << 11 | rounded2.getMinutes() << 5 | rounded2.getSeconds() >>> 1;
28545
+ number3(date2, 65535, "DOS date");
28546
+ number3(time, 65535, "DOS time");
28547
+ const dosTimestamp = dosModified(date2, time).getTime();
28548
+ const extendedTimestamp = centralMetadata.modified ?? localMetadata.modified;
28549
+ if (extendedTimestamp === void 0 ? dosTimestamp !== rounded2.getTime() : Math.floor(extendedTimestamp / 1e3) !== Math.floor(entry.modified.getTime() / 1e3)) fail2("ZIP retained or unrepresentable timestamp metadata mismatch");
28550
+ for (const [value2, maximum, label] of [[entry.versionMadeBy ?? 798, 65535, "creator version"], [entry.internalAttributes ?? 0, 65535, "internal attributes"], [entry.externalAttributes ?? 0, 4294967295, "external attributes"]]) number3(value2, maximum, label);
28551
+ if ((entry.internalAttributes ?? 0) & ~1) fail2("ZIP unsupported internal attributes");
28552
+ if (entry.externalAttributes !== void 0) {
28553
+ const host2 = (entry.versionMadeBy ?? 798) >>> 8;
28554
+ const unixMode = host2 === 3 || host2 === 19 ? entry.externalAttributes >>> 16 : 0;
28555
+ const mode = unixMode || (entry.directory ? 16877 : 33188);
28556
+ if (mode !== entry.mode || Boolean(entry.externalAttributes & 16) && !entry.directory) fail2("ZIP retained file attributes mismatch");
28557
+ }
28558
+ encoded2.push({ entry, rawName, flags: flags3, localExtra, centralExtra, comment: comment2, date: date2, time, offset: localLength });
28559
+ localLength += 30 + rawName.length + localExtra.length + entry.data.length;
28560
+ length += 76 + 2 * rawName.length + localExtra.length + centralExtra.length + comment2.length + entry.data.length;
28561
+ number3(length, Math.min(limits.maxArchiveBytes, 4294967294), "archive byte");
28562
+ }
28563
+ number3(length, Math.min(limits.maxArchiveBytes, 4294967294), "archive byte");
28564
+ const bytes3 = new Uint8Array(length);
28565
+ const view = new DataView(bytes3.buffer);
28566
+ let central = localLength;
28567
+ for (const item of encoded2) {
28568
+ await yieldTurn(signal);
28569
+ const { entry, rawName, flags: flags3, localExtra, centralExtra, comment: comment2, date: date2, time, offset } = item;
28570
+ const version = entry.method === 8 ? 20 : 10;
28571
+ view.setUint32(offset, 67324752, true);
28572
+ view.setUint16(offset + 4, version, true);
28573
+ view.setUint16(offset + 6, flags3, true);
28574
+ view.setUint16(offset + 8, entry.method, true);
28575
+ view.setUint16(offset + 10, time, true);
28576
+ view.setUint16(offset + 12, date2, true);
28577
+ view.setUint32(offset + 14, entry.crc32, true);
28578
+ view.setUint32(offset + 18, entry.data.length, true);
28579
+ view.setUint32(offset + 22, entry.size, true);
28580
+ view.setUint16(offset + 26, rawName.length, true);
28581
+ view.setUint16(offset + 28, localExtra.length, true);
28582
+ bytes3.set(rawName, offset + 30);
28583
+ bytes3.set(localExtra, offset + 30 + rawName.length);
28584
+ await copyBytes(entry.data, bytes3, offset + 30 + rawName.length + localExtra.length, chunkSize2, signal);
28585
+ view.setUint32(central, 33639248, true);
28586
+ view.setUint16(central + 4, entry.versionMadeBy ?? 798, true);
28587
+ view.setUint16(central + 6, version, true);
28588
+ view.setUint16(central + 8, flags3, true);
28589
+ view.setUint16(central + 10, entry.method, true);
28590
+ view.setUint16(central + 12, time, true);
28591
+ view.setUint16(central + 14, date2, true);
28592
+ view.setUint32(central + 16, entry.crc32, true);
28593
+ view.setUint32(central + 20, entry.data.length, true);
28594
+ view.setUint32(central + 24, entry.size, true);
28595
+ view.setUint16(central + 28, rawName.length, true);
28596
+ view.setUint16(central + 30, centralExtra.length, true);
28597
+ view.setUint16(central + 32, comment2.length, true);
28598
+ view.setUint16(central + 36, entry.internalAttributes ?? 0, true);
28599
+ view.setUint32(central + 38, entry.externalAttributes ?? (entry.mode | (entry.directory ? 16384 : entry.symlink ? 40960 : 32768)) * 65536 + (entry.directory ? 16 : 0), true);
28600
+ view.setUint32(central + 42, offset, true);
28601
+ bytes3.set(rawName, central + 46);
28602
+ bytes3.set(centralExtra, central + 46 + rawName.length);
28603
+ bytes3.set(comment2, central + 46 + rawName.length + centralExtra.length);
28604
+ central += 46 + rawName.length + centralExtra.length + comment2.length;
28605
+ }
28606
+ view.setUint32(central, 101010256, true);
28607
+ view.setUint16(central + 8, encoded2.length, true);
28608
+ view.setUint16(central + 10, encoded2.length, true);
28609
+ view.setUint32(central + 12, central - localLength, true);
28610
+ view.setUint32(central + 16, localLength, true);
28611
+ view.setUint16(central + 20, archive.comment.length, true);
28612
+ bytes3.set(archive.comment, central + 22);
28613
+ signal.throwIfAborted();
28614
+ return bytes3;
28615
+ }
28616
+
28617
+ // packages/safe-bash/src/commands/archive/zip/safety.ts
28618
+ init_platform();
28619
+ import { retainFileSystemCleanup } from "@poe-platform/safe-fs/core";
28620
+ var ZipScope = class {
28621
+ constructor(original, limits) {
28622
+ this.original = original;
28623
+ this.limits = limits;
28624
+ this.context = { ...original, signal: AbortSignal.any([original.signal, this.controller.signal]) };
28625
+ original.registerCleanup?.(this.close);
28626
+ }
28627
+ original;
28628
+ limits;
28629
+ context;
28630
+ controller = new AbortController();
28631
+ pending = /* @__PURE__ */ new Set();
28632
+ readers = /* @__PURE__ */ new Set();
28633
+ closedReason = new Error("ZIP command is closed");
28634
+ drain;
28635
+ work = 0;
28636
+ close = () => {
28637
+ if (!this.drain) {
28638
+ this.drain = Promise.resolve().then(async () => {
28639
+ while (this.pending.size) await Promise.allSettled([...this.pending]);
28640
+ const results = await Promise.allSettled([...this.readers].map((close) => close()));
28641
+ const failures = results.filter((result2) => result2.status === "rejected").map((result2) => result2.reason);
28642
+ if (failures.length === 1) throw failures[0];
28643
+ if (failures.length) throw new AggregateError(failures, "ZIP reader cleanup failed");
28644
+ });
28645
+ this.controller.abort(this.original.signal.aborted ? this.original.signal.reason : this.closedReason);
28646
+ }
28647
+ return this.drain;
28648
+ };
28649
+ async operation(action) {
28650
+ this.context.signal.throwIfAborted();
28651
+ if (++this.work > this.limits.maxPatternSteps) fail2("filesystem work limit exceeded");
28652
+ const pending = Promise.resolve().then(() => {
28653
+ this.context.signal.throwIfAborted();
28654
+ return action();
28655
+ });
28656
+ this.pending.add(pending);
28657
+ try {
28658
+ const value2 = await pending;
28659
+ this.context.signal.throwIfAborted();
28660
+ return value2;
28661
+ } finally {
28662
+ this.pending.delete(pending);
28663
+ }
28664
+ }
28665
+ async stat(path) {
28666
+ try {
28667
+ return await this.operation(() => this.context.fs.lstat(path, { signal: this.context.signal }));
28668
+ } catch (error) {
28669
+ this.context.signal.throwIfAborted();
28670
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") return void 0;
28671
+ throw error;
28672
+ }
28673
+ }
28674
+ source(source2) {
28675
+ const iterator = source2[Symbol.asyncIterator]();
28676
+ let closing;
28677
+ const close = () => closing ??= (async () => {
28678
+ try {
28679
+ await iterator.return?.();
28680
+ } finally {
28681
+ this.readers.delete(close);
28682
+ }
28683
+ })();
28684
+ this.readers.add(close);
28685
+ return { [Symbol.asyncIterator]: () => ({
28686
+ next: () => this.operation(async () => {
28687
+ const result2 = await iterator.next();
28688
+ if (result2.done) this.readers.delete(close);
28689
+ return result2;
28690
+ }),
28691
+ async return() {
28692
+ await close();
28693
+ return { done: true, value: void 0 };
28694
+ }
28695
+ }) };
28696
+ }
28697
+ async *input(path) {
28698
+ const { fs, signal } = this.context;
28699
+ const capabilities = await this.operation(() => fs.capabilitiesFor?.(path, { signal }) ?? fs.capabilities);
28700
+ if (fs.readStream && capabilities.streamingRead !== false) {
28701
+ const source2 = await this.operation(() => this.source(fs.readStream(path, { signal, chunkSize: this.limits.chunkSize })));
28702
+ yield* readBytes(source2, signal);
28703
+ } else {
28704
+ const stat = await this.operation(() => fs.stat(path, { signal }));
28705
+ if (stat.size > this.limits.maxBufferedFileBytes) fail2("filesystem lacks streaming reads: buffered file limit exceeded");
28706
+ const bytes3 = await this.operation(() => fs.readFile(path, { signal, maxBytes: this.limits.maxBufferedFileBytes }));
28707
+ if (bytes3.length > this.limits.maxBufferedFileBytes) fail2("buffered file limit exceeded");
28708
+ yield bytes3;
28709
+ }
28710
+ }
28711
+ };
28712
+ async function publishZip(scope, prepared) {
28713
+ const { fs, signal } = scope.context;
28714
+ const capabilities = await scope.operation(() => fs.capabilitiesFor?.(prepared.output, { signal }) ?? fs.capabilities);
28715
+ if (capabilities.atomicRename !== true || capabilities.exclusiveCreate !== true || capabilities.explicitDirectories !== true || capabilities.permissions !== true || !fs.rmdir || (prepared.existing ? !fs.chmod : capabilities.atomicRenameNoReplace !== true)) fail2("ZIP publication requires atomic rename, exclusive creation, private directories and mode preservation");
28716
+ let directory2;
28717
+ let temporary = "";
28718
+ let identity2;
28719
+ let published = false;
28720
+ let collision = false;
28721
+ let failure;
28722
+ const checkOwner = async () => {
28723
+ const parent = await scope.operation(() => fs.realpath(prepared.parentName, { signal }));
28724
+ const owner = directory2 && await scope.stat(directory2.path);
28725
+ if (parent !== prepared.parent || !owner || owner.type !== "directory" || !sameIdentity2(owner, directory2.stat)) fail2("ZIP temporary ownership changed before mutation");
28726
+ };
28727
+ const close = retainFileSystemCleanup(fs, async (cleanup) => {
28728
+ if (!directory2 || !hasIdentity(directory2.stat)) return;
28729
+ const parent = await cleanup.realpath(prepared.parentName);
28730
+ const owner = await cleanup.lstat(directory2.path);
28731
+ if (parent !== prepared.parent || owner.type !== "directory" || !sameIdentity2(owner, directory2.stat)) fail2("ZIP temporary ownership changed before cleanup");
28732
+ if (temporary && !published && !collision) {
28733
+ let current;
28734
+ try {
28735
+ current = await cleanup.lstat(temporary);
28736
+ } catch (error) {
28737
+ if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") throw error;
28738
+ }
28739
+ if (current) {
28740
+ if (!identity2 || !sameIdentity2(current, identity2) || current.type !== "file" || current.nlink !== 1) fail2("ZIP temporary file changed before cleanup");
28741
+ await cleanup.rm(temporary);
28742
+ }
28743
+ }
28744
+ await cleanup.rmdir(directory2.path);
28745
+ }, { maxOperations: 16 });
28746
+ try {
28747
+ for (let attempt = 0; attempt < Math.min(64, scope.limits.maxMembers); attempt++) {
28748
+ const path = `${prepared.parent === "/" ? "" : prepared.parent}/.zip-${attempt + 1}`;
28749
+ checkPath(path, scope.limits);
28750
+ if (path === prepared.output) continue;
28751
+ try {
28752
+ await scope.operation(async () => {
28753
+ await fs.mkdir(path, { signal, mode: 448 });
28754
+ directory2 = { path, stat: await fs.lstat(path) };
28755
+ });
28756
+ break;
28757
+ } catch (error) {
28758
+ signal.throwIfAborted();
28759
+ if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "EEXIST") throw error;
28760
+ }
28761
+ }
28762
+ if (!directory2) fail2("ZIP temporary directory attempt limit exceeded");
28763
+ if (directory2.stat.type !== "directory" || !hasIdentity(directory2.stat) || (directory2.stat.mode & 511) !== 448) fail2("ZIP temporary directory ownership unavailable");
28764
+ temporary = `${directory2.path}/archive.zip`;
28765
+ checkPath(temporary, scope.limits);
28766
+ await checkOwner();
28767
+ await scope.operation(async () => {
28768
+ let writeFailure;
28769
+ try {
28770
+ await fs.writeFile(temporary, prepared.bytes, { signal, flag: "wx", ...prepared.existing ? { mode: prepared.existing.mode & 4095 } : {} });
28771
+ } catch (error) {
28772
+ collision = typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
28773
+ writeFailure = { reason: error };
28774
+ }
28775
+ if (!collision) {
28776
+ await checkOwner();
28777
+ try {
28778
+ identity2 = await fs.lstat(temporary);
28779
+ } catch (error) {
28780
+ if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") throw error;
28781
+ }
28782
+ }
28783
+ if (writeFailure) throw writeFailure.reason;
28784
+ });
28785
+ if (!identity2 || !hasIdentity(identity2) || identity2.type !== "file" || identity2.nlink !== 1 || identity2.size !== prepared.bytes.length) fail2("ZIP staged archive identity or size changed");
28786
+ if (prepared.existing) {
28787
+ await checkOwner();
28788
+ await scope.operation(() => fs.chmod(temporary, prepared.existing.mode & 4095, { signal }));
28789
+ }
28790
+ const parent = await scope.operation(() => fs.realpath(prepared.parentName, { signal }));
28791
+ const current = await scope.stat(prepared.output);
28792
+ if (parent !== prepared.parent || (prepared.existing ? !current || !sameIdentity2(prepared.existing, current) || current.type !== "file" || current.nlink !== 1 || current.size !== prepared.existing.size || current.mode !== prepared.existing.mode || current.mtimeMs !== prepared.existing.mtimeMs || current.ctimeMs !== prepared.existing.ctimeMs : current !== void 0)) fail2("archive backing entry changed before publication");
28793
+ const staging = await scope.stat(temporary);
28794
+ const owner = await scope.stat(directory2.path);
28795
+ if (!staging || !sameIdentity2(staging, identity2) || staging.type !== "file" || staging.nlink !== 1 || staging.size !== prepared.bytes.length || !owner || !sameIdentity2(owner, directory2.stat) || owner.type !== "directory") fail2("ZIP temporary ownership changed before publication");
28796
+ await scope.operation(async () => {
28797
+ await fs.rename(temporary, prepared.output, { signal, ...!prepared.existing ? { noReplace: true } : {} });
28798
+ published = true;
28799
+ });
28800
+ } catch (error) {
28801
+ failure = { reason: error };
28802
+ }
28803
+ try {
28804
+ await close();
28805
+ } catch (error) {
28806
+ if (failure) throw new AggregateError([failure.reason, error], "ZIP publication and cleanup failed");
28807
+ throw error;
28808
+ }
28809
+ if (failure) throw failure.reason;
28810
+ }
28811
+
28812
+ // packages/safe-bash/src/commands/archive/zip.ts
28813
+ var ZipFailure = class extends Error {
28814
+ constructor(status2, label, detail) {
28815
+ super(detail);
28816
+ this.status = status2;
28817
+ this.label = label;
28818
+ }
28819
+ status;
28820
+ label;
28821
+ };
28822
+ function parse12(context2, limits) {
28823
+ if (context2.args.length > limits.maxArgumentBytes) fail2("argument count limit exceeded");
28824
+ let bytes3 = 0;
28825
+ for (const argument2 of context2.args) {
28826
+ const size = import_buffer.Buffer.byteLength(argument2);
28827
+ if (size > limits.maxArgumentBytes - bytes3) fail2("argument byte limit exceeded");
28828
+ bytes3 += size;
28829
+ }
28830
+ if (context2.argumentValues) {
28831
+ const argumentsValue = getCommandArguments(context2);
28832
+ let rawBytes = 0;
28833
+ for (const value2 of argumentsValue.values) {
28834
+ const size = shellValueByteLength(value2);
28835
+ if (size > limits.maxArgumentBytes - rawBytes) fail2("argument byte limit exceeded");
28836
+ rawBytes += size;
28837
+ }
28838
+ for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
28839
+ }
28840
+ let archive;
28841
+ let recursive = false;
28842
+ let literal = false;
28843
+ let firstOperand = -1;
28844
+ const operands = [];
28845
+ for (const [index, argument2] of context2.args.entries()) {
28846
+ checkPath(argument2, limits);
28847
+ if (!literal && argument2 === "--") {
28848
+ if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "can't use -- before archive name");
28849
+ literal = true;
28850
+ } else if (!literal && argument2.startsWith("-") && argument2 !== "-") {
28851
+ if (argument2.length > 1 && [...argument2.slice(1)].every((flag) => flag === "r")) recursive = true;
28852
+ else throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
28853
+ } else if (archive === void 0) archive = argument2;
28854
+ else {
28855
+ if (operands.length >= limits.maxMembers) fail2("operand limit exceeded");
28856
+ if (firstOperand < 0) firstOperand = index;
28857
+ operands.push(argument2);
28858
+ }
28859
+ }
28860
+ if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "expected zip [-r] ARCHIVE FILES...");
28861
+ if (archive === "-" || operands.includes("-")) throw new ZipFailure(16, "Invalid command arguments", "standard input/output archives are unsupported");
28862
+ if (!archive.slice(archive.lastIndexOf("/") + 1).includes(".")) archive += ".zip";
28863
+ checkPath(archive, limits);
28864
+ return { archive, recursive, operands, firstOperand };
28865
+ }
28866
+ function memberName(path, limits) {
28867
+ if (path.startsWith("//") && !path.startsWith("///")) fail2("UNC source paths are unsupported");
28868
+ let start = 0;
28869
+ while (path[start] === "/") start++;
28870
+ while (path.slice(start, start + 2) === "./") start += 2;
28871
+ const name2 = path.slice(start);
28872
+ if (name2.split("/").includes("..")) fail2("parent-component archive names are unsupported");
28873
+ if (name2 && name2 !== ".") checkPath(name2, limits);
28874
+ return name2 === "." ? "" : name2;
28875
+ }
28876
+ function unchanged4(before, after) {
28877
+ return before.type === after.type && before.size === after.size && before.mode === after.mode && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs && before.nlink === after.nlink && (!hasIdentity(before) || sameIdentity2(before, after));
28878
+ }
28879
+ async function prepare(scope, parsed, budget) {
28880
+ const context2 = scope.context;
28881
+ const limits = budget.limits;
28882
+ const outputName = vfsPath(context2.cwd, parsed.archive);
28883
+ const parentName = dirname(outputName);
28884
+ const parent = await scope.operation(() => context2.fs.realpath(parentName, { signal: context2.signal }));
28885
+ const output2 = `${parent === "/" ? "" : parent}/${outputName.slice(outputName.lastIndexOf("/") + 1)}`;
28886
+ checkPath(output2, limits);
28887
+ const existing2 = await scope.stat(output2);
28888
+ if (existing2 && (existing2.type !== "file" || !hasIdentity(existing2) || existing2.nlink !== 1)) fail2("updating archive requires a regular, single-link file with known backing identity; archive aliases are unsupported");
28889
+ let archive = { entries: [], comment: new Uint8Array() };
28890
+ if (existing2) {
28891
+ if (!Number.isSafeInteger(existing2.size) || existing2.size < 0 || existing2.size > limits.maxArchiveBytes) fail2("archive byte limit exceeded");
28892
+ const bytes4 = await collectBytes(scope.input(output2), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
28893
+ if (bytes4.length !== existing2.size) fail2("archive changed while reading");
28894
+ archive = await readZipArchive(bytes4, limits, context2.signal);
28895
+ const current = await scope.stat(output2);
28896
+ if (!current || !unchanged4(existing2, current)) fail2("archive changed while reading");
28897
+ }
28898
+ const old = new Map(archive.entries.map((entry) => [entry.name, entry]));
28899
+ const selected = /* @__PURE__ */ new Map();
28900
+ const ancestors = [];
28901
+ let visits = 0;
28902
+ let work = 0;
28903
+ let compressedBytes = 0;
28904
+ const visit = async (source2, name2, depth) => {
28905
+ context2.signal.throwIfAborted();
28906
+ if (++visits > limits.maxMembers) fail2("traversal member limit exceeded");
28907
+ if (++work > limits.maxPatternSteps) fail2("archive work limit exceeded");
28908
+ if (visits % 128 === 0) await yieldTurn(context2.signal);
28909
+ if (depth > limits.maxDepth) fail2("archive recursion depth limit exceeded");
28910
+ const path = vfsPath(context2.cwd, source2);
28911
+ checkPath(path, limits);
28912
+ let canonical;
28913
+ let stat;
28914
+ try {
28915
+ canonical = await scope.operation(() => context2.fs.realpath(path, { signal: context2.signal }));
28916
+ stat = await scope.operation(() => context2.fs.stat(path, { signal: context2.signal }));
28917
+ } catch (error) {
28918
+ context2.signal.throwIfAborted();
28919
+ if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") throw error;
28920
+ if (!old.has(name2)) await budget.output(` zip warning: name not matched: ${source2}
28921
+ `);
28922
+ return;
28923
+ }
28924
+ checkPath(canonical, limits);
28925
+ if (canonical === output2 || existing2 && sameIdentity2(existing2, stat)) return;
28926
+ if (stat.type !== "file" && stat.type !== "directory") {
28927
+ await budget.output(` zip warning: ignoring special file: ${source2}
28928
+ `);
28929
+ return;
28930
+ }
28931
+ if (existing2 && !hasIdentity(stat)) fail2("cannot exclude archive aliases when source backing identity is unknown");
28932
+ const directory2 = stat.type === "directory";
28933
+ if (directory2 && name2 && !name2.endsWith("/")) name2 += "/";
28934
+ if (name2) {
28935
+ checkPath(name2, limits);
28936
+ const previous = selected.get(name2);
28937
+ if (previous && previous.source !== source2) {
28938
+ await budget.output(` zip warning: first full name: ${previous.source}
28939
+ second full name: ${source2}
28940
+ name in zip file repeated: ${name2}
28941
+ `);
28942
+ throw new ZipFailure(16, "Invalid command arguments", "cannot repeat names in zip file");
28943
+ }
28944
+ if (!previous) {
28945
+ await budget.member(directory2 ? 0 : stat.size);
28946
+ const bytes4 = directory2 ? new Uint8Array() : await collectBytes(scope.input(path), { maxBytes: stat.size, signal: context2.signal });
28947
+ if (!directory2 && bytes4.length !== stat.size) fail2(`source changed while reading: ${source2}`);
28948
+ const current = await scope.operation(() => context2.fs.stat(path, { signal: context2.signal }));
28949
+ const currentPath = await scope.operation(() => context2.fs.realpath(path, { signal: context2.signal }));
28950
+ if (currentPath !== canonical || !unchanged4(stat, current)) fail2(`source changed while reading: ${source2}`);
28951
+ let entry = await makeZipEntry(name2, bytes4, { modified: new Date(stat.mtimeMs), mode: stat.mode, directory: directory2, symlink: false }, limits, context2.signal);
28952
+ if ([".z", ".zip", ".zoo", ".arc", ".lzh", ".arj"].some((suffix2) => name2.toLowerCase().endsWith(suffix2))) entry = { ...entry, method: 0, data: bytes4 };
28953
+ const prior = old.get(name2);
28954
+ if (prior?.comment) entry = { ...entry, comment: prior.comment };
28955
+ if (entry.data.length > limits.maxArchiveBytes - compressedBytes) fail2("archive byte limit exceeded");
28956
+ compressedBytes += entry.data.length;
28957
+ selected.set(name2, { entry, source: source2 });
28958
+ }
28959
+ }
28960
+ if (directory2 && parsed.recursive) {
28961
+ if (ancestors.some((ancestor) => ancestor.path === canonical || sameIdentity2(ancestor.stat, stat))) fail2(`directory cycle while archiving: ${source2}`);
28962
+ ancestors.push({ path: canonical, stat });
28963
+ try {
28964
+ const children = await scope.operation(() => context2.fs.readdir(path, { signal: context2.signal, maxEntries: limits.maxMembers - visits }));
28965
+ if (children.length > limits.maxMembers - visits) fail2("traversal member limit exceeded");
28966
+ for (const child of children) {
28967
+ if (!child.name || child.name === "." || child.name === ".." || child.name.includes("/") || child.name.includes("\0")) fail2("invalid filesystem directory entry");
28968
+ const prefix3 = source2 === "." ? "" : source2.endsWith("/") ? source2 : `${source2}/`;
28969
+ await visit(`${prefix3}${child.name}`, `${name2}${child.name}`, depth + 1);
28970
+ }
28971
+ } finally {
28972
+ ancestors.pop();
28973
+ }
28974
+ }
28975
+ };
28976
+ for (const operand of parsed.operands) await visit(operand, memberName(operand, limits), 0);
28977
+ if (!selected.size) {
28978
+ const detail = parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${context2.args.slice(0, parsed.firstOperand).join(" ")} . -i ${context2.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
28979
+ throw new ZipFailure(12, "Nothing to do!", detail);
28980
+ }
28981
+ const entries2 = [];
28982
+ const progress = [];
28983
+ let progressBytes = 0;
28984
+ const append = (entry, update) => {
28985
+ const percentage = entry.size ? Math.trunc((Math.trunc(200 * (entry.size - entry.data.length) / entry.size) + 1) / 2) : 0;
28986
+ const message3 = `${update ? "updating:" : " adding:"} ${entry.name} (${entry.method === 8 ? `deflated ${percentage}%` : "stored 0%"})
28987
+ `;
28988
+ const size = import_buffer.Buffer.byteLength(message3);
28989
+ if (size > limits.maxTextBytes - budget.textBytes - progressBytes) fail2("text output limit exceeded");
28990
+ progressBytes += size;
28991
+ progress.push(message3);
28992
+ };
28993
+ for (const entry of archive.entries) {
28994
+ if (++work > limits.maxPatternSteps) fail2("archive work limit exceeded");
28995
+ const replacement = selected.get(entry.name);
28996
+ if (replacement) {
28997
+ entries2.push(replacement.entry);
28998
+ append(replacement.entry, true);
28999
+ selected.delete(entry.name);
29000
+ } else {
29001
+ await budget.member(entry.size);
29002
+ entries2.push(entry);
29003
+ }
29004
+ }
29005
+ for (const { entry } of selected.values()) {
29006
+ entries2.push(entry);
29007
+ append(entry, false);
29008
+ }
29009
+ const bytes3 = await writeZipArchive({ entries: entries2, comment: archive.comment }, limits, context2.signal);
29010
+ return { output: output2, parentName, parent, existing: existing2, bytes: bytes3, progress };
29011
+ }
29012
+ function createZipCommand(options3 = {}) {
29013
+ const limits = settings2(options3);
29014
+ return { name: "zip", description: "Create or update bounded ZIP archives in the virtual filesystem", async execute(original) {
29015
+ original.signal.throwIfAborted();
29016
+ const scope = new ZipScope(original, limits);
29017
+ const context2 = scope.context;
29018
+ const budget = new Budget14(context2, limits);
29019
+ try {
29020
+ const parsed = parse12(context2, limits);
29021
+ const prepared = await prepare(scope, parsed, budget);
29022
+ await writeFileOutput(context2, prepared.bytes, () => scope.operation(() => publishZip(scope, prepared)));
29023
+ for (const message3 of prepared.progress) await budget.output(message3);
29024
+ return { exitCode: 0 };
29025
+ } catch (error) {
29026
+ original.signal.throwIfAborted();
29027
+ context2.signal.throwIfAborted();
29028
+ if (error instanceof ZipFailure) {
29029
+ await budget.output(`
29030
+ zip error: ${error.label} (${error.message})
29031
+ `);
29032
+ return { exitCode: error.status };
29033
+ }
29034
+ const message3 = escapeText(display(publicDiagnosticMessage(error, context2.onInternalError).slice(0, 1024)), "diagnostic");
29035
+ await writeBytes(context2.stderr, import_buffer.Buffer.from(`zip: ${message3}
29036
+ `).subarray(0, limits.maxDiagnosticBytes), context2.signal);
29037
+ return { exitCode: 2 };
29038
+ } finally {
29039
+ try {
29040
+ await scope.close();
29041
+ } finally {
29042
+ original.signal.throwIfAborted();
29043
+ }
29044
+ }
29045
+ } };
29046
+ }
29047
+
29048
+ // packages/safe-bash/src/commands/archive/unzip.ts
29049
+ init_platform();
29050
+
29051
+ // packages/safe-bash/src/commands/archive/unzip/arguments.ts
29052
+ init_platform();
29053
+ function parseArguments(context2, limits) {
29054
+ const { args } = context2;
29055
+ let bytes3 = 0;
29056
+ for (const argument2 of args) {
29057
+ bytes3 += import_buffer.Buffer.byteLength(argument2) + 1;
29058
+ if (bytes3 > limits.maxArgumentBytes) fail2("argument byte limit exceeded");
29059
+ if (argument2.includes("\0")) fail2("NUL in argument");
29060
+ }
29061
+ if (context2.argumentValues) {
29062
+ const argumentsValue = getCommandArguments(context2);
29063
+ let rawBytes = 0;
29064
+ for (const value2 of argumentsValue.values) {
29065
+ const size = shellValueByteLength(value2) + 1;
29066
+ if (size > limits.maxArgumentBytes - rawBytes) fail2("argument byte limit exceeded");
29067
+ rawBytes += size;
29068
+ }
29069
+ for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
29070
+ }
29071
+ let list = false;
29072
+ let overwrite = false;
29073
+ let destination2;
29074
+ let archive;
29075
+ let ended = false;
29076
+ const patterns2 = [];
29077
+ for (let index = 0; index < args.length; index++) {
29078
+ const argument2 = args[index];
29079
+ if (!ended && argument2 === "--") {
29080
+ ended = true;
29081
+ continue;
29082
+ }
29083
+ if (!ended && argument2.startsWith("-") && argument2 !== "-") {
29084
+ for (let offset = 1; offset < argument2.length; offset++) {
29085
+ const flag = argument2[offset];
29086
+ if (flag === "l") list = true;
29087
+ else if (flag === "o") overwrite = true;
29088
+ else if (flag === "d") {
29089
+ if (destination2 !== void 0) fail2("-d may only be specified once");
29090
+ destination2 = argument2.slice(offset + 1) || args[++index];
29091
+ if (!destination2) fail2("must specify directory to which to extract with -d option");
29092
+ checkPath(destination2, limits);
29093
+ break;
29094
+ } else fail2(`unsupported option: -${flag}`);
29095
+ }
29096
+ } else if (archive === void 0) archive = argument2;
29097
+ else patterns2.push(argument2);
29098
+ }
29099
+ if (archive === void 0) fail2("usage: unzip [-l] [-o] [-d DIR] ARCHIVE [FILES...]");
29100
+ checkPath(archive, limits);
29101
+ return { list, overwrite, destination: destination2, archive, patterns: patterns2 };
29102
+ }
29103
+ function tokenize2(pattern) {
29104
+ const characters = Array.from(pattern);
29105
+ const tokens2 = [];
29106
+ for (let index = 0; index < characters.length; index++) {
29107
+ const character = characters[index];
29108
+ if (character === "*") {
29109
+ if (tokens2.at(-1)?.kind !== "star") tokens2.push({ kind: "star" });
29110
+ } else if (character === "?") tokens2.push({ kind: "any" });
29111
+ else if (character === "\\") {
29112
+ const escaped3 = characters[++index];
29113
+ tokens2.push(escaped3 === void 0 ? { kind: "never" } : { kind: "literal", value: escaped3 });
29114
+ } else if (character === "[") {
29115
+ const negative = characters[index + 1] === "!" || characters[index + 1] === "^";
29116
+ if (negative) index++;
29117
+ const ranges = [];
29118
+ let closed = false;
29119
+ while (++index < characters.length) {
29120
+ let first = characters[index];
29121
+ if (first === "]") {
29122
+ closed = true;
29123
+ break;
29124
+ }
29125
+ if (first === "\\") first = characters[++index] ?? "";
29126
+ let last = first;
29127
+ if (characters[index + 1] === "-" && characters[index + 2] && characters[index + 2] !== "]") {
29128
+ index += 2;
29129
+ last = characters[index];
29130
+ if (last === "\\") last = characters[++index] ?? "";
29131
+ }
29132
+ ranges.push([first.codePointAt(0) ?? -1, last.codePointAt(0) ?? -1]);
29133
+ }
29134
+ tokens2.push(closed ? { kind: "class", ranges, negative } : { kind: "never" });
29135
+ } else tokens2.push({ kind: "literal", value: character });
29136
+ }
29137
+ return tokens2;
29138
+ }
29139
+ var Selection = class {
29140
+ constructor(patterns2, limits, signal) {
29141
+ this.limits = limits;
29142
+ this.signal = signal;
29143
+ this.patterns = patterns2.map(tokenize2);
29144
+ }
29145
+ limits;
29146
+ signal;
29147
+ work = 0;
29148
+ patterns;
29149
+ matched = /* @__PURE__ */ new Set();
29150
+ step() {
29151
+ if (++this.work > this.limits.maxPatternSteps) fail2("pattern work limit exceeded");
29152
+ }
29153
+ async matches(name2) {
29154
+ if (!this.patterns.length) return true;
29155
+ const characters = Array.from(name2);
29156
+ let selected = false;
29157
+ for (let pattern = 0; pattern < this.patterns.length; pattern++) {
29158
+ this.step();
29159
+ let states = new Uint8Array(characters.length + 1);
29160
+ states[0] = 1;
29161
+ for (const token of this.patterns[pattern]) {
29162
+ const next = new Uint8Array(states.length);
29163
+ for (let index = 0; index < states.length; index++) {
29164
+ this.step();
29165
+ if (token.kind === "star") next[index] = states[index] || (index > 0 ? next[index - 1] : 0);
29166
+ else if (states[index] && index < characters.length) {
29167
+ const character = characters[index];
29168
+ let match = token.kind === "any" || token.kind === "literal" && token.value === character;
29169
+ if (token.kind === "class") {
29170
+ let inRange = false;
29171
+ for (const [first, last] of token.ranges) {
29172
+ this.step();
29173
+ if (character.codePointAt(0) >= first && character.codePointAt(0) <= last) inRange = true;
29174
+ }
29175
+ match = inRange !== token.negative;
29176
+ }
29177
+ if (match) next[index + 1] = 1;
29178
+ }
29179
+ if (this.work % 4096 === 0) await yieldTurn(this.signal);
29180
+ }
29181
+ states = next;
29182
+ }
29183
+ if (states[characters.length]) {
29184
+ this.matched.add(pattern);
29185
+ selected = true;
29186
+ }
29187
+ }
29188
+ return selected;
29189
+ }
29190
+ };
29191
+ var Answers = class {
29192
+ constructor(source2, limits, signal) {
29193
+ this.limits = limits;
29194
+ this.signal = signal;
29195
+ this.iterator = readBytes(source2, signal)[Symbol.asyncIterator]();
29196
+ }
29197
+ limits;
29198
+ signal;
29199
+ iterator;
29200
+ chunk = new Uint8Array();
29201
+ offset = 0;
29202
+ bytes = 0;
29203
+ pulls = 0;
29204
+ async read(maximum = 9) {
29205
+ const answer = [];
29206
+ while (answer.length < maximum) {
29207
+ this.signal.throwIfAborted();
29208
+ if (this.offset === this.chunk.length) {
29209
+ if (++this.pulls > this.limits.maxPatternSteps) fail2("overwrite input work limit exceeded");
29210
+ if (this.pulls % 64 === 0) await yieldTurn(this.signal);
29211
+ const next = await this.iterator.next();
29212
+ if (next.done) break;
29213
+ if (next.value.length > this.limits.maxFilesFromBytes - this.bytes) fail2("overwrite input byte limit exceeded");
29214
+ this.bytes += next.value.length;
29215
+ this.chunk = Uint8Array.from(next.value);
29216
+ this.offset = 0;
29217
+ if (!this.chunk.length) continue;
29218
+ }
29219
+ const byte = this.chunk[this.offset++];
29220
+ answer.push(byte);
29221
+ if (byte === 10) break;
29222
+ }
29223
+ return answer.length ? import_buffer.Buffer.from(answer).toString("utf8") : void 0;
29224
+ }
29225
+ async close() {
29226
+ await this.iterator.return?.();
29227
+ }
29228
+ };
29229
+
29230
+ // packages/safe-bash/src/commands/archive/unzip/safety.ts
29231
+ init_platform();
29232
+ import { retainFileSystemCleanup as retainFileSystemCleanup2 } from "@poe-platform/safe-fs/core";
29233
+ var Extraction = class {
29234
+ constructor(context2, limits) {
29235
+ this.context = context2;
29236
+ this.limits = limits;
29237
+ }
29238
+ context;
29239
+ limits;
29240
+ pending = /* @__PURE__ */ new Set();
29241
+ publications = /* @__PURE__ */ new Set();
29242
+ readers = /* @__PURE__ */ new Set();
29243
+ closed = false;
29244
+ work = 0;
29245
+ serial = 0;
29246
+ async operation(action) {
29247
+ this.context.signal.throwIfAborted();
29248
+ if (this.closed) fail2("extraction is closed");
29249
+ if (++this.work > this.limits.maxPatternSteps) fail2("filesystem work limit exceeded");
29250
+ const pending = Promise.resolve().then(() => {
29251
+ this.context.signal.throwIfAborted();
29252
+ return action();
29253
+ });
29254
+ this.pending.add(pending);
29255
+ try {
29256
+ const value2 = await pending;
29257
+ this.context.signal.throwIfAborted();
29258
+ return value2;
29259
+ } finally {
29260
+ this.pending.delete(pending);
29261
+ }
29262
+ }
29263
+ async close() {
29264
+ this.closed = true;
29265
+ while (this.pending.size) await Promise.allSettled([...this.pending]);
29266
+ while (this.publications.size) await Promise.allSettled([...this.publications]);
29267
+ await Promise.allSettled([...this.readers].map((close) => close()));
29268
+ }
29269
+ source(source2) {
29270
+ return { [Symbol.asyncIterator]: () => {
29271
+ const state = {};
29272
+ let closing;
29273
+ const close = () => closing ??= (async () => {
29274
+ try {
29275
+ await state.iterator?.return?.();
29276
+ } finally {
29277
+ this.readers.delete(close);
29278
+ }
29279
+ })();
29280
+ this.readers.add(close);
29281
+ this.context.signal.throwIfAborted();
29282
+ state.iterator = source2[Symbol.asyncIterator]();
29283
+ return {
29284
+ next: () => this.operation(async () => {
29285
+ const result2 = await state.iterator.next();
29286
+ if (result2.done) this.readers.delete(close);
29287
+ return result2;
29288
+ }),
29289
+ async return() {
29290
+ await close();
29291
+ return { done: true, value: void 0 };
29292
+ }
29293
+ };
29294
+ } };
29295
+ }
29296
+ async *input(path) {
29297
+ const { fs, signal } = this.context;
29298
+ const capabilities = await this.operation(async () => await fs.capabilitiesFor?.(path, { signal }) ?? fs.capabilities);
29299
+ if (fs.readStream && capabilities.streamingRead !== false) {
29300
+ const source2 = await this.operation(async () => fs.readStream(path, { signal, chunkSize: this.limits.chunkSize }));
29301
+ yield* readBytes(this.source(source2), signal);
29302
+ } else {
29303
+ const stat = await this.operation(() => fs.stat(path, { signal }));
29304
+ if (stat.size > this.limits.maxBufferedFileBytes) fail2("filesystem lacks streaming reads: buffered file limit exceeded");
29305
+ const bytes3 = await this.operation(() => fs.readFile(path, { signal, maxBytes: this.limits.maxBufferedFileBytes }));
29306
+ if (bytes3.length > this.limits.maxBufferedFileBytes) fail2("buffered file limit exceeded");
29307
+ yield bytes3;
29308
+ }
29309
+ }
29310
+ async stat(path) {
29311
+ try {
29312
+ return await this.operation(() => this.context.fs.lstat(path, { signal: this.context.signal }));
29313
+ } catch (error) {
29314
+ this.context.signal.throwIfAborted();
29315
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") return void 0;
29316
+ throw error;
29317
+ }
29318
+ }
29319
+ async directory(raw, create) {
29320
+ checkPath(raw, this.limits);
29321
+ let current = "/";
29322
+ const { fs, signal } = this.context;
29323
+ for (const component of raw.split("/")) {
29324
+ if (!component || component === ".") continue;
29325
+ current = resolvePath(current, component);
29326
+ const stat = await this.stat(current);
29327
+ if (!stat && create) await this.operation(() => fs.mkdir(current, { signal, mode: 493 }));
29328
+ else if (!stat || stat.type !== "directory") fail2(`unsafe non-directory or symlink ancestor: ${display(current)}`);
29329
+ }
29330
+ return current;
29331
+ }
29332
+ async parents(root, path, create) {
29333
+ if (!isPathWithin(root, path)) fail2("extraction path escapes root");
29334
+ await this.directory(dirname(path), create);
29335
+ }
29336
+ member(root, name2) {
29337
+ checkPath(name2, this.limits);
29338
+ if (name2.startsWith("/") || name2.split("/").includes("..")) fail2(`unsafe archive member: ${display(name2)}`);
29339
+ const path = resolvePath(root, name2);
29340
+ checkPath(path, this.limits);
29341
+ if (!isPathWithin(root, path)) fail2("extraction path escapes root");
29342
+ return path;
29343
+ }
29344
+ async target(root, path, target) {
29345
+ checkPath(target, this.limits);
29346
+ if (target.startsWith("/")) fail2("symlink target escapes extraction root");
29347
+ let current = dirname(path);
29348
+ const components2 = (value2) => {
29349
+ checkPath(value2, this.limits);
29350
+ let descended = false;
29351
+ const result2 = value2.split("/");
29352
+ for (const component of result2) {
29353
+ if (component === ".." && descended) fail2("unsafe non-leading parent in symlink target");
29354
+ if (component && component !== "." && component !== "..") descended = true;
29355
+ }
29356
+ return result2;
29357
+ };
29358
+ let pending = components2(target);
29359
+ let links = 0;
29360
+ let steps = 0;
29361
+ while (pending.length) {
29362
+ if (++steps > this.limits.maxDepth * 41) fail2("symlink target resolution limit exceeded");
29363
+ const component = pending.shift();
29364
+ if (!component || component === ".") continue;
29365
+ if (component === "..") {
29366
+ if (current === root) fail2("symlink target escapes extraction root");
29367
+ current = dirname(current);
29368
+ continue;
29369
+ }
29370
+ const candidate = resolvePath(current, component);
29371
+ checkPath(candidate, this.limits);
29372
+ if (!isPathWithin(root, candidate)) fail2("symlink target escapes extraction root");
29373
+ const stat = await this.stat(candidate);
29374
+ if (stat?.type === "symlink") {
29375
+ if (++links > 40 || !this.context.fs.readlink) fail2("symlink target chain cannot be safely resolved");
29376
+ const link = await this.operation(() => this.context.fs.readlink(candidate, { signal: this.context.signal }));
29377
+ if (link.startsWith("/")) fail2("absolute symlink target chain is unsafe");
29378
+ pending = [...components2(link), ...pending];
29379
+ if (pending.length > this.limits.maxDepth * 41) fail2("symlink target resolution limit exceeded");
29380
+ } else current = candidate;
29381
+ }
29382
+ }
29383
+ async destination(path, archivePath, archiveStat) {
29384
+ const stat = await this.stat(path);
29385
+ if (path === archivePath || stat && sameIdentity2(stat, archiveStat)) fail2("entry would overwrite input archive");
29386
+ if (stat && stat.type !== "file") fail2(`unsafe non-regular destination: ${display(path)}`);
29387
+ if (stat && (!hasIdentity(stat) || !hasIdentity(archiveStat))) fail2("cannot overwrite file with unknown input-archive backing identity");
29388
+ return stat;
29389
+ }
29390
+ async checked(root, path, expected) {
29391
+ await this.parents(root, path, false);
29392
+ const current = await this.stat(path);
29393
+ if (!current || current.type !== expected.type || !sameIdentity2(current, expected)) fail2("extraction entry changed before mutation");
29394
+ }
29395
+ async metadata(root, path, identity2, mode, modified) {
29396
+ const { fs, signal } = this.context;
29397
+ if (fs.chmod && fs.capabilities.permissions !== false) {
29398
+ await this.checked(root, path, identity2);
29399
+ await this.operation(() => fs.chmod(path, mode & 511, { signal }));
29400
+ }
29401
+ if (fs.utimes && fs.capabilities.timestamps !== false) {
29402
+ await this.checked(root, path, identity2);
29403
+ await this.operation(() => fs.utimes(path, modified.getTime(), modified.getTime(), { signal }));
29404
+ }
29405
+ }
29406
+ publish(root, path, chunks, expected, mode, modified, target) {
29407
+ const publication = this.stage(root, path, chunks, expected, mode, modified, target);
29408
+ this.publications.add(publication);
29409
+ return publication.finally(() => {
29410
+ this.publications.delete(publication);
29411
+ });
29412
+ }
29413
+ async stage(root, path, chunks, expected, mode, modified, target) {
29414
+ const { fs, signal } = this.context;
29415
+ let temporary = "";
29416
+ let identity2;
29417
+ let created = false;
29418
+ let failure;
29419
+ const cleanup = retainFileSystemCleanup2(fs, async (view) => {
29420
+ if (!created || !identity2) return;
29421
+ try {
29422
+ let parent = "/";
29423
+ for (const component of dirname(temporary).split("/").filter(Boolean)) {
29424
+ parent = resolvePath(parent, component);
29425
+ if ((await view.lstat(parent)).type !== "directory") return;
29426
+ }
29427
+ const current = await view.lstat(temporary);
29428
+ if (current.type === identity2.type && sameIdentity2(current, identity2)) await view.rm(temporary);
29429
+ } catch (error) {
29430
+ if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") throw error;
29431
+ }
29432
+ }, { maxOperations: Math.min(4096, this.limits.maxDepth + 3) });
29433
+ try {
29434
+ await this.parents(root, path, true);
29435
+ for (let attempt = 0; attempt < this.limits.maxMembers; attempt++) {
29436
+ temporary = resolvePath(dirname(path), `.unzip-${++this.serial}`);
29437
+ checkPath(temporary, this.limits);
29438
+ if (temporary === path || await this.stat(temporary)) continue;
29439
+ await this.operation(async () => {
29440
+ if (target === void 0) await fs.writeFile(temporary, new Uint8Array(), { signal, flag: "wx", mode: 384 });
29441
+ else await fs.symlink(target, temporary, { signal });
29442
+ created = true;
29443
+ identity2 = await fs.lstat(temporary);
29444
+ });
29445
+ if (!identity2 || !hasIdentity(identity2)) fail2("temporary file backing identity unavailable");
29446
+ break;
29447
+ }
29448
+ if (!created) fail2("temporary file attempt limit exceeded");
29449
+ if (target === void 0) {
29450
+ for (const chunk of chunks) {
29451
+ await this.checked(root, temporary, identity2);
29452
+ await this.operation(() => fs.appendFile(temporary, chunk, { signal }));
29453
+ }
29454
+ await this.metadata(root, temporary, identity2, mode, modified);
29455
+ }
29456
+ await this.parents(root, path, false);
29457
+ const current = await this.stat(path);
29458
+ if (current ? !expected || !sameIdentity2(current, expected) || current.type !== "file" : expected !== void 0) fail2("destination changed before publication");
29459
+ const staging = await this.stat(temporary);
29460
+ if (!staging || !identity2 || !sameIdentity2(staging, identity2) || staging.type !== (target === void 0 ? "file" : "symlink")) fail2("temporary file changed before publication");
29461
+ await this.operation(() => fs.rename(temporary, path, { signal }));
29462
+ created = false;
29463
+ } catch (error) {
29464
+ failure = { reason: error };
29465
+ }
29466
+ try {
29467
+ await cleanup();
29468
+ } catch (error) {
29469
+ if (failure) throw new AggregateError([failure.reason, error], "unzip publication and cleanup failed");
29470
+ throw error;
29471
+ }
29472
+ if (failure) throw failure.reason;
29473
+ }
29474
+ };
29475
+
29476
+ // packages/safe-bash/src/commands/archive/unzip.ts
29477
+ function filtered(name2) {
29478
+ let output2 = "";
29479
+ for (const character of name2) {
29480
+ const code = character.charCodeAt(0);
29481
+ output2 += code < 32 ? `^${String.fromCharCode(code + 64)}` : character;
29482
+ }
29483
+ return output2;
29484
+ }
29485
+ function padded(name2) {
29486
+ return name2 + " ".repeat(Math.max(0, 22 - import_buffer.Buffer.byteLength(name2)));
29487
+ }
29488
+ function date(entry) {
29489
+ const modified = entry.modified;
29490
+ const pad = (value2) => String(value2).padStart(2, "0");
29491
+ return `${modified.getFullYear()}-${pad(modified.getMonth() + 1)}-${pad(modified.getDate())} ${pad(modified.getHours())}:${pad(modified.getMinutes())}`;
29492
+ }
29493
+ async function comment(bytes3, budget) {
29494
+ if (!bytes3.length) return;
29495
+ const output2 = [];
29496
+ let length = 0;
29497
+ for (const byte of bytes3) {
29498
+ if (!byte) break;
29499
+ if (byte !== 13 && byte !== 19) length += byte === 27 ? 2 : 1;
29500
+ if (length > budget.limits.maxTextBytes - budget.textBytes) fail2("text output limit exceeded");
29501
+ }
29502
+ for (const byte of bytes3) {
29503
+ if (!byte) break;
29504
+ if (byte === 13 || byte === 19) continue;
29505
+ if (byte === 27) output2.push(94, 91);
29506
+ else output2.push(byte);
29507
+ }
29508
+ if (output2.length && output2.at(-1) !== 10) output2.push(10);
29509
+ const value2 = Uint8Array.from(output2);
29510
+ if (value2.length > budget.limits.maxTextBytes - budget.textBytes) fail2("text output limit exceeded");
29511
+ budget.textBytes += value2.length;
29512
+ await writeBytes(budget.context.stdout, value2, budget.context.signal);
29513
+ }
29514
+ function createUnzipCommand(options3 = {}) {
29515
+ const limits = settings2(options3);
29516
+ return { name: "unzip", description: "List and safely extract ZIP archives in the virtual filesystem", async execute(original) {
29517
+ original.signal.throwIfAborted();
29518
+ const controller = new AbortController();
29519
+ const context2 = { ...original, signal: AbortSignal.any([original.signal, controller.signal]) };
29520
+ const extraction = new Extraction(context2, limits);
29521
+ let answers;
29522
+ let closing;
29523
+ const close = () => closing ??= (async () => {
29524
+ controller.abort(new Error("unzip command closed"));
29525
+ await extraction.close();
29526
+ await answers?.close().catch(() => {
29527
+ });
29528
+ })();
29529
+ original.registerCleanup?.(close);
29530
+ const budget = new Budget14(context2, limits);
29531
+ try {
29532
+ const parsed = parseArguments(context2, limits);
29533
+ const selection = new Selection(parsed.patterns, limits, context2.signal);
29534
+ let archive = parsed.archive;
29535
+ let archiveStat;
29536
+ for (const candidate of [archive, `${archive}.zip`, `${archive}.ZIP`]) {
29537
+ checkPath(candidate, limits);
29538
+ const candidateStat2 = await extraction.stat(vfsPath(context2.cwd, candidate));
29539
+ if (candidateStat2) {
29540
+ archive = candidate;
29541
+ archiveStat = candidateStat2;
29542
+ break;
29543
+ }
29544
+ }
29545
+ if (!archiveStat) {
29546
+ await budget.output(`unzip: cannot find or open ${archive}, ${archive}.zip or ${archive}.ZIP.
29547
+ `, true);
29548
+ return { exitCode: 9 };
29549
+ }
29550
+ const archivePath = await extraction.operation(() => context2.fs.realpath(vfsPath(context2.cwd, archive), { signal: context2.signal }));
29551
+ archiveStat = await extraction.operation(() => context2.fs.stat(archivePath, { signal: context2.signal }));
29552
+ if (archiveStat.type !== "file") fail2("input archive is not a regular file");
29553
+ const bytes3 = await collectBytes(bounded(extraction.input(archivePath), limits.maxArchiveBytes, context2.signal, limits.chunkSize), { signal: context2.signal, maxBytes: limits.maxArchiveBytes });
29554
+ await budget.output(`Archive: ${filtered(archive)}
29555
+ `);
29556
+ const zip = await readZipArchive(bytes3, limits, context2.signal);
29557
+ await comment(zip.comment, budget);
29558
+ if (!zip.entries.length) {
29559
+ await budget.output(`warning [${filtered(archive)}]: zipfile is empty
29560
+ `, true);
29561
+ return { exitCode: 1 };
29562
+ }
29563
+ if (parsed.list) await budget.output(" Length Date Time Name\n--------- ---------- ----- ----\n");
29564
+ const rootRaw = parsed.destination === void 0 ? context2.cwd : vfsPath(context2.cwd, parsed.destination);
29565
+ const root = parsed.list ? resolvePath(rootRaw) : await extraction.directory(rootRaw, true);
29566
+ answers = new Answers(extraction.source(context2.stdin), limits, context2.signal);
29567
+ let overwrite = parsed.overwrite ? "all" : "ask";
29568
+ let exitCode = 0;
29569
+ let selected = 0;
29570
+ let total = 0;
29571
+ let actualTotal = 0;
29572
+ const links = [];
29573
+ const directories = [];
29574
+ for (const entry of zip.entries) {
29575
+ await budget.member(entry.size);
29576
+ checkPath(entry.name, limits);
29577
+ if (!await selection.matches(entry.name)) continue;
29578
+ selected++;
29579
+ total += entry.size;
29580
+ if (parsed.list) {
29581
+ await budget.output(`${String(entry.size).padStart(9)} ${date(entry)} ${filtered(entry.name)}
29582
+ `);
29583
+ if (entry.comment) await comment(entry.comment, budget);
29584
+ continue;
29585
+ }
29586
+ let path = extraction.member(root, entry.name);
29587
+ const fileType = entry.mode & 61440;
29588
+ if (fileType && fileType !== 32768 && fileType !== 16384 && fileType !== 40960) fail2("unsupported special ZIP entry");
29589
+ if (path === root && !entry.directory) fail2("entry would replace extraction root");
29590
+ let shown = parsed.destination === void 0 ? entry.name : `${parsed.destination.endsWith("/") ? parsed.destination : `${parsed.destination}/`}${entry.name}`;
29591
+ await extraction.parents(root, path, true);
29592
+ if (entry.directory) {
29593
+ if (entry.size) fail2("directory has nonempty payload");
29594
+ for await (const chunk of readBytes(decodeZipEntry(entry, limits, context2.signal), context2.signal)) {
29595
+ await writeFileOutput(context2, chunk, async () => {
29596
+ if (chunk.length) fail2("directory has nonempty payload");
29597
+ });
29598
+ }
29599
+ const existing3 = await extraction.stat(path);
29600
+ if (existing3 && existing3.type !== "directory") fail2("directory destination is not a directory");
29601
+ if (!existing3) {
29602
+ await extraction.operation(() => context2.fs.mkdir(path, { signal: context2.signal, mode: 493 }));
29603
+ await budget.output(` creating: ${filtered(shown)}
29604
+ `);
29605
+ }
29606
+ const identity2 = await extraction.stat(path);
29607
+ if (!identity2 || identity2.type !== "directory") fail2("directory changed during creation");
29608
+ directories.push({ path, entry, identity: identity2 });
29609
+ continue;
29610
+ }
29611
+ let existing2 = await extraction.destination(path, archivePath, archiveStat);
29612
+ let skip = false;
29613
+ let prompting = 0;
29614
+ while (existing2 && overwrite !== "all") {
29615
+ if (overwrite === "none") {
29616
+ skip = true;
29617
+ break;
29618
+ }
29619
+ if (++prompting > limits.maxMembers) fail2("overwrite prompt work limit exceeded");
29620
+ await budget.output(`replace ${filtered(shown)}? [y]es, [n]o, [A]ll, [N]one, [r]ename: `, true);
29621
+ const answer = await answers.read();
29622
+ if (answer === void 0) {
29623
+ await budget.output(' NULL\n(EOF or read error, treating as "[N]one" ...)\n', true);
29624
+ overwrite = "none";
29625
+ exitCode = 1;
29626
+ skip = true;
29627
+ break;
29628
+ }
29629
+ const choice = answer[0];
29630
+ if (choice === "A") {
29631
+ overwrite = "all";
29632
+ break;
29633
+ }
29634
+ if (choice === "y" || choice === "Y") break;
29635
+ if (choice === "n" || choice === "N") {
29636
+ if (choice === "N") overwrite = "none";
29637
+ skip = true;
29638
+ break;
29639
+ }
29640
+ if (choice === "r" || choice === "R") {
29641
+ let renamed = "";
29642
+ while (!renamed) {
29643
+ await budget.output("new name: ", true);
29644
+ const value2 = await answers.read(limits.maxPathBytes);
29645
+ if (value2 === void 0) fail2("EOF while reading replacement name");
29646
+ renamed = value2.endsWith("\n") ? value2.slice(0, -1) : value2;
29647
+ }
29648
+ path = extraction.member(root, renamed);
29649
+ shown = parsed.destination === void 0 ? renamed : `${parsed.destination.endsWith("/") ? parsed.destination : `${parsed.destination}/`}${renamed}`;
29650
+ await extraction.parents(root, path, true);
29651
+ existing2 = await extraction.destination(path, archivePath, archiveStat);
29652
+ continue;
29653
+ }
29654
+ const response = choice === "\n" || choice === "\r" ? "{ENTER}" : answer.endsWith("\n") ? answer.slice(0, -1) : answer;
29655
+ await budget.output(`error: invalid response [${response}]
29656
+ `, true);
29657
+ }
29658
+ if (skip) continue;
29659
+ const chunks = [];
29660
+ let actual = 0;
29661
+ for await (const chunk of readBytes(decodeZipEntry(entry, limits, context2.signal), context2.signal)) {
29662
+ if (chunk.length > limits.maxEntryBytes - actual || chunk.length > limits.maxTotalBytes - actualTotal) fail2("actual decompressed byte limit exceeded");
29663
+ actual += chunk.length;
29664
+ actualTotal += chunk.length;
29665
+ await writeFileOutput(context2, chunk, async (bytes4) => {
29666
+ chunks.push(Uint8Array.from(bytes4));
29667
+ });
29668
+ }
29669
+ if (entry.symlink) {
29670
+ if (actual > limits.maxPathBytes) fail2("symlink target byte limit exceeded");
29671
+ const target = text2(import_buffer.Buffer.concat(chunks));
29672
+ await extraction.target(root, path, target);
29673
+ if (!context2.fs.symlink || context2.fs.capabilities.symlinks === false) fail2("filesystem does not support symlinks");
29674
+ links.push({ path, shown, target, existing: existing2, entry });
29675
+ await budget.output(` linking: ${padded(filtered(shown))} -> ${filtered(target)}
29676
+ `);
29677
+ } else {
29678
+ await extraction.publish(root, path, chunks, existing2, entry.mode, entry.modified);
29679
+ await budget.output(`${entry.method === 0 ? " extracting" : " inflating"}: ${padded(filtered(shown))}
29680
+ `);
29681
+ }
29682
+ }
29683
+ if (parsed.list) await budget.output(`--------- -------
29684
+ ${String(total).padStart(9)} ${selected} file${selected === 1 ? "" : "s"}
29685
+ `);
29686
+ else {
29687
+ if (links.length) await budget.output("finishing deferred symbolic links:\n");
29688
+ for (const link of links) {
29689
+ await extraction.parents(root, link.path, false);
29690
+ await extraction.target(root, link.path, link.target);
29691
+ await extraction.destination(link.path, archivePath, archiveStat);
29692
+ await extraction.publish(root, link.path, [], link.existing, link.entry.mode, link.entry.modified, link.target);
29693
+ await budget.output(` ${padded(filtered(link.shown))} -> ${filtered(link.target)}
29694
+ `);
29695
+ }
29696
+ for (const { path, entry, identity: identity2 } of directories.reverse()) {
29697
+ await extraction.metadata(root, path, identity2, entry.mode, entry.modified);
29698
+ }
29699
+ for (let index = 0; index < parsed.patterns.length; index++) if (!selection.matched.has(index)) {
29700
+ await budget.output(`caution: filename not matched: ${filtered(parsed.patterns[index])}
29701
+ `, true);
29702
+ exitCode = 11;
29703
+ }
29704
+ }
29705
+ return { exitCode: selected ? exitCode : 11 };
29706
+ } catch (error) {
29707
+ original.signal.throwIfAborted();
29708
+ const message3 = display(publicDiagnosticMessage(error, original.onInternalError).slice(0, limits.maxDiagnosticBytes));
29709
+ await writeBytes(original.stderr, import_buffer.Buffer.from(`unzip: ${message3}
29710
+ `).subarray(0, limits.maxDiagnosticBytes), original.signal);
29711
+ return { exitCode: 2 };
29712
+ } finally {
29713
+ await close();
29714
+ }
29715
+ } };
29716
+ }
29717
+
28179
29718
  // packages/safe-bash/src/commands/archive/index.ts
28180
29719
  function createTarCommand(options3 = {}) {
28181
29720
  const limits = settings2(options3);
@@ -28219,12 +29758,16 @@ function createTarCommand(options3 = {}) {
28219
29758
  } };
28220
29759
  }
28221
29760
  function createArchiveCommands(options3 = {}) {
28222
- return [createTarCommand(options3)];
29761
+ return [createTarCommand(options3), createZipCommand(options3), createUnzipCommand(options3)];
28223
29762
  }
28224
29763
  function archiveCommands(options3 = {}) {
28225
29764
  const commands = createArchiveCommands(options3);
28226
29765
  return { name: "archive-commands", setup(host2) {
28227
- if (!options3.replace && host2.commands.has("tar")) throw new Error("Command already registered: tar");
29766
+ if (!options3.replace) {
29767
+ for (const command7 of commands) {
29768
+ if (host2.commands.has(command7.name)) throw new Error(`Command already registered: ${command7.name}`);
29769
+ }
29770
+ }
28228
29771
  for (const command7 of commands) host2.commands.register(command7, { replace: options3.replace ?? false });
28229
29772
  } };
28230
29773
  }
@@ -28642,17 +30185,17 @@ function createCommCommand(options3 = {}) {
28642
30185
 
28643
30186
  // packages/safe-bash/src/commands/table-text/join.ts
28644
30187
  init_platform();
28645
- function number3(value2, label) {
30188
+ function number4(value2, label) {
28646
30189
  if (!/^[0-9]+$/u.test(value2) || !Number.isSafeInteger(Number(value2)) || Number(value2) < 1) fail3(`invalid ${label}: ${value2}`);
28647
30190
  return Number(value2);
28648
30191
  }
28649
- function parse12(context2, budget) {
30192
+ function parse13(context2, budget) {
28650
30193
  const options3 = { files: [], fields: [0, 0], unpaired: /* @__PURE__ */ new Set(), paired: true, separator: 10, delimiter: void 0, whole: false, replacement: empty, format: void 0, fold: false, header: false, order: "default" };
28651
30194
  let literal = false;
28652
30195
  let delimiterChoice;
28653
30196
  const apply = (flag, value2) => {
28654
30197
  if (flag === "1" || flag === "2" || flag === "j") {
28655
- const field2 = number3(value2, "field") - 1;
30198
+ const field2 = number4(value2, "field") - 1;
28656
30199
  if (flag !== "2") options3.fields[0] = field2;
28657
30200
  if (flag !== "1") options3.fields[1] = field2;
28658
30201
  } else if (flag === "a" || flag === "v") {
@@ -28687,7 +30230,7 @@ function parse12(context2, budget) {
28687
30230
  if (specification === "0") return { file: 0, index: 0 };
28688
30231
  const match = /^([12])\.([0-9]+)$/u.exec(specification);
28689
30232
  if (!match) fail3(`invalid output field: ${specification}`);
28690
- return { file: Number(match[1]), index: number3(match[2], "output field") - 1 };
30233
+ return { file: Number(match[1]), index: number4(match[2], "output field") - 1 };
28691
30234
  });
28692
30235
  options3.format = [...Array.isArray(options3.format) ? options3.format : [], ...fields3];
28693
30236
  budget.check(options3.format.length, budget.limits.maxFields, "field");
@@ -28769,7 +30312,7 @@ function split3(bytes3, options3, budget) {
28769
30312
  function createJoinCommand(factory = {}) {
28770
30313
  const limits = settings3(factory);
28771
30314
  return command3("join", async (context2) => {
28772
- const budget = new Budget17(context2, limits), options3 = parse12(context2, budget);
30315
+ const budget = new Budget17(context2, limits), options3 = parse13(context2, budget);
28773
30316
  requireCLocale(context2);
28774
30317
  const inputs2 = new Inputs(context2, budget, options3.separator), order = new OrderCheck(options3.order, context2);
28775
30318
  const terminator = Uint8Array.of(options3.separator), delimiter = Uint8Array.of(options3.delimiter ?? 32);
@@ -29195,9 +30738,9 @@ function tabs(specifications) {
29195
30738
  if (!entry) continue;
29196
30739
  const prefix3 = entry.match(/^[+/]+/u)?.[0] ?? "";
29197
30740
  if (prefix3) marker = prefix3.at(-1);
29198
- const number5 = entry.slice(prefix3.length);
29199
- if (!number5) continue;
29200
- const stop = integer(number5, marker ? 0 : 1);
30741
+ const number6 = entry.slice(prefix3.length);
30742
+ if (!number6) continue;
30743
+ const stop = integer(number6, marker ? 0 : 1);
29201
30744
  if (marker === "+") {
29202
30745
  if (relativeRepeat) throw new UsageError("repeating tab stop must be last");
29203
30746
  relativeRepeat = stop;
@@ -29614,9 +31157,9 @@ function fixed2(coefficient, scale, precision) {
29614
31157
  function exponentOf(coefficient, scale) {
29615
31158
  return coefficient === 0n ? 0 : (coefficient < 0n ? -coefficient : coefficient).toString().length - scale - 1;
29616
31159
  }
29617
- function formatted2(coefficient, scale, format2, negativeZero = false) {
29618
- const kind = format2.kind.toLowerCase();
29619
- let precision = format2.precision;
31160
+ function formatted2(coefficient, scale, format3, negativeZero = false) {
31161
+ const kind = format3.kind.toLowerCase();
31162
+ let precision = format3.precision;
29620
31163
  let exponent = exponentOf(coefficient, scale);
29621
31164
  let text3;
29622
31165
  if (kind === "f") text3 = fixed2(coefficient, scale, precision);
@@ -29628,24 +31171,24 @@ function formatted2(coefficient, scale, format2, negativeZero = false) {
29628
31171
  exponent = exponentOf(value2, significantScale);
29629
31172
  if (kind === "e" || exponent < -4 || exponent >= precision) {
29630
31173
  text3 = fixed2(value2, significantScale + exponent, significant - 1);
29631
- if (kind === "g" && !format2.flags.includes("#") && text3.includes(".")) text3 = text3.replace(/\.?0+$/u, "");
29632
- if (format2.flags.includes("#") && !text3.includes(".")) text3 += ".";
31174
+ if (kind === "g" && !format3.flags.includes("#") && text3.includes(".")) text3 = text3.replace(/\.?0+$/u, "");
31175
+ if (format3.flags.includes("#") && !text3.includes(".")) text3 += ".";
29633
31176
  text3 += `e${exponent < 0 ? "-" : "+"}${Math.abs(exponent).toString().padStart(2, "0")}`;
29634
31177
  } else {
29635
31178
  text3 = fixed2(value2, significantScale, Math.max(0, precision - exponent - 1));
29636
- if (!format2.flags.includes("#") && text3.includes(".")) text3 = text3.replace(/\.?0+$/u, "");
31179
+ if (!format3.flags.includes("#") && text3.includes(".")) text3 = text3.replace(/\.?0+$/u, "");
29637
31180
  }
29638
31181
  }
29639
- if (format2.flags.includes("#") && !text3.includes(".") && !text3.includes("e")) text3 += ".";
31182
+ if (format3.flags.includes("#") && !text3.includes(".") && !text3.includes("e")) text3 += ".";
29640
31183
  if ((coefficient < 0n || negativeZero) && !text3.startsWith("-")) text3 = "-" + text3;
29641
- if (coefficient >= 0n && !negativeZero) text3 = (format2.flags.includes("+") ? "+" : format2.flags.includes(" ") ? " " : "") + text3;
29642
- if (format2.kind === format2.kind.toUpperCase()) text3 = text3.toUpperCase();
29643
- if (format2.flags.includes("-")) text3 = text3.padEnd(format2.width, " ");
29644
- else if (format2.flags.includes("0")) {
31184
+ if (coefficient >= 0n && !negativeZero) text3 = (format3.flags.includes("+") ? "+" : format3.flags.includes(" ") ? " " : "") + text3;
31185
+ if (format3.kind === format3.kind.toUpperCase()) text3 = text3.toUpperCase();
31186
+ if (format3.flags.includes("-")) text3 = text3.padEnd(format3.width, " ");
31187
+ else if (format3.flags.includes("0")) {
29645
31188
  const sign = /^[+ -]/u.test(text3) ? text3[0] : "";
29646
- text3 = sign + text3.slice(sign.length).padStart(Math.max(0, format2.width - sign.length), "0");
29647
- } else text3 = text3.padStart(format2.width, " ");
29648
- return format2.prefix + text3 + format2.suffix;
31189
+ text3 = sign + text3.slice(sign.length).padStart(Math.max(0, format3.width - sign.length), "0");
31190
+ } else text3 = text3.padStart(format3.width, " ");
31191
+ return format3.prefix + text3 + format3.suffix;
29649
31192
  }
29650
31193
  function binaryDecimal(value2) {
29651
31194
  const view = new DataView(new ArrayBuffer(8));
@@ -29658,12 +31201,12 @@ function binaryDecimal(value2) {
29658
31201
  if (bits >> 63n) coefficient = -coefficient;
29659
31202
  return power2 >= 0 ? { coefficient: coefficient << BigInt(power2), scale: 0 } : { coefficient: coefficient * 5n ** BigInt(-power2), scale: -power2 };
29660
31203
  }
29661
- async function floatingSequence(first, increment, last, format2, separator, session) {
31204
+ async function floatingSequence(first, increment, last, format3, separator, session) {
29662
31205
  if (![first, increment, last].every(Number.isFinite) || increment === 0) throw new UsageError("formatted operands must fit finite binary64 with a nonzero increment");
29663
31206
  if (increment > 0 ? first > last : first < last) return;
29664
- const render2 = (number5) => {
29665
- const decimal4 = binaryDecimal(number5);
29666
- const text3 = formatted2(decimal4.coefficient, decimal4.scale, format2, Object.is(number5, -0));
31207
+ const render2 = (number6) => {
31208
+ const decimal4 = binaryDecimal(number6);
31209
+ const text3 = formatted2(decimal4.coefficient, decimal4.scale, format3, Object.is(number6, -0));
29667
31210
  session.check(import_buffer.Buffer.byteLength(text3), session.limits.maxRecordBytes, "record");
29668
31211
  return text3;
29669
31212
  };
@@ -29679,7 +31222,7 @@ async function floatingSequence(first, increment, last, format2, separator, sess
29679
31222
  const outside = increment > 0 ? current > last : current < last;
29680
31223
  const text3 = render2(current);
29681
31224
  if (outside) {
29682
- const numeric4 = text3.slice(format2.prefix.length, text3.length - format2.suffix.length);
31225
+ const numeric4 = text3.slice(format3.prefix.length, text3.length - format3.suffix.length);
29683
31226
  if (Number(numeric4) !== last || text3 === previous) break;
29684
31227
  }
29685
31228
  await session.text((index ? separator : "") + text3);
@@ -29766,9 +31309,9 @@ function createSeqCommand(limits) {
29766
31309
  let current = align(first);
29767
31310
  const step = align(increment), finish = align(last);
29768
31311
  const precision = Math.max(first.precision, increment.precision);
29769
- const format2 = formatText === void 0 ? void 0 : parseFormat(formatText, session);
29770
- if (format2) {
29771
- await floatingSequence(Number(operands.length === 1 ? "1" : operands[0]), Number(operands.length === 3 ? operands[1] : "1"), Number(operands.at(-1)), format2, separator, session);
31312
+ const format3 = formatText === void 0 ? void 0 : parseFormat(formatText, session);
31313
+ if (format3) {
31314
+ await floatingSequence(Number(operands.length === 1 ? "1" : operands[0]), Number(operands.length === 3 ? operands[1] : "1"), Number(operands.at(-1)), format3, separator, session);
29772
31315
  return;
29773
31316
  }
29774
31317
  const firstText = (first.negativeZero ? "-" : "") + fixed2(current, scale, precision);
@@ -29806,9 +31349,9 @@ function style(text3) {
29806
31349
  }
29807
31350
  function signed(text3) {
29808
31351
  if (!/^[+-]?\d+$/u.test(text3.trim())) throw new UsageError(`invalid line number: '${text3}'`);
29809
- const number5 = BigInt(text3);
29810
- if (number5 < -(1n << 63n) || number5 >= 1n << 63n) throw new UsageError(`line number out of range: '${text3}'`);
29811
- return number5;
31352
+ const number6 = BigInt(text3);
31353
+ if (number6 < -(1n << 63n) || number6 >= 1n << 63n) throw new UsageError(`line number out of range: '${text3}'`);
31354
+ return number6;
29812
31355
  }
29813
31356
  function createNlCommand(limits) {
29814
31357
  return command5("nl", limits, async (session) => {
@@ -29828,8 +31371,8 @@ function createNlCommand(limits) {
29828
31371
  const header3 = style(value(parsed, "h") ?? "n"), body = style(value(parsed, "b") ?? "t"), footer = style(value(parsed, "f") ?? "n");
29829
31372
  const start = signed(value(parsed, "v") ?? "1"), increment = signed(value(parsed, "i") ?? "1");
29830
31373
  const join = Math.max(1, integer(value(parsed, "l") ?? "1")), width = integer(value(parsed, "w") ?? "6", 1);
29831
- const separator = value(parsed, "s") ?? " ", format2 = value(parsed, "n") ?? "rn";
29832
- if (!["ln", "rn", "rz"].includes(format2)) throw new UsageError(`invalid line numbering format: '${format2}'`);
31374
+ const separator = value(parsed, "s") ?? " ", format3 = value(parsed, "n") ?? "rn";
31375
+ if (!["ln", "rn", "rz"].includes(format3)) throw new UsageError(`invalid line numbering format: '${format3}'`);
29833
31376
  session.check(width + import_buffer.Buffer.byteLength(separator), limits.maxRecordBytes, "number field");
29834
31377
  let delimiter = import_buffer.Buffer.from("\\:");
29835
31378
  for (const argument2 of parsed.values.get("d") ?? []) {
@@ -29839,14 +31382,14 @@ function createNlCommand(limits) {
29839
31382
  const delimiters2 = [1, 2, 3].map((count2) => import_buffer.Buffer.concat(Array.from({ length: count2 }, () => delimiter)));
29840
31383
  const budget = new PatternBudget(session);
29841
31384
  const unnumbered = " ".repeat(width + import_buffer.Buffer.byteLength(separator));
29842
- let current = body, number5 = start, blanks = 0;
31385
+ let current = body, number6 = start, blanks = 0;
29843
31386
  await session.files(session.names(parsed.operands), async (source2) => {
29844
31387
  for await (const record4 of records2(source2, session)) {
29845
31388
  const bytes3 = import_buffer.Buffer.from(record4);
29846
31389
  const section = delimiter.length ? delimiters2.findIndex((candidate) => candidate.equals(bytes3)) : -1;
29847
31390
  if (section >= 0) {
29848
31391
  current = section === 0 ? footer : section === 1 ? body : header3;
29849
- if (!parsed.flags.has("p")) number5 = start;
31392
+ if (!parsed.flags.has("p")) number6 = start;
29850
31393
  await session.text("\n");
29851
31394
  continue;
29852
31395
  }
@@ -29858,13 +31401,13 @@ function createNlCommand(limits) {
29858
31401
  else if (current === "n") numbered = false;
29859
31402
  else numbered = await current.find(bytes3.toString("latin1"), budget) !== void 0;
29860
31403
  if (numbered) {
29861
- if (number5 < -(1n << 63n) || number5 >= 1n << 63n) throw new UsageError("line number overflow");
29862
- let label = number5.toString();
29863
- if (format2 === "ln") label = label.padEnd(width, " ");
29864
- else if (format2 === "rz" && number5 < 0n) label = "-" + label.slice(1).padStart(width - 1, "0");
29865
- else label = label.padStart(width, format2 === "rz" ? "0" : " ");
31404
+ if (number6 < -(1n << 63n) || number6 >= 1n << 63n) throw new UsageError("line number overflow");
31405
+ let label = number6.toString();
31406
+ if (format3 === "ln") label = label.padEnd(width, " ");
31407
+ else if (format3 === "rz" && number6 < 0n) label = "-" + label.slice(1).padStart(width - 1, "0");
31408
+ else label = label.padStart(width, format3 === "rz" ? "0" : " ");
29866
31409
  await session.text(label + separator);
29867
- number5 += increment;
31410
+ number6 += increment;
29868
31411
  } else await session.text(unnumbered);
29869
31412
  await session.output(record4);
29870
31413
  await session.text("\n");
@@ -29941,13 +31484,13 @@ function tabStops(specifications, session) {
29941
31484
  for (const entry of specification.split(/[, \t]+/u).filter(Boolean)) {
29942
31485
  if (repeat) throw new UsageError("repeating tab stop must be last");
29943
31486
  const marker = entry[0] === "+" || entry[0] === "/" ? entry[0] : "";
29944
- const number5 = integer(entry.slice(marker.length), 1);
31487
+ const number6 = integer(entry.slice(marker.length), 1);
29945
31488
  if (marker) {
29946
- repeat = number5;
31489
+ repeat = number6;
29947
31490
  relative = marker === "+";
29948
31491
  } else {
29949
- if (number5 <= (stops.at(-1) ?? 0)) throw new UsageError("tab stops must be ascending");
29950
- stops.push(number5);
31492
+ if (number6 <= (stops.at(-1) ?? 0)) throw new UsageError("tab stops must be ascending");
31493
+ stops.push(number6);
29951
31494
  }
29952
31495
  }
29953
31496
  }
@@ -30080,7 +31623,7 @@ function settings6(options3) {
30080
31623
  }
30081
31624
  return limits;
30082
31625
  }
30083
- function number4(text3, label, units = false, zero2 = false) {
31626
+ function number5(text3, label, units = false, zero2 = false) {
30084
31627
  const match = /^[\t\n\v\f\r ]*\+?([0-9]*)([a-zA-Z]*)$/u.exec(text3);
30085
31628
  if (!match || !match[1] && (!units || !match[2] || text3 !== match[2])) throw new PublicDiagnostic(`invalid ${label}: '${text3}'`);
30086
31629
  const suffix2 = match[2];
@@ -30099,7 +31642,7 @@ function number4(text3, label, units = false, zero2 = false) {
30099
31642
  if (!Number.isSafeInteger(value2) || value2 < (zero2 ? 0 : 1)) throw new PublicDiagnostic(`invalid ${label}: '${text3}'`);
30100
31643
  return value2;
30101
31644
  }
30102
- function parseArguments(args, limits) {
31645
+ function parseArguments2(args, limits) {
30103
31646
  if (args.reduce((total, argument2) => total + import_buffer.Buffer.byteLength(argument2), 0) > limits.maxArgumentBytes) {
30104
31647
  throw new PublicDiagnostic("split argument limit exceeded");
30105
31648
  }
@@ -30118,14 +31661,14 @@ function parseArguments(args, limits) {
30118
31661
  if (!/^[0-9]*$/u.test(value2)) throw new PublicDiagnostic(`invalid start value for numerical suffix: '${value2}'`);
30119
31662
  numericStart = value2.replace(/^0+(?=\d)/u, "") || "0";
30120
31663
  }
30121
- } else if (option === "a") suffixLength = number4(value2, "suffix length", false, true);
31664
+ } else if (option === "a") suffixLength = number5(value2, "suffix length", false, true);
30122
31665
  else if (option === "additional-suffix") {
30123
31666
  if (value2.includes("/") || value2.includes("\0")) throw new PublicDiagnostic("invalid additional suffix: contains directory separator or NUL");
30124
31667
  additionalSuffix = value2;
30125
31668
  } else {
30126
31669
  if (mode) throw new PublicDiagnostic("cannot split in more than one way");
30127
31670
  mode = option === "l" ? "lines" : option === "b" ? "bytes" : "line-bytes";
30128
- size = number4(value2, option === "l" ? "number of lines" : "number of bytes", option !== "l");
31671
+ size = number5(value2, option === "l" ? "number of lines" : "number of bytes", option !== "l");
30129
31672
  }
30130
31673
  };
30131
31674
  const long = {
@@ -30472,7 +32015,7 @@ var LineBytes = class {
30472
32015
  }
30473
32016
  };
30474
32017
  async function run3(context2, limits) {
30475
- const args = parseArguments(context2.args, limits);
32018
+ const args = parseArguments2(context2.args, limits);
30476
32019
  const controller = new AbortController();
30477
32020
  const signal = AbortSignal.any([context2.signal, controller.signal]);
30478
32021
  const budget = new Budget18(limits, signal);
@@ -30725,22 +32268,22 @@ function millisecondsInstant(value2) {
30725
32268
  return boundedInstant(scale >= 0 ? coefficient * 10n ** BigInt(scale) : floorDivide(coefficient, 10n ** BigInt(-scale)));
30726
32269
  }
30727
32270
  function utcMilliseconds(fields3) {
30728
- const date = /* @__PURE__ */ new Date(0);
30729
- date.setUTCFullYear(fields3.year, fields3.month - 1, fields3.day);
30730
- date.setUTCHours(fields3.hour, fields3.minute, fields3.second, 0);
30731
- const value2 = date.getTime();
32271
+ const date2 = /* @__PURE__ */ new Date(0);
32272
+ date2.setUTCFullYear(fields3.year, fields3.month - 1, fields3.day);
32273
+ date2.setUTCHours(fields3.hour, fields3.minute, fields3.second, 0);
32274
+ const value2 = date2.getTime();
30732
32275
  if (!Number.isFinite(value2)) throw new CommandFailure("date is outside the supported range");
30733
32276
  return value2;
30734
32277
  }
30735
32278
  function utcFields(milliseconds) {
30736
- const date = new Date(milliseconds);
32279
+ const date2 = new Date(milliseconds);
30737
32280
  return {
30738
- year: date.getUTCFullYear(),
30739
- month: date.getUTCMonth() + 1,
30740
- day: date.getUTCDate(),
30741
- hour: date.getUTCHours(),
30742
- minute: date.getUTCMinutes(),
30743
- second: date.getUTCSeconds()
32281
+ year: date2.getUTCFullYear(),
32282
+ month: date2.getUTCMonth() + 1,
32283
+ day: date2.getUTCDate(),
32284
+ hour: date2.getUTCHours(),
32285
+ minute: date2.getUTCMinutes(),
32286
+ second: date2.getUTCSeconds()
30744
32287
  };
30745
32288
  }
30746
32289
  function sameFields(left, right) {
@@ -30905,7 +32448,7 @@ function offsetText(offset, colons) {
30905
32448
  if (colons === 1 || minutes !== "00") return { value: `${sign}${hours}:${minutes}`, width: 6 };
30906
32449
  return { value: `${sign}${hours}`, width: 3 };
30907
32450
  }
30908
- function formatDate(format2, instant, zone, limits) {
32451
+ function formatDate(format3, instant, zone, limits) {
30909
32452
  const fields3 = zone.fields(instant);
30910
32453
  const midnight = utcMilliseconds({ ...fields3, hour: 0, minute: 0, second: 0 });
30911
32454
  const weekday = new Date(midnight).getUTCDay();
@@ -30914,8 +32457,8 @@ function formatDate(format2, instant, zone, limits) {
30914
32457
  const isoYear = thursday.getUTCFullYear();
30915
32458
  const isoWeek = 1 + Math.floor((thursday.getTime() - utcMilliseconds({ year: isoYear, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 6048e5);
30916
32459
  const nano = (instant - floorDivide(instant, nanosecondsPerSecond) * nanosecondsPerSecond).toString().padStart(9, "0");
30917
- const number5 = (value2, width = 2, padding = "0") => value2.toString().padStart(width, padding);
30918
- const time = `${number5(fields3.hour)}:${number5(fields3.minute)}:${number5(fields3.second)}`;
32460
+ const number6 = (value2, width = 2, padding = "0") => value2.toString().padStart(width, padding);
32461
+ const time = `${number6(fields3.hour)}:${number6(fields3.minute)}:${number6(fields3.second)}`;
30919
32462
  const hour12 = fields3.hour % 12 || 12;
30920
32463
  const meridian = fields3.hour < 12 ? "AM" : "PM";
30921
32464
  const pieces = [];
@@ -30925,32 +32468,32 @@ function formatDate(format2, instant, zone, limits) {
30925
32468
  checkSize(size + 1, limits.maxOutputBytes, "output");
30926
32469
  pieces.push(value2);
30927
32470
  };
30928
- for (let offset = 0; offset < format2.length; ) {
30929
- const next = format2.indexOf("%", offset);
32471
+ for (let offset = 0; offset < format3.length; ) {
32472
+ const next = format3.indexOf("%", offset);
30930
32473
  if (next < 0) {
30931
- append(format2.slice(offset));
32474
+ append(format3.slice(offset));
30932
32475
  break;
30933
32476
  }
30934
- append(format2.slice(offset, next));
32477
+ append(format3.slice(offset, next));
30935
32478
  offset = next + 1;
30936
32479
  let padding, upper = false, swap = false;
30937
- while (offset < format2.length && "-_0^#".includes(format2[offset])) {
30938
- const flag = format2[offset++];
32480
+ while (offset < format3.length && "-_0^#".includes(format3[offset])) {
32481
+ const flag = format3[offset++];
30939
32482
  if (flag === "^") upper = true;
30940
32483
  else if (flag === "#") swap = true;
30941
32484
  else padding = flag === "-" ? "" : flag === "_" ? " " : "0";
30942
32485
  }
30943
32486
  let widthText = "";
30944
- while (offset < format2.length && /[0-9]/.test(format2[offset])) widthText += format2[offset++];
32487
+ while (offset < format3.length && /[0-9]/.test(format3[offset])) widthText += format3[offset++];
30945
32488
  const width = widthText ? Number(widthText) : void 0;
30946
32489
  if (width !== void 0) checkSize(width, limits.maxFormatWidth, "format width");
30947
32490
  let colons = 0;
30948
- while (format2[offset] === ":") {
32491
+ while (format3[offset] === ":") {
30949
32492
  colons++;
30950
32493
  offset++;
30951
32494
  }
30952
- const modifier = format2[offset] === "E" || format2[offset] === "O" ? format2[offset++] : void 0;
30953
- const code = format2[offset++];
32495
+ const modifier = format3[offset] === "E" || format3[offset] === "O" ? format3[offset++] : void 0;
32496
+ const code = format3[offset++];
30954
32497
  if (!code || colons > 3 || colons && code !== "z") throw new CommandFailure("unsupported date format directive");
30955
32498
  if (code === "%" && (padding !== void 0 || upper || swap || width !== void 0 || modifier)) {
30956
32499
  throw new CommandFailure("only an unmodified %% literal is supported");
@@ -30975,7 +32518,7 @@ function formatDate(format2, instant, zone, limits) {
30975
32518
  value2 = monthNames[fields3.month - 1];
30976
32519
  break;
30977
32520
  case "c":
30978
- value2 = `${weekdayNames[weekday].slice(0, 3)} ${monthNames[fields3.month - 1].slice(0, 3)} ${number5(fields3.day, 2, " ")} ${time} ${number5(fields3.year, 4)}`;
32521
+ value2 = `${weekdayNames[weekday].slice(0, 3)} ${monthNames[fields3.month - 1].slice(0, 3)} ${number6(fields3.day, 2, " ")} ${time} ${number6(fields3.year, 4)}`;
30979
32522
  break;
30980
32523
  case "C":
30981
32524
  value2 = String(Math.floor(fields3.year / 100));
@@ -30988,15 +32531,15 @@ function formatDate(format2, instant, zone, limits) {
30988
32531
  if (code === "e") defaultPadding = " ";
30989
32532
  break;
30990
32533
  case "D":
30991
- value2 = `${number5(fields3.month)}/${number5(fields3.day)}/${number5(fields3.year % 100, 2, padding ?? "0")}`;
32534
+ value2 = `${number6(fields3.month)}/${number6(fields3.day)}/${number6(fields3.year % 100, 2, padding ?? "0")}`;
30992
32535
  break;
30993
32536
  case "x":
30994
- value2 = `${number5(fields3.month)}/${number5(fields3.day)}/${number5(fields3.year % 100)}`;
32537
+ value2 = `${number6(fields3.month)}/${number6(fields3.day)}/${number6(fields3.year % 100)}`;
30995
32538
  break;
30996
32539
  case "F": {
30997
32540
  const yearWidth = width === void 0 && padding === void 0 ? 4 : Math.max(0, (width ?? 0) - 6);
30998
- const year = padding === "" ? String(fields3.year) : number5(fields3.year, yearWidth, padding ?? "0");
30999
- append(`${year}-${number5(fields3.month)}-${number5(fields3.day)}`);
32541
+ const year = padding === "" ? String(fields3.year) : number6(fields3.year, yearWidth, padding ?? "0");
32542
+ append(`${year}-${number6(fields3.month)}-${number6(fields3.day)}`);
31000
32543
  continue;
31001
32544
  }
31002
32545
  case "g":
@@ -31053,10 +32596,10 @@ function formatDate(format2, instant, zone, limits) {
31053
32596
  defaultWidth = 1;
31054
32597
  break;
31055
32598
  case "r":
31056
- value2 = `${number5(hour12)}:${number5(fields3.minute)}:${number5(fields3.second)} ${meridian}`;
32599
+ value2 = `${number6(hour12)}:${number6(fields3.minute)}:${number6(fields3.second)} ${meridian}`;
31057
32600
  break;
31058
32601
  case "R":
31059
- value2 = `${number5(fields3.hour)}:${number5(fields3.minute)}`;
32602
+ value2 = `${number6(fields3.hour)}:${number6(fields3.minute)}`;
31060
32603
  break;
31061
32604
  case "s":
31062
32605
  value2 = floorDivide(instant, nanosecondsPerSecond).toString();
@@ -31124,8 +32667,8 @@ function formatDate(format2, instant, zone, limits) {
31124
32667
  }
31125
32668
 
31126
32669
  // packages/safe-bash/src/commands/time-env/date.ts
31127
- function parseArguments2(args) {
31128
- let input3, reference, format2, style2;
32670
+ function parseArguments3(args) {
32671
+ let input3, reference, format3, style2;
31129
32672
  let utc = false, ended = false;
31130
32673
  const formatted3 = (value2) => {
31131
32674
  if (style2 !== void 0) throw new CommandFailure("multiple output formats specified");
@@ -31217,15 +32760,15 @@ function parseArguments2(args) {
31217
32760
  }
31218
32761
  } else {
31219
32762
  if (!argument2.startsWith("+")) throw new CommandFailure("expected +FORMAT; clock-setting operands are unsupported");
31220
- if (format2 !== void 0) throw new CommandFailure("extra format operand");
31221
- format2 = argument2.slice(1);
32763
+ if (format3 !== void 0) throw new CommandFailure("extra format operand");
32764
+ format3 = argument2.slice(1);
31222
32765
  }
31223
32766
  }
31224
32767
  if (input3 !== void 0 && reference !== void 0) throw new CommandFailure("--date and --reference are mutually exclusive");
31225
- if (format2 !== void 0 && style2 !== void 0) throw new CommandFailure("multiple output formats specified");
32768
+ if (format3 !== void 0 && style2 !== void 0) throw new CommandFailure("multiple output formats specified");
31226
32769
  return {
31227
32770
  utc,
31228
- format: format2 ?? style2 ?? "%a %b %e %T %Z %Y",
32771
+ format: format3 ?? style2 ?? "%a %b %e %T %Z %Y",
31229
32772
  ...input3 === void 0 ? {} : { input: input3 },
31230
32773
  ...reference === void 0 ? {} : { reference }
31231
32774
  };
@@ -31233,7 +32776,7 @@ function parseArguments2(args) {
31233
32776
  function createDateCommand(configuration) {
31234
32777
  new TimeZone(configuration.defaultTimeZone);
31235
32778
  return command6("date", configuration, async (context2) => {
31236
- const parsed = parseArguments2(context2.args);
32779
+ const parsed = parseArguments3(context2.args);
31237
32780
  if (parsed.informational) {
31238
32781
  await emit(context2, parsed.informational === "version" ? "date (safe-bash virtual command)\n" : "Usage: date [-u] [-d DATE | -r FILE] [+FORMAT]\nAlso: -I[date|hours|minutes|seconds|ns], -R, --rfc-3339=PRECISION\nDATE accepts @seconds, ISO calendar/time, RFC dates, now/today/yesterday/tomorrow, and integer seconds/minutes/hours relative to now.\nVirtual TZ defaults to UTC; no clock setting or host-locale parsing.\n", configuration.limits);
31239
32782
  return 0;
@@ -31614,7 +33157,7 @@ function environmentCharset(budget) {
31614
33157
  }
31615
33158
 
31616
33159
  // packages/safe-bash/src/commands/tree/arguments.ts
31617
- function parse13(args, budget) {
33160
+ function parse14(args, budget) {
31618
33161
  budget.check(args.length, budget.limits.maxArguments, "argument count");
31619
33162
  let bytes3 = 0;
31620
33163
  for (const arg of args) {
@@ -31983,7 +33526,7 @@ function createTreeCommand(options3 = {}) {
31983
33526
  const budget = new WalkBudget(context2, limits);
31984
33527
  let args;
31985
33528
  try {
31986
- args = parse13(context2.args, budget);
33529
+ args = parse14(context2.args, budget);
31987
33530
  } catch (error) {
31988
33531
  context2.signal.throwIfAborted();
31989
33532
  if (!(error instanceof UsageError2)) throw error;
@@ -32289,7 +33832,7 @@ function limitMessage(error) {
32289
33832
  // packages/safe-bash/src/commands/file/index.ts
32290
33833
  var profile = "virtual-bash-file-v1";
32291
33834
  var help2 = "Usage: file [-bihL] [--mime-type] [--mime-encoding] [--] FILE...\nClassify bounded VFS content; '-' reads stdin. -h is the default.\nOptions: --brief, --mime, --dereference, --no-dereference, --help, --version\nNo decompression, external magic database, or complete format validation.\n";
32292
- async function parse14(args, budget) {
33835
+ async function parse15(args, budget) {
32293
33836
  const result2 = { brief: false, follow: false, mimeType: false, mimeEncoding: false, names: [] };
32294
33837
  let argumentBytes = 0;
32295
33838
  budget.check(args.length, budget.limits.maxArgumentBytes, "argument");
@@ -32437,7 +33980,7 @@ function createFileCommand(options3 = {}) {
32437
33980
  const budget = new SharedBudget(context2, limits);
32438
33981
  let writing = false;
32439
33982
  try {
32440
- const args = await parse14(context2.args, budget);
33983
+ const args = await parse15(context2.args, budget);
32441
33984
  if (args.action) {
32442
33985
  writing = true;
32443
33986
  await budget.output(context2.stdout, args.action === "help" ? help2 : `file (${profile})
@@ -32665,7 +34208,7 @@ function readerSettings(limits) {
32665
34208
  function usage(message3) {
32666
34209
  throw new FsError("EINVAL", { message: message3 });
32667
34210
  }
32668
- function parse15(args, limits) {
34211
+ function parse16(args, limits) {
32669
34212
  if (args.length > limits.maxArgumentBytes) usage("argument count limit exceeded");
32670
34213
  let argumentBytes = 0;
32671
34214
  for (const token of args) {
@@ -33057,7 +34600,7 @@ function createColumnCommand(options3 = {}) {
33057
34600
  let rejection;
33058
34601
  try {
33059
34602
  try {
33060
- const parsed = parse15(context2.args, limits);
34603
+ const parsed = parse16(context2.args, limits);
33061
34604
  inputs2 = new ColumnInputs(context2, limits);
33062
34605
  const budget = inputs2.budget;
33063
34606
  if (parsed.help) await budget.text(helpText3);
@@ -33872,7 +35415,7 @@ This documented HTML subset is a converter, not a sanitizer or browser HTML5 par
33872
35415
 
33873
35416
  // packages/safe-bash/src/commands/html-to-markdown/render.ts
33874
35417
  init_platform();
33875
- var format = (tag) => tag === "em" || tag === "i" ? "em" : tag === "strong" || tag === "b" ? "strong" : tag === "del" || tag === "s" ? "del" : void 0;
35418
+ var format2 = (tag) => tag === "em" || tag === "i" ? "em" : tag === "strong" || tag === "b" ? "strong" : tag === "del" || tag === "s" ? "del" : void 0;
33876
35419
  var inlineAtoms = /* @__PURE__ */ new Set(["a", "img", "code", "br"]);
33877
35420
  var Renderer = class {
33878
35421
  constructor(budget) {
@@ -33951,9 +35494,9 @@ var Renderer = class {
33951
35494
  const append = async (child, target = result2) => {
33952
35495
  this.budget.work(1);
33953
35496
  await this.budget.checkpoint();
33954
- const style2 = format(child.tag);
35497
+ const style2 = format2(child.tag);
33955
35498
  const previous = target.at(-1);
33956
- if (style2 && previous && format(previous.tag) === style2) {
35499
+ if (style2 && previous && format2(previous.tag) === style2) {
33957
35500
  for (const nested of child.children) await append(nested, previous.children);
33958
35501
  } else target.push(child);
33959
35502
  };
@@ -33979,9 +35522,9 @@ var Renderer = class {
33979
35522
  this.budget.work(1);
33980
35523
  this.destinations.set(child, url);
33981
35524
  }
33982
- const style2 = format(child.tag);
35525
+ const style2 = format2(child.tag);
33983
35526
  if (child.tag !== "text" && !blockTags.has(child.tag) && !inlineAtoms.has(child.tag)) {
33984
- if (!style2 || style2 === format(node.tag)) {
35527
+ if (!style2 || style2 === format2(node.tag)) {
33985
35528
  for (const nested of child.children) await visit(nested);
33986
35529
  return;
33987
35530
  }
@@ -34003,7 +35546,7 @@ var Renderer = class {
34003
35546
  return result2;
34004
35547
  }
34005
35548
  async punctuationBoundary(node, ending) {
34006
- if (!node || !format(node.tag)) return false;
35549
+ if (!node || !format2(node.tag)) return false;
34007
35550
  const edge = async (parent) => {
34008
35551
  for (let step = 0; step < parent.children.length; step++) {
34009
35552
  this.budget.work(1);
@@ -34012,7 +35555,7 @@ var Renderer = class {
34012
35555
  if (child.tag === "text") {
34013
35556
  if (child.text) return ending ? Array.from(child.text.slice(-2)).at(-1) : String.fromCodePoint(child.text.codePointAt(0));
34014
35557
  } else if (child.tag === "br" || blockTags.has(child.tag)) return " ";
34015
- else if (format(child.tag) || inlineAtoms.has(child.tag)) return "*";
35558
+ else if (format2(child.tag) || inlineAtoms.has(child.tag)) return "*";
34016
35559
  else {
34017
35560
  const nested = await edge(child);
34018
35561
  if (nested !== void 0) return nested;
@@ -34050,8 +35593,8 @@ var Renderer = class {
34050
35593
  async children(node, maximum = this.budget.limits.maxOutputBytes - this.budget.output) {
34051
35594
  const result2 = new Builder(this.budget, maximum);
34052
35595
  const children = await this.inlineChildren(node);
34053
- const alternate = (index) => format(node.tag) === "em" || format(children[index - 1]?.tag ?? "") === "em" || format(children[index + 1]?.tag ?? "") === "em";
34054
- const separate = async (index, ending) => format(children[index]?.tag ?? "") === "strong" && alternate(index) || await this.punctuationBoundary(children[index], ending);
35596
+ const alternate = (index) => format2(node.tag) === "em" || format2(children[index - 1]?.tag ?? "") === "em" || format2(children[index + 1]?.tag ?? "") === "em";
35597
+ const separate = async (index, ending) => format2(children[index]?.tag ?? "") === "strong" && alternate(index) || await this.punctuationBoundary(children[index], ending);
34055
35598
  for (let index = 0; index < children.length; index++) {
34056
35599
  const child = children[index];
34057
35600
  this.budget.work(1);
@@ -34361,10 +35904,10 @@ function blockSize2(value2) {
34361
35904
  function ceiling(value2, divisor) {
34362
35905
  return (value2 + divisor - 1n) / divisor;
34363
35906
  }
34364
- function formatSize(value2, format2) {
35907
+ function formatSize(value2, format3) {
34365
35908
  const bytes3 = BigInt(value2);
34366
- if (!format2.human) return `${ceiling(bytes3, format2.unit)}${format2.suffix}`;
34367
- const base = BigInt(format2.human);
35909
+ if (!format3.human) return `${ceiling(bytes3, format3.unit)}${format3.suffix}`;
35910
+ const base = BigInt(format3.human);
34368
35911
  let unit2 = 1n;
34369
35912
  let exponent = 0;
34370
35913
  while (bytes3 >= unit2 * base) {
@@ -34377,13 +35920,13 @@ function formatSize(value2, format2) {
34377
35920
  exponent++;
34378
35921
  }
34379
35922
  const tenths = ceiling(bytes3 * 10n, unit2);
34380
- const number5 = tenths < 100n ? `${tenths / 10n}.${tenths % 10n}` : String(ceiling(bytes3, unit2));
34381
- const suffix2 = (format2.human === 1e3 ? "kMGTPEZYRQ" : "KMGTPEZYRQ")[exponent - 1];
34382
- return number5 + suffix2;
35923
+ const number6 = tenths < 100n ? `${tenths / 10n}.${tenths % 10n}` : String(ceiling(bytes3, unit2));
35924
+ const suffix2 = (format3.human === 1e3 ? "kMGTPEZYRQ" : "KMGTPEZYRQ")[exponent - 1];
35925
+ return number6 + suffix2;
34383
35926
  }
34384
35927
 
34385
35928
  // packages/safe-bash/src/commands/du/arguments.ts
34386
- function parse16(budget) {
35929
+ function parse17(budget) {
34387
35930
  const { args, env } = budget.context;
34388
35931
  budget.check(args.length, budget.limits.maxArguments, "argument count");
34389
35932
  let bytes3 = 0;
@@ -34397,11 +35940,11 @@ function parse16(budget) {
34397
35940
  const operands = [];
34398
35941
  let all = false, summarize = false, total = false, apparent = false, countLinks = false, nullOutput = false, help5 = false;
34399
35942
  let depth;
34400
- let format2;
35943
+ let format3;
34401
35944
  let options3 = true;
34402
35945
  const valueOption = (flag, value2) => {
34403
35946
  if (flag === "B" || flag === "block-size") {
34404
- format2 = blockSize2(value2);
35947
+ format3 = blockSize2(value2);
34405
35948
  return;
34406
35949
  }
34407
35950
  if (!/^\d+$/u.test(value2) || !Number.isSafeInteger(Number(value2))) throw new UsageError3(`invalid maximum depth '${value2}'`);
@@ -34423,18 +35966,18 @@ function parse16(budget) {
34423
35966
  break;
34424
35967
  case "h":
34425
35968
  case "human-readable":
34426
- format2 = blockSize2("human-readable");
35969
+ format3 = blockSize2("human-readable");
34427
35970
  break;
34428
35971
  case "k":
34429
- format2 = blockSize2("1024");
35972
+ format3 = blockSize2("1024");
34430
35973
  break;
34431
35974
  case "m":
34432
- format2 = blockSize2("1048576");
35975
+ format3 = blockSize2("1048576");
34433
35976
  break;
34434
35977
  case "b":
34435
35978
  case "bytes":
34436
35979
  apparent = true;
34437
- format2 = blockSize2("1");
35980
+ format3 = blockSize2("1");
34438
35981
  break;
34439
35982
  case "apparent-size":
34440
35983
  apparent = true;
@@ -34490,7 +36033,7 @@ function parse16(budget) {
34490
36033
  }
34491
36034
  if (all && summarize) throw new UsageError3("cannot combine --all and --summarize");
34492
36035
  if (summarize && depth !== void 0 && depth !== 0) throw new UsageError3("--summarize conflicts with --max-depth");
34493
- if (!format2) {
36036
+ if (!format3) {
34494
36037
  let selected;
34495
36038
  for (const name2 of ["DU_BLOCK_SIZE", "BLOCK_SIZE", "BLOCKSIZE"]) {
34496
36039
  if (Object.hasOwn(env, name2)) {
@@ -34503,16 +36046,16 @@ function parse16(budget) {
34503
36046
  budget.check(import_buffer.Buffer.byteLength(selected), budget.limits.maxArgumentBytes - bytes3, "environment bytes");
34504
36047
  budget.step(selected.length + 1);
34505
36048
  try {
34506
- format2 = blockSize2(selected);
36049
+ format3 = blockSize2(selected);
34507
36050
  } catch (error) {
34508
36051
  if (!(error instanceof UsageError3)) throw error;
34509
- format2 = blockSize2(Object.hasOwn(env, "POSIXLY_CORRECT") ? "512" : "1024");
36052
+ format3 = blockSize2(Object.hasOwn(env, "POSIXLY_CORRECT") ? "512" : "1024");
34510
36053
  }
34511
- } else format2 = blockSize2(Object.hasOwn(env, "POSIXLY_CORRECT") ? "512" : "1024");
36054
+ } else format3 = blockSize2(Object.hasOwn(env, "POSIXLY_CORRECT") ? "512" : "1024");
34512
36055
  }
34513
36056
  if (operands.length === 0) operands.push(".");
34514
36057
  for (const operand of operands) budget.text(operand);
34515
- return { operands, all, summarize, total, apparent, countLinks, nullOutput, depth: summarize ? 0 : depth ?? Number.MAX_SAFE_INTEGER, format: format2, help: help5 };
36058
+ return { operands, all, summarize, total, apparent, countLinks, nullOutput, depth: summarize ? 0 : depth ?? Number.MAX_SAFE_INTEGER, format: format3, help: help5 };
34516
36059
  }
34517
36060
  var helpText5 = `Usage: du [OPTION]... [--] [FILE]...
34518
36061
  Report provider allocation; unknown allocation is an error, never logical size.
@@ -34837,7 +36380,7 @@ function createDuCommand(options3 = {}) {
34837
36380
  const budget = new Budget21(work, limits, context2);
34838
36381
  context2.registerCleanup?.(budget.close);
34839
36382
  try {
34840
- const args = parse16(budget);
36383
+ const args = parse17(budget);
34841
36384
  if (context2.stdout.ownedOutput) operation2 = createOutputOperation(context2, context2.stdout);
34842
36385
  if (args.help) {
34843
36386
  await budget.emit(work.stdout, helpText5);
@@ -35120,9 +36663,9 @@ async function evaluateCall(operator, values, budget, match) {
35120
36663
  const candidateEnd = nextCharacter(accept, candidate, unicode);
35121
36664
  budget.charge(1 + end2 - offset);
35122
36665
  if (end2 - offset === candidateEnd - candidate) {
35123
- let equal = true;
35124
- for (let byte = 0; byte < end2 - offset; byte++) if (subject[offset + byte] !== accept[candidate + byte]) equal = false;
35125
- if (equal) return smallInteger(position2, budget);
36666
+ let equal2 = true;
36667
+ for (let byte = 0; byte < end2 - offset; byte++) if (subject[offset + byte] !== accept[candidate + byte]) equal2 = false;
36668
+ if (equal2) return smallInteger(position2, budget);
35126
36669
  }
35127
36670
  candidate = candidateEnd;
35128
36671
  await budget.yield();
@@ -35369,7 +36912,7 @@ function settings14(options3) {
35369
36912
 
35370
36913
  // packages/safe-bash/src/commands/which/which.ts
35371
36914
  var USAGE = "usage: which [-as] program ...\n";
35372
- var encoder2 = new TextEncoder();
36915
+ var encoder3 = new TextEncoder();
35373
36916
  var descriptions = {
35374
36917
  EACCES: "permission denied",
35375
36918
  EAGAIN: "resource temporarily unavailable",
@@ -35487,7 +37030,7 @@ ${USAGE}`);
35487
37030
  }
35488
37031
  async write(sink, text3) {
35489
37032
  this.check();
35490
- const bytes3 = encoder2.encode(text3);
37033
+ const bytes3 = encoder3.encode(text3);
35491
37034
  this.check();
35492
37035
  try {
35493
37036
  await writeBytes(sink, bytes3, this.context.signal);
@@ -35827,22 +37370,22 @@ function createDeadline(binding, duration2, maximumChunk) {
35827
37370
  }
35828
37371
 
35829
37372
  // packages/safe-bash/src/commands/timeout/index.ts
35830
- var encoder3 = new TextEncoder();
37373
+ var encoder4 = new TextEncoder();
35831
37374
  var records3 = Object.freeze({
35832
- missingDuration: encoder3.encode("timeout: missing duration\n"),
35833
- invalidDuration: encoder3.encode("timeout: invalid duration\n"),
35834
- durationOverflow: encoder3.encode("timeout: duration exceeds supported range\n"),
35835
- missingCommand: encoder3.encode("timeout: missing command\n"),
35836
- invalidOption: encoder3.encode("timeout: invalid option\n"),
35837
- preserveStatus: encoder3.encode("timeout: option --preserve-status is unsupported\n"),
35838
- signal: encoder3.encode("timeout: option --signal is unsupported\n"),
35839
- killAfter: encoder3.encode("timeout: option --kill-after is unsupported\n"),
35840
- foreground: encoder3.encode("timeout: option --foreground is unsupported\n"),
35841
- verbose: encoder3.encode("timeout: option --verbose is unsupported\n"),
35842
- invokeUnavailable: encoder3.encode("timeout: command invocation is unavailable\n"),
35843
- timerSetupFailed: encoder3.encode("timeout: timer setup failed\n"),
35844
- help: encoder3.encode("Usage: timeout [OPTION] DURATION COMMAND [ARG]...\nRun a virtual-bash command with a cooperative time limit.\n"),
35845
- version: encoder3.encode("timeout (virtual-bash cooperative profile)\n")
37375
+ missingDuration: encoder4.encode("timeout: missing duration\n"),
37376
+ invalidDuration: encoder4.encode("timeout: invalid duration\n"),
37377
+ durationOverflow: encoder4.encode("timeout: duration exceeds supported range\n"),
37378
+ missingCommand: encoder4.encode("timeout: missing command\n"),
37379
+ invalidOption: encoder4.encode("timeout: invalid option\n"),
37380
+ preserveStatus: encoder4.encode("timeout: option --preserve-status is unsupported\n"),
37381
+ signal: encoder4.encode("timeout: option --signal is unsupported\n"),
37382
+ killAfter: encoder4.encode("timeout: option --kill-after is unsupported\n"),
37383
+ foreground: encoder4.encode("timeout: option --foreground is unsupported\n"),
37384
+ verbose: encoder4.encode("timeout: option --verbose is unsupported\n"),
37385
+ invokeUnavailable: encoder4.encode("timeout: command invocation is unavailable\n"),
37386
+ timerSetupFailed: encoder4.encode("timeout: timer setup failed\n"),
37387
+ help: encoder4.encode("Usage: timeout [OPTION] DURATION COMMAND [ARG]...\nRun a virtual-bash command with a cooperative time limit.\n"),
37388
+ version: encoder4.encode("timeout (virtual-bash cooperative profile)\n")
35846
37389
  });
35847
37390
  function optionsObject(value2) {
35848
37391
  if (value2 === void 0) return void 0;
@@ -36125,7 +37668,7 @@ var Work2 = class {
36125
37668
  return text3.slice(start, end);
36126
37669
  }
36127
37670
  async encodeInto(text3, target, start) {
36128
- const encoder4 = new TextEncoder();
37671
+ const encoder5 = new TextEncoder();
36129
37672
  let offset = start;
36130
37673
  for (let index = 0; index < text3.length; ) {
36131
37674
  let end = Math.min(text3.length, index + 1024);
@@ -36135,7 +37678,7 @@ var Work2 = class {
36135
37678
  const chunk = text3.slice(index, end);
36136
37679
  const bytes3 = await this.utf8(chunk, target.length - offset);
36137
37680
  await this.charge(bytes3);
36138
- const encoded2 = encoder4.encodeInto(chunk, target.subarray(offset, offset + bytes3));
37681
+ const encoded2 = encoder5.encodeInto(chunk, target.subarray(offset, offset + bytes3));
36139
37682
  if (encoded2.read !== chunk.length || encoded2.written !== bytes3) throw new Error("apply_patch encoding size mismatch");
36140
37683
  offset += bytes3;
36141
37684
  index = end;
@@ -36308,7 +37851,7 @@ async function targetPath(value2, work) {
36308
37851
  if (absolute2.split("/").length - 1 > work.limits.maxPathComponents) throw new PatchError("maxPathComponents limit exceeded");
36309
37852
  return absolute2;
36310
37853
  }
36311
- async function parse17(text3, work) {
37854
+ async function parse18(text3, work) {
36312
37855
  await work.utf8(work.cwd, work.limits.maxPathBytes, 2);
36313
37856
  if (!work.cwd.startsWith("/") || work.cwd.includes("\0")) throw new PatchError("cwd must be an absolute virtual path", 2);
36314
37857
  const lines3 = await patchLines(text3, work);
@@ -36736,7 +38279,7 @@ var Invocation2 = class {
36736
38279
  let summary;
36737
38280
  try {
36738
38281
  try {
36739
- const files = await parse17(await this.input(), work);
38282
+ const files = await parse18(await this.input(), work);
36740
38283
  const plans = await this.prepare(files);
36741
38284
  const lines3 = ["Success. Updated the following files:\n"];
36742
38285
  let bytes3 = lines3[0].length;
@@ -38044,7 +39587,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
38044
39587
  const quoteLine = this.lineAt(this.position);
38045
39588
  this.position += 2;
38046
39589
  const bytes3 = [];
38047
- const encoder4 = new TextEncoder();
39590
+ const encoder5 = new TextEncoder();
38048
39591
  const escapes = { a: 7, b: 8, e: 27, E: 27, f: 12, n: 10, r: 13, t: 9, v: 11, "\\": 92, "'": 39, '"': 34, "?": 63 };
38049
39592
  while (this.position < this.source.length) {
38050
39593
  const character = String.fromCodePoint(this.source.codePointAt(this.position));
@@ -38063,7 +39606,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
38063
39606
  }
38064
39607
  }
38065
39608
  if (character !== "\\") {
38066
- bytes3.push(...encoder4.encode(character));
39609
+ bytes3.push(...encoder5.encode(character));
38067
39610
  continue;
38068
39611
  }
38069
39612
  const escape = this.source[this.position++];
@@ -38087,16 +39630,16 @@ shell: command substitution: line ${line}: \`${sourceLine}'
38087
39630
  const code = parseInt(digits, 16);
38088
39631
  if (escape === "x") bytes3.push(code);
38089
39632
  else if (this.byteLocale && code > 127) {
38090
- bytes3.push(...encoder4.encode(`\\${code <= 65535 ? "u" : "U"}${code.toString(16).toUpperCase().padStart(code <= 65535 ? 4 : 8, "0")}`));
39633
+ bytes3.push(...encoder5.encode(`\\${code <= 65535 ? "u" : "U"}${code.toString(16).toUpperCase().padStart(code <= 65535 ? 4 : 8, "0")}`));
38091
39634
  } else {
38092
39635
  if (code > 1114111 || code >= 55296 && code <= 57343) this.error("Unsupported non-scalar ANSI-C Unicode escape");
38093
- bytes3.push(...encoder4.encode(String.fromCodePoint(code)));
39636
+ bytes3.push(...encoder5.encode(String.fromCodePoint(code)));
38094
39637
  }
38095
39638
  } else if (escape === "c" && this.source[this.position] !== "'" && this.position < this.source.length) {
38096
39639
  const control = this.source[this.position++];
38097
39640
  if (control === "\\" && this.source[this.position] === "\\") this.position++;
38098
39641
  bytes3.push(control === "?" ? 127 : control.toUpperCase().charCodeAt(0) & 31);
38099
- } else bytes3.push(92, ...encoder4.encode(escape));
39642
+ } else bytes3.push(92, ...encoder5.encode(escape));
38100
39643
  }
38101
39644
  this.error("Unterminated ANSI-C quote", { quote: "'", line: quoteLine });
38102
39645
  }
@@ -38374,7 +39917,7 @@ var Parser4 = class {
38374
39917
  this.advance();
38375
39918
  let nodes = 0;
38376
39919
  const grouped = /* @__PURE__ */ new WeakSet();
38377
- const admit2 = () => {
39920
+ const admit3 = () => {
38378
39921
  if (nodes >= 4096) this.error("Conditional syntax exceeds 4096 nodes");
38379
39922
  nodes++;
38380
39923
  };
@@ -38385,7 +39928,7 @@ var Parser4 = class {
38385
39928
  const primary = (depth) => {
38386
39929
  if (depth > 64) this.error("Conditional syntax nesting exceeds 64");
38387
39930
  if (this.is("!")) {
38388
- admit2();
39931
+ admit3();
38389
39932
  this.advance();
38390
39933
  const expression2 = primary(depth + 1);
38391
39934
  if (expression2.kind === "not" && !grouped.has(expression2)) return expression2.operand;
@@ -38399,7 +39942,7 @@ var Parser4 = class {
38399
39942
  grouped.add(expression2);
38400
39943
  return expression2;
38401
39944
  }
38402
- admit2();
39945
+ admit3();
38403
39946
  this.budget.admit();
38404
39947
  const first = operand();
38405
39948
  if (conditionalBinary.has(this.current.value)) {
@@ -38415,7 +39958,7 @@ var Parser4 = class {
38415
39958
  const conjunction = (depth) => {
38416
39959
  let expression2 = primary(depth);
38417
39960
  while (this.is("&&")) {
38418
- admit2();
39961
+ admit3();
38419
39962
  this.budget.admit();
38420
39963
  this.advance();
38421
39964
  expression2 = { kind: "and", left: expression2, right: primary(depth) };
@@ -38425,7 +39968,7 @@ var Parser4 = class {
38425
39968
  const disjunction = (depth) => {
38426
39969
  let expression2 = conjunction(depth);
38427
39970
  while (this.is("||")) {
38428
- admit2();
39971
+ admit3();
38429
39972
  this.budget.admit();
38430
39973
  this.advance();
38431
39974
  expression2 = { kind: "or", left: expression2, right: conjunction(depth) };
@@ -39038,7 +40581,7 @@ async function* expandBraces(word, budget, signal) {
39038
40581
  signal.throwIfAborted();
39039
40582
  if (++work % 128 === 0) await yieldTurn(signal);
39040
40583
  };
39041
- const admit2 = (bytes3 = 64) => {
40584
+ const admit3 = (bytes3 = 64) => {
39042
40585
  budget.parsing.admit();
39043
40586
  allocation.reserveBytes(bytes3);
39044
40587
  };
@@ -39051,15 +40594,15 @@ async function* expandBraces(word, budget, signal) {
39051
40594
  return left * right;
39052
40595
  };
39053
40596
  const partNode = (part) => {
39054
- admit2();
40597
+ admit3();
39055
40598
  return { kind: "part", part, count: 1, bytes: part.kind === "text" ? shellValueByteLength(part.byteValue ?? part.value) : 0 };
39056
40599
  };
39057
40600
  const textNode = (value2) => {
39058
- admit2(value2.length * 2);
40601
+ admit3(value2.length * 2);
39059
40602
  return partNode({ kind: "text", value: value2, quoted: false });
39060
40603
  };
39061
40604
  const product = async (children) => {
39062
- admit2();
40605
+ admit3();
39063
40606
  let count2 = 1;
39064
40607
  let bytes3 = 0;
39065
40608
  for (const child of children) {
@@ -39073,24 +40616,24 @@ async function* expandBraces(word, budget, signal) {
39073
40616
  if (children.length !== 1 || children[0].kind !== "part") return void 0;
39074
40617
  const part = children[0].part;
39075
40618
  if (part.kind !== "text" || part.quoted || part.byteValue) return void 0;
39076
- admit2(32);
40619
+ admit3(32);
39077
40620
  const pieces = [];
39078
40621
  let startOffset = 0;
39079
40622
  for (let offset = 0; offset < part.value.length; offset++) {
39080
40623
  if (offset % 1024 === 0) await checkpoint();
39081
40624
  if (part.value[offset] !== "." || part.value[offset + 1] !== ".") continue;
39082
40625
  if (pieces.length === 2) return void 0;
39083
- admit2(16 + (offset - startOffset) * 2);
40626
+ admit3(16 + (offset - startOffset) * 2);
39084
40627
  pieces.push(part.value.slice(startOffset, offset));
39085
40628
  startOffset = offset + 2;
39086
40629
  offset++;
39087
40630
  }
39088
40631
  if (!pieces.length) return void 0;
39089
- admit2(16 + (part.value.length - startOffset) * 2);
40632
+ admit3(16 + (part.value.length - startOffset) * 2);
39090
40633
  pieces.push(part.value.slice(startOffset));
39091
40634
  const first = pieces[0];
39092
40635
  const last = pieces[1];
39093
- admit2(256);
40636
+ admit3(256);
39094
40637
  let start = await integer8(first, checkpoint);
39095
40638
  let end = await integer8(last, checkpoint);
39096
40639
  const numeric4 = start !== void 0 && end !== void 0;
@@ -39107,16 +40650,16 @@ async function* expandBraces(word, budget, signal) {
39107
40650
  const distance = end - start;
39108
40651
  const cardinality = (distance < 0n ? -distance : distance) / step + 1n;
39109
40652
  if (cardinality > BigInt(budget.limits.maxExpansionFields)) budget.fail("maxExpansionFields");
39110
- const padded = (value2) => value2.length > 1 && value2.startsWith("0") || value2.length > 2 && value2.startsWith("-0");
39111
- const width = numeric4 && (padded(first) || padded(last)) ? Math.max(first.length, last.length) : 0;
40653
+ const padded2 = (value2) => value2.length > 1 && value2.startsWith("0") || value2.length > 2 && value2.startsWith("-0");
40654
+ const width = numeric4 && (padded2(first) || padded2(last)) ? Math.max(first.length, last.length) : 0;
39112
40655
  const count2 = Number(cardinality);
39113
40656
  const termBytes = numeric4 ? Math.max(width, start.toString().length, end.toString().length) : 1;
39114
40657
  const bytes3 = multiply3(count2, termBytes, "maxExpansionBytes");
39115
- admit2();
40658
+ admit3();
39116
40659
  return { kind: "range", start, step: distance < 0n ? -step : step, width, numeric: numeric4, count: count2, bytes: bytes3 };
39117
40660
  };
39118
40661
  try {
39119
- admit2();
40662
+ admit3();
39120
40663
  const frames = [{ branches: [[]] }];
39121
40664
  const append = (node) => {
39122
40665
  frames.at(-1).branches.at(-1).push(node);
@@ -39136,20 +40679,20 @@ async function* expandBraces(word, budget, signal) {
39136
40679
  const character = part.value[offset];
39137
40680
  if (character !== "{" && character !== "}" && character !== ",") continue;
39138
40681
  if (start < offset) {
39139
- admit2((offset - start) * 2);
40682
+ admit3((offset - start) * 2);
39140
40683
  append(textNode(part.value.slice(start, offset)));
39141
40684
  }
39142
40685
  start = offset + 1;
39143
40686
  if (character === "{") {
39144
- admit2();
40687
+ admit3();
39145
40688
  frames.push({ branches: [[]] });
39146
40689
  } else if (character === "," && frames.length > 1) {
39147
- admit2();
40690
+ admit3();
39148
40691
  frames.at(-1).branches.push([]);
39149
40692
  } else if (character === "}" && frames.length > 1) {
39150
40693
  const frame = frames.pop();
39151
40694
  if (frame.branches.length > 1) {
39152
- admit2(frame.branches.length * 8);
40695
+ admit3(frame.branches.length * 8);
39153
40696
  const children = [];
39154
40697
  for (const branch of frame.branches) children.push(await product(branch));
39155
40698
  let count2 = 0;
@@ -39178,7 +40721,7 @@ async function* expandBraces(word, budget, signal) {
39178
40721
  if (start < part.value.length) {
39179
40722
  if (start === 0) append(partNode(part));
39180
40723
  else {
39181
- admit2((part.value.length - start) * 2);
40724
+ admit3((part.value.length - start) * 2);
39182
40725
  append(textNode(part.value.slice(start)));
39183
40726
  }
39184
40727
  }
@@ -41569,7 +43112,7 @@ var Restoration = class {
41569
43112
  this.holding?.release();
41570
43113
  }
41571
43114
  };
41572
- async function snapshotState(state, clone, signal, prepare, scope) {
43115
+ async function snapshotState(state, clone, signal, prepare2, scope) {
41573
43116
  const monitor = stateMonitor(state);
41574
43117
  if (!monitor) return clone();
41575
43118
  const session = scope ? { ...monitor.session, scope, owner: void 0, guestOwner: void 0, monitors: /* @__PURE__ */ new Set() } : monitor.session;
@@ -41659,8 +43202,8 @@ async function snapshotState(state, clone, signal, prepare, scope) {
41659
43202
  await owner.ledger.checkpoint(signal, 5);
41660
43203
  }
41661
43204
  check();
41662
- if (prepare) {
41663
- await prepare(result2.proxy, owner);
43205
+ if (prepare2) {
43206
+ await prepare2(result2.proxy, owner);
41664
43207
  check();
41665
43208
  }
41666
43209
  return result2.proxy;
@@ -42139,6 +43682,9 @@ var Budget25 = class {
42139
43682
  }
42140
43683
  fileSystemOperation() {
42141
43684
  this.cpuCheckpoint();
43685
+ this.fileSystemCleanupOperation();
43686
+ }
43687
+ fileSystemCleanupOperation() {
42142
43688
  if (this.#fileSystemOperations >= this.limits.maxFileSystemOperations) this.fail("maxFileSystemOperations");
42143
43689
  this.#fileSystemOperations++;
42144
43690
  }
@@ -42250,7 +43796,7 @@ var typedSavedVariables = /* @__PURE__ */ new WeakMap();
42250
43796
  var valueScope = /* @__PURE__ */ Symbol("shell value allocation scope");
42251
43797
  var invokedValues = /* @__PURE__ */ new WeakMap();
42252
43798
  function isolateIO(io) {
42253
- return { ...io, nameExpansionContext: void 0, ...io.descriptors ? { descriptors: new Map([...io.descriptors].map(([number5, descriptor2]) => [number5, { ...descriptor2 }])) } : {} };
43799
+ return { ...io, nameExpansionContext: void 0, ...io.descriptors ? { descriptors: new Map([...io.descriptors].map(([number6, descriptor2]) => [number6, { ...descriptor2 }])) } : {} };
42254
43800
  }
42255
43801
  function activeIO(io) {
42256
43802
  const input3 = io.descriptors?.get(0);
@@ -43008,7 +44554,7 @@ var Runtime = class _Runtime {
43008
44554
  this.cancellationMaxDepth = cancellationMaxDepth;
43009
44555
  this.outcomeFrame = outcomeFrame;
43010
44556
  this.inputProfile = inputProfile;
43011
- this.fs = scopeFileSystem(fs, () => budget.fileSystemOperation(), signal);
44557
+ this.fs = scopeFileSystem(fs, () => budget.fileSystemOperation(), signal, () => budget.fileSystemCleanupOperation());
43012
44558
  const checkpoint = () => budget.cpuCheckpoint();
43013
44559
  registerYieldCheckpoint(signal, checkpoint);
43014
44560
  registerYieldCheckpoint(commandSignal, checkpoint);
@@ -43568,9 +45114,9 @@ var Runtime = class _Runtime {
43568
45114
  async arrayIndex(binding, index, state, io, owner, create = false) {
43569
45115
  if (!binding?.associative) {
43570
45116
  const selected = index.source === void 0 ? index : literalIndex(index.source, 0, this.budget.parsing);
43571
- const number5 = numericIndex(selected);
43572
- if (number5 === void 0) throw new ArrayFailure("index outside 0..2147483647");
43573
- return number5;
45117
+ const number6 = numericIndex(selected);
45118
+ if (number6 === void 0) throw new ArrayFailure("index outside 0..2147483647");
45119
+ return number6;
43574
45120
  }
43575
45121
  const word = index.word ?? parseArraySubscript(index.source ?? index.decimal, this.budget.parsing, byteLocale(state.variables), state.depth);
43576
45122
  const fields3 = await this.valueWord(word, state, io, false);
@@ -45319,7 +46865,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45319
46865
  this.reconcileGetopts(child, state.variables.OPTIND);
45320
46866
  return child;
45321
46867
  }
45322
- async shebangStage(incoming, state, io, terminal, prepare, replacementInput, existingScope) {
46868
+ async shebangStage(incoming, state, io, terminal, prepare2, replacementInput, existingScope) {
45323
46869
  const scope = existingScope ?? io[invocationScope].child();
45324
46870
  const ownsScope = existingScope === void 0;
45325
46871
  const runtime = new _Runtime(
@@ -45380,7 +46926,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45380
46926
  if (argumentValues.values.every((value2) => typeof value2 === "string")) Reflect.deleteProperty(context2, "argumentValues");
45381
46927
  const child = await runtime.shebangState(context2, state);
45382
46928
  const childIO = { ...io, ...context2, [invocationScope]: scope };
45383
- invocationOverride.current = prepare?.(runtime, context2, child, childIO);
46929
+ invocationOverride.current = prepare2?.(runtime, context2, child, childIO);
45384
46930
  const runtimeFrame = {};
45385
46931
  const middleware = this.middleware.map((handler) => (context3, next) => {
45386
46932
  scope.assertOpen();
@@ -45876,7 +47422,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45876
47422
  async letBuiltin(context2, state) {
45877
47423
  this.signal.throwIfAborted();
45878
47424
  const { maxExpansionBytes: bytes3, maxExpansionFields: fields3 } = this.budget.limits;
45879
- const admit2 = (value3) => {
47425
+ const admit3 = (value3) => {
45880
47426
  if (typeof value3 !== "string" || value3.includes("\0")) throw new CommandFailure2("let: arguments must be strings without NUL", 2);
45881
47427
  if (value3.length > bytes3 || import_buffer.Buffer.byteLength(value3) > bytes3) this.budget.fail("maxExpansionBytes");
45882
47428
  };
@@ -45888,10 +47434,10 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45888
47434
  const { args } = context2;
45889
47435
  if (!Array.isArray(args)) throw new CommandFailure2("let: argument array required", 2);
45890
47436
  if (args.length + 1 > fields3) this.budget.fail("maxExpansionFields");
45891
- admit2(context2.command);
47437
+ admit3(context2.command);
45892
47438
  for (let index = 0; index < args.length; index++) {
45893
47439
  this.signal.throwIfAborted();
45894
- admit2(args[index]);
47440
+ admit3(args[index]);
45895
47441
  if ((index + 1) % 128 === 0) await checkpoint();
45896
47442
  }
45897
47443
  if (args[0] === "--help") throw new CommandFailure2("let: --help: unsupported option", 2);
@@ -45920,7 +47466,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45920
47466
  async getoptsBuiltin(context2, state) {
45921
47467
  this.signal.throwIfAborted();
45922
47468
  const { maxExpansionBytes: bytes3, maxExpansionFields: fields3 } = this.budget.limits;
45923
- const admit2 = (value2) => {
47469
+ const admit3 = (value2) => {
45924
47470
  if (typeof value2 !== "string") throw new CommandFailure2("getopts: arguments must be strings without NUL", 2);
45925
47471
  if (value2.length > bytes3 || import_buffer.Buffer.byteLength(value2) > bytes3) this.budget.fail("maxExpansionBytes");
45926
47472
  if (value2.includes("\0")) throw new CommandFailure2("getopts: arguments must be strings without NUL", 2);
@@ -45932,10 +47478,10 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45932
47478
  };
45933
47479
  if (!Array.isArray(context2.args)) throw new CommandFailure2("getopts: argument array required", 2);
45934
47480
  if (context2.args.length + 1 > fields3) this.budget.fail("maxExpansionFields");
45935
- admit2(context2.command);
47481
+ admit3(context2.command);
45936
47482
  for (let index = 0; index < context2.args.length; index++) {
45937
47483
  this.signal.throwIfAborted();
45938
- admit2(context2.args[index]);
47484
+ admit3(context2.args[index]);
45939
47485
  if ((index + 1) % 128 === 0) await checkpoint();
45940
47486
  }
45941
47487
  const offset = context2.args[0] === "--" ? 1 : 0;
@@ -45974,7 +47520,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
45974
47520
  const args = input3?.args ?? supplied;
45975
47521
  if (!input3 || allocation) for (let index = 0; index < args.length; index++) {
45976
47522
  this.signal.throwIfAborted();
45977
- admit2(args[index]);
47523
+ admit3(args[index]);
45978
47524
  if ((index + 1) % 128 === 0) await checkpoint();
45979
47525
  }
45980
47526
  state.getopts ??= cloneGetoptsBinding(state);
@@ -46125,8 +47671,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46125
47671
  continue;
46126
47672
  }
46127
47673
  if ((token.startsWith("+") || token.startsWith("-")) && !(command7 === "pushd" && token === "-")) {
46128
- const number5 = await work.number(token);
46129
- selected = token.startsWith("+") ? number5 : BigInt(count2) - number5;
47674
+ const number6 = await work.number(token);
47675
+ selected = token.startsWith("+") ? number6 : BigInt(count2) - number6;
46130
47676
  if (command7 === "pushd") boundedIndex(selected);
46131
47677
  continue;
46132
47678
  }
@@ -46306,8 +47852,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46306
47852
  }
46307
47853
  }
46308
47854
  const arguments_ = incoming.slice(offset);
46309
- const format2 = arguments_.args[0] === "--" ? arguments_.args[1] : arguments_.args[0];
46310
- if (format2 === void 0 || arguments_.args[0] !== "--" && format2.startsWith("-")) {
47855
+ const format3 = arguments_.args[0] === "--" ? arguments_.args[1] : arguments_.args[0];
47856
+ if (format3 === void 0 || arguments_.args[0] !== "--" && format3.startsWith("-")) {
46311
47857
  await writeDiagnostic(context2.stderr, "printf: usage: printf [-v var] format [arguments]\n");
46312
47858
  return 2;
46313
47859
  }
@@ -48783,17 +50329,17 @@ var Shell = class {
48783
50329
  if (!middleware || typeof middleware.setup !== "function") throw new TypeError("Expected middleware or shell plugin");
48784
50330
  this.#ready = this.#ready.then(async () => {
48785
50331
  let active = true;
48786
- const admit2 = () => {
50332
+ const admit3 = () => {
48787
50333
  if (this.#disposed && !active) throw new Error("Shell is disposed");
48788
50334
  };
48789
50335
  const host2 = {
48790
50336
  commands: this.commands,
48791
50337
  use: (middleware2) => {
48792
- admit2();
50338
+ admit3();
48793
50339
  this.#install(middleware2);
48794
50340
  },
48795
50341
  registerFileSystem: (scheme, factory) => {
48796
- admit2();
50342
+ admit3();
48797
50343
  this.#registerFileSystem(scheme, factory);
48798
50344
  }
48799
50345
  };
@@ -49148,7 +50694,7 @@ init_platform();
49148
50694
  // packages/safe-js/dist/browser/safe-fs.js
49149
50695
  init_platform();
49150
50696
 
49151
- // packages/safe-js/dist/browser/chunks/chunk-GQOAEEHU.js
50697
+ // packages/safe-js/dist/browser/chunks/chunk-3EJ7BQOJ.js
49152
50698
  init_platform();
49153
50699
  var platform = Object.freeze({
49154
50700
  errno(_code) {
@@ -51676,17 +53222,17 @@ var WebDavFileSystem = class {
51676
53222
  }
51677
53223
  const sizeText = directory2 ? "0" : scalar2(required("getcontentlength"));
51678
53224
  if (!/^\d+$/.test(sizeText) || !Number.isSafeInteger(Number(sizeText))) throw new Error("invalid content length property");
51679
- const date = (name2) => {
53225
+ const date2 = (name2) => {
51680
53226
  const property = properties.get(name2);
51681
53227
  if (!property) return void 0;
51682
53228
  const value2 = Date.parse(scalar2(property));
51683
53229
  if (!Number.isFinite(value2)) throw new Error("invalid date property");
51684
53230
  return value2;
51685
53231
  };
51686
- const birthtimeMs = date("creationdate");
53232
+ const birthtimeMs = date2("creationdate");
51687
53233
  const etag = properties.get("getetag");
51688
53234
  const validator = etag && scalar2(etag);
51689
- let mtimeMs = date("getlastmodified") ?? 0;
53235
+ let mtimeMs = date2("getlastmodified") ?? 0;
51690
53236
  let atimeMs = 0;
51691
53237
  if (timestampProperty) {
51692
53238
  const timestamps = JSON.parse(scalar2(timestampProperty));
@@ -52992,12 +54538,14 @@ export {
52992
54538
  createTimeoutCommands,
52993
54539
  createTreeCommand,
52994
54540
  createTreeCommands,
54541
+ createUnzipCommand,
52995
54542
  createWgetCommand,
52996
54543
  createWhichCommand,
52997
54544
  createWhichCommands,
52998
54545
  createXmlCommands,
52999
54546
  createYqCommand,
53000
54547
  createYqCommands,
54548
+ createZipCommand,
53001
54549
  curlCommands,
53002
54550
  defaultJqLimits,
53003
54551
  defaultMemoryFileSystemLimits2 as defaultMemoryFileSystemLimits,