@poe-platform/safe-bash 0.1.620 → 0.1.622

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.
@@ -2127,9 +2127,9 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
2127
2127
  for (const name2 of names) {
2128
2128
  const counts = { l: 0, w: 0, m: 0, c: 0 };
2129
2129
  let inWord = false;
2130
- const word = (whitespace2) => {
2131
- if (!whitespace2 && !inWord) counts.w++;
2132
- inWord = !whitespace2;
2130
+ const word = (whitespace3) => {
2131
+ if (!whitespace3 && !inWord) counts.w++;
2132
+ inWord = !whitespace3;
2133
2133
  };
2134
2134
  const utf82 = wcUtf8((point) => {
2135
2135
  if (point !== void 0) counts.m++;
@@ -2493,13 +2493,13 @@ function sortKey(specification) {
2493
2493
  };
2494
2494
  }
2495
2495
  async function keyBytes(line, key, separator, blanks, work) {
2496
- const fields3 = [];
2496
+ const fields4 = [];
2497
2497
  if (separator !== void 0) {
2498
2498
  let start2 = 0;
2499
2499
  for (let offset = 0; offset <= line.length; offset++) {
2500
2500
  if (offset > 0 && offset % 1024 === 0) await work.charge(1024);
2501
2501
  if (offset === line.length || line[offset] === separator) {
2502
- fields3.push({ start: start2, end: offset });
2502
+ fields4.push({ start: start2, end: offset });
2503
2503
  start2 = offset + 1;
2504
2504
  }
2505
2505
  }
@@ -2515,12 +2515,12 @@ async function keyBytes(line, key, separator, blanks, work) {
2515
2515
  while (offset < line.length && line[offset] !== 32 && line[offset] !== 9) {
2516
2516
  if (++offset % 1024 === 0) await work.charge(1024);
2517
2517
  }
2518
- fields3.push({ start: start2, end: offset });
2518
+ fields4.push({ start: start2, end: offset });
2519
2519
  }
2520
2520
  }
2521
2521
  await work.charge(line.length % 1024);
2522
- const start = (fields3[key.start - 1]?.start ?? line.length) + key.startCharacter - 1;
2523
- const last = key.end === void 0 ? void 0 : fields3[key.end - 1];
2522
+ const start = (fields4[key.start - 1]?.start ?? line.length) + key.startCharacter - 1;
2523
+ const last = key.end === void 0 ? void 0 : fields4[key.end - 1];
2524
2524
  const end = key.end === void 0 ? line.length : last === void 0 ? line.length : key.endCharacter === void 0 ? last.end : Math.min(last.end, last.start + key.endCharacter);
2525
2525
  return line.subarray(Math.min(start, line.length), Math.max(start, end));
2526
2526
  }
@@ -12459,8 +12459,8 @@ function formatted(format3, values, text3, budget) {
12459
12459
  else if (conversion === "g" || conversion === "G") part = general2(amount, precision ?? 6, flags3.includes("#"));
12460
12460
  else {
12461
12461
  const radix = conversion === "o" ? 8 : conversion === "x" || conversion === "X" ? 16 : 10;
12462
- const integer9 = BigInt(Math.trunc(amount));
12463
- part = (/[uoxX]/u.test(conversion) ? BigInt.asUintN(32, integer9) : integer9).toString(radix);
12462
+ const integer10 = BigInt(Math.trunc(amount));
12463
+ part = (/[uoxX]/u.test(conversion) ? BigInt.asUintN(32, integer10) : integer10).toString(radix);
12464
12464
  if (precision !== void 0) {
12465
12465
  const negative = part.startsWith("-");
12466
12466
  admit2(amount === 0 && precision === 0 ? 0 : Math.max(part.length, precision + Number(negative)));
@@ -13320,9 +13320,9 @@ var AwkRuntime = class {
13320
13320
  if (name2 === "NF" && this.store(name2) === this.variables) {
13321
13321
  const length = Math.trunc(number(value2));
13322
13322
  if (!Number.isSafeInteger(length) || length < 0 || length > 1e5) throw new ProgramError("invalid or excessive NF");
13323
- const fields3 = this.fields.slice(0, length);
13324
- while (fields3.length < length) fields3.push(unset);
13325
- this.rebuild(fields3);
13323
+ const fields4 = this.fields.slice(0, length);
13324
+ while (fields4.length < length) fields4.push(unset);
13325
+ this.rebuild(fields4);
13326
13326
  return;
13327
13327
  }
13328
13328
  this.storeScalar(this.store(name2), name2, value2);
@@ -13428,23 +13428,23 @@ var AwkRuntime = class {
13428
13428
  }
13429
13429
  async setRecord(record3) {
13430
13430
  this.budget.check(record3);
13431
- const fields3 = await this.split(record3, this.varText("FS"), this.varText("RS") === "");
13432
- this.replaceRecord(record3, fields3);
13431
+ const fields4 = await this.split(record3, this.varText("FS"), this.varText("RS") === "");
13432
+ this.replaceRecord(record3, fields4);
13433
13433
  }
13434
- replaceRecord(record3, fields3) {
13434
+ replaceRecord(record3, fields4) {
13435
13435
  let fieldBytes = 0;
13436
- for (const field2 of fields3) {
13436
+ for (const field2 of fields4) {
13437
13437
  if (field2.kind === "string" || field2.kind === "numeric") this.budget.check(field2.text);
13438
13438
  fieldBytes += textSize(field2);
13439
13439
  }
13440
13440
  const owned = this.retention.replace(this.record.length + this.fieldBytes, record3.length + fieldBytes, () => ({
13441
13441
  record: import_buffer.Buffer.from(record3, "latin1").toString("latin1"),
13442
- fields: fields3.map((field2, index) => field2 === this.fields[index] ? field2 : ownScalar(field2))
13442
+ fields: fields4.map((field2, index) => field2 === this.fields[index] ? field2 : ownScalar(field2))
13443
13443
  }));
13444
13444
  this.record = owned.record;
13445
13445
  this.fields = owned.fields;
13446
13446
  this.fieldBytes = fieldBytes;
13447
- this.variables.set("NF", numeric(fields3.length));
13447
+ this.variables.set("NF", numeric(fields4.length));
13448
13448
  }
13449
13449
  join(parts, separator, suffix2 = "") {
13450
13450
  this.budget.step(parts.length + 1);
@@ -13462,9 +13462,9 @@ var AwkRuntime = class {
13462
13462
  this.budget.step(this.budget.maxBufferBytes - remaining);
13463
13463
  return parts.join(separator) + suffix2;
13464
13464
  }
13465
- rebuild(fields3) {
13466
- const record3 = this.join(fields3.map((value2) => this.asText(value2)), this.varText("OFS"));
13467
- this.replaceRecord(record3, fields3);
13465
+ rebuild(fields4) {
13466
+ const record3 = this.join(fields4.map((value2) => this.asText(value2)), this.varText("OFS"));
13467
+ this.replaceRecord(record3, fields4);
13468
13468
  }
13469
13469
  async key(items) {
13470
13470
  const pieces = [];
@@ -13480,10 +13480,10 @@ var AwkRuntime = class {
13480
13480
  get: () => index === 0 ? inputValue(this.record) : this.fields[index - 1] ?? unset,
13481
13481
  set: (value2) => {
13482
13482
  if (index === 0) return this.setRecord(this.asText(value2));
13483
- const fields3 = this.fields.slice();
13484
- while (fields3.length < index) fields3.push(unset);
13485
- fields3[index - 1] = value2;
13486
- this.rebuild(fields3);
13483
+ const fields4 = this.fields.slice();
13484
+ while (fields4.length < index) fields4.push(unset);
13485
+ fields4[index - 1] = value2;
13486
+ this.rebuild(fields4);
13487
13487
  }
13488
13488
  };
13489
13489
  }
@@ -21808,14 +21808,14 @@ function flags(args) {
21808
21808
  }
21809
21809
  return result;
21810
21810
  }
21811
- async function comparisonLines(lines3, whitespace2, budget) {
21812
- if (whitespace2 === "exact") return lines3;
21811
+ async function comparisonLines(lines3, whitespace3, budget) {
21812
+ if (whitespace3 === "exact") return lines3;
21813
21813
  const result = [];
21814
21814
  for (const line of lines3) {
21815
21815
  budget.step(1 + line.length);
21816
21816
  await budget.checkpoint();
21817
21817
  const body = line.endsWith("\n") ? line.slice(0, -1) : line;
21818
- const normalized = body.replace(/[ \t\v\f\r]+/gu, whitespace2 === "all" ? "" : " ");
21818
+ const normalized = body.replace(/[ \t\v\f\r]+/gu, whitespace3 === "all" ? "" : " ");
21819
21819
  result.push(normalized.endsWith(" ") ? normalized.slice(0, -1) : normalized);
21820
21820
  }
21821
21821
  return result;
@@ -23382,8 +23382,8 @@ function timestamp2(milliseconds) {
23382
23382
  const value2 = available(milliseconds, "timestamp");
23383
23383
  if (Math.abs(value2) > 864e13) throw new FsError("EIO", { message: "invalid filesystem timestamp" });
23384
23384
  const [coefficient = "0", exponent = "0"] = Math.abs(value2).toString().split("e");
23385
- const [integer9 = "0", fraction = ""] = coefficient.split(".");
23386
- const digits = BigInt(integer9 + fraction);
23385
+ const [integer10 = "0", fraction = ""] = coefficient.split(".");
23386
+ const digits = BigInt(integer10 + fraction);
23387
23387
  const power2 = Number(exponent) - fraction.length + 6;
23388
23388
  const divisor = power2 < 0 ? 10n ** BigInt(-power2) : 1n;
23389
23389
  const magnitude = power2 < 0 ? (digits + divisor / 2n) / divisor : digits * 10n ** BigInt(power2);
@@ -23435,9 +23435,9 @@ function formatField(text3, code, flags3, width, precision, numeric4, epoch2) {
23435
23435
  if (epoch2 && precision) {
23436
23436
  const decimal4 = text3.indexOf(".");
23437
23437
  const integerWidth = width > precision + 2 && !flags3.includes("-") ? width - precision - 1 : 0;
23438
- const integer9 = formatField(text3.slice(0, decimal4), code, flags3, integerWidth, void 0, true, false);
23439
- const trailingWidth = integer9.length < width && 1 < width - integer9.length ? Math.abs(width - integer9.length - 1 - precision) : 0;
23440
- return import_buffer.Buffer.concat([integer9, import_buffer.Buffer.from(text3.slice(decimal4)), import_buffer.Buffer.alloc(trailingWidth, 32)]);
23438
+ const integer10 = formatField(text3.slice(0, decimal4), code, flags3, integerWidth, void 0, true, false);
23439
+ const trailingWidth = integer10.length < width && 1 < width - integer10.length ? Math.abs(width - integer10.length - 1 - precision) : 0;
23440
+ return import_buffer.Buffer.concat([integer10, import_buffer.Buffer.from(text3.slice(decimal4)), import_buffer.Buffer.alloc(trailingWidth, 32)]);
23441
23441
  }
23442
23442
  const encoded2 = import_buffer.Buffer.from(text3);
23443
23443
  const bytes3 = !numeric4 && precision !== void 0 ? encoded2.subarray(0, precision) : encoded2;
@@ -23524,9 +23524,9 @@ async function render(context2, path, name2, stat, format3, escapes, limit) {
23524
23524
  const value2 = times[code.toUpperCase()];
23525
23525
  text3 = code === "w" && value2 === void 0 ? "-" : timestamp2(available(value2, code));
23526
23526
  } else {
23527
- const fields3 = { s: stat.size, a: stat.mode & 4095, f: stat.mode, i: stat.ino, h: stat.nlink, u: stat.uid, g: stat.gid, d: stat.dev, D: stat.dev };
23528
- if (!Object.hasOwn(fields3, code)) throw new FsError("ENOTSUP", { message: `unsupported stat format: %${code}` });
23529
- const value2 = available(fields3[code], code);
23527
+ const fields4 = { s: stat.size, a: stat.mode & 4095, f: stat.mode, i: stat.ino, h: stat.nlink, u: stat.uid, g: stat.gid, d: stat.dev, D: stat.dev };
23528
+ if (!Object.hasOwn(fields4, code)) throw new FsError("ENOTSUP", { message: `unsupported stat format: %${code}` });
23529
+ const value2 = available(fields4[code], code);
23530
23530
  text3 = value2.toString(code === "a" ? 8 : code === "f" || code === "D" ? 16 : 10);
23531
23531
  numeric4 = true;
23532
23532
  }
@@ -26612,6 +26612,216 @@ async function readArchive(context2, source2, options2, budget) {
26612
26612
  // packages/safe-bash/src/commands/archive/zip.ts
26613
26613
  init_platform();
26614
26614
 
26615
+ // packages/safe-bash/src/commands/archive/zip/dates.ts
26616
+ init_platform();
26617
+
26618
+ // packages/safe-bash/src/commands/archive/zip/options.ts
26619
+ init_platform();
26620
+ var ZipFailure = class extends Error {
26621
+ constructor(status2, label, detail) {
26622
+ super(detail);
26623
+ this.status = status2;
26624
+ this.label = label;
26625
+ }
26626
+ status;
26627
+ label;
26628
+ };
26629
+ var longOptions = {
26630
+ "recurse-paths": "r",
26631
+ quiet: "q",
26632
+ "junk-paths": "j",
26633
+ "no-dir-entries": "D",
26634
+ symlinks: "y",
26635
+ test: "T",
26636
+ "names-stdin": "@",
26637
+ update: "u",
26638
+ freshen: "f",
26639
+ filesync: "FS",
26640
+ delete: "d",
26641
+ include: "i",
26642
+ exclude: "x",
26643
+ suffixes: "n",
26644
+ store: "0",
26645
+ "compression-method": "Z",
26646
+ "compress-1": "1",
26647
+ "compress-2": "2",
26648
+ "compress-3": "3",
26649
+ "compress-4": "4",
26650
+ "compress-5": "5",
26651
+ "compress-6": "6",
26652
+ "compress-7": "7",
26653
+ "compress-8": "8",
26654
+ "compress-9": "9",
26655
+ "force-zip64": "fz",
26656
+ "strip-extra": "X",
26657
+ "force-descriptors": "fd",
26658
+ "no-wild": "nw",
26659
+ "wild-stop-dirs": "ws",
26660
+ "recurse-patterns": "R",
26661
+ "from-date": "t",
26662
+ "before-date": "tt",
26663
+ "copy-entries": "U",
26664
+ "output-file": "O",
26665
+ "must-match": "MM"
26666
+ };
26667
+ var reservedOptions = [
26668
+ "adjust-sfx",
26669
+ "temp-path",
26670
+ "entry-comments",
26671
+ "display-bytes",
26672
+ "display-counts",
26673
+ "display-dots",
26674
+ "display-globaldots",
26675
+ "dot-size",
26676
+ "display-usize",
26677
+ "display-volume",
26678
+ "difference-archive",
26679
+ "encrypt",
26680
+ "fix",
26681
+ "fixfix",
26682
+ "fifo",
26683
+ "grow",
26684
+ "help",
26685
+ "more-help",
26686
+ "junk-sfx",
26687
+ "DOS-names",
26688
+ "to-crlf",
26689
+ "from-crlf",
26690
+ "logfile-path",
26691
+ "log-append",
26692
+ "log-info",
26693
+ "license",
26694
+ "move",
26695
+ "latest-time",
26696
+ "paths",
26697
+ "password",
26698
+ "regex",
26699
+ "split-size",
26700
+ "split-pause",
26701
+ "split-verbose",
26702
+ "split-bell",
26703
+ "show-command",
26704
+ "show-debug",
26705
+ "show-files",
26706
+ "show-options",
26707
+ "unzip-command",
26708
+ "verbose",
26709
+ "version",
26710
+ "archive-comment"
26711
+ ];
26712
+ function normalizeZipOption(argument2) {
26713
+ if (!argument2.startsWith("--") || argument2 === "--") return argument2;
26714
+ const equal2 = argument2.indexOf("=");
26715
+ const rawName = argument2.slice(2, equal2 < 0 ? void 0 : equal2);
26716
+ const negate2 = rawName.endsWith("-");
26717
+ const name2 = negate2 ? rawName.slice(0, -1) : rawName;
26718
+ const names = [...Object.keys(longOptions), ...reservedOptions];
26719
+ const matches2 = names.includes(name2) ? [name2] : names.filter((option) => option.startsWith(name2));
26720
+ if (matches2.length > 1) throw new ZipFailure(16, "Invalid command arguments", `long option '${name2}' ambiguous`);
26721
+ const matched = matches2[0];
26722
+ const short = matched === void 0 ? void 0 : longOptions[matched];
26723
+ if (!short) throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
26724
+ if (negate2 && short !== "fz" && short !== "X") throw new ZipFailure(16, "Invalid command arguments", `option ${matched} is not negatable`);
26725
+ if (equal2 >= 0 && short !== "i" && short !== "x" && short !== "n" && short !== "Z" && short !== "t" && short !== "tt" && short !== "O") {
26726
+ throw new ZipFailure(16, "Invalid command arguments", `option '${matched}' does not allow a value`);
26727
+ }
26728
+ return `-${short}${negate2 ? "-" : ""}${equal2 < 0 ? "" : argument2.slice(equal2)}`;
26729
+ }
26730
+
26731
+ // packages/safe-bash/src/commands/archive/zip/dates.ts
26732
+ function integer4(input3, start, width) {
26733
+ let offset = start;
26734
+ while (" \r\n\v\f".includes(input3[offset] ?? "\0")) offset++;
26735
+ const end = offset + width;
26736
+ let sign = 1;
26737
+ if (input3[offset] === "+" || input3[offset] === "-") {
26738
+ sign = input3[offset] === "-" ? -1 : 1;
26739
+ offset++;
26740
+ }
26741
+ let digits = 0;
26742
+ let value2 = 0;
26743
+ while (offset < end && input3[offset] !== void 0 && input3[offset] >= "0" && input3[offset] <= "9") {
26744
+ value2 = value2 * 10 + Number(input3[offset++]);
26745
+ digits++;
26746
+ }
26747
+ return digits ? { value: value2 * sign, end: offset } : void 0;
26748
+ }
26749
+ function fields2(input3, iso) {
26750
+ const first = integer4(input3, 0, iso ? 4 : 2);
26751
+ if (!first || iso && input3[first.end] !== "-") return;
26752
+ const second = integer4(input3, first.end + (iso ? 1 : 0), 2);
26753
+ if (!second || iso && input3[second.end] !== "-") return;
26754
+ const third = integer4(input3, second.end + (iso ? 1 : 0), iso ? 2 : 4);
26755
+ if (!third) return;
26756
+ return iso ? [first.value, second.value, third.value] : [third.value, first.value, second.value];
26757
+ }
26758
+ function parseZipDate(input3, option) {
26759
+ const result = fields2(input3, true) ?? fields2(input3, false);
26760
+ if (!result || result[1] < 1 || result[1] > 12 || result[2] < 1 || result[2] > 31) {
26761
+ throw new ZipFailure(16, "Invalid command arguments", `invalid date entered for -${option} option - use mmddyyyy or yyyy-mm-dd`);
26762
+ }
26763
+ const [year, month, day] = result;
26764
+ return year < 1980 ? 2162688 : (year - 1980) * 33554432 + month * 2097152 + day * 65536;
26765
+ }
26766
+ function zipDateMatches(modified, from, until) {
26767
+ if (from === void 0 && until === void 0) return true;
26768
+ const rounded2 = new Date(Math.ceil(Math.floor(modified.getTime() / 1e3) / 2) * 2e3);
26769
+ const key = rounded2.getFullYear() < 1980 ? 2162688 : (rounded2.getFullYear() - 1980) * 33554432 + (rounded2.getMonth() + 1) * 2097152 + rounded2.getDate() * 65536 + rounded2.getHours() * 2048 + rounded2.getMinutes() * 32 + rounded2.getSeconds() / 2;
26770
+ return (from === void 0 || key >= from) && (until === void 0 || key < until);
26771
+ }
26772
+
26773
+ // packages/safe-bash/src/commands/archive/zip/environment.ts
26774
+ init_platform();
26775
+ function whitespace(character) {
26776
+ return character === " " || character === " " || character === "\n" || character === "\r" || character === "\v" || character === "\f";
26777
+ }
26778
+ function zipEnvironmentArguments(env, argv, limits) {
26779
+ let value2 = "";
26780
+ let selectedBytes = 0;
26781
+ for (const key of ["ZIPOPT", "ZIP_OPTS"]) {
26782
+ const candidate = env[key] ?? "";
26783
+ if (import_buffer.Buffer.byteLength(candidate) > limits.maxArgumentBytes) fail("environment argument byte limit exceeded");
26784
+ let start = 0;
26785
+ while (whitespace(candidate[start])) start++;
26786
+ if (start < candidate.length) {
26787
+ value2 = candidate.slice(start);
26788
+ selectedBytes = import_buffer.Buffer.byteLength(candidate);
26789
+ break;
26790
+ }
26791
+ }
26792
+ if (!value2) return argv;
26793
+ if (value2.includes("\0") || import_buffer.Buffer.from(value2).toString("utf8") !== value2) fail("invalid environment argument text");
26794
+ let bytes3 = selectedBytes;
26795
+ for (const argument2 of argv) {
26796
+ bytes3 += import_buffer.Buffer.byteLength(argument2);
26797
+ if (bytes3 > limits.maxArgumentBytes) fail("argument byte limit exceeded");
26798
+ }
26799
+ const defaults = [];
26800
+ let offset = 0;
26801
+ while (offset < value2.length) {
26802
+ let argument2 = "";
26803
+ if (value2[offset] === '"') {
26804
+ offset++;
26805
+ while (offset < value2.length && value2[offset] !== '"') {
26806
+ if (value2[offset] === "\\") {
26807
+ offset++;
26808
+ if (offset === value2.length) break;
26809
+ }
26810
+ argument2 += value2[offset++];
26811
+ }
26812
+ if (value2[offset] === '"') offset++;
26813
+ } else {
26814
+ const start = offset;
26815
+ while (offset < value2.length && !whitespace(value2[offset])) offset++;
26816
+ argument2 = value2.slice(start, offset);
26817
+ }
26818
+ if (defaults.length + argv.length >= limits.maxArgumentBytes) fail("argument count limit exceeded");
26819
+ defaults.push(argument2);
26820
+ while (whitespace(value2[offset])) offset++;
26821
+ }
26822
+ return [...defaults, ...argv];
26823
+ }
26824
+
26615
26825
  // packages/safe-bash/src/commands/archive/zip-format.ts
26616
26826
  init_platform();
26617
26827
 
@@ -27059,7 +27269,7 @@ function updateZipExtras(entry, previous, mode, limits) {
27059
27269
  const fresh = mode === "strip" ? new Uint8Array() : timestampExtra(entry.modified);
27060
27270
  const retained = [];
27061
27271
  for (const [original, central] of [[previous?.localExtra, false], [previous?.centralExtra, true]]) {
27062
- const fields3 = [];
27272
+ const fields4 = [];
27063
27273
  let length = fresh.length;
27064
27274
  if (mode === "all" && original) {
27065
27275
  extras(original, previous.rawName ?? pathBytes(previous.name, limits), previous.comment ?? new Uint8Array(), central, limits);
@@ -27068,7 +27278,7 @@ function updateZipExtras(entry, previous, mode, limits) {
27068
27278
  const identifier = view.getUint16(offset2, true);
27069
27279
  const next = offset2 + 4 + view.getUint16(offset2 + 2, true);
27070
27280
  if (identifier !== 1 && identifier !== 21589 && identifier !== 28789 && identifier !== 25461) {
27071
- fields3.push(original.subarray(offset2, next));
27281
+ fields4.push(original.subarray(offset2, next));
27072
27282
  length += next - offset2;
27073
27283
  }
27074
27284
  offset2 = next;
@@ -27077,7 +27287,7 @@ function updateZipExtras(entry, previous, mode, limits) {
27077
27287
  number3(length, Math.min(limits.maxPaxBytes, 65535), "extra field");
27078
27288
  const bytes3 = new Uint8Array(length);
27079
27289
  let offset = 0;
27080
- for (const field2 of fields3) {
27290
+ for (const field2 of fields4) {
27081
27291
  bytes3.set(field2, offset);
27082
27292
  offset += field2.length;
27083
27293
  }
@@ -27578,126 +27788,14 @@ var Answers = class {
27578
27788
  }
27579
27789
  };
27580
27790
 
27581
- // packages/safe-bash/src/commands/archive/zip/options.ts
27582
- init_platform();
27583
- var ZipFailure = class extends Error {
27584
- constructor(status2, label, detail) {
27585
- super(detail);
27586
- this.status = status2;
27587
- this.label = label;
27588
- }
27589
- status;
27590
- label;
27591
- };
27592
- var longOptions = {
27593
- "recurse-paths": "r",
27594
- quiet: "q",
27595
- "junk-paths": "j",
27596
- "no-dir-entries": "D",
27597
- symlinks: "y",
27598
- test: "T",
27599
- "names-stdin": "@",
27600
- update: "u",
27601
- freshen: "f",
27602
- delete: "d",
27603
- include: "i",
27604
- exclude: "x",
27605
- suffixes: "n",
27606
- store: "0",
27607
- "compression-method": "Z",
27608
- "compress-1": "1",
27609
- "compress-2": "2",
27610
- "compress-3": "3",
27611
- "compress-4": "4",
27612
- "compress-5": "5",
27613
- "compress-6": "6",
27614
- "compress-7": "7",
27615
- "compress-8": "8",
27616
- "compress-9": "9",
27617
- "force-zip64": "fz",
27618
- "strip-extra": "X",
27619
- "force-descriptors": "fd",
27620
- "no-wild": "nw",
27621
- "wild-stop-dirs": "ws",
27622
- "recurse-patterns": "R"
27623
- };
27624
- var reservedOptions = [
27625
- "adjust-sfx",
27626
- "temp-path",
27627
- "entry-comments",
27628
- "display-bytes",
27629
- "display-counts",
27630
- "display-dots",
27631
- "display-globaldots",
27632
- "dot-size",
27633
- "display-usize",
27634
- "display-volume",
27635
- "difference-archive",
27636
- "encrypt",
27637
- "fix",
27638
- "fixfix",
27639
- "fifo",
27640
- "filesync",
27641
- "grow",
27642
- "help",
27643
- "more-help",
27644
- "junk-sfx",
27645
- "DOS-names",
27646
- "to-crlf",
27647
- "from-crlf",
27648
- "logfile-path",
27649
- "log-append",
27650
- "log-info",
27651
- "license",
27652
- "move",
27653
- "must-match",
27654
- "latest-time",
27655
- "output-file",
27656
- "paths",
27657
- "password",
27658
- "regex",
27659
- "split-size",
27660
- "split-pause",
27661
- "split-verbose",
27662
- "split-bell",
27663
- "show-command",
27664
- "show-debug",
27665
- "show-files",
27666
- "show-options",
27667
- "from-date",
27668
- "before-date",
27669
- "unzip-command",
27670
- "copy-entries",
27671
- "verbose",
27672
- "version",
27673
- "archive-comment"
27674
- ];
27675
- function normalizeZipOption(argument2) {
27676
- if (!argument2.startsWith("--") || argument2 === "--") return argument2;
27677
- const equal2 = argument2.indexOf("=");
27678
- const rawName = argument2.slice(2, equal2 < 0 ? void 0 : equal2);
27679
- const negate2 = rawName.endsWith("-");
27680
- const name2 = negate2 ? rawName.slice(0, -1) : rawName;
27681
- const names = [...Object.keys(longOptions), ...reservedOptions];
27682
- const matches2 = names.includes(name2) ? [name2] : names.filter((option) => option.startsWith(name2));
27683
- if (matches2.length > 1) throw new ZipFailure(16, "Invalid command arguments", `long option '${name2}' ambiguous`);
27684
- const matched = matches2[0];
27685
- const short = matched === void 0 ? void 0 : longOptions[matched];
27686
- if (!short) throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
27687
- if (negate2 && short !== "fz" && short !== "X") throw new ZipFailure(16, "Invalid command arguments", `option ${matched} is not negatable`);
27688
- if (equal2 >= 0 && short !== "i" && short !== "x" && short !== "n" && short !== "Z") {
27689
- throw new ZipFailure(16, "Invalid command arguments", `option '${matched}' does not allow a value`);
27690
- }
27691
- return `-${short}${negate2 ? "-" : ""}${equal2 < 0 ? "" : argument2.slice(equal2)}`;
27692
- }
27693
-
27694
27791
  // packages/safe-bash/src/commands/archive/zip.ts
27695
27792
  var defaultStoreSuffixes = [".Z", ".zip", ".zoo", ".arc", ".lzh", ".arj"];
27696
27793
  async function parse12(scope, limits) {
27697
27794
  const context2 = scope.context;
27698
- if (context2.args.length > limits.maxArgumentBytes) fail("argument count limit exceeded");
27795
+ const args = zipEnvironmentArguments(context2.env, context2.args, limits);
27796
+ if (args.length > limits.maxArgumentBytes) fail("argument count limit exceeded");
27699
27797
  let bytes3 = 0;
27700
- for (const argument2 of context2.args) {
27798
+ for (const argument2 of args) {
27701
27799
  const size = import_buffer.Buffer.byteLength(argument2);
27702
27800
  if (size > limits.maxArgumentBytes - bytes3) fail("argument byte limit exceeded");
27703
27801
  bytes3 += size;
@@ -27713,6 +27811,7 @@ async function parse12(scope, limits) {
27713
27811
  for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
27714
27812
  }
27715
27813
  let archive;
27814
+ let output2;
27716
27815
  let action = "add";
27717
27816
  let recursive = false;
27718
27817
  let recursivePatterns = false;
@@ -27723,6 +27822,10 @@ async function parse12(scope, limits) {
27723
27822
  let omitDirectories = false;
27724
27823
  let storeLinks = false;
27725
27824
  let test = false;
27825
+ let mustMatch = false;
27826
+ let filesync = false;
27827
+ let fromDate;
27828
+ let beforeDate;
27726
27829
  let descriptors = false;
27727
27830
  let zip64;
27728
27831
  let metadata3 = "default";
@@ -27735,8 +27838,8 @@ async function parse12(scope, limits) {
27735
27838
  const operands = [];
27736
27839
  const includes = [];
27737
27840
  const excludes = [];
27738
- for (let index = 0; index < context2.args.length; index++) {
27739
- const original = context2.args[index];
27841
+ for (let index = 0; index < args.length; index++) {
27842
+ const original = args[index];
27740
27843
  checkPath(original, limits);
27741
27844
  const argument2 = literal ? original : normalizeZipOption(original);
27742
27845
  if (!literal && argument2 === "--") {
@@ -27756,8 +27859,8 @@ async function parse12(scope, limits) {
27756
27859
  } else if (flag === "f" && argument2[offset + 1] === "z") {
27757
27860
  zip64 = argument2[offset + 2] !== "-";
27758
27861
  offset += zip64 ? 1 : 2;
27759
- } else if (flag === "d" || flag === "u" || flag === "f") {
27760
- const next = flag === "d" ? "delete" : flag === "u" ? "update" : "freshen";
27862
+ } else if (flag === "d" || flag === "u" || flag === "f" || flag === "U") {
27863
+ const next = flag === "d" ? "delete" : flag === "u" ? "update" : flag === "U" ? "copy" : "freshen";
27761
27864
  if (action !== "add" && action !== next) throw new ZipFailure(16, "Invalid command arguments", "specify just one action");
27762
27865
  action = next;
27763
27866
  } else if (flag === "n" && argument2[offset + 1] === "w" || flag === "w" && argument2[offset + 1] === "s") {
@@ -27765,6 +27868,14 @@ async function parse12(scope, limits) {
27765
27868
  if (flag === "n") noWild = true;
27766
27869
  else stopAtDirectories = true;
27767
27870
  offset++;
27871
+ } else if (flag === "M" && argument2[offset + 1] === "M") {
27872
+ if (argument2[offset + 2] === "-") throw new ZipFailure(16, "Invalid command arguments", "option MM is not negatable");
27873
+ mustMatch = true;
27874
+ offset++;
27875
+ } else if (flag === "F" && argument2[offset + 1] === "S") {
27876
+ if (argument2[offset + 2] === "-") throw new ZipFailure(16, "Invalid command arguments", "option FS is not negatable");
27877
+ filesync = true;
27878
+ offset++;
27768
27879
  } else if (flag === "q") quiet = true;
27769
27880
  else if (flag === "j") junkPaths = true;
27770
27881
  else if (flag === "X") {
@@ -27777,10 +27888,26 @@ async function parse12(scope, limits) {
27777
27888
  else if (flag !== void 0 && flag >= "0" && flag <= "9") {
27778
27889
  level = Number(flag);
27779
27890
  if (level === 0) method = "store";
27891
+ } else if (flag === "O") {
27892
+ let value2 = argument2.slice(offset + 1) || args[++index];
27893
+ if (value2?.startsWith("=")) value2 = value2.slice(1);
27894
+ if (value2 === void 0) throw new ZipFailure(16, "Invalid command arguments", "option O requires a value");
27895
+ output2 = value2;
27896
+ break;
27897
+ } else if (flag === "t") {
27898
+ const option = argument2[offset + 1] === "t" ? "tt" : "t";
27899
+ if (option === "tt") offset++;
27900
+ let value2 = argument2.slice(offset + 1);
27901
+ if (!value2) value2 = args[++index] ?? "";
27902
+ if (value2.startsWith("=")) value2 = value2.slice(1);
27903
+ const date2 = parseZipDate(value2, option);
27904
+ if (option === "t") fromDate = date2;
27905
+ else beforeDate = date2;
27906
+ break;
27780
27907
  } else if (flag === "n" || flag === "Z") {
27781
27908
  let value2 = argument2.slice(offset + 1);
27782
27909
  if (!value2) {
27783
- const next = context2.args[index + 1];
27910
+ const next = args[index + 1];
27784
27911
  if (next === void 0 || next.startsWith("-") && next !== "-") throw new ZipFailure(16, "Invalid command arguments", `option '${flag}' requires a value`);
27785
27912
  value2 = next;
27786
27913
  index++;
@@ -27810,8 +27937,8 @@ async function parse12(scope, limits) {
27810
27937
  const value2 = argument2.slice(offset + 1);
27811
27938
  append(value2.startsWith("=") ? value2.slice(1) : value2);
27812
27939
  }
27813
- while (!attached && index + 1 < context2.args.length) {
27814
- const next = context2.args[index + 1];
27940
+ while (!attached && index + 1 < args.length) {
27941
+ const next = args[index + 1];
27815
27942
  if (next === "@") {
27816
27943
  index++;
27817
27944
  break;
@@ -27832,12 +27959,19 @@ async function parse12(scope, limits) {
27832
27959
  }
27833
27960
  }
27834
27961
  if (archive === void 0) {
27962
+ if (includes.length || excludes.length) throw new ZipFailure(16, "Invalid command arguments", "nothing to select from");
27835
27963
  if (action !== "add") throw new ZipFailure(16, "Invalid command arguments", "expected archive name");
27836
27964
  archive = "-";
27837
27965
  if (!stdinNames) operands.push("-");
27838
27966
  }
27839
27967
  if (archive !== "-" && !archive.slice(archive.lastIndexOf("/") + 1).includes(".")) archive += ".zip";
27840
27968
  checkPath(archive, limits);
27969
+ if (output2 !== void 0) {
27970
+ if (!output2.slice(output2.lastIndexOf("/") + 1).includes(".")) output2 += ".zip";
27971
+ checkPath(output2, limits);
27972
+ if (action === "add" && archive !== "-" && !operands.length && !stdinNames) action = "copy";
27973
+ }
27974
+ if (action === "copy" && output2 === void 0) throw new ZipFailure(16, "Invalid command arguments", "-U (--copy) requires -O (--out)");
27841
27975
  const names = [];
27842
27976
  if (stdinNames) {
27843
27977
  const input3 = await collectBytes(scope.stdin, { maxBytes: limits.maxFilesFromBytes, signal: context2.signal });
@@ -27860,7 +27994,8 @@ async function parse12(scope, limits) {
27860
27994
  }
27861
27995
  }
27862
27996
  if (recursivePatterns && !names.length && !operands.length) throw new ZipFailure(16, "Invalid command arguments", "nothing to select from");
27863
- return { action, archive, recursive, recursivePatterns, noWild, stopAtDirectories, quiet, junkPaths, omitDirectories, storeLinks, test, descriptors, zip64, metadata: metadata3, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
27997
+ if (filesync && action !== "add") throw new ZipFailure(16, "Invalid command arguments", "can't use -d, -f, -u, -U, or -g with filesync -FS\n");
27998
+ return { args, action, archive, output: output2, recursive, recursivePatterns, noWild, stopAtDirectories, quiet, junkPaths, omitDirectories, storeLinks, test, mustMatch, filesync, fromDate, beforeDate, descriptors, zip64, metadata: metadata3, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
27864
27999
  }
27865
28000
  function memberName(path, limits) {
27866
28001
  if (path.startsWith("//") && !path.startsWith("///")) fail("UNC source paths are unsupported");
@@ -27905,7 +28040,7 @@ async function prepare(scope, parsed, budget) {
27905
28040
  if (parsed.archive === "-" && parsed.action !== "add") throw new ZipFailure(16, "Invalid command arguments", "can't use -d, -f, -u, -U, or -g on stdout\n");
27906
28041
  let publication;
27907
28042
  if (parsed.archive !== "-") {
27908
- const outputName = vfsPath(context2.cwd, parsed.archive);
28043
+ const outputName = vfsPath(context2.cwd, parsed.output ?? parsed.archive);
27909
28044
  const parentName = dirname(outputName);
27910
28045
  const parent = await scope.operation(() => context2.fs.realpath(parentName, { signal: context2.signal }));
27911
28046
  const parentStat = await scope.operation(() => context2.fs.lstat(parent, { signal: context2.signal }));
@@ -27915,16 +28050,37 @@ async function prepare(scope, parsed, budget) {
27915
28050
  publication = { output: output3, parentName, parent, parentStat, existing: existing3 };
27916
28051
  }
27917
28052
  const output2 = publication?.output;
27918
- const existing2 = publication?.existing;
28053
+ let input3 = publication?.output;
28054
+ let existing2 = publication?.existing;
28055
+ if (parsed.output !== void 0) {
28056
+ if (parsed.archive === "-") {
28057
+ input3 = void 0;
28058
+ existing2 = void 0;
28059
+ } else {
28060
+ const name2 = vfsPath(context2.cwd, parsed.archive);
28061
+ try {
28062
+ const parent = await scope.operation(() => context2.fs.realpath(dirname(name2), { signal: context2.signal }));
28063
+ input3 = `${parent === "/" ? "" : parent}/${name2.slice(name2.lastIndexOf("/") + 1)}`;
28064
+ existing2 = await scope.stat(input3);
28065
+ } catch (error) {
28066
+ context2.signal.throwIfAborted();
28067
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "EACCES")) throw new ZipFailure(18, "File not found or no read permission", parsed.archive);
28068
+ throw error;
28069
+ }
28070
+ if (input3 === output2 || existing2 && publication?.existing && sameIdentity2(existing2, publication.existing)) throw new ZipFailure(16, "Invalid command arguments", `--out path must be different than in path: ${parsed.archive}`);
28071
+ }
28072
+ }
28073
+ if ((parsed.action === "copy" || parsed.output !== void 0 && parsed.archive !== "-") && !existing2) throw new ZipFailure(18, "File not found or no read permission", parsed.archive);
28074
+ if (publication?.existing && (publication.existing.type !== "file" || !hasIdentity(publication.existing) || publication.existing.nlink !== 1)) fail("output archive requires a regular, single-link file with known backing identity");
27919
28075
  if (parsed.archive === "-" && parsed.test && !parsed.quiet) await budget.output(" zip warning: can't use -T on stdout, -T ignored\n");
27920
28076
  if (existing2 && (existing2.type !== "file" || !hasIdentity(existing2) || existing2.nlink !== 1)) fail("updating archive requires a regular, single-link file with known backing identity; archive aliases are unsupported");
27921
28077
  let archive = { entries: [], comment: new Uint8Array() };
27922
- if (existing2 && publication) {
28078
+ if (existing2 && input3) {
27923
28079
  if (!Number.isSafeInteger(existing2.size) || existing2.size < 0 || existing2.size > limits.maxArchiveBytes) fail("archive byte limit exceeded");
27924
- const bytes4 = await collectBytes(scope.input(publication.output), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
28080
+ const bytes4 = await collectBytes(scope.input(input3), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
27925
28081
  if (bytes4.length !== existing2.size) fail("archive changed while reading");
27926
28082
  archive = await readZipArchive(bytes4, limits, context2.signal);
27927
- const current = await scope.stat(publication.output);
28083
+ const current = await scope.stat(input3);
27928
28084
  if (!current || !unchanged4(existing2, current)) fail("archive changed while reading");
27929
28085
  }
27930
28086
  const old = new Map(archive.entries.map((entry) => [entry.name, entry]));
@@ -27932,8 +28088,10 @@ async function prepare(scope, parsed, budget) {
27932
28088
  `);
27933
28089
  const selected = /* @__PURE__ */ new Map();
27934
28090
  const deleted = /* @__PURE__ */ new Set();
28091
+ const synchronized = /* @__PURE__ */ new Map();
27935
28092
  const selection = new Selection([...parsed.includes, ...parsed.excludes], limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
27936
28093
  const recursiveSelection = parsed.recursivePatterns ? new Selection(parsed.operands, limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories, trailingComponents: true }) : void 0;
28094
+ let archiveOperandMatches;
27937
28095
  const ancestors = [];
27938
28096
  let visits = 0;
27939
28097
  let work = 0;
@@ -27964,6 +28122,11 @@ async function prepare(scope, parsed, budget) {
27964
28122
  if (previous || !await filterName(name2, selection, parsed.includes.length)) return;
27965
28123
  const prior2 = old.get(name2);
27966
28124
  const modified = /* @__PURE__ */ new Date();
28125
+ if (!zipDateMatches(modified, parsed.fromDate, parsed.beforeDate)) return;
28126
+ if (parsed.filesync) {
28127
+ if (synchronized.has(name2) && synchronized.get(name2) !== source2) throw new ZipFailure(16, "Invalid command arguments", "cannot repeat names in zip file");
28128
+ synchronized.set(name2, source2);
28129
+ }
27967
28130
  if (parsed.action === "freshen" && !prior2 || prior2 && (parsed.action === "update" || parsed.action === "freshen") && Math.floor(modified.getTime() / 1e3) <= Math.floor(prior2.modified.getTime() / 1e3)) return;
27968
28131
  const bytes4 = await collectBytes(scope.stdin, { maxBytes: Math.min(limits.maxEntryBytes, limits.maxTotalBytes - budget.totalBytes), signal: context2.signal });
27969
28132
  await budget.member(bytes4.length);
@@ -27978,28 +28141,49 @@ async function prepare(scope, parsed, budget) {
27978
28141
  ({ canonical, stat } = await inspectSource(scope, path, parsed.storeLinks));
27979
28142
  } catch (error) {
27980
28143
  context2.signal.throwIfAborted();
27981
- if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") throw error;
28144
+ if (typeof error !== "object" || error === null || !("code" in error)) throw error;
28145
+ if (parsed.mustMatch && error.code === "EACCES") throw new ZipFailure(18, "File not found or no read permission", source2);
28146
+ if (error.code !== "ENOENT") throw error;
28147
+ if (parsed.mustMatch && !old.has(name2)) {
28148
+ if (!archiveOperandMatches) {
28149
+ const fallback = new Selection(parsed.operands.map((operand) => {
28150
+ const pattern = memberName(operand, limits);
28151
+ return parsed.junkPaths ? pattern.slice(pattern.lastIndexOf("/") + 1) : pattern;
28152
+ }), limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
28153
+ for (const entry of archive.entries) await fallback.matches(entry.name);
28154
+ archiveOperandMatches = new Set([...fallback.matched].map((index) => parsed.operands[index]));
28155
+ }
28156
+ if (archiveOperandMatches.has(source2)) return;
28157
+ if (!parsed.quiet) await budget.output(` zip warning: name not matched: ${source2}
28158
+ `);
28159
+ throw new ZipFailure(18, "File not found or no read permission", source2);
28160
+ }
27982
28161
  if (!parsed.quiet && !old.has(name2)) await budget.output(` zip warning: name not matched: ${source2}
27983
28162
  `);
27984
28163
  return;
27985
28164
  }
27986
28165
  checkPath(canonical, limits);
27987
- if (canonical === output2 || existing2 && sameIdentity2(existing2, stat)) return;
28166
+ if (canonical === output2 || canonical === input3 || existing2 && sameIdentity2(existing2, stat) || publication?.existing && sameIdentity2(publication.existing, stat)) return;
27988
28167
  const symlink = parsed.storeLinks && stat.type === "symlink";
27989
28168
  if (stat.type !== "file" && stat.type !== "directory" && !symlink) {
27990
28169
  if (!parsed.quiet) await budget.output(` zip warning: ignoring special file: ${source2}
27991
28170
  `);
27992
28171
  return;
27993
28172
  }
27994
- if (existing2 && !hasIdentity(stat)) fail("cannot exclude archive aliases when source backing identity is unknown");
28173
+ if ((existing2 || publication?.existing) && !hasIdentity(stat)) fail("cannot exclude archive aliases when source backing identity is unknown");
27995
28174
  const directory2 = stat.type === "directory";
27996
28175
  if (directory2 && name2 && !name2.endsWith("/")) name2 += "/";
27997
- const included = await filterName(name2, selection, parsed.includes.length) && (!recursiveSelection || await recursiveSelection.matches(name2, true));
28176
+ const included = zipDateMatches(new Date(stat.mtimeMs), parsed.fromDate, parsed.beforeDate) && await filterName(name2, selection, parsed.includes.length) && (!recursiveSelection || await recursiveSelection.matches(name2, true));
27998
28177
  const sourceName = name2;
27999
28178
  if (parsed.junkPaths) name2 = directory2 ? "" : name2.slice(name2.lastIndexOf("/") + 1);
28000
28179
  const prior = old.get(name2);
28180
+ if (parsed.filesync && name2 && included && !(directory2 && parsed.omitDirectories)) {
28181
+ if (synchronized.has(name2) && synchronized.get(name2) !== source2) throw new ZipFailure(16, "Invalid command arguments", "cannot repeat names in zip file");
28182
+ synchronized.set(name2, source2);
28183
+ }
28184
+ const current = parsed.filesync && prior && prior.size === (directory2 ? 0 : stat.size) && Math.ceil(Math.floor(stat.mtimeMs / 1e3) / 2) === Math.ceil(Math.floor(prior.modified.getTime() / 1e3) / 2);
28001
28185
  const eligible = parsed.action !== "update" && parsed.action !== "freshen" || (prior ? Math.floor(stat.mtimeMs / 1e3) > Math.floor(prior.modified.getTime() / 1e3) : parsed.action === "update");
28002
- if (name2 && included && eligible && !(directory2 && parsed.omitDirectories)) {
28186
+ if (name2 && included && eligible && !current && !(directory2 && parsed.omitDirectories)) {
28003
28187
  checkPath(name2, limits);
28004
28188
  const previous = selected.get(name2);
28005
28189
  if (previous && previous.source !== source2) {
@@ -28018,10 +28202,18 @@ async function prepare(scope, parsed, budget) {
28018
28202
  const target = await scope.operation(() => context2.fs.readlink(path, { signal: context2.signal }));
28019
28203
  if (import_buffer.Buffer.byteLength(target) > stat.size) fail(`source changed while reading: ${source2}`);
28020
28204
  bytes4 = import_buffer.Buffer.from(target);
28021
- } else bytes4 = await collectBytes(scope.input(path), { maxBytes: stat.size, signal: context2.signal });
28205
+ } else {
28206
+ try {
28207
+ bytes4 = await collectBytes(scope.input(path), { maxBytes: stat.size, signal: context2.signal });
28208
+ } catch (error) {
28209
+ context2.signal.throwIfAborted();
28210
+ if (parsed.mustMatch && typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "EACCES")) throw new ZipFailure(18, "File not found or no read permission", `was zipping ${source2}`);
28211
+ throw error;
28212
+ }
28213
+ }
28022
28214
  if (!directory2 && bytes4.length !== stat.size) fail(`source changed while reading: ${source2}`);
28023
- const current = await inspectSource(scope, path, parsed.storeLinks);
28024
- if (current.canonical !== canonical || !unchanged4(stat, current.stat)) fail(`source changed while reading: ${source2}`);
28215
+ const current2 = await inspectSource(scope, path, parsed.storeLinks);
28216
+ if (current2.canonical !== canonical || !unchanged4(stat, current2.stat)) fail(`source changed while reading: ${source2}`);
28025
28217
  await encodeSelected(source2, name2, bytes4, { modified: new Date(stat.mtimeMs), mode: stat.mode, directory: directory2, symlink });
28026
28218
  }
28027
28219
  }
@@ -28041,14 +28233,27 @@ async function prepare(scope, parsed, budget) {
28041
28233
  }
28042
28234
  }
28043
28235
  };
28044
- if (parsed.action === "delete") {
28236
+ if (parsed.action === "copy") {
28237
+ const operands = new Selection(parsed.operands, limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
28238
+ for (const entry of archive.entries) {
28239
+ if (await operands.matches(entry.name) && await filterName(entry.name, selection, parsed.includes.length) && zipDateMatches(entry.modified, parsed.fromDate, parsed.beforeDate)) {
28240
+ await budget.member(entry.size);
28241
+ selected.set(entry.name, { entry, source: entry.name });
28242
+ }
28243
+ }
28244
+ } else if (parsed.action === "delete") {
28045
28245
  if (!parsed.quiet && parsed.recursive) await budget.output(" zip warning: invalid option(s) used with -d; ignored.\n");
28046
28246
  if (!parsed.quiet && !archive.entries.length) await budget.output(` zip warning: ${parsed.archive} not found or empty
28047
28247
  `);
28048
28248
  const operands = new Selection(parsed.recursivePatterns ? [] : parsed.operands, limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
28049
28249
  if (parsed.operands.length && !parsed.recursivePatterns) {
28050
28250
  for (const entry of archive.entries) {
28051
- if (await operands.matches(entry.name) && await filterName(entry.name, selection, parsed.includes.length)) deleted.add(entry.name);
28251
+ if (await operands.matches(entry.name) && await filterName(entry.name, selection, parsed.includes.length) && zipDateMatches(entry.modified, parsed.fromDate, parsed.beforeDate)) deleted.add(entry.name);
28252
+ }
28253
+ }
28254
+ if (parsed.mustMatch && !parsed.recursivePatterns) {
28255
+ for (const [index, operand] of parsed.operands.entries()) {
28256
+ if (!operands.matched.has(index)) throw new ZipFailure(18, "File not found or no read permission", operand);
28052
28257
  }
28053
28258
  }
28054
28259
  if (!parsed.quiet) {
@@ -28062,9 +28267,17 @@ async function prepare(scope, parsed, budget) {
28062
28267
  if (parsed.recursivePatterns) await visit(".", "", 0);
28063
28268
  else for (const operand of operands) await visit(operand, memberName(operand, limits), 0);
28064
28269
  }
28270
+ if (parsed.filesync) {
28271
+ if (!synchronized.size) throw new ZipFailure(12, "Nothing to do!", parsed.archive);
28272
+ for (const entry of archive.entries) if (!synchronized.has(entry.name)) deleted.add(entry.name);
28273
+ if (!selected.size && !deleted.size) {
28274
+ if (!parsed.quiet) await budget.output("Archive is current\n");
28275
+ return { kind: "current" };
28276
+ }
28277
+ }
28065
28278
  if (!selected.size && (parsed.action === "freshen" || parsed.action === "update" && (existing2 || !parsed.includes.length))) return void 0;
28066
- if (!selected.size && !deleted.size && (parsed.action === "delete" || parsed.recursivePatterns || !parsed.includes.length)) {
28067
- const detail = parsed.action !== "delete" && parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${context2.args.slice(0, parsed.firstOperand).join(" ")} . -i ${context2.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
28279
+ if (!selected.size && !deleted.size && (parsed.action === "delete" || parsed.action === "copy" || parsed.recursivePatterns || parsed.fromDate !== void 0 || parsed.beforeDate !== void 0 || !parsed.includes.length)) {
28280
+ const detail = parsed.action !== "delete" && parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${parsed.args.slice(0, parsed.firstOperand).join(" ")} . -i ${parsed.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
28068
28281
  throw new ZipFailure(12, "Nothing to do!", detail);
28069
28282
  }
28070
28283
  const entries2 = [];
@@ -28090,6 +28303,15 @@ async function prepare(scope, parsed, budget) {
28090
28303
  continue;
28091
28304
  }
28092
28305
  const replacement = selected.get(entry.name);
28306
+ if (parsed.action === "copy") {
28307
+ if (replacement) {
28308
+ entries2.push(replacement.entry);
28309
+ queue(` copying: ${entry.name}
28310
+ `);
28311
+ selected.delete(entry.name);
28312
+ }
28313
+ continue;
28314
+ }
28093
28315
  if (replacement) {
28094
28316
  entries2.push(replacement.entry);
28095
28317
  append(replacement.entry, true);
@@ -28104,7 +28326,7 @@ async function prepare(scope, parsed, budget) {
28104
28326
  append(entry, false);
28105
28327
  }
28106
28328
  if (!entries2.length) queue(" zip warning: zip file empty\n");
28107
- if (parsed.archive === "-") return { kind: "stream", archive: { entries: entries2, comment: archive.comment }, progress };
28329
+ if (!publication) return { kind: "stream", archive: { entries: entries2, comment: archive.comment }, progress };
28108
28330
  const bytes3 = await writeZipArchive({ entries: entries2, comment: archive.comment }, limits, context2.signal, false, parsed.zip64 === true);
28109
28331
  if (parsed.test && parsed.archive !== "-") {
28110
28332
  for (const message3 of progress) await budget.output(message3);
@@ -28145,6 +28367,7 @@ function createZipCommand(options2 = {}) {
28145
28367
  if (parsed.archive === "-") budget = new Budget14({ ...context2, stdout: context2.stderr }, limits);
28146
28368
  const prepared = await prepare(scope, parsed, budget);
28147
28369
  if (!prepared) return { exitCode: 12 };
28370
+ if (prepared.kind === "current") return { exitCode: 0 };
28148
28371
  if (prepared.kind === "file") {
28149
28372
  const publication = prepared.publication;
28150
28373
  if (!publication) fail("ZIP missing file publication");
@@ -29208,13 +29431,13 @@ function parse13(context2, budget) {
29208
29431
  }
29209
29432
  const values = value2.split(/[, \t]+/u);
29210
29433
  budget.check(values.length, budget.limits.maxFields, "field");
29211
- const fields3 = values.map((specification) => {
29434
+ const fields4 = values.map((specification) => {
29212
29435
  if (specification === "0") return { file: 0, index: 0 };
29213
29436
  const match = /^([12])\.([0-9]+)$/u.exec(specification);
29214
29437
  if (!match) fail2(`invalid output field: ${specification}`);
29215
29438
  return { file: Number(match[1]), index: number4(match[2], "output field") - 1 };
29216
29439
  });
29217
- options2.format = [...Array.isArray(options2.format) ? options2.format : [], ...fields3];
29440
+ options2.format = [...Array.isArray(options2.format) ? options2.format : [], ...fields4];
29218
29441
  budget.check(options2.format.length, budget.limits.maxFields, "field");
29219
29442
  }
29220
29443
  };
@@ -29267,10 +29490,10 @@ function parse13(context2, budget) {
29267
29490
  }
29268
29491
  function split3(bytes3, options2, budget) {
29269
29492
  if (options2.whole) return [bytes3];
29270
- const fields3 = [];
29493
+ const fields4 = [];
29271
29494
  const add3 = (start, end) => {
29272
- budget.check(fields3.length + 1, budget.limits.maxFields, "field");
29273
- fields3.push(bytes3.subarray(start, end));
29495
+ budget.check(fields4.length + 1, budget.limits.maxFields, "field");
29496
+ fields4.push(bytes3.subarray(start, end));
29274
29497
  };
29275
29498
  if (options2.delimiter !== void 0) {
29276
29499
  let start = 0;
@@ -29289,7 +29512,7 @@ function split3(bytes3, options2, budget) {
29289
29512
  if (offset > start) add3(start, offset);
29290
29513
  }
29291
29514
  }
29292
- return fields3;
29515
+ return fields4;
29293
29516
  }
29294
29517
  function createJoinCommand(factory = {}) {
29295
29518
  const limits = settings3(factory);
@@ -29304,36 +29527,36 @@ function createJoinCommand(factory = {}) {
29304
29527
  const next = async (file, reset = false) => {
29305
29528
  const bytes3 = await readers[file].next();
29306
29529
  if (bytes3 === void 0) return void 0;
29307
- const fields3 = split3(bytes3, options2, budget), key = fields3[options2.fields[file]] ?? empty;
29530
+ const fields4 = split3(bytes3, options2, budget), key = fields4[options2.fields[file]] ?? empty;
29308
29531
  if (!reset) await order.check(previous[file], key, file + 1, options2.fold);
29309
29532
  previous[file] = key;
29310
- return { bytes: bytes3, fields: fields3, key };
29533
+ return { bytes: bytes3, fields: fields4, key };
29311
29534
  };
29312
29535
  const rows2 = [await next(0), await next(1)];
29313
29536
  const counts = rows2.map((row) => row?.fields.length ?? 0);
29314
29537
  const emit2 = async (left, right) => {
29315
- const pair = [left, right], fields3 = [];
29538
+ const pair = [left, right], fields4 = [];
29316
29539
  const key = (left ?? right)?.key ?? empty;
29317
29540
  if (Array.isArray(options2.format)) {
29318
29541
  for (const field2 of options2.format) {
29319
29542
  await budget.step();
29320
- fields3.push(field2.file === 0 ? key : pair[field2.file - 1]?.fields[field2.index] ?? empty);
29543
+ fields4.push(field2.file === 0 ? key : pair[field2.file - 1]?.fields[field2.index] ?? empty);
29321
29544
  }
29322
29545
  } else {
29323
- fields3.push(key);
29546
+ fields4.push(key);
29324
29547
  for (let file = 0; file < 2; file++) {
29325
29548
  const count2 = options2.format === "auto" ? counts[file] : pair[file]?.fields.length ?? 0;
29326
29549
  for (let index = 0; index < count2; index++) {
29327
29550
  await budget.step();
29328
- if (index !== options2.fields[file]) fields3.push(pair[file]?.fields[index] ?? empty);
29551
+ if (index !== options2.fields[file]) fields4.push(pair[file]?.fields[index] ?? empty);
29329
29552
  }
29330
29553
  }
29331
29554
  }
29332
29555
  const parts = [];
29333
- for (let index = 0; index < fields3.length; index++) {
29556
+ for (let index = 0; index < fields4.length; index++) {
29334
29557
  await budget.step();
29335
29558
  if (index) parts.push(delimiter);
29336
- parts.push(fields3[index].length ? fields3[index] : options2.replacement);
29559
+ parts.push(fields4[index].length ? fields4[index] : options2.replacement);
29337
29560
  }
29338
29561
  parts.push(terminator);
29339
29562
  await budget.output(parts);
@@ -31249,10 +31472,10 @@ function millisecondsInstant(value2) {
31249
31472
  const scale = Number(match[4] ?? 0) - fraction.length + 6;
31250
31473
  return boundedInstant(scale >= 0 ? coefficient * 10n ** BigInt(scale) : floorDivide(coefficient, 10n ** BigInt(-scale)));
31251
31474
  }
31252
- function utcMilliseconds(fields3) {
31475
+ function utcMilliseconds(fields4) {
31253
31476
  const date2 = /* @__PURE__ */ new Date(0);
31254
- date2.setUTCFullYear(fields3.year, fields3.month - 1, fields3.day);
31255
- date2.setUTCHours(fields3.hour, fields3.minute, fields3.second, 0);
31477
+ date2.setUTCFullYear(fields4.year, fields4.month - 1, fields4.day);
31478
+ date2.setUTCHours(fields4.hour, fields4.minute, fields4.second, 0);
31256
31479
  const value2 = date2.getTime();
31257
31480
  if (!Number.isFinite(value2)) throw new CommandFailure("date is outside the supported range");
31258
31481
  return value2;
@@ -31271,8 +31494,8 @@ function utcFields(milliseconds) {
31271
31494
  function sameFields(left, right) {
31272
31495
  return left.year === right.year && left.month === right.month && left.day === right.day && left.hour === right.hour && left.minute === right.minute && left.second === right.second;
31273
31496
  }
31274
- function checkCalendar(fields3, restrictYear = true) {
31275
- if (restrictYear && (fields3.year < 0 || fields3.year > 9999) || fields3.month < 1 || fields3.month > 12 || fields3.day < 1 || fields3.day > 31 || fields3.hour < 0 || fields3.hour > 23 || fields3.minute < 0 || fields3.minute > 59 || fields3.second < 0 || fields3.second > 59 || !sameFields(fields3, utcFields(utcMilliseconds(fields3)))) throw new CommandFailure("invalid calendar date or time");
31497
+ function checkCalendar(fields4, restrictYear = true) {
31498
+ if (restrictYear && (fields4.year < 0 || fields4.year > 9999) || fields4.month < 1 || fields4.month > 12 || fields4.day < 1 || fields4.day > 31 || fields4.hour < 0 || fields4.hour > 23 || fields4.minute < 0 || fields4.minute > 59 || fields4.second < 0 || fields4.second > 59 || !sameFields(fields4, utcFields(utcMilliseconds(fields4)))) throw new CommandFailure("invalid calendar date or time");
31276
31499
  }
31277
31500
  function signedOffset(text3) {
31278
31501
  const match = /^([+-])(\d{2})(?::?(\d{2}))?(?::(\d{2}))?$/.exec(text3);
@@ -31321,15 +31544,15 @@ var TimeZone = class {
31321
31544
  boundedInstant(instant);
31322
31545
  const seconds = floorDivide(instant, nanosecondsPerSecond);
31323
31546
  const milliseconds = Number(seconds * 1000n);
31324
- let fields3, offset, zone;
31547
+ let fields4, offset, zone;
31325
31548
  if (this.fixedOffset !== void 0) {
31326
- fields3 = utcFields(milliseconds + this.fixedOffset * 1e3);
31549
+ fields4 = utcFields(milliseconds + this.fixedOffset * 1e3);
31327
31550
  offset = this.fixedOffset;
31328
31551
  zone = this.label;
31329
31552
  } else {
31330
31553
  const parts = Object.fromEntries(this.formatter.formatToParts(new Date(milliseconds)).map((part) => [part.type, part.value]));
31331
31554
  const year = Number(parts.year);
31332
- fields3 = {
31555
+ fields4 = {
31333
31556
  year: parts.era === "BC" ? 1 - year : year,
31334
31557
  month: Number(parts.month),
31335
31558
  day: Number(parts.day),
@@ -31337,22 +31560,22 @@ var TimeZone = class {
31337
31560
  minute: Number(parts.minute),
31338
31561
  second: Number(parts.second)
31339
31562
  };
31340
- offset = (utcMilliseconds(fields3) - milliseconds) / 1e3;
31563
+ offset = (utcMilliseconds(fields4) - milliseconds) / 1e3;
31341
31564
  zone = parts.timeZoneName;
31342
31565
  }
31343
- checkCalendar(fields3, restrictYear);
31344
- return { ...fields3, offset, zone };
31566
+ checkCalendar(fields4, restrictYear);
31567
+ return { ...fields4, offset, zone };
31345
31568
  }
31346
- instant(fields3, fraction = 0n) {
31347
- checkCalendar(fields3);
31348
- const wall = utcMilliseconds(fields3);
31569
+ instant(fields4, fraction = 0n) {
31570
+ checkCalendar(fields4);
31571
+ const wall = utcMilliseconds(fields4);
31349
31572
  if (this.fixedOffset !== void 0) return boundedInstant(BigInt(wall) * 1000000n - BigInt(this.fixedOffset) * nanosecondsPerSecond + fraction);
31350
31573
  const offsets = /* @__PURE__ */ new Set();
31351
31574
  for (const days of [-2, -1, 0, 1, 2]) offsets.add(this.observedFields(BigInt(wall + days * 864e5) * 1000000n, false).offset);
31352
31575
  const candidates = [];
31353
31576
  for (const offset of offsets) {
31354
31577
  const candidate = BigInt(wall) * 1000000n - BigInt(offset) * nanosecondsPerSecond + fraction;
31355
- if (sameFields(this.observedFields(candidate, false), fields3)) candidates.push(candidate);
31578
+ if (sameFields(this.observedFields(candidate, false), fields4)) candidates.push(candidate);
31356
31579
  }
31357
31580
  if (candidates.length === 0) throw new CommandFailure("nonexistent local time in virtual TZ");
31358
31581
  if (candidates.length !== 1) throw new CommandFailure("ambiguous local time; specify an explicit UTC offset");
@@ -31378,8 +31601,8 @@ function parseDate(text3, zone, now) {
31378
31601
  if (["today", "yesterday", "tomorrow"].includes(value2)) {
31379
31602
  const current = now();
31380
31603
  if (value2 === "today") return current;
31381
- const fields3 = zone.fields(current);
31382
- const changed = utcFields(utcMilliseconds(fields3) + (value2 === "yesterday" ? -864e5 : 864e5));
31604
+ const fields4 = zone.fields(current);
31605
+ const changed = utcFields(utcMilliseconds(fields4) + (value2 === "yesterday" ? -864e5 : 864e5));
31383
31606
  return zone.instant(changed, current - floorDivide(current, nanosecondsPerSecond) * nanosecondsPerSecond);
31384
31607
  }
31385
31608
  const relative = /^(?:now\s+)?([+-]?\d+)\s+(seconds?|minutes?|hours?)(?:\s+(ago))?$/.exec(value2);
@@ -31391,7 +31614,7 @@ function parseDate(text3, zone, now) {
31391
31614
  }
31392
31615
  const iso = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:[.,](\d{1,9}))?)?)?(?:\s*(Z|UTC|GMT|[+-]\d{2}(?::?\d{2})?(?::\d{2})?))?$/.exec(value2);
31393
31616
  if (iso) {
31394
- const fields3 = {
31617
+ const fields4 = {
31395
31618
  year: Number(iso[1]),
31396
31619
  month: Number(iso[2]),
31397
31620
  day: Number(iso[3]),
@@ -31399,11 +31622,11 @@ function parseDate(text3, zone, now) {
31399
31622
  minute: Number(iso[5] ?? 0),
31400
31623
  second: Number(iso[6] ?? 0)
31401
31624
  };
31402
- return parsedZone(iso[8], zone).instant(fields3, BigInt((iso[7] ?? "").padEnd(9, "0")));
31625
+ return parsedZone(iso[8], zone).instant(fields4, BigInt((iso[7] ?? "").padEnd(9, "0")));
31403
31626
  }
31404
31627
  const rfc = /^(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?(\d{1,2})\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+(GMT|UTC|[+-]\d{4})$/.exec(value2);
31405
31628
  if (rfc) {
31406
- const fields3 = {
31629
+ const fields4 = {
31407
31630
  year: Number(rfc[4]),
31408
31631
  month: monthNames.findIndex((name2) => name2.startsWith(rfc[3])) + 1,
31409
31632
  day: Number(rfc[2]),
@@ -31411,8 +31634,8 @@ function parseDate(text3, zone, now) {
31411
31634
  minute: Number(rfc[6]),
31412
31635
  second: Number(rfc[7])
31413
31636
  };
31414
- if (rfc[1] && !weekdayNames[new Date(utcMilliseconds(fields3)).getUTCDay()].startsWith(rfc[1])) throw new CommandFailure("weekday does not match calendar date");
31415
- return parsedZone(rfc[8], zone).instant(fields3);
31637
+ if (rfc[1] && !weekdayNames[new Date(utcMilliseconds(fields4)).getUTCDay()].startsWith(rfc[1])) throw new CommandFailure("weekday does not match calendar date");
31638
+ return parsedZone(rfc[8], zone).instant(fields4);
31416
31639
  }
31417
31640
  throw new CommandFailure(`unsupported or invalid date: ${text3}`);
31418
31641
  }
@@ -31431,18 +31654,18 @@ function offsetText(offset, colons) {
31431
31654
  return { value: `${sign}${hours}`, width: 3 };
31432
31655
  }
31433
31656
  function formatDate(format3, instant, zone, limits) {
31434
- const fields3 = zone.fields(instant);
31435
- const midnight = utcMilliseconds({ ...fields3, hour: 0, minute: 0, second: 0 });
31657
+ const fields4 = zone.fields(instant);
31658
+ const midnight = utcMilliseconds({ ...fields4, hour: 0, minute: 0, second: 0 });
31436
31659
  const weekday = new Date(midnight).getUTCDay();
31437
- const ordinal = Math.floor((midnight - utcMilliseconds({ ...fields3, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 864e5) + 1;
31660
+ const ordinal = Math.floor((midnight - utcMilliseconds({ ...fields4, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 864e5) + 1;
31438
31661
  const thursday = new Date(midnight + (3 - (weekday + 6) % 7) * 864e5);
31439
31662
  const isoYear = thursday.getUTCFullYear();
31440
31663
  const isoWeek = 1 + Math.floor((thursday.getTime() - utcMilliseconds({ year: isoYear, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 6048e5);
31441
31664
  const nano = (instant - floorDivide(instant, nanosecondsPerSecond) * nanosecondsPerSecond).toString().padStart(9, "0");
31442
31665
  const number6 = (value2, width = 2, padding = "0") => value2.toString().padStart(width, padding);
31443
- const time = `${number6(fields3.hour)}:${number6(fields3.minute)}:${number6(fields3.second)}`;
31444
- const hour12 = fields3.hour % 12 || 12;
31445
- const meridian = fields3.hour < 12 ? "AM" : "PM";
31666
+ const time = `${number6(fields4.hour)}:${number6(fields4.minute)}:${number6(fields4.second)}`;
31667
+ const hour12 = fields4.hour % 12 || 12;
31668
+ const meridian = fields4.hour < 12 ? "AM" : "PM";
31446
31669
  const pieces = [];
31447
31670
  let size = 0;
31448
31671
  const append = (value2) => {
@@ -31494,34 +31717,34 @@ function formatDate(format3, instant, zone, limits) {
31494
31717
  break;
31495
31718
  case "b":
31496
31719
  case "h":
31497
- value2 = monthNames[fields3.month - 1].slice(0, 3);
31720
+ value2 = monthNames[fields4.month - 1].slice(0, 3);
31498
31721
  break;
31499
31722
  case "B":
31500
- value2 = monthNames[fields3.month - 1];
31723
+ value2 = monthNames[fields4.month - 1];
31501
31724
  break;
31502
31725
  case "c":
31503
- value2 = `${weekdayNames[weekday].slice(0, 3)} ${monthNames[fields3.month - 1].slice(0, 3)} ${number6(fields3.day, 2, " ")} ${time} ${number6(fields3.year, 4)}`;
31726
+ value2 = `${weekdayNames[weekday].slice(0, 3)} ${monthNames[fields4.month - 1].slice(0, 3)} ${number6(fields4.day, 2, " ")} ${time} ${number6(fields4.year, 4)}`;
31504
31727
  break;
31505
31728
  case "C":
31506
- value2 = String(Math.floor(fields3.year / 100));
31729
+ value2 = String(Math.floor(fields4.year / 100));
31507
31730
  defaultWidth = 2;
31508
31731
  break;
31509
31732
  case "d":
31510
31733
  case "e":
31511
- value2 = String(fields3.day);
31734
+ value2 = String(fields4.day);
31512
31735
  defaultWidth = 2;
31513
31736
  if (code === "e") defaultPadding = " ";
31514
31737
  break;
31515
31738
  case "D":
31516
- value2 = `${number6(fields3.month)}/${number6(fields3.day)}/${number6(fields3.year % 100, 2, padding ?? "0")}`;
31739
+ value2 = `${number6(fields4.month)}/${number6(fields4.day)}/${number6(fields4.year % 100, 2, padding ?? "0")}`;
31517
31740
  break;
31518
31741
  case "x":
31519
- value2 = `${number6(fields3.month)}/${number6(fields3.day)}/${number6(fields3.year % 100)}`;
31742
+ value2 = `${number6(fields4.month)}/${number6(fields4.day)}/${number6(fields4.year % 100)}`;
31520
31743
  break;
31521
31744
  case "F": {
31522
31745
  const yearWidth = width === void 0 && padding === void 0 ? 4 : Math.max(0, (width ?? 0) - 6);
31523
- const year = padding === "" ? String(fields3.year) : number6(fields3.year, yearWidth, padding ?? "0");
31524
- append(`${year}-${number6(fields3.month)}-${number6(fields3.day)}`);
31746
+ const year = padding === "" ? String(fields4.year) : number6(fields4.year, yearWidth, padding ?? "0");
31747
+ append(`${year}-${number6(fields4.month)}-${number6(fields4.day)}`);
31525
31748
  continue;
31526
31749
  }
31527
31750
  case "g":
@@ -31534,7 +31757,7 @@ function formatDate(format3, instant, zone, limits) {
31534
31757
  break;
31535
31758
  case "H":
31536
31759
  case "k":
31537
- value2 = String(fields3.hour);
31760
+ value2 = String(fields4.hour);
31538
31761
  defaultWidth = 2;
31539
31762
  if (code === "k") defaultPadding = " ";
31540
31763
  break;
@@ -31549,11 +31772,11 @@ function formatDate(format3, instant, zone, limits) {
31549
31772
  defaultWidth = 3;
31550
31773
  break;
31551
31774
  case "m":
31552
- value2 = String(fields3.month);
31775
+ value2 = String(fields4.month);
31553
31776
  defaultWidth = 2;
31554
31777
  break;
31555
31778
  case "M":
31556
- value2 = String(fields3.minute);
31779
+ value2 = String(fields4.minute);
31557
31780
  defaultWidth = 2;
31558
31781
  break;
31559
31782
  case "n":
@@ -31574,21 +31797,21 @@ function formatDate(format3, instant, zone, limits) {
31574
31797
  value2 = meridian.toLowerCase();
31575
31798
  break;
31576
31799
  case "q":
31577
- value2 = String(Math.ceil(fields3.month / 3));
31800
+ value2 = String(Math.ceil(fields4.month / 3));
31578
31801
  defaultWidth = 1;
31579
31802
  break;
31580
31803
  case "r":
31581
- value2 = `${number6(hour12)}:${number6(fields3.minute)}:${number6(fields3.second)} ${meridian}`;
31804
+ value2 = `${number6(hour12)}:${number6(fields4.minute)}:${number6(fields4.second)} ${meridian}`;
31582
31805
  break;
31583
31806
  case "R":
31584
- value2 = `${number6(fields3.hour)}:${number6(fields3.minute)}`;
31807
+ value2 = `${number6(fields4.hour)}:${number6(fields4.minute)}`;
31585
31808
  break;
31586
31809
  case "s":
31587
31810
  value2 = floorDivide(instant, nanosecondsPerSecond).toString();
31588
31811
  defaultWidth = 1;
31589
31812
  break;
31590
31813
  case "S":
31591
- value2 = String(fields3.second);
31814
+ value2 = String(fields4.second);
31592
31815
  defaultWidth = 2;
31593
31816
  break;
31594
31817
  case "t":
@@ -31619,21 +31842,21 @@ function formatDate(format3, instant, zone, limits) {
31619
31842
  defaultWidth = 2;
31620
31843
  break;
31621
31844
  case "y":
31622
- value2 = String(fields3.year % 100);
31845
+ value2 = String(fields4.year % 100);
31623
31846
  defaultWidth = 2;
31624
31847
  break;
31625
31848
  case "Y":
31626
- value2 = String(fields3.year);
31849
+ value2 = String(fields4.year);
31627
31850
  defaultWidth = 4;
31628
31851
  break;
31629
31852
  case "z": {
31630
- const offset2 = offsetText(fields3.offset, colons);
31853
+ const offset2 = offsetText(fields4.offset, colons);
31631
31854
  value2 = offset2.value;
31632
31855
  defaultWidth = offset2.width;
31633
31856
  break;
31634
31857
  }
31635
31858
  case "Z":
31636
- value2 = fields3.zone;
31859
+ value2 = fields4.zone;
31637
31860
  break;
31638
31861
  default:
31639
31862
  throw new CommandFailure(`unsupported date format directive: %${code}`);
@@ -32439,13 +32662,13 @@ var Walker2 = class {
32439
32662
  const name2 = depth === 0 || this.args.full ? entry.display : entry.name;
32440
32663
  const annotation = entry.error ?? (entry.cycle ? "recursive, not followed" : void 0);
32441
32664
  if (this.args.json) {
32442
- const fields3 = {
32665
+ const fields4 = {
32443
32666
  type: entry.stat?.type === "symlink" ? "link" : entry.stat?.type ?? "unknown",
32444
32667
  name: name2,
32445
32668
  ...entry.target === void 0 ? {} : { target: entry.target },
32446
32669
  ...annotation === void 0 ? {} : { error: annotation }
32447
32670
  };
32448
- await this.write(`${this.padding(depth + 1)}${serialized(fields3, this.budget).slice(0, -1)}`);
32671
+ await this.write(`${this.padding(depth + 1)}${serialized(fields4, this.budget).slice(0, -1)}`);
32449
32672
  if (children.length) {
32450
32673
  await this.write(`,"contents":[${this.newline()}`);
32451
32674
  for (let index = 0; index < children.length; index++) {
@@ -32991,7 +33214,7 @@ init_platform();
32991
33214
 
32992
33215
  // packages/safe-bash/src/commands/column/display.ts
32993
33216
  init_platform();
32994
- function whitespace(character) {
33217
+ function whitespace2(character) {
32995
33218
  return character === " " || character === " " || character === "\r" || character === "\v" || character === "\f";
32996
33219
  }
32997
33220
  function widthOf(point) {
@@ -33029,7 +33252,7 @@ function decode2(bytes3) {
33029
33252
  throw new FsError("EINVAL", { message: "invalid UTF-8 input" });
33030
33253
  }
33031
33254
  }
33032
- async function fields2(text3, separator, budget, remainingCells) {
33255
+ async function fields3(text3, separator, budget, remainingCells) {
33033
33256
  const result = [];
33034
33257
  let start = 0, offset = 0;
33035
33258
  const append = (end) => {
@@ -33039,7 +33262,7 @@ async function fields2(text3, separator, budget, remainingCells) {
33039
33262
  };
33040
33263
  for (const character of text3) {
33041
33264
  await budget.step();
33042
- if (separator ? separator.has(character) : whitespace(character)) {
33265
+ if (separator ? separator.has(character) : whitespace2(character)) {
33043
33266
  if (separator || offset > start) append(offset);
33044
33267
  start = offset + character.length;
33045
33268
  }
@@ -33521,7 +33744,7 @@ function createColumnCommand(options2 = {}) {
33521
33744
  await budget.work(bytes3.length);
33522
33745
  const text3 = decode2(bytes3);
33523
33746
  if (!text3.length) continue;
33524
- const values = parsed.table ? await fields2(text3, parsed.separator, budget, limits.maxCells - cellCount) : [text3];
33747
+ const values = parsed.table ? await fields3(text3, parsed.separator, budget, limits.maxCells - cellCount) : [text3];
33525
33748
  if (parsed.table && !values.length) continue;
33526
33749
  if (!parsed.table) {
33527
33750
  let blank2 = true;
@@ -34345,21 +34568,21 @@ var Renderer = class {
34345
34568
  this.budget.work(1);
34346
34569
  await this.budget.checkpoint();
34347
34570
  if (child.tag !== "text") return false;
34348
- let whitespace2 = this.whitespace.get(child);
34349
- if (whitespace2 === void 0) {
34350
- whitespace2 = true;
34571
+ let whitespace3 = this.whitespace.get(child);
34572
+ if (whitespace3 === void 0) {
34573
+ whitespace3 = true;
34351
34574
  for (const character of child.text) {
34352
34575
  this.budget.work(1);
34353
34576
  await this.budget.checkpoint();
34354
34577
  if (!htmlSpace(character)) {
34355
- whitespace2 = false;
34578
+ whitespace3 = false;
34356
34579
  break;
34357
34580
  }
34358
34581
  }
34359
34582
  this.budget.work(1);
34360
- this.whitespace.set(child, whitespace2);
34583
+ this.whitespace.set(child, whitespace3);
34361
34584
  }
34362
- if (!whitespace2) return false;
34585
+ if (!whitespace3) return false;
34363
34586
  }
34364
34587
  return true;
34365
34588
  }
@@ -35496,13 +35719,13 @@ function numeric3(value2, budget) {
35496
35719
  budget.allocation(value2.length);
35497
35720
  return BigInt(new TextDecoder().decode(value2));
35498
35721
  }
35499
- function integer4(value2, budget) {
35722
+ function integer5(value2, budget) {
35500
35723
  const result = numeric3(value2, budget);
35501
35724
  if (result === void 0) throw new ExprError("non-integer argument");
35502
35725
  return result;
35503
35726
  }
35504
35727
  function arithmetic(operator, left, right, budget) {
35505
- const first = integer4(left, budget), second = integer4(right, budget);
35728
+ const first = integer5(left, budget), second = integer5(right, budget);
35506
35729
  if ((operator === "/" || operator === "%") && second === 0n) throw new ExprError("division by zero");
35507
35730
  const firstDigits = left instanceof Uint8Array ? left.length : left.text.length;
35508
35731
  const secondDigits = right instanceof Uint8Array ? right.length : right.text.length;
@@ -35516,7 +35739,7 @@ function arithmetic(operator, left, right, budget) {
35516
35739
  }
35517
35740
  function compare5(left, right, budget) {
35518
35741
  if (numericShape(left, budget) && numericShape(right, budget)) {
35519
- const first = integer4(left, budget), second = integer4(right, budget);
35742
+ const first = integer5(left, budget), second = integer5(right, budget);
35520
35743
  return first < second ? -1 : first > second ? 1 : 0;
35521
35744
  }
35522
35745
  requireByteCollation(budget.context);
@@ -36105,7 +36328,7 @@ function parseDuration(token) {
36105
36328
  let sawPoint = false;
36106
36329
  let trailingDigits = 0;
36107
36330
  let integerDigits = 0;
36108
- let integer9 = 0;
36331
+ let integer10 = 0;
36109
36332
  let place = 1;
36110
36333
  let placeOverflow = false;
36111
36334
  let integerOverflow = false;
@@ -36122,8 +36345,8 @@ function parseDuration(token) {
36122
36345
  fractionSticky ||= temporary % 10 !== 0;
36123
36346
  } else integerDigits++;
36124
36347
  if (digit3 !== 0) {
36125
- if (placeOverflow || digit3 > Math.floor((quotient - integer9) / place)) integerOverflow = true;
36126
- else integer9 += digit3 * place;
36348
+ if (placeOverflow || digit3 > Math.floor((quotient - integer10) / place)) integerOverflow = true;
36349
+ else integer10 += digit3 * place;
36127
36350
  }
36128
36351
  if (!placeOverflow) {
36129
36352
  if (place > Math.floor(quotient / 10)) placeOverflow = true;
@@ -36135,7 +36358,7 @@ function parseDuration(token) {
36135
36358
  if (sawPoint) invalid3 = true;
36136
36359
  else {
36137
36360
  sawPoint = true;
36138
- integer9 = 0;
36361
+ integer10 = 0;
36139
36362
  place = 1;
36140
36363
  placeOverflow = false;
36141
36364
  integerOverflow = false;
@@ -36148,7 +36371,7 @@ function parseDuration(token) {
36148
36371
  if (invalid3) return { kind: "invalid" };
36149
36372
  if (integerOverflow) return { kind: "overflow" };
36150
36373
  const fraction = sawPoint ? fractionCarry + (fractionSticky ? 1 : 0) : 0;
36151
- const product = integer9 * millisecondsPerUnit;
36374
+ const product = integer10 * millisecondsPerUnit;
36152
36375
  if (fraction > maximumMilliseconds - product) return { kind: "overflow" };
36153
36376
  return { kind: "value", milliseconds: product + fraction };
36154
36377
  }
@@ -37630,7 +37853,7 @@ var precedence = {
37630
37853
  "%": 13,
37631
37854
  "**": 14
37632
37855
  };
37633
- function integer5(text3) {
37856
+ function integer6(text3) {
37634
37857
  if (/^0[xX][\da-fA-F]+$/u.test(text3)) return BigInt(text3);
37635
37858
  if (/^0[0-7]+$/u.test(text3)) return BigInt(`0o${text3.slice(1)}`);
37636
37859
  if (/^0\d+$/u.test(text3)) throw new PublicDiagnostic("Invalid octal constant");
@@ -37688,7 +37911,7 @@ function parseArithmetic(source2, offset = 0, budget = new ParseBudget()) {
37688
37911
  } else {
37689
37912
  budget.admit();
37690
37913
  try {
37691
- left = { kind: "literal", value: BigInt.asIntN(64, integer5(token)) };
37914
+ left = { kind: "literal", value: BigInt.asIntN(64, integer6(token)) };
37692
37915
  } catch {
37693
37916
  error("Invalid arithmetic operand");
37694
37917
  }
@@ -38031,7 +38254,7 @@ async function patternAdmission(pattern, context2) {
38031
38254
  }
38032
38255
  if (bracket) unsupported2("unclosed bracket pattern");
38033
38256
  }
38034
- async function integer6(value2, context2) {
38257
+ async function integer7(value2, context2) {
38035
38258
  await charge(context2, value2.length);
38036
38259
  const text3 = value2.trim();
38037
38260
  if (!text3) return 0n;
@@ -38125,7 +38348,7 @@ async function leaf(node, context2) {
38125
38348
  const order = import_buffer.Buffer.compare(import_buffer.Buffer.from(left), import_buffer.Buffer.from(right));
38126
38349
  return node.operator === "<" ? order < 0 : order > 0;
38127
38350
  }
38128
- const first = await integer6(left, context2), second = await integer6(right, context2);
38351
+ const first = await integer7(left, context2), second = await integer7(right, context2);
38129
38352
  switch (node.operator) {
38130
38353
  case "-eq":
38131
38354
  return first === second;
@@ -39660,7 +39883,7 @@ import { scopeFileSystem } from "@poe-platform/safe-fs/core";
39660
39883
  init_platform();
39661
39884
  var BraceExpansionFailure = class extends Error {
39662
39885
  };
39663
- async function integer7(text3, checkpoint) {
39886
+ async function integer8(text3, checkpoint) {
39664
39887
  let offset = text3.startsWith("-") || text3.startsWith("+") ? 1 : 0;
39665
39888
  if (offset === text3.length) return void 0;
39666
39889
  while (text3[offset] === "0") {
@@ -39734,8 +39957,8 @@ async function* expandBraces(word, budget, signal) {
39734
39957
  const first = pieces[0];
39735
39958
  const last = pieces[1];
39736
39959
  admit2(256);
39737
- let start = await integer7(first, checkpoint);
39738
- let end = await integer7(last, checkpoint);
39960
+ let start = await integer8(first, checkpoint);
39961
+ let end = await integer8(last, checkpoint);
39739
39962
  const numeric4 = start !== void 0 && end !== void 0;
39740
39963
  if (!numeric4) {
39741
39964
  const alphabetic = (value2) => value2.length === 1 && (value2 >= "a" && value2 <= "z" || value2 >= "A" && value2 <= "Z");
@@ -39743,7 +39966,7 @@ async function* expandBraces(word, budget, signal) {
39743
39966
  start = BigInt(first.charCodeAt(0));
39744
39967
  end = BigInt(last.charCodeAt(0));
39745
39968
  }
39746
- let step = pieces.length === 3 ? await integer7(pieces[2], checkpoint) : 1n;
39969
+ let step = pieces.length === 3 ? await integer8(pieces[2], checkpoint) : 1n;
39747
39970
  if (step === void 0) return void 0;
39748
39971
  if (step < 0n) step = -step;
39749
39972
  if (step === 0n) step = 1n;
@@ -40569,7 +40792,7 @@ var GetoptsError = class extends Error {
40569
40792
  function record(value2) {
40570
40793
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
40571
40794
  }
40572
- function integer8(value2, minimum, name2) {
40795
+ function integer9(value2, minimum, name2) {
40573
40796
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < minimum) {
40574
40797
  throw new GetoptsError("INVALID_INPUT", `${name2} must be a safe integer >= ${minimum}`);
40575
40798
  }
@@ -40579,16 +40802,16 @@ function createGetoptsState() {
40579
40802
  }
40580
40803
  function cloneGetoptsState(state) {
40581
40804
  if (!record(state)) throw new GetoptsError("INVALID_INPUT", "Invalid getopts state");
40582
- integer8(state.index, 0, "index");
40805
+ integer9(state.index, 0, "index");
40583
40806
  if (state.active === void 0) return { index: state.index };
40584
40807
  if (!record(state.active)) throw new GetoptsError("INVALID_INPUT", "Invalid getopts active cursor");
40585
- integer8(state.active.argument, 0, "active.argument");
40586
- integer8(state.active.offset, 1, "active.offset");
40808
+ integer9(state.active.argument, 0, "active.argument");
40809
+ integer9(state.active.offset, 1, "active.offset");
40587
40810
  return { index: state.index, active: { argument: state.active.argument, offset: state.active.offset } };
40588
40811
  }
40589
40812
  function withGetoptsIndex(state, index) {
40590
40813
  const copy2 = cloneGetoptsState(state);
40591
- integer8(index, Number.MIN_SAFE_INTEGER, "index");
40814
+ integer9(index, Number.MIN_SAFE_INTEGER, "index");
40592
40815
  return index <= 1 ? createGetoptsState() : { ...copy2, index };
40593
40816
  }
40594
40817
  var ScanWork = class {
@@ -40603,10 +40826,10 @@ var ScanWork = class {
40603
40826
  checkpoint;
40604
40827
  constructor(work) {
40605
40828
  if (!record(work)) throw new GetoptsError("INVALID_INPUT", "Explicit getopts work controls are required");
40606
- integer8(work.maxArguments, 0, "maxArguments");
40607
- integer8(work.maxBytes, 0, "maxBytes");
40608
- integer8(work.maxSteps, 0, "maxSteps");
40609
- integer8(work.yieldEvery, 1, "yieldEvery");
40829
+ integer9(work.maxArguments, 0, "maxArguments");
40830
+ integer9(work.maxBytes, 0, "maxBytes");
40831
+ integer9(work.maxSteps, 0, "maxSteps");
40832
+ integer9(work.yieldEvery, 1, "yieldEvery");
40610
40833
  if (typeof work.checkpoint !== "function") throw new GetoptsError("INVALID_INPUT", "A getopts checkpoint is required");
40611
40834
  if (work.signal !== void 0 && (!record(work.signal) || typeof work.signal.throwIfAborted !== "function" || typeof work.signal.addEventListener !== "function" || typeof work.signal.removeEventListener !== "function")) {
40612
40835
  throw new GetoptsError("INVALID_INPUT", "Invalid getopts signal");
@@ -41314,9 +41537,9 @@ var Admission = class {
41314
41537
  }
41315
41538
  };
41316
41539
  var ArrayLedger = class _ArrayLedger {
41317
- constructor(bytes3, fields3, initialTicket = 0) {
41540
+ constructor(bytes3, fields4, initialTicket = 0) {
41318
41541
  this.bytes = bytes3;
41319
- this.fields = fields3;
41542
+ this.fields = fields4;
41320
41543
  if (!Number.isSafeInteger(initialTicket) || initialTicket < 0) throw new RangeError("Invalid private initial ticket");
41321
41544
  this.#sequence.lastIssued = initialTicket;
41322
41545
  }
@@ -41373,8 +41596,8 @@ var ArrayLedger = class _ArrayLedger {
41373
41596
  }
41374
41597
  derive() {
41375
41598
  const bytes3 = BigInt(this.bytes);
41376
- const fields3 = BigInt(this.fields);
41377
- const values = [fields3, fields3, bytes3, 128n * fields3, 8n * bytes3 + 512n * fields3, 8n * fields3, 32n * bytes3 + 256n * fields3];
41599
+ const fields4 = BigInt(this.fields);
41600
+ const values = [fields4, fields4, bytes3, 128n * fields4, 8n * bytes3 + 512n * fields4, 8n * fields4, 32n * bytes3 + 256n * fields4];
41378
41601
  const result = [0, 0, 0, 0, 0, 0, 0];
41379
41602
  for (let index = 0; index < values.length; index++) {
41380
41603
  const value2 = values[index];
@@ -41927,8 +42150,8 @@ async function mapfileOptions(context2, work, allocation) {
41927
42150
  const numeric4 = async (text3, maximum) => {
41928
42151
  let value2 = 0;
41929
42152
  let index = 0;
41930
- const whitespace2 = (code) => code === 32 || code >= 9 && code <= 13;
41931
- while (index < text3.length && whitespace2(text3.charCodeAt(index))) {
42153
+ const whitespace3 = (code) => code === 32 || code >= 9 && code <= 13;
42154
+ while (index < text3.length && whitespace3(text3.charCodeAt(index))) {
41932
42155
  const pending = stringCheckpoint(work);
41933
42156
  if (pending) await pending;
41934
42157
  index++;
@@ -41948,7 +42171,7 @@ async function mapfileOptions(context2, work, allocation) {
41948
42171
  for (; index < text3.length; index++) {
41949
42172
  const pending = stringCheckpoint(work);
41950
42173
  if (pending) await pending;
41951
- if (!whitespace2(text3.charCodeAt(index))) throw new MapfileUsageError(`${text3}: invalid number`, 1);
42174
+ if (!whitespace3(text3.charCodeAt(index))) throw new MapfileUsageError(`${text3}: invalid number`, 1);
41952
42175
  }
41953
42176
  if (!digits || negative && value2 !== 0) throw new MapfileUsageError(`${text3}: invalid number`, 1);
41954
42177
  return value2;
@@ -42599,12 +42822,12 @@ function* pathTargets(name2, path, limits, signal, fail4) {
42599
42822
  yield name2;
42600
42823
  return;
42601
42824
  }
42602
- let fields3 = 1;
42825
+ let fields4 = 1;
42603
42826
  for (let separator = path.indexOf(":"); separator >= 0; separator = path.indexOf(":", separator + 1)) {
42604
42827
  signal.throwIfAborted();
42605
- if (++fields3 > limits.maxExpansionFields) fail4("maxExpansionFields");
42828
+ if (++fields4 > limits.maxExpansionFields) fail4("maxExpansionFields");
42606
42829
  }
42607
- if (fields3 > limits.maxExpansionFields) fail4("maxExpansionFields");
42830
+ if (fields4 > limits.maxExpansionFields) fail4("maxExpansionFields");
42608
42831
  let start = 0;
42609
42832
  let consulted = 0;
42610
42833
  while (start <= path.length) {
@@ -43529,8 +43752,8 @@ var DirectoryStackWork = class {
43529
43752
  for (let offset = 1; offset < token.length; offset++) {
43530
43753
  await this.charge(1);
43531
43754
  const code = token.charCodeAt(offset);
43532
- const whitespace2 = code === 32 || code >= 9 && code <= 13;
43533
- if (phase === "leading" && whitespace2) continue;
43755
+ const whitespace3 = code === 32 || code >= 9 && code <= 13;
43756
+ if (phase === "leading" && whitespace3) continue;
43534
43757
  if (phase === "leading" && (code === 43 || code === 45)) {
43535
43758
  negative = code === 45;
43536
43759
  phase = "sign";
@@ -43541,7 +43764,7 @@ var DirectoryStackWork = class {
43541
43764
  digits = true;
43542
43765
  value2 = value2 * 10n + BigInt(code - 48);
43543
43766
  if (value2 > (negative ? 9223372036854775808n : 9223372036854775807n)) this.fail("invalid directory stack index", 2);
43544
- } else if (phase === "digits" && whitespace2 || phase === "trailing" && whitespace2) phase = "trailing";
43767
+ } else if (phase === "digits" && whitespace3 || phase === "trailing" && whitespace3) phase = "trailing";
43545
43768
  else this.fail("invalid directory stack index", 2);
43546
43769
  }
43547
43770
  if (!digits) this.fail("invalid directory stack index", 2);
@@ -44396,8 +44619,8 @@ var Runtime = class _Runtime {
44396
44619
  return number6;
44397
44620
  }
44398
44621
  const word = index.word ?? parseArraySubscript(index.source ?? index.decimal, this.budget.parsing, byteLocale(state.variables), state.depth);
44399
- const fields3 = await this.valueWord(word, state, io, false);
44400
- const value2 = fields3.length === 1 ? fields3[0] : concatShellValues(fields3, io[valueScope]);
44622
+ const fields4 = await this.valueWord(word, state, io, false);
44623
+ const value2 = fields4.length === 1 ? fields4[0] : concatShellValues(fields4, io[valueScope]);
44401
44624
  if (shellValueByteLength(value2) === 0) {
44402
44625
  await this.diagnostic(io, "associative array: bad array subscript");
44403
44626
  if (create) throw completedExit(1);
@@ -44481,8 +44704,8 @@ var Runtime = class _Runtime {
44481
44704
  const join = async (values) => values.every((value2) => typeof value2 === "string") ? this.arrayJoin(operation2, values, "") : concatShellValues(values, io[valueScope]);
44482
44705
  if (assignment.kind === "element") {
44483
44706
  const index = await this.arrayIndex(staged, assignment.index, state, io, operation2, true);
44484
- const fields3 = await this.valueWord(assignment.value, state, io, false);
44485
- let value2 = await join(fields3);
44707
+ const fields4 = await this.valueWord(assignment.value, state, io, false);
44708
+ let value2 = await join(fields4);
44486
44709
  if (assignment.append) value2 = await join([staged.values.get(index)?.text.rawValue ?? staged.get(index) ?? "", value2]);
44487
44710
  await insert(index, value2);
44488
44711
  } else for (const entry of assignment.entries) {
@@ -44500,12 +44723,12 @@ var Runtime = class _Runtime {
44500
44723
  }
44501
44724
  if (expandedEntry) continue;
44502
44725
  }
44503
- const fields3 = await this.valueWord(entry.value, state, io, entry.index === void 0);
44726
+ const fields4 = await this.valueWord(entry.value, state, io, entry.index === void 0);
44504
44727
  if (entry.index) {
44505
44728
  const index = numericIndex(entry.index);
44506
- await insert(index, await join(fields3));
44729
+ await insert(index, await join(fields4));
44507
44730
  cursor = index + 1;
44508
- } else for (const value2 of fields3) {
44731
+ } else for (const value2 of fields4) {
44509
44732
  await insert(cursor, value2);
44510
44733
  cursor++;
44511
44734
  }
@@ -45520,8 +45743,8 @@ var Runtime = class _Runtime {
45520
45743
  throw new ArrayFailure("indexed binding cannot be a command prefix");
45521
45744
  }
45522
45745
  await this.arrayZero(state, assignment.name, async () => {
45523
- const fields3 = await this.valueWord(assignment.value, state, io, false);
45524
- return fields3.every((value3) => typeof value3 === "string") ? this.arrayJoin(requireArrays(state).owner, fields3, "") : concatShellValues(fields3, io[valueScope]);
45746
+ const fields4 = await this.valueWord(assignment.value, state, io, false);
45747
+ return fields4.every((value3) => typeof value3 === "string") ? this.arrayJoin(requireArrays(state).owner, fields4, "") : concatShellValues(fields4, io[valueScope]);
45525
45748
  }, assignment.append);
45526
45749
  continue;
45527
45750
  }
@@ -46860,7 +47083,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46860
47083
  }
46861
47084
  async letBuiltin(context2, state) {
46862
47085
  this.signal.throwIfAborted();
46863
- const { maxExpansionBytes: bytes3, maxExpansionFields: fields3 } = this.budget.limits;
47086
+ const { maxExpansionBytes: bytes3, maxExpansionFields: fields4 } = this.budget.limits;
46864
47087
  const admit2 = (value3) => {
46865
47088
  if (typeof value3 !== "string" || value3.includes("\0")) throw new CommandFailure2("let: arguments must be strings without NUL", 2);
46866
47089
  if (value3.length > bytes3 || import_buffer.Buffer.byteLength(value3) > bytes3) this.budget.fail("maxExpansionBytes");
@@ -46872,7 +47095,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46872
47095
  };
46873
47096
  const { args } = context2;
46874
47097
  if (!Array.isArray(args)) throw new CommandFailure2("let: argument array required", 2);
46875
- if (args.length + 1 > fields3) this.budget.fail("maxExpansionFields");
47098
+ if (args.length + 1 > fields4) this.budget.fail("maxExpansionFields");
46876
47099
  admit2(context2.command);
46877
47100
  for (let index = 0; index < args.length; index++) {
46878
47101
  this.signal.throwIfAborted();
@@ -46904,7 +47127,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46904
47127
  }
46905
47128
  async getoptsBuiltin(context2, state) {
46906
47129
  this.signal.throwIfAborted();
46907
- const { maxExpansionBytes: bytes3, maxExpansionFields: fields3 } = this.budget.limits;
47130
+ const { maxExpansionBytes: bytes3, maxExpansionFields: fields4 } = this.budget.limits;
46908
47131
  const admit2 = (value2) => {
46909
47132
  if (typeof value2 !== "string") throw new CommandFailure2("getopts: arguments must be strings without NUL", 2);
46910
47133
  if (value2.length > bytes3 || import_buffer.Buffer.byteLength(value2) > bytes3) this.budget.fail("maxExpansionBytes");
@@ -46916,7 +47139,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46916
47139
  this.signal.throwIfAborted();
46917
47140
  };
46918
47141
  if (!Array.isArray(context2.args)) throw new CommandFailure2("getopts: argument array required", 2);
46919
- if (context2.args.length + 1 > fields3) this.budget.fail("maxExpansionFields");
47142
+ if (context2.args.length + 1 > fields4) this.budget.fail("maxExpansionFields");
46920
47143
  admit2(context2.command);
46921
47144
  for (let index = 0; index < context2.args.length; index++) {
46922
47145
  this.signal.throwIfAborted();
@@ -46939,10 +47162,10 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46939
47162
  const monitor = explicit ? void 0 : stateMonitor(state);
46940
47163
  const revision = monitor?.positionalRevision;
46941
47164
  const supplied = explicit ? context2.args.slice(offset + 2) : state.positional;
46942
- if (supplied.length > fields3) this.budget.fail("maxExpansionFields");
47165
+ if (supplied.length > fields4) this.budget.fail("maxExpansionFields");
46943
47166
  const maxBytes = saturatedProduct(bytes3, saturatedSum(supplied.length, 1));
46944
47167
  const maxSteps = saturatedSum(saturatedProduct(maxBytes, 2), saturatedSum(supplied.length, 2));
46945
- const work = { maxArguments: fields3, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint };
47168
+ const work = { maxArguments: fields4, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint };
46946
47169
  let input3 = monitor?.getoptsInput;
46947
47170
  let allocation;
46948
47171
  let result;
@@ -48023,27 +48246,27 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48023
48246
  let position = 0;
48024
48247
  point = 0;
48025
48248
  const separator = () => position < end && !line.escaped.has(point) && separators.includes(String.fromCodePoint(line.value.codePointAt(position)));
48026
- const whitespace2 = () => separator() && " \n".includes(line.value[position]);
48249
+ const whitespace3 = () => separator() && " \n".includes(line.value[position]);
48027
48250
  const advance = () => {
48028
48251
  position += line.value.codePointAt(position) > 65535 ? 2 : 1;
48029
48252
  point++;
48030
48253
  };
48031
- while (position < end && whitespace2()) advance();
48032
- const fields3 = [];
48033
- while (position < end && fields3.length < names.length) {
48254
+ while (position < end && whitespace3()) advance();
48255
+ const fields4 = [];
48256
+ while (position < end && fields4.length < names.length) {
48034
48257
  const start = position;
48035
48258
  while (position < end && !separator()) advance();
48036
- fields3.push({ start, end: position });
48037
- while (position < end && whitespace2()) advance();
48259
+ fields4.push({ start, end: position });
48260
+ while (position < end && whitespace3()) advance();
48038
48261
  if (position < end && separator()) advance();
48039
- while (position < end && whitespace2()) advance();
48262
+ while (position < end && whitespace3()) advance();
48040
48263
  }
48041
48264
  for (let index = 0; index < names.length; index++) {
48042
48265
  if (state.readonlyVariables?.has(names[index])) {
48043
48266
  await this.diagnostic(context2, `${names[index]}: readonly variable`);
48044
48267
  return index === names.length - 1 ? 1 : 2;
48045
48268
  }
48046
- const field2 = fields3[index];
48269
+ const field2 = fields4[index];
48047
48270
  await this.assignVariable(state, names[index], field2 ? line.value.slice(field2.start, index === names.length - 1 && position < end ? end : field2.end) : "");
48048
48271
  }
48049
48272
  }
@@ -48087,13 +48310,13 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48087
48310
  return (await this.valueWords(words, state, io, declaration)).map(shellValueText);
48088
48311
  }
48089
48312
  async valueWords(words, state, io, declaration = false) {
48090
- const fields3 = [];
48313
+ const fields4 = [];
48091
48314
  for (const word of words) {
48092
48315
  const values = await this.valueWord(word, state, io, !(declaration && this.assignment(word)), false, false, false, void 0, true);
48093
- if (values.length > this.budget.limits.maxExpansionFields - fields3.length) this.budget.fail("maxExpansionFields");
48094
- for (const value2 of values) fields3.push(value2);
48316
+ if (values.length > this.budget.limits.maxExpansionFields - fields4.length) this.budget.fail("maxExpansionFields");
48317
+ for (const value2 of values) fields4.push(value2);
48095
48318
  }
48096
- return fields3;
48319
+ return fields4;
48097
48320
  }
48098
48321
  async part(part, state, io, hereString = false) {
48099
48322
  return shellValueText(await this.valuePart(part, state, io, hereString));
@@ -48581,20 +48804,20 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48581
48804
  }
48582
48805
  async valueWord(word, state, io, split4 = true, pattern = false, hereString = false, conditionalPattern = false, regexAppend, braces = split4 && !pattern && !hereString) {
48583
48806
  if (braces && state.braceexpand !== false && word.parts.some((part) => part.kind === "text" && !part.quoted && part.value.includes("{"))) {
48584
- const fields3 = [];
48807
+ const fields4 = [];
48585
48808
  let bytes3 = 0;
48586
48809
  for await (const expanded of expandBraces(word, this.budget, this.signal)) {
48587
48810
  const values = await this.valueWord(expanded, state, io, split4, pattern, hereString, conditionalPattern, regexAppend, false);
48588
- if (values.length > this.budget.limits.maxExpansionFields - fields3.length) this.budget.fail("maxExpansionFields");
48811
+ if (values.length > this.budget.limits.maxExpansionFields - fields4.length) this.budget.fail("maxExpansionFields");
48589
48812
  for (const value2 of values) {
48590
48813
  const size = shellValueByteLength(value2);
48591
48814
  if (size > this.budget.limits.maxExpansionBytes - bytes3) this.budget.fail("maxExpansionBytes");
48592
48815
  bytes3 += size;
48593
48816
  io[valueScope]?.reserve(32 + (typeof value2 === "string" ? value2.length * 2 : 0), 0);
48594
- fields3.push(value2);
48817
+ fields4.push(value2);
48595
48818
  }
48596
48819
  }
48597
- return fields3;
48820
+ return fields4;
48598
48821
  }
48599
48822
  const arrayOwned = word.parts.some((part) => part.kind === "variable" && !part.prefixNames && (getArraySelector(part) !== void 0 || arrayStore(state)?.get(part.name) !== void 0));
48600
48823
  const prefixOwned = word.parts.some((part) => part.kind === "variable" && (part.prefixNames === "@" || part.transform && part.name === "@"));
@@ -48605,14 +48828,14 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48605
48828
  if (owner) await this.prepareArrayObservers(state, owner);
48606
48829
  owner?.reserve({ metadata: 128 + word.parts.length * 32, allocatedSlots: word.parts.length + 1, work: word.parts.length + 5 });
48607
48830
  scratch?.reserve(word.parts.length * 32, 0);
48608
- const fields3 = [];
48831
+ const fields4 = [];
48609
48832
  let emptyNameGroups;
48610
48833
  let quoteGroup;
48611
48834
  const addField = () => {
48612
- if (fields3.length >= this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48835
+ if (fields4.length >= this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48613
48836
  scratch?.reserve(32, 0);
48614
48837
  owner?.reserve({ metadata: 32, allocatedSlots: 1, work: 3 });
48615
- fields3.push({ fragments: [], bytes: false, patterns: void 0, present: false, independentPresence: false });
48838
+ fields4.push({ fragments: [], bytes: false, patterns: void 0, present: false, independentPresence: false });
48616
48839
  };
48617
48840
  addField();
48618
48841
  let expansionBytes = 0;
@@ -48621,7 +48844,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48621
48844
  const size = shellValueByteLength(value2);
48622
48845
  if (size > this.budget.limits.maxExpansionBytes - expansionBytes) this.budget.fail("maxExpansionBytes");
48623
48846
  expansionBytes += size;
48624
- const field2 = fields3.at(-1);
48847
+ const field2 = fields4.at(-1);
48625
48848
  let escapes = 0;
48626
48849
  if (!glob) {
48627
48850
  const special = conditionalPattern ? "\\*?[]-^()|+!@" : "\\*?[]-^";
@@ -48684,9 +48907,9 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48684
48907
  const point = typeof piece === "string" ? piece.codePointAt(0) : void 0;
48685
48908
  if (typeof piece === "string" && point !== void 0 && piece.length === (point > 65535 ? 2 : 1) && points.has(point)) {
48686
48909
  if (!" \n".includes(piece)) {
48687
- fields3.at(-1).present = true;
48910
+ fields4.at(-1).present = true;
48688
48911
  addField();
48689
- } else if (fields3.at(-1).present) boundary = true;
48912
+ } else if (fields4.at(-1).present) boundary = true;
48690
48913
  } else {
48691
48914
  if (boundary) addField();
48692
48915
  boundary = false;
@@ -48750,18 +48973,18 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48750
48973
  if (position > 0) addField();
48751
48974
  append(stateMonitor(state)?.positionals.get(String(position), state.positional[position]) ?? state.positional[position], false, true);
48752
48975
  }
48753
- if (state.positional.length === 0 && word.parts.every((entry) => entry.kind === "text" && entry.value === "" || entry === part)) fields3[0].present = false;
48976
+ if (state.positional.length === 0 && word.parts.every((entry) => entry.kind === "text" && entry.value === "" || entry === part)) fields4[0].present = false;
48754
48977
  } else {
48755
48978
  const value2 = part.kind === "text" ? part.byteValue ?? part.value : await this.valuePart(part, state, partIO, hereString);
48756
48979
  if (part.quoted || !split4 || state.variables.IFS === "") append(value2, !part.quoted, quotedPresence || !split4 || shellValueByteLength(value2) > 0);
48757
48980
  else await appendSplit(value2);
48758
48981
  }
48759
- if (fields3.length > this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48982
+ if (fields4.length > this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48760
48983
  if (owner) await owner.ledger.checkpoint(this.signal);
48761
48984
  }
48762
48985
  const result = [];
48763
48986
  let resultBytes = 0;
48764
- for (const field2 of fields3) {
48987
+ for (const field2 of fields4) {
48765
48988
  if (!field2.present && split4) continue;
48766
48989
  if (split4 && !field2.independentPresence && field2.quoteGroups) {
48767
48990
  const work = { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
@@ -52027,7 +52250,7 @@ function* entities2(text3) {
52027
52250
  }
52028
52251
  function* validDeclaration(content, expectedEncoding) {
52029
52252
  let offset = 0;
52030
- const whitespace2 = function* () {
52253
+ const whitespace3 = function* () {
52031
52254
  const start = offset;
52032
52255
  while (offset < content.length && " \n\r".includes(content[offset])) {
52033
52256
  offset++;
@@ -52040,9 +52263,9 @@ function* validDeclaration(content, expectedEncoding) {
52040
52263
  if (content.slice(offset, offset + name2.length).toLowerCase() !== name2) return void 0;
52041
52264
  offset += name2.length;
52042
52265
  yield name2.length;
52043
- yield* whitespace2();
52266
+ yield* whitespace3();
52044
52267
  if (content[offset++] !== "=") return void 0;
52045
- yield* whitespace2();
52268
+ yield* whitespace3();
52046
52269
  const quote5 = content[offset++];
52047
52270
  if (quote5 !== "'" && quote5 !== '"') return void 0;
52048
52271
  const start = offset;
@@ -52054,20 +52277,20 @@ function* validDeclaration(content, expectedEncoding) {
52054
52277
  if (offset >= content.length) return void 0;
52055
52278
  return content.slice(start, offset++);
52056
52279
  };
52057
- if (!(yield* whitespace2()) || (yield* field2("version")) !== "1.0") return false;
52058
- let spacing = yield* whitespace2();
52280
+ if (!(yield* whitespace3()) || (yield* field2("version")) !== "1.0") return false;
52281
+ let spacing = yield* whitespace3();
52059
52282
  if (content.slice(offset, offset + 8).toLowerCase() === "encoding") {
52060
52283
  if (!spacing) return false;
52061
52284
  const encoding = yield* field2("encoding");
52062
52285
  if (encoding === void 0 || encoding.length > 8 || !["utf-8", "utf-16", "utf-16le", "utf-16be"].includes(encoding.toLowerCase())) return false;
52063
52286
  if (expectedEncoding !== void 0 && encoding.toLowerCase() !== expectedEncoding.toLowerCase()) return false;
52064
- spacing = yield* whitespace2();
52287
+ spacing = yield* whitespace3();
52065
52288
  }
52066
52289
  if (content.slice(offset, offset + 10).toLowerCase() === "standalone") {
52067
52290
  if (!spacing) return false;
52068
52291
  const standalone = yield* field2("standalone");
52069
52292
  if (standalone === void 0 || standalone.length > 3 || !["yes", "no"].includes(standalone.toLowerCase())) return false;
52070
- yield* whitespace2();
52293
+ yield* whitespace3();
52071
52294
  }
52072
52295
  return offset === content.length;
52073
52296
  }
@@ -52116,7 +52339,7 @@ function* parseXmlSteps(input3, limits = {}) {
52116
52339
  const admitContent = () => {
52117
52340
  if (++contentNodes > maxContentNodes) throw new XmlLimitError("maxContentNodes", "XML content node limit exceeded");
52118
52341
  };
52119
- const whitespace2 = function* () {
52342
+ const whitespace3 = function* () {
52120
52343
  let work = 0;
52121
52344
  while (offset < source2.length && " \n\r".includes(source2[offset])) {
52122
52345
  offset++;
@@ -52211,7 +52434,7 @@ function* parseXmlSteps(input3, limits = {}) {
52211
52434
  } else if (source2.startsWith("</", offset)) {
52212
52435
  offset += 2;
52213
52436
  const name2 = yield* readName();
52214
- yield* whitespace2();
52437
+ yield* whitespace3();
52215
52438
  if (source2[offset++] !== ">" || stack.pop()?.name !== name2) invalid("mismatched closing tag");
52216
52439
  } else {
52217
52440
  offset++;
@@ -52221,16 +52444,16 @@ function* parseXmlSteps(input3, limits = {}) {
52221
52444
  let ownsNamespaces = stack.length === 0;
52222
52445
  while (true) {
52223
52446
  const beforeSpace = offset;
52224
- yield* whitespace2();
52447
+ yield* whitespace3();
52225
52448
  if (source2[offset] === "/" || source2[offset] === ">") break;
52226
52449
  if (offset === beforeSpace) invalid("attributes require whitespace");
52227
52450
  const attribute = yield* readName();
52228
52451
  if (attributes.has(attribute)) invalid("duplicate attribute");
52229
52452
  if (++attributeCount > maxAttributes) throw new XmlLimitError("maxAttributes", "XML attribute limit exceeded");
52230
52453
  if (attributes.size >= maxAttributesPerElement) throw new XmlLimitError("maxAttributesPerElement", "XML attribute limit exceeded");
52231
- yield* whitespace2();
52454
+ yield* whitespace3();
52232
52455
  if (source2[offset++] !== "=") invalid("missing attribute equals");
52233
- yield* whitespace2();
52456
+ yield* whitespace3();
52234
52457
  const quote5 = source2[offset++];
52235
52458
  if (quote5 !== '"' && quote5 !== "'") invalid("unquoted attribute");
52236
52459
  const end = yield* find2(source2, quote5, offset);