@poe-platform/safe-bash 0.1.748 → 0.1.750

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,7 +67,8 @@ All private command plugins are available from `@poe-platform/safe-bash/core` in
67
67
  - `if`/`elif`/`else`, `case`, `for name in …`, `while`, `until`, functions,
68
68
  groups `{ …; }`, subshells `( … )` (including adjacent nested subshells),
69
69
  `[[ … ]]` (including file age/identity, special-file, mode and nameref
70
- predicates; literal/glob and ASCII ERE comparisons also accept UTF-8 locales,
70
+ predicates; ordering uses byte comparison in C/POSIX and host Intl collation
71
+ in supported UTF-8 locales. Literal/glob and ASCII ERE comparisons also accept UTF-8 locales,
71
72
  with ranges limited to C/POSIX collation, including C.UTF-8), arithmetic commands `(( … ))`, and indexed arrays with arithmetic
72
73
  and relative negative element indices, including `declare -a`, `local -a`,
73
74
  and `readonly -a` array literals. Arithmetic array operands such as `a[i]`
@@ -48712,6 +48712,9 @@ var lookupSpecialForms = {
48712
48712
  if (offsets[2] < 0 || offsets[2] >= areas.length) return error("#REF!");
48713
48713
  value3 = areas[offsets[2]];
48714
48714
  if (value3.kind === "error") return value3;
48715
+ } else if (value3.kind === "range" && value3.sheets.length > 1) {
48716
+ if (offsets[2] < 0 || offsets[2] >= value3.sheets.length) return error("#REF!");
48717
+ value3 = { ...value3, sheets: [value3.sheets[offsets[2]]] };
48715
48718
  } else if (offsets[2] !== 0) return error("#REF!");
48716
48719
  const row = offsets[0], column = offsets[1], dims = dimensions(value3);
48717
48720
  if (row < 0 || column < 0 || row >= dims.height || column >= dims.width) return error("#REF!");
@@ -52500,6 +52503,73 @@ init_platform();
52500
52503
 
52501
52504
  // packages/safe-bash-command-ssconvert/src/codecs/xlsx.ts
52502
52505
  init_platform();
52506
+
52507
+ // packages/safe-bash-command-ssconvert/src/formulas/index-sheet-areas.ts
52508
+ init_platform();
52509
+ function expandIndexSheetAreas(document6, onWork) {
52510
+ const order = document6.sheetOrder;
52511
+ if (!order) return document6;
52512
+ let ids, names2;
52513
+ const sheetIndex = (endpoint) => {
52514
+ if (!ids || !names2) {
52515
+ ids = /* @__PURE__ */ new Map();
52516
+ names2 = /* @__PURE__ */ new Map();
52517
+ for (let index2 = 0; index2 < order.length; index2++) {
52518
+ onWork();
52519
+ const id = order[index2];
52520
+ ids.set(id, index2);
52521
+ names2.set(foldSheetName(document6.sheetNames?.[id] ?? id), index2);
52522
+ }
52523
+ }
52524
+ const name5 = endpoint.sheet ?? document6.position.sheet;
52525
+ return ids.get(name5) ?? names2.get(foldSheetName(name5)) ?? -1;
52526
+ };
52527
+ const visit = (node3) => {
52528
+ onWork();
52529
+ if (node3.kind === "parentheses" || node3.kind === "unary") return { ...node3, child: visit(node3.child) };
52530
+ if (node3.kind === "binary") return { ...node3, left: visit(node3.left), right: visit(node3.right) };
52531
+ if (node3.kind === "array") return { ...node3, rows: node3.rows.map((row) => row.map(visit)) };
52532
+ if (node3.kind !== "call") return node3;
52533
+ const args = node3.args.map(visit);
52534
+ let source = args[0];
52535
+ while (source?.kind === "parentheses") source = source.child;
52536
+ if (node3.name === "INDEX" && args.length >= 1 && args.length <= 4 && source?.kind === "reference" && source.last && source.first.workbook === void 0 && source.last.workbook === void 0 && !source.label) {
52537
+ const first = sheetIndex(source.first), last2 = sheetIndex(source.last);
52538
+ if (first >= 0 && last2 >= 0 && first !== last2) {
52539
+ let areas = [];
52540
+ for (let index2 = Math.min(first, last2); index2 <= Math.max(first, last2); index2++) {
52541
+ onWork();
52542
+ const sheet = document6.sheetNames?.[order[index2]] ?? order[index2];
52543
+ const first2 = { ...source.first, sheet };
52544
+ const last3 = { ...source.last, sheet };
52545
+ delete first2.sheetOffset;
52546
+ delete last3.sheetOffset;
52547
+ areas.push({ ...source, first: first2, last: last3 });
52548
+ }
52549
+ while (areas.length > 1) {
52550
+ const next = [];
52551
+ for (let index2 = 0; index2 < areas.length; index2 += 2) {
52552
+ onWork();
52553
+ next.push(areas[index2 + 1] ? {
52554
+ kind: "binary",
52555
+ op: "union",
52556
+ start: source.start,
52557
+ end: source.end,
52558
+ left: areas[index2],
52559
+ right: areas[index2 + 1]
52560
+ } : areas[index2]);
52561
+ }
52562
+ areas = next;
52563
+ }
52564
+ args[0] = { kind: "parentheses", start: source.start, end: source.end, child: areas[0] };
52565
+ }
52566
+ }
52567
+ return { ...node3, args };
52568
+ };
52569
+ return { ...document6, root: visit(document6.root) };
52570
+ }
52571
+
52572
+ // packages/safe-bash-command-ssconvert/src/codecs/xlsx.ts
52503
52573
  import { parseXmlSteps as parseXmlSteps3, XmlLimitError } from "@poe-platform/safe-fs/core";
52504
52574
 
52505
52575
  // packages/safe-bash-command-ssconvert/src/codecs/xlsx-schema.ts
@@ -56406,7 +56476,7 @@ function createXlsxWriter(edition) {
56406
56476
  ...array ? { t: "array", ref: rangeText(array.range) } : {},
56407
56477
  ...formulaSemanticsAttributes(array?.arrayStringLiterals ?? cell.arrayStringLiterals, true, cell.formula)
56408
56478
  },
56409
- escapeXlsx(exportXlsxFormula(cell.formula, sheet, cell.row, cell.column, context2, array?.arrayStringLiterals ?? cell.arrayStringLiterals))
56479
+ escapeXlsx(exportXlsxFormula(book, cell.formula, sheet, cell.row, cell.column, context2, array?.arrayStringLiterals ?? cell.arrayStringLiterals))
56410
56480
  );
56411
56481
  if (value3.kind === "string") {
56412
56482
  if ((stringCounts.get(stringKey) ?? 0) > 1) {
@@ -56450,7 +56520,7 @@ function createXlsxWriter(edition) {
56450
56520
  };
56451
56521
  for (const [gnm, xlsx, invert] of [["DisplayFormulas", "showFormulas", false], ["HideZero", "showZeros", true], ["HideGrid", "showGridLines", true], ["HideColHeader", "showRowColHeaders", true], ["DisplayOutlines", "showOutlineSymbols", false], ["RTL_Layout", "rightToLeft", false]])
56452
56522
  if (view2[gnm] !== void 0) viewAttrs[xlsx] = (invert ? !Number(view2[gnm]) : !!Number(view2[gnm])) ? 1 : 0;
56453
- const metadata3 = await writeXlsxSheetMetadata(sheet, index2 + 1, xml2, context2, namespace5, exportXlsxFormula, styles, charge);
56523
+ const metadata3 = await writeXlsxSheetMetadata(sheet, index2 + 1, xml2, context2, namespace5, exportXlsxFormula.bind(null, book), styles, charge);
56454
56524
  let cols = "", nextColumn = 0;
56455
56525
  for (const c4 of [...sheet.columns ?? []].sort((a3, b3) => a3.index - b3.index)) {
56456
56526
  const importedColumn = metadataNode(c4.style?.gnumeric, charge);
@@ -56531,7 +56601,7 @@ function createXlsxWriter(edition) {
56531
56601
  localSheetId: index2 < 0 ? void 0 : index2,
56532
56602
  ...formulaSemanticsAttributes(name5.arrayStringLiterals, true, name5.expression, name5.position ? { ...name5.position, sheet: book.sheets.find((s) => s.id === name5.position.sheet)?.name ?? name5.position.sheet } : void 0)
56533
56603
  },
56534
- escapeXlsx(exportXlsxFormula(name5.expression, sheet, name5.position?.row ?? 0, name5.position?.column ?? 0, context2, name5.arrayStringLiterals))
56604
+ escapeXlsx(exportXlsxFormula(book, name5.expression, sheet, name5.position?.row ?? 0, name5.position?.column ?? 0, context2, name5.arrayStringLiterals))
56535
56605
  );
56536
56606
  }
56537
56607
  for (const [index2, sheet] of book.sheets.entries()) {
@@ -56608,17 +56678,24 @@ function createXlsxWriter(edition) {
56608
56678
  }
56609
56679
  };
56610
56680
  }
56611
- function exportXlsxFormula(source, sheet, row, column, context2, arrayStringLiterals = false) {
56681
+ function exportXlsxFormula(book, source, sheet, row, column, context2, arrayStringLiterals = false) {
56612
56682
  const position = { sheet: sheet.id, row, column };
56683
+ let work = 0;
56684
+ const onWork = () => {
56685
+ context2.signal.throwIfAborted();
56686
+ if (++work > (context2.limits.workbookNodes ?? Infinity))
56687
+ throw new SsconvertError("resource-limit", "ssconvert XLSX formula node limit exceeded");
56688
+ };
56613
56689
  const parsed = parseExpression(source.startsWith("=") || source.startsWith("of:=") ? source : "=" + source, {
56614
56690
  position,
56615
56691
  arrayStringLiterals,
56692
+ workbook: book,
56616
56693
  signal: context2.signal,
56617
56694
  maximumLength: context2.limits.workbookTextBytes ?? context2.limits.outputBytes,
56618
56695
  maximumNodes: context2.limits.workbookNodes ?? Infinity
56619
56696
  });
56620
56697
  if (!parsed.ok) throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: unparsed XLSX formula");
56621
- const result2 = serializeExpression(parsed.document, excelGrammar, false, true, { relativeSheets: "fixed" });
56698
+ const result2 = serializeExpression(expandIndexSheetAreas(parsed.document, onWork), excelGrammar, false, true, { relativeSheets: "fixed" });
56622
56699
  return result2.startsWith("=") ? result2.slice(1) : result2;
56623
56700
  }
56624
56701
 
@@ -62830,6 +62907,40 @@ var BiffOutput = class {
62830
62907
  this.length += bytes.length;
62831
62908
  return at;
62832
62909
  }
62910
+ /** Keep tokens/elements intact; oversized UTF-16 array strings carry width flags. */
62911
+ continuedRecord(opcode, payload, boundaries, strings = []) {
62912
+ const at = this.length;
62913
+ let offset = 0, next = 0, stringIndex = 0;
62914
+ do {
62915
+ while (strings[stringIndex] && strings[stringIndex].end <= offset) stringIndex++;
62916
+ const continuedString = strings[stringIndex] && strings[stringIndex].start < offset;
62917
+ const prefix2 = continuedString ? 1 : 0;
62918
+ const maximum = Math.min(payload.length, offset + this.maximumRecord - prefix2);
62919
+ let end2 = maximum;
62920
+ if (boundaries && maximum < payload.length) {
62921
+ end2 = offset;
62922
+ while (next < boundaries.length && boundaries[next] <= maximum) end2 = boundaries[next++];
62923
+ let candidate = stringIndex;
62924
+ while (strings[candidate] && strings[candidate].end <= maximum) candidate++;
62925
+ const string = strings[candidate];
62926
+ if (string && string.end - string.start + 4 > this.maximumRecord && string.start < maximum && maximum < string.end) {
62927
+ const characterEnd = maximum - (maximum - string.start) % 2;
62928
+ if (characterEnd > string.start) end2 = Math.max(end2, characterEnd);
62929
+ }
62930
+ if (end2 <= offset) throw new SsconvertError("unsupported-feature", "Excel BIFF formula token is too large");
62931
+ }
62932
+ let part = payload.subarray(offset, end2);
62933
+ if (prefix2) {
62934
+ const continued = new Uint8Array(part.length + 1);
62935
+ continued[0] = 1;
62936
+ continued.set(part, 1);
62937
+ part = continued;
62938
+ }
62939
+ this.record(offset === 0 ? opcode : 60, part);
62940
+ offset = end2;
62941
+ } while (offset < payload.length);
62942
+ return at;
62943
+ }
62833
62944
  finish() {
62834
62945
  this.context.signal.throwIfAborted();
62835
62946
  const bytes = new Uint8Array(this.length);
@@ -74924,8 +75035,8 @@ var operators = {
74924
75035
  ">=": 12,
74925
75036
  ">": 13,
74926
75037
  "<>": 14,
74927
- " ": 15,
74928
- ",": 16,
75038
+ intersection: 15,
75039
+ union: 16,
74929
75040
  ":": 17
74930
75041
  };
74931
75042
  var functions = new Map(Object.entries(biffFunctions).map(([id, spec]) => [spec[0], { id: Number(id), min: spec[1], max: spec[2] }]));
@@ -74958,7 +75069,6 @@ var BiffFormulaWriter = class {
74958
75069
  macroNames = [];
74959
75070
  workbookIndices = /* @__PURE__ */ new Map();
74960
75071
  linkIndices = /* @__PURE__ */ new Map();
74961
- uniqueNameId = 0;
74962
75072
  relocations = [];
74963
75073
  externalBook(workbook) {
74964
75074
  let index2 = this.workbookIndices.get(workbook);
@@ -75069,11 +75179,21 @@ var BiffFormulaWriter = class {
75069
75179
  maximumLength: this.context.limits.workbookTextBytes ?? this.context.limits.outputBytes
75070
75180
  });
75071
75181
  if (!parsed.ok) throw new SsconvertError("unsupported-feature", `Cannot export Excel formula: ${expression2}`);
75072
- return parsed.document.root;
75182
+ let work = 0;
75183
+ return expandIndexSheetAreas(parsed.document, () => {
75184
+ this.context.signal.throwIfAborted();
75185
+ if (++work > (this.context.limits.workbookNodes ?? this.context.limits.cells))
75186
+ throw new SsconvertError("resource-limit", "ssconvert BIFF formula node limit exceeded");
75187
+ }).root;
75073
75188
  };
75074
75189
  const relative = definition !== void 0;
75075
75190
  const root = definition ? parseNamedExpression(definition, this.book, parse3, () => this.context.signal.throwIfAborted()) : parse3(source, { sheet, row, column });
75076
75191
  const bytes = [], arrays = [], diagnostics = [];
75192
+ const tokenBoundaries = [], arrayBoundaries = [];
75193
+ const arrayStrings = [];
75194
+ const boundary = () => {
75195
+ if (bytes.length && tokenBoundaries.at(-1) !== bytes.length) tokenBoundaries.push(bytes.length);
75196
+ };
75077
75197
  let sheetLossReported = false;
75078
75198
  const relocations = [];
75079
75199
  const push = (part, target = bytes) => {
@@ -75116,12 +75236,14 @@ var BiffFormulaWriter = class {
75116
75236
  push([23]);
75117
75237
  push(biffString(text2, this.revision, this.context, 1));
75118
75238
  if (index2) push([8]);
75239
+ boundary();
75119
75240
  });
75120
75241
  if (chunks.length > 1) push([21]);
75121
75242
  }
75122
75243
  };
75123
75244
  const visit = (node3) => {
75124
75245
  this.context.signal.throwIfAborted();
75246
+ boundary();
75125
75247
  if (node3.kind === "literal") literal2(node3.value);
75126
75248
  else if (node3.kind === "omitted") push([22]);
75127
75249
  else if (node3.kind === "parentheses") {
@@ -75274,24 +75396,15 @@ var BiffFormulaWriter = class {
75274
75396
  push([28, 29]);
75275
75397
  return;
75276
75398
  }
75277
- if (node3.sheet !== void 0 && scope !== void 0) {
75278
- const data4 = new Uint8Array(this.revision === 8 ? 7 : 25), view2 = new DataView(data4.buffer);
75399
+ if (node3.sheet !== void 0 && scope !== void 0 && this.revision === 8) {
75400
+ const data4 = new Uint8Array(7), view2 = new DataView(data4.buffer);
75279
75401
  data4[0] = 89;
75280
75402
  const scopeIndex = this.book.sheets.indexOf(scope);
75281
- if (this.revision === 8) {
75282
- const externalIndex = this.sheetLink(void 0, scopeIndex, scopeIndex);
75283
- relocations.push({ offset: bytes.length + 1, index: externalIndex, kind: "sheet" });
75284
- view2.setUint16(1, externalIndex, true);
75285
- view2.setUint16(3, index2 + 1, true);
75286
- } else {
75287
- const externalIndex = current === scope ? this.book.sheets.length + 1 : scopeIndex;
75288
- view2.setInt16(1, -(externalIndex + 1), true);
75289
- view2.setUint16(9, 1, true);
75290
- view2.setUint16(11, index2 + 1, true);
75291
- view2.setUint16(19, 15, true);
75292
- view2.setUint32(21, ++this.uniqueNameId, true);
75293
- }
75294
- relocations.push({ offset: bytes.length + (this.revision === 8 ? 3 : 11), index: index2, kind: "name" });
75403
+ const externalIndex = this.sheetLink(void 0, scopeIndex, scopeIndex);
75404
+ relocations.push({ offset: bytes.length + 1, index: externalIndex, kind: "sheet" });
75405
+ view2.setUint16(1, externalIndex, true);
75406
+ view2.setUint16(3, index2 + 1, true);
75407
+ relocations.push({ offset: bytes.length + 3, index: index2, kind: "name" });
75295
75408
  push(data4);
75296
75409
  } else {
75297
75410
  const data4 = new Uint8Array(this.revision === 8 ? 5 : 15);
@@ -75349,12 +75462,15 @@ var BiffFormulaWriter = class {
75349
75462
  if (!columns || columns > 256 || node3.rows.length > 65536) throw new SsconvertError("unsupported-feature", "Excel BIFF array dimensions exceed limits");
75350
75463
  push([64, ...new Uint8Array(7)]);
75351
75464
  push([this.revision === 8 ? columns - 1 : columns & 255, ...words(node3.rows.length - (this.revision === 8 ? 1 : 0))], arrays);
75465
+ arrayBoundaries.push(arrays.length);
75352
75466
  for (const arrayRow of node3.rows) for (const item of arrayRow) {
75353
75467
  if (item.kind !== "literal") throw new SsconvertError("unsupported-feature", "Excel BIFF array requires literals");
75354
75468
  const value3 = item.value;
75355
75469
  if (value3.kind === "string") {
75470
+ const start = arrays.length + 4;
75356
75471
  push([2], arrays);
75357
75472
  push(biffString(value3.value, this.revision, this.context, this.revision === 8 ? 2 : 1), arrays);
75473
+ if (this.revision === 8 && arrays.length > start) arrayStrings.push({ start, end: arrays.length });
75358
75474
  } else {
75359
75475
  const data4 = new Uint8Array(9), view2 = new DataView(data4.buffer);
75360
75476
  data4[0] = value3.kind === "number" ? 1 : value3.kind === "boolean" ? 4 : value3.kind === "error" ? 16 : 0;
@@ -75363,15 +75479,23 @@ var BiffFormulaWriter = class {
75363
75479
  else if (value3.kind === "error") data4[1] = biffError(value3.value);
75364
75480
  push(data4, arrays);
75365
75481
  }
75482
+ arrayBoundaries.push(arrays.length);
75366
75483
  }
75367
75484
  }
75485
+ boundary();
75368
75486
  };
75369
75487
  visit(root);
75488
+ boundary();
75489
+ if (bytes.length > 65535)
75490
+ throw new SsconvertError("unsupported-feature", "Excel BIFF formula token length exceeds version limits");
75370
75491
  const tokens3 = new Uint8Array(bytes);
75371
75492
  for (const relocation of relocations) this.relocations.push({ ...relocation, tokens: tokens3 });
75372
75493
  return {
75373
75494
  tokens: tokens3,
75495
+ tokenBoundaries,
75374
75496
  arrays: new Uint8Array(arrays),
75497
+ arrayBoundaries,
75498
+ arrayStrings,
75375
75499
  diagnostics,
75376
75500
  nameDependencies: relocations.filter((relocation) => relocation.kind === "name").map((relocation) => relocation.index)
75377
75501
  };
@@ -75964,7 +76088,10 @@ async function writeBiffStream(book, revision2, dual, context2, filepass) {
75964
76088
  if (group) {
75965
76089
  formulas.set(cell, {
75966
76090
  tokens: new Uint8Array([dataTables.has(group) ? 2 : 1, ...words(group.range.startRow, group.range.startColumn)]),
76091
+ tokenBoundaries: [5],
75967
76092
  arrays: new Uint8Array(),
76093
+ arrayBoundaries: [],
76094
+ arrayStrings: [],
75968
76095
  diagnostics: [],
75969
76096
  nameDependencies: []
75970
76097
  });
@@ -76054,8 +76181,22 @@ async function writeBiffStream(book, revision2, dual, context2, filepass) {
76054
76181
  header4[3] = text2[0];
76055
76182
  view3.setUint16(4, formula3.tokens.length, true);
76056
76183
  const scope = name5.sheet === void 0 ? 0 : book.sheets.findIndex((sheet) => sheet.id === name5.sheet) + 1;
76057
- view3.setUint16(revision2 === 8 ? 8 : 6, scope, true);
76058
- output2.record(24, join(join(header4, text2.subarray(1)), join(formula3.tokens, formula3.arrays)));
76184
+ if (revision2 === 7 && scope) view3.setUint16(6, scope - 1, true);
76185
+ view3.setUint16(8, scope, true);
76186
+ const start = header4.length + text2.length - 1;
76187
+ output2.continuedRecord(
76188
+ 24,
76189
+ join(join(header4, text2.subarray(1)), join(formula3.tokens, formula3.arrays)),
76190
+ [
76191
+ start,
76192
+ ...formula3.tokenBoundaries.map((offset) => offset + start),
76193
+ ...formula3.arrayBoundaries.map((offset) => offset + start + formula3.tokens.length)
76194
+ ],
76195
+ formula3.arrayStrings.map((span2) => ({
76196
+ start: start + formula3.tokens.length + span2.start,
76197
+ end: start + formula3.tokens.length + span2.end
76198
+ }))
76199
+ );
76059
76200
  }
76060
76201
  if (revision2 === 8) {
76061
76202
  metadata3.global(output2);
@@ -76109,7 +76250,19 @@ async function writeBiffStream(book, revision2, dual, context2, filepass) {
76109
76250
  view3.setUint16(12, formula3.tokens.length, true);
76110
76251
  data4.set(formula3.tokens, 14);
76111
76252
  data4.set(formula3.arrays, 14 + formula3.tokens.length);
76112
- output2.record(545, data4);
76253
+ output2.continuedRecord(
76254
+ 545,
76255
+ data4,
76256
+ [
76257
+ 14,
76258
+ ...formula3.tokenBoundaries.map((offset) => offset + 14),
76259
+ ...formula3.arrayBoundaries.map((offset) => offset + 14 + formula3.tokens.length)
76260
+ ],
76261
+ formula3.arrayStrings.map((span2) => ({
76262
+ start: 14 + formula3.tokens.length + span2.start,
76263
+ end: 14 + formula3.tokens.length + span2.end
76264
+ }))
76265
+ );
76113
76266
  }
76114
76267
  }
76115
76268
  const cached = cell.cachedResult ?? cell.value;
@@ -76191,7 +76344,19 @@ async function writeCell(output2, cell, xf, revision2, strings, context2, formul
76191
76344
  view2.setUint16(20, formula3.tokens.length, true);
76192
76345
  data4.set(formula3.tokens, 22);
76193
76346
  data4.set(formula3.arrays, 22 + formula3.tokens.length);
76194
- output2.record(6, data4);
76347
+ output2.continuedRecord(
76348
+ 6,
76349
+ data4,
76350
+ [
76351
+ 22,
76352
+ ...formula3.tokenBoundaries.map((offset) => offset + 22),
76353
+ ...formula3.arrayBoundaries.map((offset) => offset + 22 + formula3.tokens.length)
76354
+ ],
76355
+ formula3.arrayStrings.map((span2) => ({
76356
+ start: 22 + formula3.tokens.length + span2.start,
76357
+ end: 22 + formula3.tokens.length + span2.end
76358
+ }))
76359
+ );
76195
76360
  return;
76196
76361
  }
76197
76362
  if (value3.kind === "number") {
@@ -77122,6 +77287,33 @@ async function readBiff(borrowed, context2, encoding) {
77122
77287
  while (records[index2 + 1]?.opcode === 60) parts.push(records[++index2].data);
77123
77288
  return { parts, next: index2 };
77124
77289
  };
77290
+ const formulaParts = (index2, offset, length) => {
77291
+ const first = records[index2].data;
77292
+ let tokens3;
77293
+ if (offset + length <= first.bytes.length) {
77294
+ tokens3 = first.slice(offset, length);
77295
+ offset += length;
77296
+ } else {
77297
+ accountFormulaWork(length);
77298
+ tokens3 = new Uint8Array(length);
77299
+ let written = 0;
77300
+ while (written < length) {
77301
+ context2.signal.throwIfAborted();
77302
+ const part = records[index2].data;
77303
+ const count = Math.min(length - written, part.bytes.length - offset);
77304
+ tokens3.set(part.slice(offset, count), written);
77305
+ written += count;
77306
+ offset += count;
77307
+ if (written < length) {
77308
+ if (records[index2 + 1]?.opcode !== 60) invalidBiff("truncated formula tokens/CONTINUE");
77309
+ index2++;
77310
+ offset = 0;
77311
+ }
77312
+ }
77313
+ }
77314
+ const extra = stringParts(index2, offset);
77315
+ return { tokens: tokens3, arrays: extra.parts, next: extra.next };
77316
+ };
77125
77317
  for (let index2 = 0; index2 < records.length; index2++) {
77126
77318
  context2.signal.throwIfAborted();
77127
77319
  const record7 = records[index2], data4 = record7.data, opcode = record7.opcode;
@@ -77320,13 +77512,12 @@ async function readBiff(borrowed, context2, encoding) {
77320
77512
  const name5 = accountText(ver >= 8 ? cursor.unicode(length).text : cursor.legacy(length));
77321
77513
  const end2 = 7 + cursor.consumedBytes;
77322
77514
  const tokenLength = end2 + 2 <= data4.bytes.length ? data4.u16(end2) : 0;
77323
- const tokens3 = tokenLength ? data4.slice(end2 + 2, tokenLength) : new Uint8Array();
77515
+ const formula4 = tokenLength ? formulaParts(index2, end2 + 2, tokenLength) : { tokens: new Uint8Array(), arrays: [], next: index2 };
77324
77516
  const legacyLink = (sheet?.legacyExternalLinks ?? legacyExternalLinks).get((sheet?.legacyExternalSheets ?? legacyExternalSheets).length - 1);
77325
77517
  const table10 = ver >= 8 ? supbooks.at(-1)?.names : legacyLink?.names;
77326
77518
  if (!table10) invalidBiff("EXTERNNAME without workbook link");
77327
- const arrays = tokenLength ? stringParts(index2, end2 + 2 + tokenLength) : { parts: [], next: index2 };
77328
- index2 = arrays.next;
77329
- table10.push({ name: name5, sheetIndex: data4.u16(2), tokens: tokens3, arrays: arrays.parts, revision: ver, codepage, supported: flags2 === 0, record: record7 });
77519
+ index2 = formula4.next;
77520
+ table10.push({ name: name5, sheetIndex: data4.u16(2), tokens: formula4.tokens, arrays: formula4.arrays, revision: ver, codepage, supported: flags2 === 0, record: record7 });
77330
77521
  const addin = ver >= 8 ? supbooks.at(-1)?.kind === "addin" : legacyLink?.addin;
77331
77522
  const externalIdentity = (ver >= 8 ? supbooks.at(-1)?.workbook : legacyLink?.workbook) !== void 0 && flags2 === 0;
77332
77523
  if (!addin || flags2 !== 0) await retain(record7, sheet?.unsupportedRecords ?? unsupported10, !externalIdentity);
@@ -77356,7 +77547,9 @@ async function readBiff(borrowed, context2, encoding) {
77356
77547
  }
77357
77548
  if (opcode === 24 || opcode === 536) {
77358
77549
  const flags2 = data4.u16(0), length = data4.u8(3), tokenLength = ver === 2 ? data4.u8(4) : data4.u16(4);
77359
- const start = ver >= 7 ? 14 : ver >= 3 ? 6 : 5, sheetIndex = ver >= 8 ? data4.u16(8) : ver >= 7 ? data4.u16(6) : 0;
77550
+ const start = ver >= 7 ? 14 : ver >= 3 ? 6 : 5;
77551
+ const scopeIsWorksheet = ver >= 8 || ver >= 7 && data4.u16(8) !== 0;
77552
+ const sheetIndex = scopeIsWorksheet ? data4.u16(8) : ver >= 7 ? data4.u16(6) : 0;
77360
77553
  const cursor = new BiffStrings([new Binary(data4.slice(start, data4.bytes.length - start))], context2, codepage);
77361
77554
  let name5;
77362
77555
  if (flags2 & 32 && length) {
@@ -77380,10 +77573,20 @@ async function readBiff(borrowed, context2, encoding) {
77380
77573
  ][builtin];
77381
77574
  name5 = (base ?? `_BIFF_BUILTIN_${builtin}`) + text2.slice(1);
77382
77575
  } else name5 = ver >= 8 ? cursor.unicode(length).text : cursor.legacy(length);
77383
- const tokens3 = data4.slice(start + cursor.consumedBytes, tokenLength);
77384
- const arrays = stringParts(index2, start + cursor.consumedBytes + tokenLength);
77385
- index2 = arrays.next;
77386
- names2.push({ name: accountText(name5), flags: flags2, tokens: tokens3, arrays: arrays.parts, sheetIndex, revision: ver, codepage, record: record7, ...sheet ? { owner: sheet } : {} });
77576
+ const formula4 = formulaParts(index2, start + cursor.consumedBytes, tokenLength);
77577
+ index2 = formula4.next;
77578
+ names2.push({
77579
+ name: accountText(name5),
77580
+ flags: flags2,
77581
+ tokens: formula4.tokens,
77582
+ arrays: formula4.arrays,
77583
+ sheetIndex,
77584
+ scopeIsWorksheet,
77585
+ revision: ver,
77586
+ codepage,
77587
+ record: record7,
77588
+ ...sheet ? { owner: sheet } : {}
77589
+ });
77387
77590
  continue;
77388
77591
  }
77389
77592
  if (ignoredOpcodes.has(opcode)) continue;
@@ -77457,13 +77660,15 @@ async function readBiff(borrowed, context2, encoding) {
77457
77660
  if (kind > 3) invalidBiff("invalid formula cache tag");
77458
77661
  }
77459
77662
  lastFormula = addCell(sheet, data4, value3, { cachedResult: value3, formulaDirty: !!(data4.u16(14) & 3) });
77460
- lastFormula.tokens = data4.slice(tokenStart, tokenLength);
77461
- const arrays = stringParts(index2, tokenStart + tokenLength);
77462
- index2 = arrays.next;
77463
- lastFormula.arrays = arrays.parts;
77663
+ const formula4 = formulaParts(index2, tokenStart, tokenLength);
77664
+ index2 = formula4.next;
77665
+ lastFormula.tokens = formula4.tokens;
77666
+ lastFormula.arrays = formula4.arrays;
77464
77667
  const nextOpcode = records[index2 + 1]?.opcode;
77465
77668
  const groupFollows = nextOpcode === 1212 || nextOpcode === 33 || nextOpcode === 545 || nextOpcode === 54 || nextOpcode === 55 || nextOpcode === 566;
77466
- const stringOpcode = records[index2 + (groupFollows ? 2 : 1)]?.opcode;
77669
+ let stringIndex = index2 + (groupFollows ? 2 : 1);
77670
+ if (groupFollows) while (records[stringIndex]?.opcode === 60) stringIndex++;
77671
+ const stringOpcode = records[stringIndex]?.opcode;
77467
77672
  if (stringCache2 && stringOpcode !== 7 && stringOpcode !== 519) {
77468
77673
  const error3 = { kind: "error", value: "MISSING STRING" };
77469
77674
  lastFormula.cell = { ...lastFormula.cell, value: error3, cachedResult: error3 };
@@ -77503,10 +77708,17 @@ async function readBiff(borrowed, context2, encoding) {
77503
77708
  }
77504
77709
  const kind = opcode === 1212 ? "shared" : "array";
77505
77710
  const start = kind === "shared" ? 10 : ver === 2 ? 8 : ver <= 4 ? 10 : 14;
77506
- const tokens3 = data4.slice(start, ver === 2 && kind === "array" ? data4.u8(start - 1) : data4.u16(start - 2));
77507
- const arrays = stringParts(index2, start + tokens3.length);
77508
- index2 = arrays.next;
77509
- sheet.groups.push({ id: `biff-${sheet.offset}-${record7.offset}`, kind, range: range5, tokens: tokens3, arrays: arrays.parts, keyRow: lastFormula.cell.row, keyColumn: lastFormula.cell.column });
77711
+ const formula4 = formulaParts(index2, start, ver === 2 && kind === "array" ? data4.u8(start - 1) : data4.u16(start - 2));
77712
+ index2 = formula4.next;
77713
+ sheet.groups.push({
77714
+ id: `biff-${sheet.offset}-${record7.offset}`,
77715
+ kind,
77716
+ range: range5,
77717
+ tokens: formula4.tokens,
77718
+ arrays: formula4.arrays,
77719
+ keyRow: lastFormula.cell.row,
77720
+ keyColumn: lastFormula.cell.column
77721
+ });
77510
77722
  continue;
77511
77723
  }
77512
77724
  if (opcode === 7 || opcode === 519) {
@@ -77614,7 +77826,7 @@ async function readBiff(borrowed, context2, encoding) {
77614
77826
  const localSheets = sheets.map((sheet) => sheet.name);
77615
77827
  const nameSheets = names2.map((name5) => {
77616
77828
  if (!name5.sheetIndex) return void 0;
77617
- return (name5.revision >= 8 ? sheets[name5.sheetIndex - 1]?.name : (name5.owner?.legacyExternalSheets ?? legacyExternalSheets)[name5.sheetIndex - 1]) ?? void 0;
77829
+ return (name5.scopeIsWorksheet ? sheets[name5.sheetIndex - 1]?.name : (name5.owner?.legacyExternalSheets ?? legacyExternalSheets)[name5.sheetIndex - 1]) ?? void 0;
77618
77830
  });
77619
77831
  const externalNameTables = /* @__PURE__ */ new Map();
77620
77832
  const formulaNames = names2.map((name5) => name5.name);
@@ -164396,4 +164608,4 @@ tslib/tslib.js:
164396
164608
  @noble/ciphers/utils.js:
164397
164609
  (*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) *)
164398
164610
  */
164399
- //# sourceMappingURL=chunk-MSEZFB2F.js.map
164611
+ //# sourceMappingURL=chunk-U7DRVFRD.js.map
@@ -81,7 +81,7 @@ import {
81
81
  updateWorkbook,
82
82
  validSheetSize,
83
83
  visitFormula
84
- } from "./chunk-MSEZFB2F.js";
84
+ } from "./chunk-U7DRVFRD.js";
85
85
  import "./chunk-CVAVQZSF.js";
86
86
  import "./chunk-RCM5PZBN.js";
87
87
  import "./chunk-LSRHLNCR.js";
@@ -171,4 +171,4 @@ export {
171
171
  validSheetSize,
172
172
  visitFormula
173
173
  };
174
- //# sourceMappingURL=src-2MBSXQOA.js.map
174
+ //# sourceMappingURL=src-YKSQQDD3.js.map
@@ -84,7 +84,7 @@ export function basicCommands() {
84
84
  return { exitCode: 0 };
85
85
  }),
86
86
  define("basename", async (context) => {
87
- const parsed = options(context.args, "as:z", { multiple: "a", suffix: "s", zero: "z" });
87
+ const parsed = options(context.args, "as:z", { multiple: "a", suffix: "s", zero: "z" }, true);
88
88
  const multiple = parsed.flags.has("a") || parsed.flags.has("s");
89
89
  requireOperands(parsed.operands, 1, multiple ? Infinity : 2);
90
90
  const suffix = value(parsed, "s") ?? (multiple ? undefined : parsed.operands[1]);
@@ -97,7 +97,7 @@ export function basicCommands() {
97
97
  return { exitCode: 0 };
98
98
  }, 1, 1),
99
99
  define("dirname", async (context) => {
100
- const parsed = options(context.args, "z", { zero: "z" });
100
+ const parsed = options(context.args, "z", { zero: "z" }, true);
101
101
  requireOperands(parsed.operands);
102
102
  for (const operand of parsed.operands) {
103
103
  const parent = dirname(operand);