@poe-platform/safe-bash 0.1.736 → 0.1.738

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/safe-bash/chunks/{chunk-ZFV5FGGH.js → chunk-E2FTAYLG.js} +15 -16
  2. package/dist/safe-bash/chunks/{chunk-ZFV5FGGH.js.map → chunk-E2FTAYLG.js.map} +2 -2
  3. package/dist/safe-bash/chunks/{chunk-DFNSXDHP.js → chunk-JNHKE26E.js} +2 -2
  4. package/dist/safe-bash/chunks/{chunk-N3RTTKMA.js → chunk-JTKTBT3B.js} +2 -2
  5. package/dist/safe-bash/command-assets/git_rust-NOIGQE52.wasm +0 -0
  6. package/dist/safe-bash/command-chunks/{chunk-L6GGCZOK.js → chunk-5EOMWWKN.js} +16 -15
  7. package/dist/safe-bash/command-chunks/chunk-5EOMWWKN.js.map +7 -0
  8. package/dist/safe-bash/command-chunks/{chunk-YXAPLUY4.js → chunk-WFMUMKBQ.js} +2 -2
  9. package/dist/safe-bash/core.browser.js +928 -218
  10. package/dist/safe-bash/core.browser.js.map +3 -3
  11. package/dist/safe-bash/shell/arithmetic.d.ts.map +1 -1
  12. package/dist/safe-bash/shell/arithmetic.js +10 -1
  13. package/dist/safe-bash/shell/arithmetic.js.map +1 -1
  14. package/dist/safe-bash/shell/getopts.d.ts +1 -0
  15. package/dist/safe-bash/shell/getopts.d.ts.map +1 -1
  16. package/dist/safe-bash/shell/getopts.js +71 -0
  17. package/dist/safe-bash/shell/getopts.js.map +1 -1
  18. package/dist/safe-bash/shell/runtime.d.ts +5 -0
  19. package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
  20. package/dist/safe-bash/shell/runtime.js +1043 -247
  21. package/dist/safe-bash/shell/runtime.js.map +1 -1
  22. package/dist/safe-bash-command-git/index.js +1 -1
  23. package/dist/safe-bash-regex-engine/index.js +2 -2
  24. package/dist/safe-bash-regex-engine/text/regex.js +2 -2
  25. package/dist/safe-bash-regex-engine/text/replacement-buffer.js +1 -1
  26. package/package.json +2 -2
  27. package/dist/safe-bash/command-assets/git_rust-VC5UCZXR.wasm +0 -0
  28. package/dist/safe-bash/command-chunks/chunk-L6GGCZOK.js.map +0 -7
  29. /package/dist/safe-bash/chunks/{chunk-DFNSXDHP.js.map → chunk-JNHKE26E.js.map} +0 -0
  30. /package/dist/safe-bash/chunks/{chunk-N3RTTKMA.js.map → chunk-JTKTBT3B.js.map} +0 -0
  31. /package/dist/safe-bash/command-chunks/{chunk-YXAPLUY4.js.map → chunk-WFMUMKBQ.js.map} +0 -0
@@ -55003,13 +55003,16 @@ function fastSafeInt(text3, budget) {
55003
55003
  function canEvalSafeSmiTree(node, depth = 0) {
55004
55004
  if (depth > 32) return false;
55005
55005
  if (node.kind === "literal") return node.value >= -94906265n && node.value <= 94906265n;
55006
- if (node.kind === "name") return node.subscript === void 0 || /^[0-9]{1,7}$/.test(node.subscript) || /^\$?[a-zA-Z_][a-zA-Z_0-9]*$/.test(node.subscript);
55006
+ if (node.kind === "name") return node.subscript === void 0 || /^[0-9]{1,7}$/.test(node.subscript) || /^\$?[a-zA-Z_][a-zA-Z_0-9]*$/.test(node.subscript) || /^\s*[a-zA-Z_][a-zA-Z_0-9]*\s*(?:[-+*]\s*(?:0|[1-9][0-9]{0,6})|[/%]\s*[1-9][0-9]{0,6})\s*$/.test(node.subscript);
55007
55007
  if (node.kind === "unary") {
55008
55008
  if (node.operator === "+" || node.operator === "-" || node.operator === "!") return canEvalSafeSmiTree(node.operand, depth + 1);
55009
55009
  if (node.operator === "++" || node.operator === "--") return node.operand.kind === "name" && canEvalSafeSmiTree(node.operand, depth + 1) && depth === 0;
55010
55010
  return false;
55011
55011
  }
55012
55012
  if (node.kind === "binary") {
55013
+ if (node.operator === "," && depth === 0) {
55014
+ return canEvalSafeSmiTree(node.left, 0) && canEvalSafeSmiTree(node.right, 0);
55015
+ }
55013
55016
  if ((node.operator === "=" || node.operator === "+=" || node.operator === "-=" || node.operator === "*=") && depth === 0) {
55014
55017
  return node.left.kind === "name" && canEvalSafeSmiTree(node.left, depth + 1) && canEvalSafeSmiTree(node.right, depth + 1);
55015
55018
  }
@@ -55048,6 +55051,11 @@ function evalSafeSmi(node, refs, budget) {
55048
55051
  return void 0;
55049
55052
  }
55050
55053
  if (node.kind === "binary") {
55054
+ if (node.operator === ",") {
55055
+ const l2 = evalSafeSmi(node.left, refs, budget);
55056
+ if (l2 === void 0) return void 0;
55057
+ return evalSafeSmi(node.right, refs, budget);
55058
+ }
55051
55059
  if (node.operator === "=") {
55052
55060
  const r2 = evalSafeSmi(node.right, refs, budget);
55053
55061
  if (r2 === void 0 || r2 < -94906265 || r2 > 94906265) return void 0;
@@ -64256,6 +64264,68 @@ async function scanGetopts(state, optstring, input3, options2) {
64256
64264
  }
64257
64265
  return finish("option", option, { kind: "unset" }, null);
64258
64266
  }
64267
+ var syncSpecScratch = new Int8Array(128);
64268
+ function scanGetoptsSync(state, optstring, args) {
64269
+ if (!record2(state) || typeof state.index !== "number" || !Number.isSafeInteger(state.index) || state.index < 0 || args.length > 1024 || optstring.length > 256) return void 0;
64270
+ for (let i = 0; i < optstring.length; i++) {
64271
+ const c = optstring.charCodeAt(i);
64272
+ if (c === 0 || c > 127) return void 0;
64273
+ }
64274
+ for (let i = 0; i < args.length; i++) {
64275
+ const a = args[i];
64276
+ if (a.length > 4096 || a.includes("\0")) return void 0;
64277
+ }
64278
+ const silent = optstring.charCodeAt(0) === 58;
64279
+ syncSpecScratch.fill(-1);
64280
+ for (let position = silent ? 1 : 0; position < optstring.length; position++) {
64281
+ const code2 = optstring.charCodeAt(position);
64282
+ if (code2 !== 58 && code2 !== 63 && syncSpecScratch[code2] === -1) syncSpecScratch[code2] = Number(optstring.charCodeAt(position + 1) === 58);
64283
+ }
64284
+ let index = state.index || 1;
64285
+ let active = state.index === 0 ? void 0 : state.active;
64286
+ if (index > args.length) {
64287
+ index = args.length + 1;
64288
+ return { state: { index }, kind: "end", status: 1, option: "?", optind: index, argument: { kind: "unset" }, diagnostic: null };
64289
+ }
64290
+ if (active && (args[active.argument] === void 0 || active.offset >= args[active.argument].length)) active = void 0;
64291
+ if (!active) {
64292
+ const token2 = args[index - 1];
64293
+ if (token2.length < 2 || token2.charCodeAt(0) !== 45) {
64294
+ return { state: { index }, kind: "end", status: 1, option: "?", optind: index, argument: { kind: "unset" }, diagnostic: null };
64295
+ }
64296
+ if (token2 === "--") {
64297
+ index++;
64298
+ return { state: { index }, kind: "end", status: 1, option: "?", optind: index, argument: { kind: "unset" }, diagnostic: null };
64299
+ }
64300
+ active = { argument: index - 1, offset: 1 };
64301
+ }
64302
+ const token = args[active.argument];
64303
+ const option = token[active.offset];
64304
+ const code = option.charCodeAt(0);
64305
+ if (code > 127) return void 0;
64306
+ const offset = active.offset + 1;
64307
+ const attached = offset < token.length;
64308
+ active = attached ? { argument: active.argument, offset } : void 0;
64309
+ if (!attached) index++;
64310
+ if (syncSpecScratch[code] === -1) {
64311
+ if (!silent) return void 0;
64312
+ return { state: active === void 0 ? { index } : { index, active }, kind: "unknown-option", status: 0, option: "?", optind: index, argument: { kind: "set", value: option }, diagnostic: null };
64313
+ }
64314
+ if (syncSpecScratch[code] === 1) {
64315
+ if (attached) {
64316
+ index++;
64317
+ return { state: { index }, kind: "option", status: 0, option, optind: index, argument: { kind: "set", value: token.slice(offset) }, diagnostic: null };
64318
+ }
64319
+ if (index <= args.length) {
64320
+ const value2 = args[index - 1];
64321
+ index++;
64322
+ return { state: active === void 0 ? { index } : { index, active }, kind: "option", status: 0, option, optind: index, argument: { kind: "set", value: value2 }, diagnostic: null };
64323
+ }
64324
+ if (!silent) return void 0;
64325
+ return { state: active === void 0 ? { index } : { index, active }, kind: "missing-argument", status: 0, option: ":", optind: index, argument: { kind: "set", value: option }, diagnostic: null };
64326
+ }
64327
+ return { state: active === void 0 ? { index } : { index, active }, kind: "option", status: 0, option, optind: index, argument: { kind: "unset" }, diagnostic: null };
64328
+ }
64259
64329
 
64260
64330
  // packages/safe-bash/src/shell/cancellation.ts
64261
64331
  init_platform();
@@ -69874,6 +69944,26 @@ function hasActiveVariableAttributes(state) {
69874
69944
  }
69875
69945
  return false;
69876
69946
  }
69947
+ function hasNonNamerefAttributes(state) {
69948
+ const attrs = state.variableAttributes;
69949
+ if (!attrs || attrs.size === 0) return false;
69950
+ for (const [k, val] of attrs.entries()) {
69951
+ if (val.length === 0) continue;
69952
+ if (val !== "n") return true;
69953
+ const ref = state.variables[k];
69954
+ if (!ref || !isShellIdentifier(ref) || ref === k || attrs.get(ref)) return true;
69955
+ }
69956
+ return false;
69957
+ }
69958
+ function resolveSyncNameref(state, name2) {
69959
+ const attrs = state.variableAttributes;
69960
+ if (!attrs || attrs.size === 0) return name2;
69961
+ if (attrs.get(name2) === "n") {
69962
+ const ref = state.variables[name2];
69963
+ if (ref && isShellIdentifier(ref) && ref !== name2 && !attrs.get(ref)) return ref;
69964
+ }
69965
+ return name2;
69966
+ }
69877
69967
  function publishVariable(state, name2, value2) {
69878
69968
  const monitor = stateMonitor(state);
69879
69969
  if (monitor) {
@@ -71082,6 +71172,7 @@ function resolveSimpleArithOperand(tok, rawState, monitor, activeArrayStore, syn
71082
71172
  }
71083
71173
  tok = c1 === 123 ? tok.slice(2, -1) : tok.slice(1);
71084
71174
  }
71175
+ tok = resolveSyncNameref(rawState, tok);
71085
71176
  if (rawState.nounset || activeArrayStore?.bindings.has(tok) || monitor?.hasOverlay(tok) || activeArrayStore?.watches.has(tok)) return void 0;
71086
71177
  const raw = rawState.variables[tok];
71087
71178
  if (raw === void 0 || raw === "") return 0;
@@ -71811,7 +71902,11 @@ var Runtime = class _Runtime {
71811
71902
  isSync: true,
71812
71903
  resolve: (variable, subscript) => {
71813
71904
  this.signal.throwIfAborted();
71814
- if (this._syncArithState.variableAttributes?.get(variable)?.includes("n")) throw new ArrayFailure("nameref in sync arithmetic");
71905
+ if (this._syncArithState.variableAttributes?.get(variable)?.includes("n")) {
71906
+ const resolved = resolveSyncNameref(this._syncArithState, variable);
71907
+ if (resolved === variable) throw new ArrayFailure("nameref in sync arithmetic");
71908
+ variable = resolved;
71909
+ }
71815
71910
  if (subscript !== void 0) {
71816
71911
  let resolvedSub = subscript;
71817
71912
  if (resolvedSub.charCodeAt(0) === 36 && /^\$[a-zA-Z_][a-zA-Z_0-9]*$/.test(resolvedSub)) {
@@ -71829,6 +71924,13 @@ var Runtime = class _Runtime {
71829
71924
  const rawSub = this._syncArithRawVars[resolvedSub];
71830
71925
  resolvedSub = rawSub === void 0 || rawSub === "" ? "0" : (0, value_exports.shellValueText)(stateMonitor(st)?.values.get(resolvedSub, rawSub) ?? rawSub);
71831
71926
  }
71927
+ } else {
71928
+ const st = this._syncArithState;
71929
+ const binding = arrayStore(st)?.get(variable);
71930
+ if (!binding || !binding.associative) {
71931
+ const subStr = tryEvalSimpleExpandedArith(resolvedSub, st, stateMonitor(st), arrayStore(st), this._syncArithRawWriteOnly ? this._syncArithTouched : void 0);
71932
+ if (subStr !== void 0 && !subStr.startsWith("-")) resolvedSub = subStr;
71933
+ }
71832
71934
  }
71833
71935
  if (resolvedSub.length === 0 || resolvedSub.length > 128 || !/^[a-zA-Z0-9_.\-/:@]+$/.test(resolvedSub)) throw new ArrayFailure("complex subscript in sync arithmetic");
71834
71936
  return `[idx]${variable}:${resolvedSub}`;
@@ -71959,14 +72061,29 @@ var Runtime = class _Runtime {
71959
72061
  }
71960
72062
  }
71961
72063
  canSyncArithmeticOperands(tree, state, line, depth = 0) {
71962
- if (!tree || depth > 128 || hasActiveVariableAttributes(state) || state.readonlyVariables?.size) return false;
72064
+ if (!tree || depth > 128 || hasNonNamerefAttributes(state) || state.readonlyVariables?.size) return false;
71963
72065
  switch (tree.kind) {
71964
72066
  case "literal":
71965
72067
  return true;
71966
72068
  case "name": {
71967
- if (tree.subscript !== void 0 || tree.name === "OPTIND" || tree.name === "PIPESTATUS" || arrayStore(state)?.get(tree.name)) return false;
72069
+ const effName = resolveSyncNameref(state, tree.name);
72070
+ if (effName === "OPTIND" || effName === "PIPESTATUS") return false;
71968
72071
  const monitor = stateMonitor(state);
71969
- if (monitor?.hasOverlay(tree.name) || monitor?.store?.watches.has(tree.name)) return false;
72072
+ if (monitor?.hasOverlay(effName) || monitor?.store?.watches.has(effName)) return false;
72073
+ if (tree.subscript !== void 0) {
72074
+ if (state.nounset || hasUnpreparedLocal(state, tree.name)) return false;
72075
+ const binding = arrayStore(state)?.get(tree.name);
72076
+ if (!binding) return false;
72077
+ if (binding.associative) {
72078
+ if (/^\$[a-zA-Z_][a-zA-Z_0-9]*$/.test(tree.subscript)) {
72079
+ const sv = tree.subscript.slice(1);
72080
+ return !arrayStore(state)?.get(sv) && !monitor?.hasOverlay(sv);
72081
+ }
72082
+ return /^[a-zA-Z0-9_.\-/:@]+$/.test(tree.subscript);
72083
+ }
72084
+ return /^(?:0|[1-9][0-9]{0,6})$/.test(tree.subscript) || /^\$?[a-zA-Z_][a-zA-Z_0-9]*$/.test(tree.subscript) || /^\s*[a-zA-Z_][a-zA-Z_0-9]*\s*(?:[-+*]\s*(?:0|[1-9][0-9]{0,6})|[/%]\s*[1-9][0-9]{0,6})\s*$/.test(tree.subscript);
72085
+ }
72086
+ if (arrayStore(state)?.get(tree.name)) return false;
71970
72087
  const value2 = state.variables[tree.name] ?? (tree.name === "LINENO" ? String(line ?? 1) : tree.name === "_" ? state.lastArgument ?? "" : tree.name === "FUNCNAME" ? state.functionNames?.[0] : void 0);
71971
72088
  const text3 = value2 === void 0 ? void 0 : this._syncArithRawWriteOnly && this._syncArithTouched?.has(tree.name) ? value2 : monitor?.values.get(tree.name, value2) ?? value2;
71972
72089
  if (text3 === void 0 || text3 === "") return true;
@@ -72226,26 +72343,51 @@ var Runtime = class _Runtime {
72226
72343
  name2 = this.referenceName(state, name2);
72227
72344
  const binding = arrayStore(state)?.get(name2);
72228
72345
  if (binding) return binding.get(binding.associative ? binding.keys.get("30")?.index ?? -1 : 0);
72346
+ if (name2 === "DIRSTACK") return state.cwd;
72229
72347
  if (name2 === "FUNCNAME" && state.variables.FUNCNAME === void 0) return state.functionNames?.[0];
72230
72348
  if (name2 === "_" && state.variables._ === void 0) return state.lastArgument ?? "";
72231
72349
  return state.variables[name2];
72232
72350
  }
72233
72351
  async variablePresent(state, name2, io) {
72352
+ const simple = this.tryVariablePresentSync(state, name2);
72353
+ if (simple !== void 0) return simple;
72234
72354
  name2 = this.referenceName(state, name2);
72235
72355
  const bracket = name2.indexOf("[");
72236
72356
  const base = bracket < 0 ? name2 : name2.slice(0, bracket);
72237
- const validName = base.length > 0 && [...base].every((character, index2) => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".includes(character) || index2 > 0 && "0123456789".includes(character));
72238
- if (!validName || bracket >= 0 && !name2.endsWith("]")) return false;
72239
72357
  const resolved = this.referenceName(state, base);
72240
72358
  const binding = arrayStore(state)?.get(resolved);
72241
- if (bracket < 0) return this.variable(state, base) !== void 0;
72242
72359
  const selector = name2.slice(bracket + 1, -1);
72243
- if (!binding?.associative && (selector === "@" || selector === "*")) return binding ? binding.values.size > 0 : this.variable(state, base) !== void 0;
72244
- const store = arrayStore(state);
72245
- if (!store) return selector === "0" && this.variable(state, base) !== void 0;
72246
- const index = await this.arrayIndex(binding, { decimal: selector, source: selector }, state, io, store.owner);
72360
+ const entries = this.presenceArrayEntries(state, resolved);
72361
+ const store = requireArrays(state);
72362
+ const index = await this.arrayIndex(binding, { decimal: selector, source: selector }, state, io, store.owner, false, entries ? entries.length - 1 : binding?.maximum ?? (this.variable(state, base) === void 0 ? -1 : 0));
72363
+ if (entries) return index !== void 0 && entries[index] !== void 0;
72247
72364
  return index !== void 0 && (binding ? binding.getValue(index) !== void 0 : index === 0 && this.variable(state, base) !== void 0);
72248
72365
  }
72366
+ presenceArrayEntries(state, name2) {
72367
+ if (name2 === "DIRSTACK") return [state.cwd, ...state.directoryStack?.entries ?? []];
72368
+ if (name2 === "FUNCNAME" && state.variables.FUNCNAME === void 0 && !arrayStore(state)?.get(name2)) return state.functionNames ?? [];
72369
+ return void 0;
72370
+ }
72371
+ tryVariablePresentSync(state, name2) {
72372
+ name2 = this.referenceName(state, name2);
72373
+ const bracket = name2.indexOf("[");
72374
+ const base = bracket < 0 ? name2 : name2.slice(0, bracket);
72375
+ if (!isShellIdentifier(base) || bracket >= 0 && !name2.endsWith("]")) return false;
72376
+ const resolved = this.referenceName(state, base);
72377
+ const binding = arrayStore(state)?.get(resolved);
72378
+ const entries = this.presenceArrayEntries(state, resolved);
72379
+ if (bracket < 0) return entries ? entries[0] !== void 0 : this.variable(state, base) !== void 0;
72380
+ const selector = name2.slice(bracket + 1, -1);
72381
+ if (binding?.associative) {
72382
+ if (selector.length === 0 || selector.length > 4096 || [...selector].some((character) => "$`\\\"'".includes(character))) return void 0;
72383
+ const key = binding.keys.get(fastStringHexIdentity(selector));
72384
+ return key !== void 0 && binding.getValue(key.index) !== void 0;
72385
+ }
72386
+ if (selector === "@" || selector === "*") return entries ? entries.length > 0 : binding ? binding.values.size > 0 : this.variable(state, base) !== void 0;
72387
+ if (selector.length === 0 || selector.length > 9 || [...selector].some((character) => !"0123456789".includes(character)) || selector.length > 1 && selector[0] === "0") return void 0;
72388
+ const index = Number(selector);
72389
+ return entries ? entries[index] !== void 0 : binding ? binding.getValue(index) !== void 0 : index === 0 && this.variable(state, base) !== void 0;
72390
+ }
72249
72391
  requireParameter(value2, name2, state, io, line) {
72250
72392
  if (value2 === void 0 && state.nounset) throw new NounsetFailure(`${name2}: unbound variable`, io.diagnosticLine ?? line);
72251
72393
  }
@@ -72642,19 +72784,121 @@ var Runtime = class _Runtime {
72642
72784
  }
72643
72785
  }
72644
72786
  }
72787
+ canSyncArrayMembersWord(w, rawState) {
72788
+ if (rawState.nounset) return false;
72789
+ const p02 = w.parts.length === 1 ? w.parts[0] : w.parts.length === 2 && w.parts[0].kind === "text" && w.parts[0].value === "" ? w.parts[1] : void 0;
72790
+ if (!p02) return false;
72791
+ if (p02.kind !== "variable" || !p02.quoted || p02.indirect || p02.prefixNames || p02.length || p02.transform || p02.operator !== void 0) return false;
72792
+ const sel0 = getArraySelector(p02);
72793
+ if (!sel0 || sel0.kind !== "members" && sel0.kind !== "keys" || sel0.separator !== "@") return false;
72794
+ if (p02.substring) {
72795
+ if (sel0.kind !== "members" || p02.keys) return false;
72796
+ const b = stateMonitor(rawState)?.store?.get(resolveSyncNameref(rawState, p02.name));
72797
+ if (b && b.associative) return false;
72798
+ if (!this.isPureSyncValueWord(p02.substring.offset, rawState)) return false;
72799
+ if (p02.substring.length && !this.isPureSyncValueWord(p02.substring.length, rawState)) return false;
72800
+ }
72801
+ return true;
72802
+ }
72803
+ tryExpandSyncArrayMembersWord(w, rawState, io, diagnosticLine) {
72804
+ if (rawState.nounset) return void 0;
72805
+ const p02 = w.parts.length === 1 ? w.parts[0] : w.parts.length === 2 && w.parts[0].kind === "text" && w.parts[0].value === "" ? w.parts[1] : void 0;
72806
+ if (!p02) return void 0;
72807
+ if (p02.kind !== "variable" || !p02.quoted || p02.indirect || p02.prefixNames || p02.length || p02.transform || p02.operator !== void 0) return void 0;
72808
+ const sel0 = getArraySelector(p02);
72809
+ if (!sel0 || sel0.kind !== "members" && sel0.kind !== "keys" || sel0.separator !== "@") return void 0;
72810
+ const monitor = stateMonitor(rawState);
72811
+ const activeStore = monitor?.store ?? arrayStore(rawState);
72812
+ const resolvedName = resolveSyncNameref(rawState, p02.name);
72813
+ const b = activeStore?.get(resolvedName);
72814
+ if (p02.substring) {
72815
+ if (sel0.kind !== "members" || p02.keys || b && b.associative) return void 0;
72816
+ if (b && b.maximum >= 4096) return void 0;
72817
+ const evalSliceInt = (sw) => {
72818
+ if (sw.parts.length === 0) return 0;
72819
+ let expanded;
72820
+ try {
72821
+ expanded = this.fastValueWord(sw, rawState, io, false, false, false, false, void 0, diagnosticLine);
72822
+ } catch {
72823
+ return void 0;
72824
+ }
72825
+ if (typeof expanded !== "string") return void 0;
72826
+ const trimmed = expanded.trim();
72827
+ if (trimmed.length === 0) return 0;
72828
+ const syncTouched = this._syncArithRawWriteOnly ? this._syncArithTouched : void 0;
72829
+ const directOp = resolveSimpleArithOperand(trimmed, rawState, monitor, activeStore, syncTouched);
72830
+ if (directOp !== void 0) return directOp;
72831
+ const simpleExpr = tryEvalSimpleExpandedArith(trimmed, rawState, monitor, activeStore, syncTouched);
72832
+ if (simpleExpr !== void 0) return Number(simpleExpr);
72833
+ return void 0;
72834
+ };
72835
+ const offNum = evalSliceInt(p02.substring.offset);
72836
+ if (offNum === void 0) return void 0;
72837
+ let maxCount2 = Infinity;
72838
+ if (p02.substring.length) {
72839
+ const lenNum = evalSliceInt(p02.substring.length);
72840
+ if (lenNum === void 0 || lenNum < 0) return void 0;
72841
+ maxCount2 = lenNum;
72842
+ }
72843
+ if (!b) {
72844
+ const sv2 = rawState.variables[resolvedName];
72845
+ if (sv2 === void 0) return [];
72846
+ const mv2 = this._syncArithRawWriteOnly && this._syncArithTouched?.has(resolvedName) ? sv2 : monitor?.values.get(resolvedName, sv2) ?? sv2;
72847
+ if (typeof mv2 !== "string") return void 0;
72848
+ const startIdx2 = offNum < 0 ? 1 + offNum : offNum;
72849
+ if (startIdx2 < 0 || startIdx2 > 0 || maxCount2 === 0) return [];
72850
+ return [mv2];
72851
+ }
72852
+ if (b.values.size === 0 || maxCount2 === 0) return [];
72853
+ const startIdx = offNum < 0 ? b.maximum + 1 + offNum : offNum;
72854
+ if (startIdx < 0) return [];
72855
+ const out = [];
72856
+ for (let k = startIdx; k <= b.maximum && out.length < maxCount2; k++) {
72857
+ const slot = b.values.get(k);
72858
+ if (!slot) continue;
72859
+ const v = slot.text.shellValue;
72860
+ if (typeof v !== "string") return void 0;
72861
+ out.push(v);
72862
+ }
72863
+ return out;
72864
+ }
72865
+ const isKeys = sel0.kind === "keys" || p02.keys === true;
72866
+ if (b) {
72867
+ if (b.maximum >= 4096) return void 0;
72868
+ const out = [];
72869
+ for (let k = 0; k <= b.maximum; k++) {
72870
+ const slot = b.values.get(k);
72871
+ if (!slot) continue;
72872
+ const v = isKeys ? b.associative ? b.keys.get(b.keyByIndex.get(k))?.text.shellValue : String(k) : slot.text.shellValue;
72873
+ if (typeof v !== "string") return void 0;
72874
+ out.push(v);
72875
+ }
72876
+ return out;
72877
+ }
72878
+ const sv = rawState.variables[resolvedName];
72879
+ if (sv === void 0) return [];
72880
+ if (isKeys) return ["0"];
72881
+ const mv = this._syncArithRawWriteOnly && this._syncArithTouched?.has(resolvedName) ? sv : monitor?.values.get(resolvedName, sv) ?? sv;
72882
+ if (typeof mv !== "string") return void 0;
72883
+ return [mv];
72884
+ }
72645
72885
  tryFastArrayAssignmentSync(assignment, state, io, diagnosticLine, declaration, associative, ignoreYield = false) {
72646
72886
  if (!ignoreYield && (0, yield_exports.hasYieldCheckpoint)(this.signal)) return false;
72647
72887
  if (declaration) return false;
72648
- const name2 = assignment.name;
72649
- if (hasUnpreparedLocal(state, name2)) return false;
72650
- this._syncArithTouched?.delete(name2);
72651
72888
  const monitor = stateMonitor(state);
72652
72889
  const rawState = monitor ? monitor.raw : state;
72890
+ const name2 = resolveSyncNameref(rawState, assignment.name);
72891
+ if (hasUnpreparedLocal(state, name2)) return false;
72892
+ this._syncArithTouched?.delete(name2);
72653
72893
  if (rawState.readonlyVariables?.has(name2) || rawState.variableAttributes?.get(name2) || rawState.exported.has(name2) || controlNames.has(name2)) {
72654
72894
  return false;
72655
72895
  }
72656
- const store = monitor?.store ?? (monitor && !this.budget._arraySession?.hasActiveLedger ? requireArrays(rawState) : void 0);
72896
+ const store = monitor?.store ?? (monitor && (this.budget.limits.maxExpansionBytes === Infinity && this.budget.limits.maxExpansionFields === Infinity) ? requireArrays(rawState) : void 0);
72657
72897
  let current = store?.get(name2);
72898
+ if (assignment.kind === "compound" && !(associative ?? current?.associative) && state.braceexpand !== false && assignment.entries.some((entry) => {
72899
+ const original = compoundEntryWords.get(entry);
72900
+ return entry.index !== void 0 && original?.parts.some((part) => part.kind === "text" && !part.quoted && part.value.includes("{"));
72901
+ })) return false;
72658
72902
  if (!monitor || !store || store.watches.has(name2) || monitor.hasOverlay(name2) || current && (current.references !== 1 || associative !== void 0 && current.associative !== associative) || !current && rawState.variables[name2] !== void 0) {
72659
72903
  return false;
72660
72904
  }
@@ -72698,7 +72942,7 @@ var Runtime = class _Runtime {
72698
72942
  let val = "";
72699
72943
  if (entry.value.parts.length > 0) {
72700
72944
  try {
72701
- val = this.fastValueWord(entry.value, rawState, io, false, false, false, false, void 0, diagnosticLine);
72945
+ val = this.fastValueWord(entry.value, rawState, io, false, false, false, false, entry.index === void 0 ? void 0 : 0, diagnosticLine);
72702
72946
  } catch {
72703
72947
  return false;
72704
72948
  }
@@ -72737,18 +72981,31 @@ var Runtime = class _Runtime {
72737
72981
  for (let i = 0; i < assignment.entries.length; i++) {
72738
72982
  const entry = assignment.entries[i];
72739
72983
  if (entry.append) return false;
72984
+ if (rawState.braceexpand !== false && entry.value.parts.some((p) => !p.quoted && p.kind === "text" && p.value.includes("{"))) return false;
72740
72985
  let explicitIdx;
72741
72986
  if (entry.index !== void 0) {
72742
72987
  const kSrc = (entry.index.source ?? entry.index.decimal).trim();
72743
72988
  if (!/^(?:0|[1-9][0-9]{0,8})$/.test(kSrc)) return false;
72744
72989
  explicitIdx = Number(kSrc);
72745
- } else if (entry.value.parts.length === 0 || !entry.value.parts.every((p) => p.quoted || p.kind === "text" && p.value.length > 0 && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true))) {
72746
- return false;
72990
+ } else {
72991
+ const expandedArr = this.tryExpandSyncArrayMembersWord(entry.value, rawState, io, diagnosticLine);
72992
+ if (expandedArr !== void 0) {
72993
+ for (let mIdx = 0; mIdx < expandedArr.length; mIdx++) {
72994
+ const mVal = expandedArr[mIdx];
72995
+ const bLen2 = shellValueByteLength(mVal);
72996
+ if (bLen2 > this.budget.limits.maxExpansionBytes) return false;
72997
+ items.push({ explicitIdx: void 0, val: mVal, bLen: bLen2 });
72998
+ }
72999
+ continue;
73000
+ }
73001
+ if (entry.value.parts.length === 0 || !entry.value.parts.every((p) => p.quoted || p.kind === "text" && p.value.length > 0 && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true))) {
73002
+ return false;
73003
+ }
72747
73004
  }
72748
73005
  let val = "";
72749
73006
  if (entry.value.parts.length > 0) {
72750
73007
  try {
72751
- val = this.fastValueWord(entry.value, rawState, io, false, false, false, false, void 0, diagnosticLine);
73008
+ val = this.fastValueWord(entry.value, rawState, io, false, false, false, false, entry.index === void 0 ? void 0 : 0, diagnosticLine);
72752
73009
  } catch {
72753
73010
  return false;
72754
73011
  }
@@ -73092,7 +73349,7 @@ var Runtime = class _Runtime {
73092
73349
  if (expandedEntry) continue;
73093
73350
  }
73094
73351
  const index = entry.index ? await this.arrayIndex(targetBinding, entry.index, state, io, operation2, true) : void 0;
73095
- const fields3 = await this.valueWord(entry.value, state, io, entry.index === void 0);
73352
+ const fields3 = await this.valueWord(entry.value, state, io, entry.index === void 0, false, false, false, void 0, false, entry.index === void 0, entry.index === void 0 ? void 0 : 0);
73096
73353
  if (index !== void 0) {
73097
73354
  const value2 = await join(fields3);
73098
73355
  await insert(index, value2, entry.append);
@@ -73606,6 +73863,7 @@ var Runtime = class _Runtime {
73606
73863
  if (state.readonlyVariables?.has(name2)) throw new ArrayFailure("readonly binding");
73607
73864
  if (!watch.valid()) throw new ArrayFailure("binding changed during writer admission");
73608
73865
  prepared.validate();
73866
+ if (clear) prepared.binding.assigned = true;
73609
73867
  let retirement;
73610
73868
  monitor.publish(prepared.tickets, name2, () => {
73611
73869
  delete state.variables[name2];
@@ -75258,13 +75516,13 @@ var Runtime = class _Runtime {
75258
75516
  const r0 = command7.redirects[0];
75259
75517
  const rOp = r0.operator;
75260
75518
  const isDevNull = (r0.descriptor === void 0 || r0.descriptor === 1) && !r0.move && !r0.document && (rOp === ">" || rOp === ">>" || rOp === ">|") && r0.target.plain === "/dev/null";
75261
- const isReadCmd = w0Plain === "read" || command7.words[1]?.plain === "read" && w0.parts[0]?.kind === "text" && w0.parts[0].value.startsWith("IFS=");
75519
+ const isReadCmd = w0Plain === "read" || w0Plain === "mapfile" || w0Plain === "readarray" || command7.words[1]?.plain === "read" && w0.parts[0]?.kind === "text" && w0.parts[0].value.startsWith("IFS=");
75262
75520
  if (!isDevNull && w0Plain !== "echo" && w0Plain !== "printf" && !(isReadCmd && rOp === "<<<")) {
75263
75521
  pipeline._skipTrySync = true;
75264
75522
  return void 0;
75265
75523
  }
75266
75524
  } else if (wordsLen >= 2) {
75267
- if (w0Plain !== "echo" && w0Plain !== "printf" && w0Plain !== "[" && w0Plain !== "test" && w0Plain !== "mkdir" && w0Plain !== "rm" && w0Plain !== "local" && w0Plain !== "declare" && w0Plain !== "typeset" && w0Plain !== "return" && w0Plain !== "break" && w0Plain !== "continue" && w0Plain !== "shift" && w0Plain !== "read" && w0Plain !== "eval" && w0Plain !== "unset" && w0Plain !== "export" && w0Plain !== "let" && !(command7.words[1]?.plain === "read" && w0.parts[0]?.kind === "text" && w0.parts[0].value.startsWith("IFS=")) && !(w0Plain !== void 0 && state.functions.has(w0Plain))) {
75525
+ if (w0Plain !== ":" && w0Plain !== "true" && w0Plain !== "false" && w0Plain !== "getopts" && w0Plain !== "echo" && w0Plain !== "printf" && w0Plain !== "[" && w0Plain !== "test" && w0Plain !== "mkdir" && w0Plain !== "rm" && w0Plain !== "local" && w0Plain !== "declare" && w0Plain !== "typeset" && w0Plain !== "return" && w0Plain !== "break" && w0Plain !== "continue" && w0Plain !== "shift" && w0Plain !== "read" && w0Plain !== "eval" && w0Plain !== "unset" && w0Plain !== "export" && w0Plain !== "let" && !(command7.words[1]?.plain === "read" && w0.parts[0]?.kind === "text" && w0.parts[0].value.startsWith("IFS=")) && !(w0Plain !== void 0 && state.functions.has(w0Plain))) {
75268
75526
  return void 0;
75269
75527
  }
75270
75528
  } else if (w0Plain !== "echo" && w0Plain !== "printf" && w0Plain !== ":" && w0Plain !== "true" && w0Plain !== "false" && w0Plain !== "return" && w0Plain !== "break" && w0Plain !== "continue" && w0Plain !== "shift" && w0Plain !== "eval" && !(w0Plain !== void 0 && state.functions.has(w0Plain)) && !(w0.parts[0]?.kind === "text" && w0.parts[0].value.includes("=")) && !getArrayAssignment(w0)) {
@@ -75343,7 +75601,7 @@ var Runtime = class _Runtime {
75343
75601
  const fnBody = rawState.functions.get(w0Plain);
75344
75602
  return fnBody.kind === "group" && fnBody.redirects.length === 0 && this.canSyncScriptCompound(fnBody.body, rawState, depth + 1);
75345
75603
  }
75346
- const st = stateMonitor(rawState)?.store ?? (stateMonitor(rawState) && !this.budget._arraySession?.hasActiveLedger ? requireArrays(rawState) : void 0);
75604
+ const st = stateMonitor(rawState)?.store ?? (stateMonitor(rawState) && (this.budget.limits.maxExpansionBytes === Infinity && this.budget.limits.maxExpansionFields === Infinity) ? requireArrays(rawState) : void 0);
75347
75605
  const arrayAssign = getArrayAssignment(w0);
75348
75606
  if (arrayAssign) {
75349
75607
  if (!st) return false;
@@ -75351,7 +75609,7 @@ var Runtime = class _Runtime {
75351
75609
  return false;
75352
75610
  }
75353
75611
  if (arrayAssign.kind === "compound") {
75354
- const isAssoc = Boolean(st?.get(arrayAssign.name)?.associative);
75612
+ const isAssoc = Boolean(st?.get(resolveSyncNameref(rawState, arrayAssign.name))?.associative);
75355
75613
  return arrayAssign.entries.length <= 32 && arrayAssign.entries.every((e) => {
75356
75614
  if (e.append) return false;
75357
75615
  if (isAssoc) {
@@ -75362,13 +75620,14 @@ var Runtime = class _Runtime {
75362
75620
  const kSrc = (e.index.source ?? e.index.decimal).trim();
75363
75621
  return /^(?:0|[1-9][0-9]{0,8})$/.test(kSrc) && isNoBraceSyncAssignWord(e.value);
75364
75622
  }
75623
+ if (this.canSyncArrayMembersWord(e.value, rawState)) return true;
75365
75624
  return isNoBraceSyncWord(e.value) && e.value.parts.length > 0 && e.value.parts.every((p) => p.quoted || p.kind === "text" && p.value.length > 0 && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true));
75366
75625
  });
75367
75626
  }
75368
75627
  return isNoBraceSyncAssignWord(arrayAssign.value);
75369
75628
  }
75370
75629
  const assignment = this.assignment(w0);
75371
- return Boolean(assignment && assignment.name !== "OPTIND" && assignment.name !== "PIPESTATUS" && !assignment.name.includes("[") && !rawState.readonlyVariables?.has(assignment.name) && (!st?.get(assignment.name) || !assignment.append && !hasUnpreparedLocal(rawState, assignment.name) && !rawState.exported.has(assignment.name)) && isNoBraceSyncAssignWord(assignment.value));
75630
+ return Boolean(assignment && (assignment.name !== "OPTIND" || !assignment.append && !rawState.variableAttributes?.get("OPTIND")) && assignment.name !== "PIPESTATUS" && !assignment.name.includes("[") && !rawState.readonlyVariables?.has(assignment.name) && (!st?.get(assignment.name) || !assignment.append && !hasUnpreparedLocal(rawState, assignment.name) && !rawState.exported.has(assignment.name)) && isNoBraceSyncAssignWord(assignment.value));
75372
75631
  }
75373
75632
  if (w0Plain !== void 0 && command7.words.length <= 64 && rawState.functions.has(w0Plain) && this.firstInternalDiscovery(w0Plain, rawState, false) === "function" && !hasActiveExtensions(rawState)) {
75374
75633
  const fnBody = rawState.functions.get(w0Plain);
@@ -75394,7 +75653,7 @@ var Runtime = class _Runtime {
75394
75653
  }
75395
75654
  }
75396
75655
  if (command7.words.length >= 2 && command7.words.length <= 16) {
75397
- if (w0Plain === "unset" && rawState.locals.length === 0 && !hasShellFunction(rawState, "unset") && !rawState.extensions?.builtins.has("unset")) {
75656
+ if (w0Plain === "unset" && depth === 0 && rawState.locals.length === 0 && !hasShellFunction(rawState, "unset") && !rawState.extensions?.builtins.has("unset")) {
75398
75657
  const uStart = command7.words[1]?.plain === "-v" ? 2 : 1;
75399
75658
  if (uStart < command7.words.length) {
75400
75659
  let allOk = true;
@@ -75411,7 +75670,7 @@ var Runtime = class _Runtime {
75411
75670
  if (allOk) return true;
75412
75671
  }
75413
75672
  }
75414
- if (w0Plain === "export" && rawState.locals.length === 0 && !hasShellFunction(rawState, "export") && !rawState.extensions?.builtins.has("export")) {
75673
+ if (w0Plain === "export" && rawState.locals.length === 0 && depth === 0 && !hasShellFunction(rawState, "export") && !rawState.extensions?.builtins.has("export")) {
75415
75674
  let allOk = true;
75416
75675
  for (let ei = 1; ei < command7.words.length; ei++) {
75417
75676
  const we = command7.words[ei];
@@ -75458,22 +75717,28 @@ var Runtime = class _Runtime {
75458
75717
  }
75459
75718
  if (command7.words.length >= 2 && command7.words.length <= 16 && w0Plain !== void 0 && (w0Plain === "local" ? rawState.locals.length > 0 || depth > 0 : w0Plain === "declare" || w0Plain === "typeset") && !hasShellFunction(rawState, w0Plain) && !rawState.extensions?.builtins.has(w0Plain)) {
75460
75719
  if (command7.words[1]?.plain === "-a" || command7.words[1]?.plain === "-A") return false;
75720
+ const isNamerefDecl = command7.words[1]?.plain === "-n" && (rawState.locals.length > 0 || depth > 0) && command7.words.length >= 3;
75721
+ const isGlobalDecl = command7.words[1]?.plain === "-g" && (w0Plain === "declare" || w0Plain === "typeset") && command7.words.length >= 3;
75461
75722
  let allValidLocal = true;
75462
- for (let idx = 1; idx < command7.words.length; idx++) {
75723
+ for (let idx = isNamerefDecl || isGlobalDecl ? 2 : 1; idx < command7.words.length; idx++) {
75463
75724
  const wArg = command7.words[idx];
75464
75725
  const assignment = !getArrayAssignment(wArg) ? this.assignment(wArg) : void 0;
75465
75726
  if (assignment) {
75466
- if (assignment.name === "OPTIND" || assignment.name === "PIPESTATUS" || assignment.name.includes("[") || !isNoBraceSyncAssignWord(assignment.value)) {
75727
+ if (!isNamerefDecl && rawState.variableAttributes?.get(assignment.name) || assignment.name === "OPTIND" && (assignment.append || rawState.variableAttributes?.get("OPTIND")) || assignment.name === "PIPESTATUS" || assignment.name.includes("[") || !isNoBraceSyncAssignWord(assignment.value)) {
75467
75728
  allValidLocal = false;
75468
75729
  break;
75469
75730
  }
75470
- } else if (!wArg.plain || !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(wArg.plain) || wArg.plain === "OPTIND" || wArg.plain === "PIPESTATUS") {
75731
+ } else if (!wArg.plain || !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(wArg.plain) || wArg.plain === "OPTIND" && rawState.variableAttributes?.get("OPTIND") || wArg.plain === "PIPESTATUS") {
75471
75732
  allValidLocal = false;
75472
75733
  break;
75473
75734
  }
75474
75735
  }
75475
75736
  if (allValidLocal) return true;
75476
75737
  }
75738
+ if ((w0Plain === ":" || w0Plain === "true" || w0Plain === "false") && command7.words.length <= 16 && !hasShellFunction(rawState, w0Plain) && !rawState.extensions?.builtins.has(w0Plain) && command7.words.slice(1).every(isNoBraceSyncWord)) {
75739
+ return true;
75740
+ }
75741
+ if (w0Plain === "getopts") return false;
75477
75742
  if (w0Plain === "echo" && !hasShellFunction(rawState, "echo") && !rawState.extensions?.builtins.has("echo")) {
75478
75743
  const w1Plain = command7.words[1]?.plain;
75479
75744
  if (w1Plain === void 0 || !w1Plain.startsWith("-") || w1Plain === "-n" || w1Plain === "-e" || w1Plain === "-ne" || w1Plain === "-en") {
@@ -75501,7 +75766,15 @@ var Runtime = class _Runtime {
75501
75766
  }
75502
75767
  if (w0Plain !== void 0 && rawState.functions.has(w0Plain) && command7.words.slice(1).every(isNoBraceSyncWord)) {
75503
75768
  const fnBody = rawState.functions.get(w0Plain);
75504
- return fnBody.kind === "group" && fnBody.redirects.length === 0 && this.canSyncScriptCompound(fnBody.body, rawState, depth + 1);
75769
+ if (fnBody.kind !== "group" || fnBody.redirects.length !== 0) return false;
75770
+ rawState.locals.push(/* @__PURE__ */ new Map());
75771
+ rawState.functionDepth++;
75772
+ try {
75773
+ return this.canSyncScriptCompound(fnBody.body, rawState, depth + 1);
75774
+ } finally {
75775
+ rawState.functionDepth--;
75776
+ rawState.locals.pop();
75777
+ }
75505
75778
  }
75506
75779
  return false;
75507
75780
  }
@@ -75522,7 +75795,31 @@ var Runtime = class _Runtime {
75522
75795
  const checkCondNoFile = (e) => {
75523
75796
  if (e.kind === "nonempty") return this.isPureSyncValueWord(e.operand, rawState);
75524
75797
  if (e.kind === "unary") return (e.operator === "-n" || e.operator === "-z" || e.operator === "-v") && this.isPureSyncValueWord(e.operand, rawState);
75525
- if (e.kind === "binary") return this.isPureSyncValueWord(e.left, rawState) && (e.operator === "==" || e.operator === "=" || e.operator === "!=" ? this.canSyncPatternWordParts(e.right, rawState) : this.isPureSyncValueWord(e.right, rawState));
75798
+ if (e.kind === "binary") {
75799
+ if (e.operator === "=~") {
75800
+ if (!this.isPureSyncValueWord(e.left, rawState) || !this.extractSimpleErePattern(e.right) || rawState.readonlyVariables?.has("BASH_REMATCH") || rawState.exported.has("BASH_REMATCH") || hasUnpreparedLocal(rawState, "BASH_REMATCH")) return false;
75801
+ const mon = stateMonitor(rawState);
75802
+ if (!mon || (this.budget.limits.maxExpansionBytes !== Infinity || this.budget.limits.maxExpansionFields !== Infinity) || mon.hasOverlay("BASH_REMATCH")) return false;
75803
+ const st = mon.store ?? requireArrays(rawState);
75804
+ if (st.watches.has("BASH_REMATCH")) return false;
75805
+ let rem = st.get("BASH_REMATCH");
75806
+ if (!rem) {
75807
+ if (rawState.variables.BASH_REMATCH !== void 0) return false;
75808
+ const created = IndexedBinding.create(st.owner, false);
75809
+ const prepared = st.prepareExistingName("BASH_REMATCH", 12, st.owner, this.signal);
75810
+ if (!prepared) {
75811
+ void created.release();
75812
+ return false;
75813
+ }
75814
+ const initTickets = st.owner.charge({ generation: true, version: true, epoch: true, work: 8 });
75815
+ st.publish("BASH_REMATCH", created, initTickets, prepared, false, st.owner);
75816
+ mon.epoch = initTickets.epoch;
75817
+ rem = created;
75818
+ }
75819
+ return !rem.associative && rem.references === 1;
75820
+ }
75821
+ return this.isPureSyncValueWord(e.left, rawState) && (e.operator === "==" || e.operator === "=" || e.operator === "!=" ? this.canSyncPatternWordParts(e.right, rawState) : this.isPureSyncValueWord(e.right, rawState));
75822
+ }
75526
75823
  if (e.kind === "not") return checkCondNoFile(e.operand);
75527
75824
  if (e.kind === "and" || e.kind === "or") return checkCondNoFile(e.left) && checkCondNoFile(e.right);
75528
75825
  return false;
@@ -75552,11 +75849,11 @@ var Runtime = class _Runtime {
75552
75849
  const sel0 = p02?.kind === "variable" ? getArraySelector(p02) : void 0;
75553
75850
  const isArrAt = Boolean(p02?.kind === "variable" && p02.quoted && !p02.indirect && !p02.prefixNames && !p02.length && !p02.substring && !p02.transform && p02.operator === void 0 && (sel0?.kind === "members" || sel0?.kind === "keys") && sel0.separator === "@");
75554
75851
  const isBraceRange = Boolean(p02?.kind === "text" && !p02.quoted && /^\{-?\d+\.\.-?\d+(?:\.\.-?\d+)?\}$/.test(p02.value));
75555
- if (!isArrAt && !isBraceRange && !(this.isPureSyncValueWord(w0, rawState) && w0.parts.every((p) => p.quoted || p.kind === "text" && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true)))) return false;
75852
+ if (!isArrAt && !isBraceRange && !this.canSyncArrayMembersWord(w0, rawState) && !(this.isPureSyncValueWord(w0, rawState) && w0.parts.every((p) => p.quoted || p.kind === "text" && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true)))) return false;
75556
75853
  } else {
75557
75854
  for (let i = 0; i < command7.words.length; i++) {
75558
75855
  const w = command7.words[i];
75559
- if (!this.isPureSyncValueWord(w, rawState) || !w.parts.every((p) => p.quoted || p.kind === "text" && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true))) return false;
75856
+ if (!this.canSyncArrayMembersWord(w, rawState) && (!this.isPureSyncValueWord(w, rawState) || !w.parts.every((p) => p.quoted || p.kind === "text" && !p.value.includes(" ") && !p.value.includes(" ") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true)))) return false;
75560
75857
  }
75561
75858
  }
75562
75859
  }
@@ -75634,7 +75931,9 @@ var Runtime = class _Runtime {
75634
75931
  }
75635
75932
  } else if (wp0 === "local" || wp0 === "declare" || wp0 === "typeset") {
75636
75933
  const isArrDecl = c.words[1]?.plain === "-a" || c.words[1]?.plain === "-A";
75637
- for (let k = isArrDecl ? 2 : 1; k < c.words.length; k++) {
75934
+ const isNameref = c.words[1]?.plain === "-n";
75935
+ const isGlobal = c.words[1]?.plain === "-g";
75936
+ for (let k = isArrDecl || isNameref || isGlobal ? 2 : 1; k < c.words.length; k++) {
75638
75937
  const wk = c.words[k];
75639
75938
  const aa = getArrayAssignment(wk);
75640
75939
  if (aa) {
@@ -75647,6 +75946,8 @@ var Runtime = class _Runtime {
75647
75946
  if (isArrDecl) {
75648
75947
  arrayVars.add(nm);
75649
75948
  if (wp0 === "local" || d > 0) localArrayVars.add(nm);
75949
+ } else if (isNameref) {
75950
+ localArrayVars.add(nm);
75650
75951
  } else {
75651
75952
  scalarVars.add(nm);
75652
75953
  const pv = asg?.value.plain;
@@ -75655,14 +75956,25 @@ var Runtime = class _Runtime {
75655
75956
  }
75656
75957
  }
75657
75958
  }
75658
- } else if (wp0 === "printf" && c.words[1]?.plain === "-v" && c.words[2]?.plain) {
75659
- const target = c.words[2].plain;
75959
+ } else if (wp0 === "printf" && c.words[1]?.plain === "-v" && (c.words[2]?.plain || c.words[2]?.parts[0]?.kind === "text")) {
75960
+ const target = c.words[2].plain ?? c.words[2].parts[0].value;
75660
75961
  const br = target.indexOf("[");
75661
75962
  if (br > 0) arrayVars.add(target.slice(0, br));
75662
75963
  else {
75663
75964
  scalarVars.add(target);
75664
75965
  nonIntScalarVars.add(target);
75665
75966
  }
75967
+ } else if (wp0 === "mapfile" || wp0 === "readarray") {
75968
+ arrayVars.add(c.words[2]?.plain ?? "MAPFILE");
75969
+ } else if (wp0 === "getopts") {
75970
+ const ov = c.words[2]?.plain;
75971
+ if (ov && isShellIdentifier(ov)) {
75972
+ scalarVars.add(ov);
75973
+ nonIntScalarVars.add(ov);
75974
+ }
75975
+ scalarVars.add("OPTIND");
75976
+ scalarVars.add("OPTARG");
75977
+ nonIntScalarVars.add("OPTARG");
75666
75978
  } else if (wp0 === "read" || c.words[1]?.plain === "read") {
75667
75979
  for (let k = 1; k < c.words.length; k++) {
75668
75980
  const vp = c.words[k]?.plain;
@@ -75800,31 +76112,8 @@ var Runtime = class _Runtime {
75800
76112
  if (expr.operator === "-n") return val.length > 0 ? 0 : 1;
75801
76113
  if (expr.operator === "-z") return val.length === 0 ? 0 : 1;
75802
76114
  if (expr.operator === "-v") {
75803
- const bracket = val.indexOf("[");
75804
- if (bracket < 0) {
75805
- if (!isShellIdentifier(val)) return 1;
75806
- const b2 = store?.get(val);
75807
- if (b2) return b2.get(b2.associative ? b2.keys.get("30")?.index ?? -1 : 0) !== void 0 ? 0 : 1;
75808
- return this.variable(rawState, val) !== void 0 ? 0 : 1;
75809
- }
75810
- if (!val.endsWith("]")) return 1;
75811
- const base = val.slice(0, bracket);
75812
- if (!isShellIdentifier(base)) return 1;
75813
- const sub = val.slice(bracket + 1, -1);
75814
- const b = store?.get(base);
75815
- if (!b?.associative && (sub === "@" || sub === "*")) {
75816
- return (b ? b.values.size > 0 : this.variable(rawState, base) !== void 0) ? 0 : 1;
75817
- }
75818
- if (b?.associative) {
75819
- if (sub.length === 0 || sub.length > 4096 || /[$\x60\\"']/.test(sub)) return void 0;
75820
- const ek = b.keys.get(fastStringHexIdentity(sub));
75821
- return ek !== void 0 && b.getValue(ek.index) !== void 0 ? 0 : 1;
75822
- }
75823
- if (/^(?:0|[1-9][0-9]{0,8})$/.test(sub)) {
75824
- const idx = Number(sub);
75825
- return (b ? b.getValue(idx) !== void 0 : idx === 0 && this.variable(rawState, base) !== void 0) ? 0 : 1;
75826
- }
75827
- return void 0;
76115
+ const present = this.tryVariablePresentSync(rawState, val);
76116
+ return present === void 0 ? void 0 : present ? 0 : 1;
75828
76117
  }
75829
76118
  if (syncConditionalFileUnaryOps.has(expr.operator)) {
75830
76119
  const fileRes = this.tryEvalFastMemoryFileUnary(expr.operator, val, rawState);
@@ -75955,7 +76244,22 @@ var Runtime = class _Runtime {
75955
76244
  }
75956
76245
  return void 0;
75957
76246
  }
75958
- finishSyncPipeStatus(rawState, monitor, store, existing, elem0, scope, finalStatus, restEpoch) {
76247
+ setSyncPipeStatusCell(existing, status2) {
76248
+ const cell2 = existing.values.get(0);
76249
+ if (cell2 && cell2.text.references === 1 && cell2.text.bytes === status2.length) {
76250
+ cell2.text.shellValue = status2;
76251
+ } else {
76252
+ existing.owner.chargeWork(status2.length);
76253
+ const token = new OwnedText(status2, status2.length, existing.owner.reserve({ payload: status2.length, metadata: 32, work: 4 }));
76254
+ try {
76255
+ existing.insert(0, token);
76256
+ } catch (error) {
76257
+ token.release();
76258
+ throw error;
76259
+ }
76260
+ }
76261
+ }
76262
+ finishSyncPipeStatus(rawState, monitor, store, existing, _elem0, scope, finalStatus, restEpoch) {
75959
76263
  if (!existing) {
75960
76264
  if (store) {
75961
76265
  if (publishPipelineStatus(rawState, finalStatus === 0 ? singleStatusZero : singleStatusOne, this.signal, scope)) return void 0;
@@ -75964,7 +76268,7 @@ var Runtime = class _Runtime {
75964
76268
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
75965
76269
  }
75966
76270
  } else {
75967
- (elem0 ?? existing.values.get(0)).text.shellValue = finalStatus === 0 ? "0" : "1";
76271
+ this.setSyncPipeStatusCell(existing, finalStatus === 0 ? "0" : "1");
75968
76272
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
75969
76273
  }
75970
76274
  rawState.status = finalStatus;
@@ -75980,7 +76284,7 @@ var Runtime = class _Runtime {
75980
76284
  if (!monitor) return void 0;
75981
76285
  const rawState = monitor.raw;
75982
76286
  const gArrays = guestArrays(rawState);
75983
- if (io.terminal || io.asyncDefaultInput || hasActiveExtensions(rawState) || hasActiveVariableAttributes(rawState) || gArrays && gArrays.watches.size > 0) return void 0;
76287
+ if (io.terminal || io.asyncDefaultInput || hasActiveExtensions(rawState) || hasNonNamerefAttributes(rawState) || gArrays && gArrays.watches.size > 0) return void 0;
75984
76288
  if ((this.budget.commands + 1 & 127) === 0) {
75985
76289
  if ((0, yield_exports.hasYieldCheckpoint)(this.signal) || this._syncReturnDepth === 0 && (this.budget.commands + 1 & 8191) === 0) return void 0;
75986
76290
  (0, yield_exports.runYieldCheckpoint)(this.signal);
@@ -75993,7 +76297,7 @@ var Runtime = class _Runtime {
75993
76297
  let existing = store?.get("PIPESTATUS");
75994
76298
  if (store && !existing) {
75995
76299
  const initTarget = pipelineStatusTarget(rawState);
75996
- if (!this.budget._arraySession?.hasActiveLedger && (initTarget === "indexed" || initTarget === "absent") && !store.watches.has("PIPESTATUS") && !monitor.hasOverlay("PIPESTATUS") && !store.owner.ledger.checkpoint(this.signal, 0)) {
76300
+ if (this.budget.limits.maxExpansionBytes === Infinity && this.budget.limits.maxExpansionFields === Infinity && (initTarget === "indexed" || initTarget === "absent") && !store.watches.has("PIPESTATUS") && !monitor.hasOverlay("PIPESTATUS") && !store.owner.ledger.checkpoint(this.signal, 0)) {
75997
76301
  try {
75998
76302
  if (!publishPipelineStatus(rawState, monitor.lazyPipeStatus ?? singleStatusZero, this.signal, scope)) {
75999
76303
  existing = store.get("PIPESTATUS");
@@ -76011,9 +76315,9 @@ var Runtime = class _Runtime {
76011
76315
  return void 0;
76012
76316
  }
76013
76317
  const elem0 = existing?.values.get(0);
76014
- if (existing && (!elem0 || elem0.text.bytes !== 1)) return void 0;
76318
+ if (existing && !elem0) return void 0;
76015
76319
  const canMutatePipeStatus = !existing || existing.references === 1 && elem0.text.references === 1;
76016
- const diagnosticLine = io.diagnosticCommandLines?.get(command7) ?? (command7.line ?? 1) + (io.diagnosticOffset ?? 0);
76320
+ const diagnosticLine = io.diagnosticCommandLines?.get(command7) ?? io.substitutionDiagnosticLines?.get(command7) ?? (command7.line ?? 1) + (io.diagnosticOffset ?? 0);
76017
76321
  if (command7.kind === "function") {
76018
76322
  if (pipeline.negate || !canMutatePipeStatus || command7.redirects.length > 0 || rawState.readonlyFunctions?.has(command7.name) || rawState.profile === "sh" && (specialBuiltinNames.has(command7.name) || rawState.extensions?.builtins.get(command7.name)?.special)) {
76019
76323
  return void 0;
@@ -76069,7 +76373,7 @@ var Runtime = class _Runtime {
76069
76373
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76070
76374
  }
76071
76375
  } else {
76072
- activeExisting.values.get(0).text.shellValue = finalStatus === 0 ? "0" : "1";
76376
+ this.setSyncPipeStatusCell(activeExisting, finalStatus === 0 ? "0" : "1");
76073
76377
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76074
76378
  }
76075
76379
  rawState.status = finalStatus;
@@ -76161,13 +76465,13 @@ var Runtime = class _Runtime {
76161
76465
  }
76162
76466
  const scalarMutMatch = fastSrc.length <= 64 ? SIMPLE_SCALAR_MUT_RE.exec(fastSrc) : null;
76163
76467
  if (scalarMutMatch) {
76164
- const varName = scalarMutMatch[1];
76468
+ const varName = resolveSyncNameref(rawState, scalarMutMatch[1]);
76165
76469
  const binOp = scalarMutMatch[2];
76166
76470
  const rhs1 = Number(scalarMutMatch[3]);
76167
76471
  const rhsOp = scalarMutMatch[4];
76168
76472
  const rhs2 = scalarMutMatch[5] !== void 0 ? Number(scalarMutMatch[5]) : 0;
76169
76473
  const rhsNum = rhsOp === "+" ? rhs1 + rhs2 : rhsOp === "-" ? rhs1 - rhs2 : rhsOp === "*" ? rhs1 * rhs2 : rhs1;
76170
- if (varName !== "OPTIND" && varName !== "PIPESTATUS" && !store?.get(varName) && !hasActiveVariableAttributes(rawState)) {
76474
+ if (varName !== "OPTIND" && varName !== "PIPESTATUS" && !store?.get(varName) && !hasNonNamerefAttributes(rawState)) {
76171
76475
  const curVal = this._syncArithRawWriteOnly && this._syncArithTouched?.has(varName) ? rawState.variables[varName] ?? "0" : monitor.values.get(varName, rawState.variables[varName] ?? "0") ?? rawState.variables[varName] ?? "0";
76172
76476
  if (typeof curVal === "string" && (curVal === "" || /^-?(?:0|[1-9][0-9]{0,12})$/.test(curVal))) {
76173
76477
  const curNum = curVal === "" ? 0 : Number(curVal);
@@ -76236,7 +76540,13 @@ var Runtime = class _Runtime {
76236
76540
  }
76237
76541
  const dynProg = prepareArithmetic(fastSrc, this.budget.parsing);
76238
76542
  if (!dynProg.error && isSafeSmiProgram(dynProg) && this.canSyncArithmeticWithoutFault(dynProg.tree, rawState, diagnosticLine)) {
76239
- const nonZero = this.syncShellArithmeticNonZero(dynProg, rawState, diagnosticLine);
76543
+ let nonZero;
76544
+ try {
76545
+ nonZero = this.syncShellArithmeticNonZero(dynProg, rawState, diagnosticLine);
76546
+ } catch (err) {
76547
+ if (err instanceof ArrayFailure) return void 0;
76548
+ throw err;
76549
+ }
76240
76550
  if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
76241
76551
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
76242
76552
  this.budget.tick();
@@ -76247,7 +76557,13 @@ var Runtime = class _Runtime {
76247
76557
  }
76248
76558
  }
76249
76559
  if (!expr.error && isSafeSmiProgram(expr) && this.canSyncArithmeticWithoutFault(expr.tree, rawState, diagnosticLine)) {
76250
- const nonZero = this.syncShellArithmeticNonZero(expr, rawState, diagnosticLine);
76560
+ let nonZero;
76561
+ try {
76562
+ nonZero = this.syncShellArithmeticNonZero(expr, rawState, diagnosticLine);
76563
+ } catch (err) {
76564
+ if (err instanceof ArrayFailure) return void 0;
76565
+ throw err;
76566
+ }
76251
76567
  if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
76252
76568
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
76253
76569
  this.budget.tick();
@@ -76296,8 +76612,11 @@ var Runtime = class _Runtime {
76296
76612
  }
76297
76613
  return res;
76298
76614
  }
76299
- const fastLoopRes = this.trySyncLoop(command7, pipeline, rawState, monitor, store, existing, elem0, canMutatePipeStatus, io, diagnosticLine);
76300
- if (fastLoopRes !== void 0) return fastLoopRes;
76615
+ if (!command7._skipTrySyncLoop) {
76616
+ const fastLoopRes = this.trySyncLoop(command7, pipeline, rawState, monitor, store, existing, elem0, canMutatePipeStatus, io, diagnosticLine);
76617
+ if (fastLoopRes !== void 0) return fastLoopRes;
76618
+ command7._skipTrySyncLoop = true;
76619
+ }
76301
76620
  }
76302
76621
  if (command7.kind === "group" || command7.kind === "if" || command7.kind === "case" || command7.kind === "while" || command7.kind === "until" || command7.kind === "for" || command7.kind === "arithmetic-for") {
76303
76622
  if (command7.redirects.length !== 0 || pipeline.negate || !canMutatePipeStatus || !ignored && rawState.errexit || rawState.nounset || rawState.readonlyVariables?.size || (0, yield_exports.hasYieldCheckpoint)(this.signal) || this._syncReturnDepth === 0 && ((this.budget.commands + 32 & 8191) < 32 || !this.canSyncCommandCompound(command7, rawState, 0, rawState.loopDepth))) {
@@ -76352,6 +76671,12 @@ var Runtime = class _Runtime {
76352
76671
  if (command7.kind === "while" || command7.kind === "until") {
76353
76672
  this.budget.tick();
76354
76673
  let lastStatus = 0;
76674
+ const enableBatchRawWrite = !this._syncArithRawWriteOnly && !hasActiveExtensions(rawState) && !hasActiveVariableAttributes(rawState) && !rawState.readonlyVariables?.size && !rawState.allexport;
76675
+ const batchTouched = enableBatchRawWrite ? /* @__PURE__ */ new Set() : void 0;
76676
+ if (enableBatchRawWrite) {
76677
+ this._syncArithRawWriteOnly = true;
76678
+ this._syncArithTouched = batchTouched;
76679
+ }
76355
76680
  rawState.loopDepth++;
76356
76681
  this._syncReturnDepth++;
76357
76682
  try {
@@ -76398,6 +76723,15 @@ var Runtime = class _Runtime {
76398
76723
  } finally {
76399
76724
  this._syncReturnDepth--;
76400
76725
  rawState.loopDepth--;
76726
+ if (enableBatchRawWrite && batchTouched) {
76727
+ this._syncArithRawWriteOnly = false;
76728
+ this._syncArithTouched = void 0;
76729
+ for (const vName of batchTouched) {
76730
+ const vVal = rawState.variables[vName];
76731
+ if (typeof vVal === "string") monitor.publishStringVariable(vName, vVal);
76732
+ else if (vVal === void 0) delete monitor.proxy.variables[vName];
76733
+ }
76734
+ }
76401
76735
  }
76402
76736
  rawState.status = lastStatus;
76403
76737
  return lastStatus;
@@ -76408,11 +76742,17 @@ var Runtime = class _Runtime {
76408
76742
  return void 0;
76409
76743
  }
76410
76744
  this.budget.tick();
76411
- if (e0) this.syncShellArithmeticNonZero(e0, rawState, diagnosticLine);
76745
+ const enableBatchRawWrite = !this._syncArithRawWriteOnly && !hasActiveExtensions(rawState) && !hasActiveVariableAttributes(rawState) && !rawState.readonlyVariables?.size && !rawState.allexport;
76746
+ const batchTouched = enableBatchRawWrite ? /* @__PURE__ */ new Set() : void 0;
76747
+ if (enableBatchRawWrite) {
76748
+ this._syncArithRawWriteOnly = true;
76749
+ this._syncArithTouched = batchTouched;
76750
+ }
76412
76751
  let lastStatus = 0;
76413
76752
  rawState.loopDepth++;
76414
76753
  this._syncReturnDepth++;
76415
76754
  try {
76755
+ if (e0) this.syncShellArithmeticNonZero(e0, rawState, diagnosticLine);
76416
76756
  let iter = 0;
76417
76757
  while (true) {
76418
76758
  if (++iter > 4096) return void 0;
@@ -76447,6 +76787,15 @@ var Runtime = class _Runtime {
76447
76787
  } finally {
76448
76788
  this._syncReturnDepth--;
76449
76789
  rawState.loopDepth--;
76790
+ if (enableBatchRawWrite && batchTouched) {
76791
+ this._syncArithRawWriteOnly = false;
76792
+ this._syncArithTouched = void 0;
76793
+ for (const vName of batchTouched) {
76794
+ const vVal = rawState.variables[vName];
76795
+ if (typeof vVal === "string") monitor.publishStringVariable(vName, vVal);
76796
+ else if (vVal === void 0) delete monitor.proxy.variables[vName];
76797
+ }
76798
+ }
76450
76799
  }
76451
76800
  rawState.status = lastStatus;
76452
76801
  return lastStatus;
@@ -76458,10 +76807,10 @@ var Runtime = class _Runtime {
76458
76807
  items = pos.slice();
76459
76808
  } else if (command7.words.length === 1) {
76460
76809
  const w0 = command7.words[0];
76461
- const nonEmpty0 = w0.parts.filter((p) => !(p.kind === "text" && p.value === ""));
76462
- const p02 = nonEmpty0.length === 1 ? nonEmpty0[0] : void 0;
76810
+ items = this.tryExpandSyncArrayMembersWord(w0, rawState, io, diagnosticLine);
76811
+ const p02 = items ? void 0 : w0.parts.length === 1 ? w0.parts[0] : w0.parts.length === 2 && w0.parts[0].kind === "text" && w0.parts[0].value === "" ? w0.parts[1] : void 0;
76463
76812
  const sel0 = p02?.kind === "variable" ? getArraySelector(p02) : void 0;
76464
- if (p02?.kind === "variable" && p02.quoted && (sel0?.kind === "members" || sel0?.kind === "keys") && sel0.separator === "@") {
76813
+ if (p02?.kind === "variable" && p02.quoted && !p02.substring && (sel0?.kind === "members" || sel0?.kind === "keys") && sel0.separator === "@") {
76465
76814
  const b = monitor.store?.get(p02.name);
76466
76815
  items = [];
76467
76816
  if (b) {
@@ -76492,6 +76841,11 @@ var Runtime = class _Runtime {
76492
76841
  if (!items && command7.words) {
76493
76842
  items = [];
76494
76843
  for (let i = 0; i < command7.words.length; i++) {
76844
+ const expandedArr = this.tryExpandSyncArrayMembersWord(command7.words[i], rawState, io, diagnosticLine);
76845
+ if (expandedArr !== void 0) {
76846
+ for (let mIdx = 0; mIdx < expandedArr.length; mIdx++) items.push(expandedArr[mIdx]);
76847
+ continue;
76848
+ }
76495
76849
  let fv;
76496
76850
  try {
76497
76851
  fv = this.fastValueWord(command7.words[i], rawState, io, false, false, false, false, void 0, diagnosticLine);
@@ -76505,6 +76859,12 @@ var Runtime = class _Runtime {
76505
76859
  if (!items || items.length > 4096) return void 0;
76506
76860
  this.budget.tick();
76507
76861
  let lastStatus = 0;
76862
+ const enableBatchRawWrite = !this._syncArithRawWriteOnly && !hasActiveExtensions(rawState) && !hasActiveVariableAttributes(rawState) && !rawState.readonlyVariables?.size && !rawState.allexport;
76863
+ const batchTouched = enableBatchRawWrite ? /* @__PURE__ */ new Set() : void 0;
76864
+ if (enableBatchRawWrite) {
76865
+ this._syncArithRawWriteOnly = true;
76866
+ this._syncArithTouched = batchTouched;
76867
+ }
76508
76868
  rawState.loopDepth++;
76509
76869
  this._syncReturnDepth++;
76510
76870
  try {
@@ -76514,7 +76874,10 @@ var Runtime = class _Runtime {
76514
76874
  (0, yield_exports.runYieldCheckpoint)(this.signal);
76515
76875
  }
76516
76876
  this.budget.loop();
76517
- monitor.publishStringVariable(command7.name, items[idx]);
76877
+ if (this._syncArithRawWriteOnly && this._syncArithTouched) {
76878
+ rawState.variables[command7.name] = items[idx];
76879
+ this._syncArithTouched.add(command7.name);
76880
+ } else monitor.publishStringVariable(command7.name, items[idx]);
76518
76881
  if (rawState.allexport) rawState.exported.add(command7.name);
76519
76882
  const bodyRes = this.trySyncScript(command7.body, state, io, ignored);
76520
76883
  if (typeof bodyRes !== "number") return void 0;
@@ -76535,6 +76898,15 @@ var Runtime = class _Runtime {
76535
76898
  } finally {
76536
76899
  this._syncReturnDepth--;
76537
76900
  rawState.loopDepth--;
76901
+ if (enableBatchRawWrite && batchTouched) {
76902
+ this._syncArithRawWriteOnly = false;
76903
+ this._syncArithTouched = void 0;
76904
+ for (const vName of batchTouched) {
76905
+ const vVal = rawState.variables[vName];
76906
+ if (typeof vVal === "string") monitor.publishStringVariable(vName, vVal);
76907
+ else if (vVal === void 0) delete monitor.proxy.variables[vName];
76908
+ }
76909
+ }
76538
76910
  }
76539
76911
  rawState.status = lastStatus;
76540
76912
  return lastStatus;
@@ -76649,7 +77021,7 @@ var Runtime = class _Runtime {
76649
77021
  monitor.lazyPipeStatus = singleStatusZero;
76650
77022
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76651
77023
  } else {
76652
- elem0.text.shellValue = "0";
77024
+ this.setSyncPipeStatusCell(existing, "0");
76653
77025
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76654
77026
  }
76655
77027
  const finalStatus2 = pipeline.negate ? 1 : 0;
@@ -76728,7 +77100,7 @@ var Runtime = class _Runtime {
76728
77100
  monitor.lazyPipeStatus = singleStatusZero;
76729
77101
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76730
77102
  } else {
76731
- elem0.text.shellValue = "0";
77103
+ this.setSyncPipeStatusCell(existing, "0");
76732
77104
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76733
77105
  }
76734
77106
  const finalStatus = pipeline.negate ? 1 : 0;
@@ -76743,7 +77115,6 @@ var Runtime = class _Runtime {
76743
77115
  if (w0Plain === "return" && (rawState.functionDepth > 0 || rawState.sourceDepth) && !hasActiveExtensions(rawState) && !hasShellFunction(rawState, "return") && !rawState.extensions?.builtins.has("return") && !pipeline.negate && canMutatePipeStatus) {
76744
77116
  const retStatus = rawState.status;
76745
77117
  const statusStr = retStatus === 0 ? "0" : retStatus === 1 ? "1" : String(retStatus);
76746
- if (existing && elem0.text.bytes !== statusStr.length) return void 0;
76747
77118
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
76748
77119
  this.budget.tick();
76749
77120
  rawState.substitutionStatus = 0;
@@ -76754,7 +77125,7 @@ var Runtime = class _Runtime {
76754
77125
  monitor.lazyPipeStatus = retStatus === 0 ? singleStatusZero : retStatus === 1 ? singleStatusOne : [retStatus];
76755
77126
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76756
77127
  } else {
76757
- elem0.text.shellValue = statusStr;
77128
+ this.setSyncPipeStatusCell(existing, statusStr);
76758
77129
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76759
77130
  }
76760
77131
  rawState.status = retStatus;
@@ -76781,7 +77152,7 @@ var Runtime = class _Runtime {
76781
77152
  monitor.lazyPipeStatus = singleStatusZero;
76782
77153
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76783
77154
  } else {
76784
- elem0.text.shellValue = "0";
77155
+ this.setSyncPipeStatusCell(existing, "0");
76785
77156
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76786
77157
  }
76787
77158
  rawState.status = 0;
@@ -76806,7 +77177,7 @@ var Runtime = class _Runtime {
76806
77177
  monitor.lazyPipeStatus = rawStatus === 0 ? singleStatusZero : singleStatusOne;
76807
77178
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76808
77179
  } else {
76809
- elem0.text.shellValue = statusChar;
77180
+ this.setSyncPipeStatusCell(existing, statusChar);
76810
77181
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76811
77182
  }
76812
77183
  rawState.status = finalStatus;
@@ -76836,7 +77207,7 @@ var Runtime = class _Runtime {
76836
77207
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76837
77208
  }
76838
77209
  } else {
76839
- activeExisting.values.get(0).text.shellValue = "0";
77210
+ this.setSyncPipeStatusCell(activeExisting, "0");
76840
77211
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76841
77212
  }
76842
77213
  const finalStatus = pipeline.negate ? 1 : 0;
@@ -76847,9 +77218,10 @@ var Runtime = class _Runtime {
76847
77218
  }
76848
77219
  const assignment = this.assignment(w0);
76849
77220
  if (assignment) {
77221
+ const targetAssignName = resolveSyncNameref(rawState, assignment.name);
76850
77222
  const hasSubPart = assignment.value.parts.some((part) => part.kind === "substitution");
76851
- const existingArrAssign = store?.get(assignment.name);
76852
- if (assignment.name === "OPTIND" || assignment.name === "PIPESTATUS" || assignment.name.includes("[") || hasSubPart && !this.isPureSyncValueWord(assignment.value, rawState) || rawState.readonlyVariables?.has(assignment.name) || existingArrAssign && (assignment.append || hasUnpreparedLocal(rawState, assignment.name) || rawState.exported.has(assignment.name))) {
77223
+ const existingArrAssign = store?.get(targetAssignName);
77224
+ if (targetAssignName === "OPTIND" && (assignment.append || rawState.variableAttributes?.get("OPTIND")) || targetAssignName === "PIPESTATUS" || targetAssignName.includes("[") || hasSubPart && !this.isPureSyncValueWord(assignment.value, rawState) || rawState.readonlyVariables?.has(targetAssignName) || existingArrAssign && (assignment.append || hasUnpreparedLocal(rawState, targetAssignName) || rawState.exported.has(targetAssignName))) {
76853
77225
  return void 0;
76854
77226
  }
76855
77227
  if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
@@ -76860,8 +77232,13 @@ var Runtime = class _Runtime {
76860
77232
  return void 0;
76861
77233
  }
76862
77234
  if (typeof fastAssigned !== "string") return void 0;
77235
+ if (targetAssignName === "OPTIND") {
77236
+ const trimmedOptind = fastAssigned.trim();
77237
+ if (!/^[0-9]{1,6}$/.test(trimmedOptind)) return void 0;
77238
+ fastAssigned = String(Number(trimmedOptind));
77239
+ }
76863
77240
  if (existingArrAssign) {
76864
- if (!this.tryFastArraySubscriptWriteSync(rawState, assignment.name, "0", fastAssigned)) return void 0;
77241
+ if (!this.tryFastArraySubscriptWriteSync(rawState, targetAssignName, "0", fastAssigned)) return void 0;
76865
77242
  const restEpoch2 = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
76866
77243
  this.budget.tick();
76867
77244
  if (!hasSubPart) rawState.substitutionStatus = 0;
@@ -76878,7 +77255,7 @@ var Runtime = class _Runtime {
76878
77255
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76879
77256
  }
76880
77257
  } else {
76881
- activeExisting.values.get(0).text.shellValue = "0";
77258
+ this.setSyncPipeStatusCell(activeExisting, "0");
76882
77259
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76883
77260
  }
76884
77261
  const finalStatus2 = pipeline.negate ? 1 : 0;
@@ -76889,8 +77266,8 @@ var Runtime = class _Runtime {
76889
77266
  }
76890
77267
  let finalAssigned = fastAssigned;
76891
77268
  if (assignment.append) {
76892
- const curRaw = rawState.variables[assignment.name];
76893
- const curStr = curRaw === void 0 ? "" : monitor.values.get(assignment.name, curRaw) ?? curRaw;
77269
+ const curRaw = rawState.variables[targetAssignName];
77270
+ const curStr = curRaw === void 0 ? "" : monitor.values.get(targetAssignName, curRaw) ?? curRaw;
76894
77271
  if (typeof curStr !== "string") return void 0;
76895
77272
  finalAssigned = curStr + finalAssigned;
76896
77273
  if (finalAssigned.length > this.budget.limits.maxExpansionBytes || finalAssigned.length * 3 > this.budget.limits.maxExpansionBytes && shellValueByteLength(finalAssigned) > this.budget.limits.maxExpansionBytes) return void 0;
@@ -76898,19 +77275,23 @@ var Runtime = class _Runtime {
76898
77275
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
76899
77276
  this.budget.tick();
76900
77277
  if (!hasSubPart) rawState.substitutionStatus = 0;
76901
- if (assignment.name !== "_" && rawState.variables._ !== void 0) delete rawState.variables._;
77278
+ if (targetAssignName !== "_" && rawState.variables._ !== void 0) delete rawState.variables._;
76902
77279
  rawState.lastArgument = "";
76903
77280
  if (this._syncArithRawWriteOnly && this._syncArithTouched) {
76904
- rawState.variables[assignment.name] = finalAssigned;
76905
- this._syncArithTouched.add(assignment.name);
76906
- } else monitor.publishStringVariable(assignment.name, finalAssigned);
76907
- if (rawState.allexport) monitor.proxy.exported.add(assignment.name);
77281
+ rawState.variables[targetAssignName] = finalAssigned;
77282
+ this._syncArithTouched.add(targetAssignName);
77283
+ } else monitor.publishStringVariable(targetAssignName, finalAssigned);
77284
+ if (targetAssignName === "OPTIND") {
77285
+ rawState.variables.OPTIND = finalAssigned;
77286
+ this.syncGetopts(rawState);
77287
+ }
77288
+ if (rawState.allexport) monitor.proxy.exported.add(targetAssignName);
76908
77289
  if (io.assignmentDiagnosticContext) io.assignmentDiagnosticContext.name = void 0;
76909
77290
  if (!existing) {
76910
77291
  monitor.lazyPipeStatus = singleStatusZero;
76911
77292
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76912
77293
  } else {
76913
- elem0.text.shellValue = "0";
77294
+ this.setSyncPipeStatusCell(existing, "0");
76914
77295
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
76915
77296
  }
76916
77297
  const finalStatus = pipeline.negate ? 1 : 0;
@@ -76924,51 +77305,196 @@ var Runtime = class _Runtime {
76924
77305
  if (command7.words.length >= 1) {
76925
77306
  const w0Plain = command7.words[0].plain;
76926
77307
  if (this.budget.limits.maxExpansionFields === Infinity && command7.words.length >= 4 && w0Plain === "printf" && command7.words[1]?.plain === "-v" && command7.redirects.length === 0 && canMutatePipeStatus && (!pipeline.negate || ignored || !rawState.errexit) && !hasShellFunction(rawState, "printf") && !rawState.extensions?.builtins.has("printf")) {
76927
- const targetVar = command7.words[2]?.plain;
76928
77308
  const def = this.commands.get("printf");
76929
- if (targetVar && isShellIdentifier(targetVar) && targetVar !== "OPTIND" && targetVar !== "PIPESTATUS" && targetVar !== "_" && !rawState.readonlyVariables?.has(targetVar) && !store?.get(targetVar) && !monitor.hasOverlay(targetVar) && def && def.execute === printfCommand.execute && command7.words.length <= this.budget.maxExpansionFieldsSmi && this.arePureArgWords(command7.words, rawState)) {
76930
- fastSubScratchArgs.length = 0;
76931
- let allStrings = true;
76932
- try {
76933
- for (let i = 3; i < command7.words.length; i++) {
76934
- const v = this.fastValueWord(command7.words[i], rawState, io, true, false, false, true, void 0, diagnosticLine);
76935
- if (typeof v !== "string") {
77309
+ if (def && def.execute === printfCommand.execute && command7.words.length <= this.budget.maxExpansionFieldsSmi && this.arePureArgWords(command7.words, rawState)) {
77310
+ let targetSpec = command7.words[2]?.plain;
77311
+ if (targetSpec === void 0) {
77312
+ try {
77313
+ targetSpec = this.fastValueWord(command7.words[2], rawState, io, true, false, false, true, void 0, diagnosticLine);
77314
+ } catch {
77315
+ targetSpec = void 0;
77316
+ }
77317
+ }
77318
+ if (typeof targetSpec === "string") {
77319
+ const openBr = targetSpec.indexOf("[");
77320
+ const isSubTarget = openBr > 0 && targetSpec.endsWith("]") && targetSpec.length > openBr + 2;
77321
+ const rawTargetVar = isSubTarget ? targetSpec.slice(0, openBr) : targetSpec;
77322
+ const targetVar = isShellIdentifier(rawTargetVar) ? resolveSyncNameref(rawState, rawTargetVar) : "";
77323
+ if (targetVar && isShellIdentifier(targetVar) && targetVar !== "OPTIND" && targetVar !== "PIPESTATUS" && targetVar !== "_" && !rawState.readonlyVariables?.has(targetVar) && !monitor.hasOverlay(targetVar) && (isSubTarget || !store?.get(targetVar))) {
77324
+ fastSubScratchArgs.length = 0;
77325
+ let allStrings = true;
77326
+ try {
77327
+ for (let i = 3; i < command7.words.length; i++) {
77328
+ const v = this.fastValueWord(command7.words[i], rawState, io, true, false, false, true, void 0, diagnosticLine);
77329
+ if (typeof v !== "string") {
77330
+ allStrings = false;
77331
+ break;
77332
+ }
77333
+ fastSubScratchArgs.push(v);
77334
+ }
77335
+ } catch {
76936
77336
  allStrings = false;
76937
- break;
76938
77337
  }
76939
- fastSubScratchArgs.push(v);
77338
+ const lastArg = fastSubScratchArgs.length > 0 ? fastSubScratchArgs[fastSubScratchArgs.length - 1] : targetSpec;
77339
+ const formatted3 = allStrings ? tryFastPrintf(fastSubScratchArgs) : void 0;
77340
+ fastSubScratchArgs.length = 0;
77341
+ if (formatted3 !== void 0 && formatted3.length <= this.budget.limits.maxExpansionBytes && (formatted3.length * 3 <= this.budget.limits.maxExpansionBytes || shellValueByteLength(formatted3) <= this.budget.limits.maxExpansionBytes)) {
77342
+ let wroteTarget = true;
77343
+ if (isSubTarget) {
77344
+ let subKey = targetSpec.slice(openBr + 1, -1);
77345
+ const existingArr = store?.get(targetVar);
77346
+ if (!existingArr?.associative && !/^(?:0|[1-9][0-9]{0,8})$/.test(subKey)) {
77347
+ const syncTouched = this._syncArithRawWriteOnly ? this._syncArithTouched : void 0;
77348
+ const directIdx = resolveSimpleArithOperand(subKey.trim(), rawState, monitor, store, syncTouched);
77349
+ if (directIdx !== void 0 && directIdx >= 0) subKey = String(directIdx);
77350
+ else {
77351
+ const exprIdx = tryEvalSimpleExpandedArith(subKey.trim(), rawState, monitor, store, syncTouched);
77352
+ if (exprIdx !== void 0 && Number(exprIdx) >= 0) subKey = exprIdx;
77353
+ else wroteTarget = false;
77354
+ }
77355
+ }
77356
+ if (wroteTarget && !this.tryFastArraySubscriptWriteSync(rawState, targetVar, subKey, formatted3)) wroteTarget = false;
77357
+ } else if (this._syncArithRawWriteOnly && this._syncArithTouched) {
77358
+ rawState.variables[targetVar] = formatted3;
77359
+ this._syncArithTouched.add(targetVar);
77360
+ } else monitor.publishStringVariable(targetVar, formatted3);
77361
+ if (wroteTarget) {
77362
+ if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
77363
+ const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
77364
+ this.budget.tick();
77365
+ rawState.substitutionStatus = 0;
77366
+ if (rawState.variables._ !== void 0) delete rawState.variables._;
77367
+ rawState.lastArgument = lastArg;
77368
+ if (!isSubTarget && rawState.allexport) monitor.proxy.exported.add(targetVar);
77369
+ if (io.assignmentDiagnosticContext) io.assignmentDiagnosticContext.name = void 0;
77370
+ if (!existing) {
77371
+ monitor.lazyPipeStatus = singleStatusZero;
77372
+ monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77373
+ } else {
77374
+ this.setSyncPipeStatusCell(existing, "0");
77375
+ store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77376
+ }
77377
+ const finalStatus = pipeline.negate ? 1 : 0;
77378
+ rawState.status = finalStatus;
77379
+ monitor.epoch = restEpoch;
77380
+ if (store) store.epoch = restEpoch;
77381
+ return finalStatus;
77382
+ }
77383
+ }
76940
77384
  }
76941
- } catch {
76942
- allStrings = false;
76943
77385
  }
76944
- const lastArg = fastSubScratchArgs.length > 0 ? fastSubScratchArgs[fastSubScratchArgs.length - 1] : targetVar;
76945
- const formatted3 = allStrings ? tryFastPrintf(fastSubScratchArgs) : void 0;
76946
- fastSubScratchArgs.length = 0;
76947
- if (formatted3 !== void 0 && formatted3.length <= this.budget.limits.maxExpansionBytes && (formatted3.length * 3 <= this.budget.limits.maxExpansionBytes || shellValueByteLength(formatted3) <= this.budget.limits.maxExpansionBytes)) {
76948
- if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
76949
- const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
76950
- this.budget.tick();
76951
- rawState.substitutionStatus = 0;
76952
- if (rawState.variables._ !== void 0) delete rawState.variables._;
76953
- rawState.lastArgument = lastArg;
76954
- if (this._syncArithRawWriteOnly && this._syncArithTouched) {
76955
- rawState.variables[targetVar] = formatted3;
76956
- this._syncArithTouched.add(targetVar);
76957
- } else monitor.publishStringVariable(targetVar, formatted3);
76958
- if (rawState.allexport) monitor.proxy.exported.add(targetVar);
76959
- if (io.assignmentDiagnosticContext) io.assignmentDiagnosticContext.name = void 0;
76960
- if (!existing) {
76961
- monitor.lazyPipeStatus = singleStatusZero;
76962
- monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
76963
- } else {
76964
- elem0.text.shellValue = "0";
76965
- store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77386
+ }
77387
+ }
77388
+ if (command7.words.length >= 2 && command7.words.length <= 16 && (w0Plain === ":" || w0Plain === "true" || w0Plain === "false") && command7.redirects.length === 0 && !hasShellFunction(rawState, w0Plain) && !rawState.extensions?.builtins.has(w0Plain)) {
77389
+ const rawStatus = w0Plain === "false" ? 1 : 0;
77390
+ const statusChar = rawStatus === 0 ? "0" : "1";
77391
+ if (!canMutatePipeStatus && elem0.text.shellValue !== statusChar) return void 0;
77392
+ const finalStatus = pipeline.negate ? Number(rawStatus === 0) : rawStatus;
77393
+ if (finalStatus !== 0 && !ignored && rawState.errexit) return void 0;
77394
+ let lastArg = w0Plain;
77395
+ let argsOk = true;
77396
+ try {
77397
+ for (let i = 1; i < command7.words.length; i++) {
77398
+ const v = this.fastValueWord(command7.words[i], rawState, io, true, false, false, true, void 0, diagnosticLine);
77399
+ if (typeof v !== "string") {
77400
+ argsOk = false;
77401
+ break;
77402
+ }
77403
+ lastArg = v;
77404
+ }
77405
+ } catch {
77406
+ argsOk = false;
77407
+ }
77408
+ if (argsOk) {
77409
+ if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
77410
+ const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
77411
+ this.budget.tick();
77412
+ rawState.substitutionStatus = 0;
77413
+ if (rawState.variables._ !== void 0) delete rawState.variables._;
77414
+ rawState.lastArgument = lastArg;
77415
+ if (io.assignmentDiagnosticContext) io.assignmentDiagnosticContext.name = void 0;
77416
+ return this.finishSyncPipeStatus(rawState, monitor, monitor.store, monitor.store?.get("PIPESTATUS"), elem0, scope, finalStatus, restEpoch);
77417
+ }
77418
+ }
77419
+ if (command7.words.length >= 3 && command7.words.length <= 16 && w0Plain === "getopts" && command7.redirects.length === 0 && !hasShellFunction(rawState, "getopts") && !rawState.extensions?.builtins.has("getopts")) {
77420
+ const optVar = command7.words[2]?.plain;
77421
+ if (optVar && isShellIdentifier(optVar) && optVar !== "OPTIND" && optVar !== "PIPESTATUS" && optVar !== "_" && !rawState.readonlyVariables?.has(optVar) && !rawState.readonlyVariables?.has("OPTIND") && !rawState.readonlyVariables?.has("OPTARG") && !rawState.variableAttributes?.get(optVar) && !rawState.variableAttributes?.get("OPTIND") && !rawState.variableAttributes?.get("OPTARG") && !store?.get(optVar) && !store?.get("OPTIND") && !store?.get("OPTARG") && !monitor.hasOverlay(optVar)) {
77422
+ let optstring;
77423
+ let scanArgs;
77424
+ let lastArg = optVar;
77425
+ try {
77426
+ optstring = command7.words[1].plain ?? this.fastValueWord(command7.words[1], rawState, io, true, false, false, true, void 0, diagnosticLine);
77427
+ if (typeof optstring === "string") {
77428
+ if (command7.words.length === 3) {
77429
+ scanArgs = this._fastSubPositional ?? rawState.positional;
77430
+ } else if (command7.words.length === 4 && (() => {
77431
+ const ne = command7.words[3].parts.filter((p) => !(p.kind === "text" && p.value === ""));
77432
+ return ne.length === 1 && ne[0].kind === "variable" && ne[0].name === "@" && ne[0].quoted && !ne[0].length && !ne[0].substring && !ne[0].operator && !ne[0].transform && !ne[0].indirect && !ne[0].prefixNames && getArraySelector(ne[0]) === void 0;
77433
+ })()) {
77434
+ scanArgs = this._fastSubPositional ?? rawState.positional;
77435
+ if (scanArgs.length > 0) lastArg = scanArgs[scanArgs.length - 1];
77436
+ } else {
77437
+ const customArgs = [];
77438
+ let customOk = true;
77439
+ for (let i = 3; i < command7.words.length; i++) {
77440
+ const v = this.fastValueWord(command7.words[i], rawState, io, true, false, false, true, void 0, diagnosticLine);
77441
+ if (typeof v !== "string") {
77442
+ customOk = false;
77443
+ break;
77444
+ }
77445
+ customArgs.push(v);
77446
+ lastArg = v;
77447
+ }
77448
+ if (customOk) scanArgs = customArgs;
77449
+ }
77450
+ }
77451
+ } catch {
77452
+ scanArgs = void 0;
77453
+ }
77454
+ if (typeof optstring === "string" && optstring.startsWith(":") && scanArgs !== void 0) {
77455
+ rawState.getopts ??= cloneGetoptsBinding(rawState);
77456
+ const res = scanGetoptsSync(rawState.getopts.cursor, optstring, scanArgs);
77457
+ if (res !== void 0) {
77458
+ const rawStatus = res.status;
77459
+ const statusChar = rawStatus === 0 ? "0" : "1";
77460
+ if (canMutatePipeStatus || elem0.text.shellValue === statusChar) {
77461
+ const finalStatus = pipeline.negate ? Number(rawStatus === 0) : rawStatus;
77462
+ if (finalStatus === 0 || ignored || !rawState.errexit) {
77463
+ if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
77464
+ const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
77465
+ this.budget.tick();
77466
+ rawState.substitutionStatus = 0;
77467
+ if (rawState.variables._ !== void 0) delete rawState.variables._;
77468
+ rawState.lastArgument = lastArg;
77469
+ rawState.getopts.cursor = res.state;
77470
+ const optindStr = String(res.optind);
77471
+ if (this._syncArithRawWriteOnly && this._syncArithTouched) {
77472
+ rawState.variables.OPTIND = optindStr;
77473
+ this._syncArithTouched.add("OPTIND");
77474
+ } else monitor.publishStringVariable("OPTIND", optindStr);
77475
+ if (rawState.allexport) monitor.proxy.exported.add("OPTIND");
77476
+ if (res.argument.kind === "set") {
77477
+ if (this._syncArithRawWriteOnly && this._syncArithTouched) {
77478
+ rawState.variables.OPTARG = res.argument.value;
77479
+ this._syncArithTouched.add("OPTARG");
77480
+ } else monitor.publishStringVariable("OPTARG", res.argument.value);
77481
+ if (rawState.allexport) monitor.proxy.exported.add("OPTARG");
77482
+ } else {
77483
+ delete rawState.variables.OPTARG;
77484
+ rawState.exported.delete("OPTARG");
77485
+ if (this._syncArithRawWriteOnly && this._syncArithTouched) this._syncArithTouched.add("OPTARG");
77486
+ else monitor.values.invalidate("OPTARG");
77487
+ }
77488
+ if (this._syncArithRawWriteOnly && this._syncArithTouched) {
77489
+ rawState.variables[optVar] = res.option;
77490
+ this._syncArithTouched.add(optVar);
77491
+ } else monitor.publishStringVariable(optVar, res.option);
77492
+ if (rawState.allexport) monitor.proxy.exported.add(optVar);
77493
+ if (io.assignmentDiagnosticContext) io.assignmentDiagnosticContext.name = void 0;
77494
+ return this.finishSyncPipeStatus(rawState, monitor, monitor.store, monitor.store?.get("PIPESTATUS"), elem0, scope, finalStatus, restEpoch);
77495
+ }
77496
+ }
76966
77497
  }
76967
- const finalStatus = pipeline.negate ? 1 : 0;
76968
- rawState.status = finalStatus;
76969
- monitor.epoch = restEpoch;
76970
- if (store) store.epoch = restEpoch;
76971
- return finalStatus;
76972
77498
  }
76973
77499
  }
76974
77500
  }
@@ -77000,7 +77526,7 @@ var Runtime = class _Runtime {
77000
77526
  monitor.lazyPipeStatus = singleStatusZero;
77001
77527
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77002
77528
  } else {
77003
- elem0.text.shellValue = "0";
77529
+ this.setSyncPipeStatusCell(existing, "0");
77004
77530
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77005
77531
  }
77006
77532
  rawState.status = 0;
@@ -77084,7 +77610,7 @@ var Runtime = class _Runtime {
77084
77610
  monitor.lazyPipeStatus = singleStatusZero;
77085
77611
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77086
77612
  } else {
77087
- elem0.text.shellValue = "0";
77613
+ this.setSyncPipeStatusCell(existing, "0");
77088
77614
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77089
77615
  }
77090
77616
  const finalStatus = pipeline.negate ? 1 : 0;
@@ -77101,6 +77627,81 @@ var Runtime = class _Runtime {
77101
77627
  const w0 = command7.words[0];
77102
77628
  const w0Plain = w0.plain;
77103
77629
  const isHereStringRead = command7.words.length >= 2 && command7.redirects.length === 1 && command7.redirects[0].operator === "<<<" && !command7.redirects[0].move && !command7.redirects[0].document && (command7.redirects[0].descriptor === void 0 || command7.redirects[0].descriptor === 0);
77630
+ if ((w0Plain === "mapfile" || w0Plain === "readarray") && isHereStringRead && (command7.words.length === 2 || command7.words.length === 3) && command7.words[1]?.plain === "-t" && canMutatePipeStatus && !pipeline.negate && !rawState.allexport && !hasShellFunction(rawState, w0Plain) && !rawState.extensions?.builtins.has(w0Plain)) {
77631
+ const arrayTarget = command7.words[2]?.plain ?? "MAPFILE";
77632
+ if (!hasUnpreparedLocal(rawState, arrayTarget) && isShellIdentifier(arrayTarget) && !rawState.readonlyVariables?.has(arrayTarget) && !rawState.exported.has(arrayTarget) && !rawState.variableAttributes?.get(arrayTarget) && !controlNames.has(arrayTarget)) {
77633
+ let hv;
77634
+ try {
77635
+ hv = this.fastValueWord(command7.redirects[0].target, rawState, io, false, false, false, false, void 0, diagnosticLine);
77636
+ } catch {
77637
+ hv = void 0;
77638
+ }
77639
+ if (typeof hv === "string" && !hv.includes("\0") && hv.length + 1 < this.budget.limits.maxExpansionBytes && hv.length + 1 <= this.budget.limits.maxInputBytes) {
77640
+ const arrStore = monitor.store ?? requireArrays(rawState);
77641
+ let existingArrayBinding = arrStore.get(arrayTarget);
77642
+ if (!existingArrayBinding && rawState.variables[arrayTarget] === void 0 && !arrStore.watches.has(arrayTarget) && !monitor.hasOverlay(arrayTarget)) {
77643
+ const recTickets = arrStore.owner.charge({ generation: true, version: true, epoch: true, work: 8 });
77644
+ const recBinding = arrStore.takeRecycled(arrayTarget, false, true, recTickets);
77645
+ if (recBinding) {
77646
+ monitor.epoch = recTickets.epoch;
77647
+ existingArrayBinding = recBinding;
77648
+ } else {
77649
+ try {
77650
+ const created = IndexedBinding.create(arrStore.owner, false);
77651
+ const prepared = arrStore.prepareExistingName(arrayTarget, shellValueByteLength(arrayTarget), arrStore.owner, this.signal);
77652
+ if (prepared) {
77653
+ const initTickets = arrStore.owner.charge({ generation: true, version: true, epoch: true, work: 8 });
77654
+ arrStore.publish(arrayTarget, created, initTickets, prepared, false, arrStore.owner);
77655
+ monitor.epoch = initTickets.epoch;
77656
+ existingArrayBinding = created;
77657
+ } else {
77658
+ void created.release();
77659
+ }
77660
+ } catch {
77661
+ }
77662
+ }
77663
+ }
77664
+ if (existingArrayBinding && !existingArrayBinding.associative && existingArrayBinding.references === 1 && !arrStore.watches.has(arrayTarget) && !monitor.hasOverlay(arrayTarget)) {
77665
+ const lines3 = hv.split("\n");
77666
+ const fieldLen = lines3.length;
77667
+ if (fieldLen <= 256) {
77668
+ if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
77669
+ const tickets = arrStore.owner.charge({ generation: true, version: true, epoch: true, work: 8 + fieldLen * 4 });
77670
+ if (existingArrayBinding.values.size !== fieldLen || existingArrayBinding.maximum !== fieldLen - 1) {
77671
+ for (const k of [...existingArrayBinding.values.keys()]) {
77672
+ if (k >= fieldLen) existingArrayBinding.remove(k);
77673
+ }
77674
+ existingArrayBinding.maximum = fieldLen - 1;
77675
+ }
77676
+ for (let idx = 0; idx < fieldLen; idx++) {
77677
+ const val = lines3[idx];
77678
+ const byteLen = shellValueByteLength(val);
77679
+ const slot = existingArrayBinding.values.get(idx);
77680
+ if (slot && slot.text.references === 1 && slot.text.bytes === byteLen) {
77681
+ existingArrayBinding.owner.chargeWork(byteLen);
77682
+ slot.text.shellValue = val;
77683
+ } else {
77684
+ existingArrayBinding.owner.chargeWork(byteLen);
77685
+ const token = new OwnedText(val, byteLen, existingArrayBinding.owner.reserve({ payload: byteLen, metadata: 32, work: 4 }));
77686
+ existingArrayBinding.insert(idx, token);
77687
+ }
77688
+ }
77689
+ delete rawState.variables[arrayTarget];
77690
+ monitor.values.invalidate(arrayTarget);
77691
+ monitor.epoch = tickets.epoch;
77692
+ arrStore.revise(arrayTarget, existingArrayBinding, tickets);
77693
+ const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
77694
+ this.budget.tick();
77695
+ rawState.substitutionStatus = 0;
77696
+ if (rawState.variables._ !== void 0) delete rawState.variables._;
77697
+ rawState.lastArgument = command7.words[command7.words.length - 1].plain ?? arrayTarget;
77698
+ if (io.assignmentDiagnosticContext) io.assignmentDiagnosticContext.name = void 0;
77699
+ return this.finishSyncPipeStatus(rawState, monitor, monitor.store, monitor.store?.get("PIPESTATUS"), elem0, scope, 0, restEpoch);
77700
+ }
77701
+ }
77702
+ }
77703
+ }
77704
+ }
77104
77705
  if ((w0Plain === "read" || command7.words[1]?.plain === "read" && w0.parts[0]?.kind === "text" && w0.parts[0].value.startsWith("IFS=")) && canMutatePipeStatus && !pipeline.negate && !rawState.allexport && !hasShellFunction(rawState, "read") && !rawState.extensions?.builtins.has("read") && (command7.redirects.length === 0 ? io.stdin instanceof ShellInput : isHereStringRead)) {
77105
77706
  let ifs;
77106
77707
  let readWordIdx = 1;
@@ -77152,7 +77753,7 @@ var Runtime = class _Runtime {
77152
77753
  if (nextW.plain !== void 0) delimStr = nextW.plain;
77153
77754
  else {
77154
77755
  try {
77155
- const fv = this.fastValueWord(nextW, rawState, io, false, false, false, false, 0, diagnosticLine);
77756
+ const fv = this.fastValueWord(nextW, rawState, io, true, false, false, false, void 0, diagnosticLine);
77156
77757
  if (typeof fv === "string") delimStr = fv;
77157
77758
  } catch {
77158
77759
  delimStr = void 0;
@@ -77189,29 +77790,13 @@ var Runtime = class _Runtime {
77189
77790
  const varCount = command7.words.length - readWordIdx;
77190
77791
  let existingArrayBinding;
77191
77792
  if (arrayTarget !== void 0) {
77192
- if (hasUnpreparedLocals(rawState)) return void 0;
77793
+ if (hasUnpreparedLocal(rawState, arrayTarget)) return void 0;
77193
77794
  if (varCount !== 0 || !isShellIdentifier(arrayTarget) || rawState.readonlyVariables?.has(arrayTarget) || rawState.exported.has(arrayTarget) || rawState.variableAttributes?.get(arrayTarget) || controlNames.has(arrayTarget)) {
77194
77795
  simpleRead = false;
77195
77796
  } else {
77196
77797
  const arrStore = monitor.store ?? requireArrays(rawState);
77197
77798
  existingArrayBinding = arrStore.get(arrayTarget);
77198
- if (!existingArrayBinding && rawState.variables[arrayTarget] === void 0 && !arrStore.watches.has(arrayTarget) && !monitor.hasOverlay(arrayTarget)) {
77199
- try {
77200
- const created = IndexedBinding.create(arrStore.owner, false);
77201
- const nameByteLen = shellValueByteLength(arrayTarget);
77202
- const prepared = arrStore.prepareExistingName(arrayTarget, nameByteLen, arrStore.owner, this.signal);
77203
- if (prepared) {
77204
- const initTickets = arrStore.owner.charge({ generation: true, version: true, epoch: true, work: 8 });
77205
- arrStore.publish(arrayTarget, created, initTickets, prepared, false, arrStore.owner);
77206
- monitor.epoch = initTickets.epoch;
77207
- existingArrayBinding = created;
77208
- } else {
77209
- void created.release();
77210
- }
77211
- } catch {
77212
- }
77213
- }
77214
- if (!existingArrayBinding || existingArrayBinding.associative || existingArrayBinding.references !== 1 || arrStore.watches.has(arrayTarget) || monitor.hasOverlay(arrayTarget)) {
77799
+ if ((existingArrayBinding ? existingArrayBinding.associative || existingArrayBinding.references !== 1 : rawState.variables[arrayTarget] !== void 0) || arrStore.watches.has(arrayTarget) || monitor.hasOverlay(arrayTarget)) {
77215
77800
  simpleRead = false;
77216
77801
  }
77217
77802
  }
@@ -77250,6 +77835,31 @@ var Runtime = class _Runtime {
77250
77835
  }
77251
77836
  } else lineStr = io.stdin.tryReadSimpleRawAsciiLineSync(readDelim, raw);
77252
77837
  if (lineStr !== void 0) {
77838
+ if (arrayTarget !== void 0 && !existingArrayBinding) {
77839
+ const arrStore = monitor.store ?? requireArrays(rawState);
77840
+ if (!existingArrayBinding && rawState.variables[arrayTarget] === void 0 && !arrStore.watches.has(arrayTarget) && !monitor.hasOverlay(arrayTarget)) {
77841
+ const recTickets = arrStore.owner.charge({ generation: true, version: true, epoch: true, work: 8 });
77842
+ const recBinding = arrStore.takeRecycled(arrayTarget, false, true, recTickets);
77843
+ if (recBinding) {
77844
+ monitor.epoch = recTickets.epoch;
77845
+ existingArrayBinding = recBinding;
77846
+ } else try {
77847
+ const created = IndexedBinding.create(arrStore.owner, false);
77848
+ const nameByteLen = shellValueByteLength(arrayTarget);
77849
+ const prepared = arrStore.prepareExistingName(arrayTarget, nameByteLen, arrStore.owner, this.signal);
77850
+ if (prepared) {
77851
+ const initTickets = arrStore.owner.charge({ generation: true, version: true, epoch: true, work: 8 });
77852
+ arrStore.publish(arrayTarget, created, initTickets, prepared, false, arrStore.owner);
77853
+ monitor.epoch = initTickets.epoch;
77854
+ existingArrayBinding = created;
77855
+ } else {
77856
+ void created.release();
77857
+ }
77858
+ } catch {
77859
+ }
77860
+ }
77861
+ if (!existingArrayBinding) return void 0;
77862
+ }
77253
77863
  if (rawState.extensions && !rawState.extensions.eventDepth) publishCommandSpelling(rawState, commandSpelling(command7));
77254
77864
  if (arrayTarget !== void 0 && existingArrayBinding) {
77255
77865
  const isSep = (c) => {
@@ -77299,6 +77909,7 @@ var Runtime = class _Runtime {
77299
77909
  readArrayScratchFields.length = 0;
77300
77910
  delete rawState.variables[arrayTarget];
77301
77911
  monitor.epoch = tickets.epoch;
77912
+ existingArrayBinding.assigned = true;
77302
77913
  activeArrStore.revise(arrayTarget, existingArrayBinding, tickets);
77303
77914
  } catch (error) {
77304
77915
  readArrayScratchFields.length = 0;
@@ -77355,7 +77966,7 @@ var Runtime = class _Runtime {
77355
77966
  monitor.lazyPipeStatus = singleStatusZero;
77356
77967
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77357
77968
  } else {
77358
- elem0.text.shellValue = "0";
77969
+ this.setSyncPipeStatusCell(existing, "0");
77359
77970
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77360
77971
  }
77361
77972
  rawState.status = 0;
@@ -77513,7 +78124,7 @@ var Runtime = class _Runtime {
77513
78124
  monitor.lazyPipeStatus = singleStatusZero;
77514
78125
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77515
78126
  } else {
77516
- elem0.text.shellValue = "0";
78127
+ this.setSyncPipeStatusCell(existing, "0");
77517
78128
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77518
78129
  }
77519
78130
  rawState.status = 0;
@@ -77578,7 +78189,7 @@ var Runtime = class _Runtime {
77578
78189
  monitor.lazyPipeStatus = singleStatusZero;
77579
78190
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77580
78191
  } else {
77581
- elem0.text.shellValue = "0";
78192
+ this.setSyncPipeStatusCell(existing, "0");
77582
78193
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77583
78194
  }
77584
78195
  rawState.status = 0;
@@ -77646,6 +78257,7 @@ var Runtime = class _Runtime {
77646
78257
  if (isLocalScope) {
77647
78258
  let existingLocal = currentFrame.get(an);
77648
78259
  if (!existingLocal) {
78260
+ if (this._syncArithRawWriteOnly && this._syncArithTouched?.has(an)) monitor.values.invalidate(an);
77649
78261
  existingLocal = saveVariable(state, an);
77650
78262
  syncLocalArrayVariables.add(existingLocal);
77651
78263
  currentFrame.set(an, existingLocal);
@@ -77702,13 +78314,15 @@ var Runtime = class _Runtime {
77702
78314
  }
77703
78315
  return void 0;
77704
78316
  }
78317
+ const isNamerefDecl = command7.words[1]?.plain === "-n" && rawState.locals.length > 0 && command7.words.length >= 3;
78318
+ const isGlobalDecl = command7.words[1]?.plain === "-g" && (w0Plain === "declare" || w0Plain === "typeset") && command7.words.length >= 3;
77705
78319
  const parsedLocals = [];
77706
78320
  let allValidLocal = true;
77707
- for (let idx = 1; idx < command7.words.length; idx++) {
78321
+ for (let idx = isNamerefDecl || isGlobalDecl ? 2 : 1; idx < command7.words.length; idx++) {
77708
78322
  const wArg = command7.words[idx];
77709
78323
  const assignment = !getArrayAssignment(wArg) ? this.assignment(wArg) : void 0;
77710
78324
  if (assignment) {
77711
- if (assignment.name === "OPTIND" || assignment.name === "PIPESTATUS" || assignment.name.includes("[") || rawState.readonlyVariables?.has(assignment.name) || store?.get(assignment.name)) {
78325
+ if (!isNamerefDecl && rawState.variableAttributes?.get(assignment.name) || assignment.name === "OPTIND" && (assignment.append || rawState.variableAttributes?.get("OPTIND")) || assignment.name === "PIPESTATUS" || assignment.name.includes("[") || rawState.readonlyVariables?.has(assignment.name) || store?.get(assignment.name)) {
77712
78326
  allValidLocal = false;
77713
78327
  break;
77714
78328
  }
@@ -77722,16 +78336,43 @@ var Runtime = class _Runtime {
77722
78336
  allValidLocal = false;
77723
78337
  break;
77724
78338
  }
78339
+ if (assignment.name === "OPTIND") {
78340
+ const trimmedOptind = fastAssigned.trim();
78341
+ if (!/^[0-9]{1,6}$/.test(trimmedOptind)) {
78342
+ allValidLocal = false;
78343
+ break;
78344
+ }
78345
+ fastAssigned = String(Number(trimmedOptind));
78346
+ }
77725
78347
  parsedLocals.push({ name: assignment.name, val: fastAssigned, append: assignment.append, lastArg: `${assignment.name}=${fastAssigned}` });
77726
- } else if (wArg.plain && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(wArg.plain) && wArg.plain !== "OPTIND" && wArg.plain !== "PIPESTATUS" && !rawState.readonlyVariables?.has(wArg.plain) && !store?.get(wArg.plain)) {
78348
+ } else if (wArg.plain && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(wArg.plain) && (wArg.plain !== "OPTIND" || !rawState.variableAttributes?.get("OPTIND")) && wArg.plain !== "PIPESTATUS" && !rawState.readonlyVariables?.has(wArg.plain) && !store?.get(wArg.plain)) {
77727
78349
  parsedLocals.push({ name: wArg.plain, val: void 0, append: false, lastArg: wArg.plain });
77728
78350
  } else {
77729
78351
  allValidLocal = false;
77730
78352
  break;
77731
78353
  }
77732
78354
  }
78355
+ if (isNamerefDecl && allValidLocal) {
78356
+ for (let i = 0; i < parsedLocals.length; i++) {
78357
+ const it = parsedLocals[i];
78358
+ if (!it.val || it.append || !isShellIdentifier(it.val) || it.val === it.name || rawState.variableAttributes?.get(it.val)) {
78359
+ allValidLocal = false;
78360
+ break;
78361
+ }
78362
+ }
78363
+ }
78364
+ if (isGlobalDecl && allValidLocal && rawState.locals.length > 0) {
78365
+ for (let i = 0; i < parsedLocals.length; i++) {
78366
+ const it = parsedLocals[i];
78367
+ if (rawState.locals.some((f) => f.has(it.name))) {
78368
+ allValidLocal = false;
78369
+ break;
78370
+ }
78371
+ }
78372
+ }
77733
78373
  if (allValidLocal && parsedLocals.length > 0) {
77734
- const locals = rawState.locals.length > 0 ? rawState.locals[rawState.locals.length - 1] : void 0;
78374
+ if ((rawState.locals.length === 0 || isGlobalDecl) && parsedLocals.some((item) => item.val === void 0 && !rawState.variableAttributes?.has(item.name))) return void 0;
78375
+ const locals = !isGlobalDecl && rawState.locals.length > 0 ? rawState.locals[rawState.locals.length - 1] : void 0;
77735
78376
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
77736
78377
  this.budget.tick();
77737
78378
  rawState.substitutionStatus = 0;
@@ -77742,7 +78383,7 @@ var Runtime = class _Runtime {
77742
78383
  if (locals && isNewLocal) {
77743
78384
  if (this._syncArithRawWriteOnly && this._syncArithTouched) {
77744
78385
  const curVal = this._syncArithTouched.has(item.name) ? rawState.variables[item.name] : rawState.variables[item.name] === void 0 ? void 0 : monitor.values.get(item.name, rawState.variables[item.name]) ?? rawState.variables[item.name];
77745
- locals.set(item.name, { attributes: void 0, value: typeof curVal === "string" ? curVal : void 0, exported: false, readOnly: false });
78386
+ locals.set(item.name, { attributes: void 0, value: typeof curVal === "string" ? curVal : void 0, exported: rawState.exported.has(item.name), readOnly: false, ...item.name === "OPTIND" ? { getopts: cloneGetoptsBinding(rawState) } : {} });
77746
78387
  } else locals.set(item.name, saveVariable(state, item.name));
77747
78388
  delete rawState.variables[item.name];
77748
78389
  if (this._syncArithRawWriteOnly && this._syncArithTouched) this._syncArithTouched.add(item.name);
@@ -77755,16 +78396,25 @@ var Runtime = class _Runtime {
77755
78396
  rawState.variables[item.name] = finalVal;
77756
78397
  this._syncArithTouched.add(item.name);
77757
78398
  } else monitor.publishStringVariable(item.name, finalVal);
78399
+ if (item.name === "OPTIND") {
78400
+ rawState.variables.OPTIND = finalVal;
78401
+ this.syncGetopts(rawState);
78402
+ }
77758
78403
  if (rawState.allexport) monitor.proxy.exported.add(item.name);
77759
78404
  rawState.lastArgument = `${item.name}=${finalVal}`;
77760
- if (!rawState.variableAttributes?.has(item.name)) {
78405
+ if (isNamerefDecl) {
77761
78406
  rawState.variableAttributes ??= /* @__PURE__ */ new Map();
77762
- rawState.variableAttributes.set(item.name, "");
77763
- }
78407
+ rawState.variableAttributes.set(item.name, "n");
78408
+ } else if (isNewLocal && rawState.variableAttributes?.has(item.name)) rawState.variableAttributes.delete(item.name);
77764
78409
  } else {
77765
- if (!rawState.variableAttributes?.has(item.name)) {
77766
- rawState.variableAttributes ??= /* @__PURE__ */ new Map();
77767
- rawState.variableAttributes.set(item.name, "");
78410
+ if (item.name === "OPTIND") this.syncGetopts(rawState);
78411
+ if (!locals) {
78412
+ if (!rawState.variableAttributes?.has(item.name)) {
78413
+ rawState.variableAttributes ??= /* @__PURE__ */ new Map();
78414
+ rawState.variableAttributes.set(item.name, "");
78415
+ }
78416
+ } else if (isNewLocal && rawState.variableAttributes?.has(item.name)) {
78417
+ rawState.variableAttributes.delete(item.name);
77768
78418
  }
77769
78419
  rawState.lastArgument = item.lastArg;
77770
78420
  }
@@ -77778,7 +78428,7 @@ var Runtime = class _Runtime {
77778
78428
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77779
78429
  }
77780
78430
  } else {
77781
- elem0.text.shellValue = "0";
78431
+ this.setSyncPipeStatusCell(existing, "0");
77782
78432
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77783
78433
  }
77784
78434
  rawState.status = 0;
@@ -77801,7 +78451,6 @@ var Runtime = class _Runtime {
77801
78451
  if (fastArg.length > 0 && fastArg.length <= 15 && /^-?[0-9]+$/.test(fastArg)) {
77802
78452
  const retStatus = (Number(fastArg) % 256 + 256) % 256;
77803
78453
  const statusStr = retStatus === 0 ? "0" : retStatus === 1 ? "1" : String(retStatus);
77804
- if (existing && elem0.text.bytes !== statusStr.length) return void 0;
77805
78454
  const prevStatus = rawState.status;
77806
78455
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
77807
78456
  this.budget.tick();
@@ -77813,7 +78462,7 @@ var Runtime = class _Runtime {
77813
78462
  monitor.lazyPipeStatus = retStatus === 0 ? singleStatusZero : retStatus === 1 ? singleStatusOne : [retStatus];
77814
78463
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77815
78464
  } else {
77816
- elem0.text.shellValue = statusStr;
78465
+ this.setSyncPipeStatusCell(existing, statusStr);
77817
78466
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77818
78467
  }
77819
78468
  rawState.status = retStatus;
@@ -77851,9 +78500,13 @@ var Runtime = class _Runtime {
77851
78500
  } else {
77852
78501
  const savedPos = rawState.positional;
77853
78502
  rawState.positional = fnArgs;
78503
+ rawState.locals.push(/* @__PURE__ */ new Map());
78504
+ rawState.functionDepth++;
77854
78505
  try {
77855
78506
  canSyncFn = this.canSyncScriptCompound(fnBody.body, rawState, 1);
77856
78507
  } finally {
78508
+ rawState.functionDepth--;
78509
+ rawState.locals.pop();
77857
78510
  rawState.positional = savedPos;
77858
78511
  }
77859
78512
  }
@@ -77941,9 +78594,13 @@ var Runtime = class _Runtime {
77941
78594
  rawState.locals.pop();
77942
78595
  rawState.functionNames?.shift();
77943
78596
  for (const [k, previous] of locals) {
77944
- if (this._syncArithRawWriteOnly && this._syncArithTouched && !syncLocalArrayVariables.has(previous) && !previous.heldValue && !previous.attributes && !previous.exported && !previous.readOnly && k !== "OPTIND") {
78597
+ if (this._syncArithRawWriteOnly && this._syncArithTouched && !syncLocalArrayVariables.has(previous) && !previous.heldValue && !previous.attributes && !previous.exported && !previous.readOnly) {
77945
78598
  if (previous.value === void 0) delete rawState.variables[k];
77946
78599
  else rawState.variables[k] = (0, value_exports.shellValueText)(previous.value);
78600
+ if (k === "OPTIND" && previous.getopts) {
78601
+ rawState.getopts = { integer: previous.getopts.integer, cursor: cloneGetoptsState(previous.getopts.cursor) };
78602
+ }
78603
+ rawState.variableAttributes?.delete(k);
77947
78604
  this._syncArithTouched.add(k);
77948
78605
  } else tryRestoreVariableSync(state, k, previous);
77949
78606
  }
@@ -77959,8 +78616,8 @@ var Runtime = class _Runtime {
77959
78616
  monitor.lazyPipeStatus = exitStatus === 0 ? singleStatusZero : exitStatus === 1 ? singleStatusOne : [exitStatus];
77960
78617
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
77961
78618
  }
77962
- } else if (activeExisting.values.get(0).text.bytes === statusStr.length) {
77963
- activeExisting.values.get(0).text.shellValue = statusStr;
78619
+ } else {
78620
+ this.setSyncPipeStatusCell(activeExisting, statusStr);
77964
78621
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
77965
78622
  }
77966
78623
  rawState.status = exitStatus;
@@ -78013,7 +78670,7 @@ var Runtime = class _Runtime {
78013
78670
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
78014
78671
  }
78015
78672
  } else {
78016
- activeExisting.values.get(0).text.shellValue = "0";
78673
+ this.setSyncPipeStatusCell(activeExisting, "0");
78017
78674
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
78018
78675
  }
78019
78676
  rawState.status = 0;
@@ -78042,7 +78699,7 @@ var Runtime = class _Runtime {
78042
78699
  rawState.depth++;
78043
78700
  let evalStatus;
78044
78701
  try {
78045
- evalStatus = this.trySyncScript(cachedUnit.script, state, io, Boolean(ignored));
78702
+ evalStatus = this.trySyncScript(cachedUnit.script, state, { ...io, diagnosticOffset: (diagnosticLine ?? 1) - 1, functionCommandLines: void 0, assignmentDiagnosticContext: { name: "eval" } }, Boolean(ignored));
78046
78703
  } finally {
78047
78704
  rawState.depth--;
78048
78705
  }
@@ -78058,7 +78715,7 @@ var Runtime = class _Runtime {
78058
78715
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
78059
78716
  }
78060
78717
  } else {
78061
- activeExisting.values.get(0).text.shellValue = "0";
78718
+ this.setSyncPipeStatusCell(activeExisting, "0");
78062
78719
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
78063
78720
  }
78064
78721
  }
@@ -78129,7 +78786,7 @@ var Runtime = class _Runtime {
78129
78786
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
78130
78787
  }
78131
78788
  } else {
78132
- elem0.text.shellValue = statusChar;
78789
+ this.setSyncPipeStatusCell(existing, statusChar);
78133
78790
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
78134
78791
  }
78135
78792
  const finalStatus = pipeline.negate ? Number(fastPred === 0) : fastPred;
@@ -78189,7 +78846,7 @@ var Runtime = class _Runtime {
78189
78846
  } else {
78190
78847
  const idxNum = /^(?:0|[1-9][0-9]{0,8})$/.test(subExpr) ? Number(subExpr) : resolveSimpleArithOperand(subExpr, rawState, monitor, arrStore, this._syncArithRawWriteOnly ? this._syncArithTouched : void 0);
78191
78848
  if (idxNum !== void 0 && idxNum >= 0 && idxNum <= 2147483647) {
78192
- if (!curB && rawState.variables[arrName] === void 0 && !arrStore.watches.has(arrName) && !monitor.hasOverlay(arrName)) {
78849
+ if (!curB && !hasUnpreparedLocal(rawState, arrName) && rawState.variables[arrName] === void 0 && !arrStore.watches.has(arrName) && !monitor.hasOverlay(arrName)) {
78193
78850
  const created = IndexedBinding.create(arrStore.owner, false);
78194
78851
  const prepared = arrStore.prepareExistingName(arrName, shellValueByteLength(arrName), arrStore.owner, this.signal);
78195
78852
  if (prepared) {
@@ -78226,7 +78883,7 @@ var Runtime = class _Runtime {
78226
78883
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
78227
78884
  }
78228
78885
  } else {
78229
- activeExisting.values.get(0).text.shellValue = "0";
78886
+ this.setSyncPipeStatusCell(activeExisting, "0");
78230
78887
  activeStore.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
78231
78888
  }
78232
78889
  const finalStatus = pipeline.negate ? 1 : 0;
@@ -78299,7 +78956,7 @@ var Runtime = class _Runtime {
78299
78956
  monitor.lazyPipeStatus = singleStatusZero;
78300
78957
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
78301
78958
  } else {
78302
- elem0.text.shellValue = "0";
78959
+ this.setSyncPipeStatusCell(existing, "0");
78303
78960
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
78304
78961
  }
78305
78962
  const finalStatus = pipeline.negate ? 1 : 0;
@@ -78344,7 +79001,7 @@ var Runtime = class _Runtime {
78344
79001
  if (rawState.nounset && part.name >= "1" && part.name <= "9" && rawState.positional[part.name.charCodeAt(0) - 49] === void 0) return false;
78345
79002
  continue;
78346
79003
  }
78347
- if (part.prefixNames || part.specialParameter || part.transform || part.name === "@" || part.name === "*" || part.name === "PIPESTATUS" || part.name === "LINENO" || part.name === "_" || part.name === "FUNCNAME" || !isShellIdentifier(part.name)) {
79004
+ if (part.prefixNames || part.specialParameter || part.transform || part.name === "@" || part.name === "*" || part.name === "PIPESTATUS" || part.name === "LINENO" || part.name === "_" || part.name === "FUNCNAME" || part.name === "DIRSTACK" || !isShellIdentifier(part.name)) {
78348
79005
  return false;
78349
79006
  }
78350
79007
  if (part.indirect) {
@@ -78397,8 +79054,9 @@ var Runtime = class _Runtime {
78397
79054
  }
78398
79055
  } else if (part.operator === "^" || part.operator === "^^" || part.operator === "," || part.operator === ",,") {
78399
79056
  if (part.alternate && part.alternate.parts.length > 0) return false;
78400
- } else if (part.operator === "-" || part.operator === ":-" || part.operator === "+" || part.operator === ":+") {
79057
+ } else if (part.operator === "-" || part.operator === ":-" || part.operator === "+" || part.operator === ":+" || part.operator === "=" || part.operator === ":=") {
78401
79058
  if (!part.alternate || !part.alternate.parts.every((p) => p.kind === "text" || p.kind === "arithmetic" || p.kind === "variable" && !p.operator && !p.substring)) return false;
79059
+ if ((part.operator === "=" || part.operator === ":=") && (!isShellIdentifier(part.name) || part.name === "OPTIND" || part.name === "PIPESTATUS" || part.name === "_" || rawState.readonlyVariables?.has(part.name) || rawState.variableAttributes?.get(part.name) || stateMonitor(rawState)?.store?.get(part.name))) return false;
78402
79060
  } else if (part.operator === "#" || part.operator === "##" || part.operator === "%" || part.operator === "%%") {
78403
79061
  if (!part.alternate || part.alternate.parts.length === 0) return false;
78404
79062
  const q0 = part.alternate.parts[0].quoted;
@@ -78427,7 +79085,15 @@ var Runtime = class _Runtime {
78427
79085
  if (!collectPureReadOnlySmiNames(part.expression, names)) {
78428
79086
  if (rawState.nounset) return false;
78429
79087
  const em = SIMPLE_EXPANDED_ARITH_RE.exec(part.source);
78430
- if (!em || (em[2] === "/" || em[2] === "%") && !(em[3] && /^[1-9][0-9]*$/.test(em[3]))) return false;
79088
+ if (!em || (em[2] === "/" || em[2] === "%") && !(em[3] && /^[1-9][0-9]*$/.test(em[3]))) {
79089
+ if (part.source.includes("<<") || part.source.includes(">>") || part.source.includes("**") || /[/%](?!\s*[1-9][0-9]*\b)/.test(part.source)) return false;
79090
+ try {
79091
+ const expW = parseArithmeticExpansion(part.source, this.budget.parsing, false, 0, void 0, rawState.extensions?.syntax);
79092
+ if (!this.isPureSyncValueWord(expW, rawState)) return false;
79093
+ } catch {
79094
+ return false;
79095
+ }
79096
+ }
78431
79097
  }
78432
79098
  continue;
78433
79099
  }
@@ -78749,7 +79415,7 @@ var Runtime = class _Runtime {
78749
79415
  monitor.lazyPipeStatus = singleStatusZero;
78750
79416
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
78751
79417
  } else {
78752
- elem0.text.shellValue = "0";
79418
+ this.setSyncPipeStatusCell(existing, "0");
78753
79419
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
78754
79420
  }
78755
79421
  }
@@ -79101,7 +79767,7 @@ var Runtime = class _Runtime {
79101
79767
  monitor.lazyPipeStatus = singleStatusZero;
79102
79768
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
79103
79769
  } else {
79104
- elem0.text.shellValue = "0";
79770
+ this.setSyncPipeStatusCell(existing, "0");
79105
79771
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
79106
79772
  }
79107
79773
  }
@@ -79315,7 +79981,7 @@ var Runtime = class _Runtime {
79315
79981
  monitor.lazyPipeStatus = singleStatusZero;
79316
79982
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
79317
79983
  } else {
79318
- elem0.text.shellValue = "0";
79984
+ this.setSyncPipeStatusCell(existing, "0");
79319
79985
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
79320
79986
  }
79321
79987
  }
@@ -81604,7 +82270,7 @@ ${s1}
81604
82270
  previous.set(assignment.name, saved);
81605
82271
  const existingArray = arrayStore(state)?.get(assignment.name);
81606
82272
  const canSkipTypedScalarOverlay = !existingArray && words[0] === "read" && !state.functions.has("read") && !state.extensions?.builtins.has("read") && !words.some((w) => w.startsWith("-a") || w.startsWith("-") && !w.startsWith("--") && w.includes("a"));
81607
- if (words.length && !canSkipTypedScalarOverlay && (guestArrays(state) || assignment.name === "PIPESTATUS" && existingArray)) {
82273
+ if (words.length && !canSkipTypedScalarOverlay && (guestArrays(state) || existingArray)) {
81608
82274
  const store = requireArrays(state);
81609
82275
  await this.prepareVariable(state, assignment.name, saved, !existingArray);
81610
82276
  if (existingArray) {
@@ -81626,15 +82292,28 @@ ${s1}
81626
82292
  overlayOpen = true;
81627
82293
  }
81628
82294
  if (inlineInput || (state.profile === "sh" || !words.length) && assignments2.some((assignment) => state.readonlyVariables?.has(assignment.name))) await assign();
81629
- if (inlineInput && functionCommand && previous?.size) {
82295
+ if (inlineInput && previous?.size) {
81630
82296
  if (stateMonitor(state)?.lazyPipeStatus !== void 0) stateMonitor(state).activate(true);
81631
82297
  const redirectState = tryCloneStateSync(state) ?? await cloneState(state, this.signal);
81632
82298
  const variables = redirectState.variables;
81633
82299
  const redirectAssignments = /* @__PURE__ */ new Map();
81634
82300
  for (const [name2, saved] of previous) {
81635
82301
  redirectAssignments.set(name2, stateMonitor(state).values.get(name2, state.variables[name2]));
82302
+ if (saved.exported) redirectState.exported.add(name2);
82303
+ else redirectState.exported.delete(name2);
81636
82304
  if (saved.value === void 0) delete variables[name2];
81637
82305
  else publishVariable(redirectState, name2, saved.heldValue?.value ?? saved.value);
82306
+ const binding = typedSavedVariables.get(saved)?.binding;
82307
+ if (binding) {
82308
+ const store = requireArrays(redirectState);
82309
+ const prepared = await store.prepareName(name2, store.owner, this.signal);
82310
+ const tickets = store.tickets(name2);
82311
+ try {
82312
+ await store.publish(name2, binding.retain(), tickets, prepared);
82313
+ } finally {
82314
+ tickets.release();
82315
+ }
82316
+ }
81638
82317
  }
81639
82318
  redirectState.redirectAssignments = redirectAssignments;
81640
82319
  const savedIndex = previous.get("OPTIND");
@@ -81650,7 +82329,7 @@ ${s1}
81650
82329
  }
81651
82330
  const epoch2 = stateMonitor(state)?.epoch;
81652
82331
  try {
81653
- io = await this.redirect(command7.redirects, redirectState, io, inputs, outputs, false, true, false, command7.line ?? 1);
82332
+ io = await this.redirect(command7.redirects, redirectState, io, inputs, outputs, isolatedInlineInput, !isolatedInlineInput, false, command7.line ?? 1);
81654
82333
  if (parentStore && stateMonitor(state).epoch !== epoch2) throw new ArrayFailure("stale state snapshot");
81655
82334
  } finally {
81656
82335
  try {
@@ -81671,6 +82350,12 @@ ${s1}
81671
82350
  if (!previous.has(name2)) publishVariable(state, name2, stateMonitor(redirectState).values.get(name2, value2));
81672
82351
  }
81673
82352
  for (const [name2, saved] of previous) {
82353
+ const typed = typedSavedVariables.get(saved);
82354
+ const binding = arrayStore(redirectState)?.get(name2);
82355
+ if (typed && binding !== typed.binding) {
82356
+ typedSavedVariables.set(saved, { ...typed, binding: binding?.retain() });
82357
+ await typed.binding?.release();
82358
+ }
81674
82359
  saved.value = variables[name2];
81675
82360
  const value2 = stateMonitor(redirectState).values.get(name2, saved.value ?? "");
81676
82361
  const held = saved.value === void 0 ? void 0 : stateMonitor(state).values.scope.hold(value2);
@@ -85429,6 +86114,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
85429
86114
  seen.add(name2);
85430
86115
  names.push(name2);
85431
86116
  };
86117
+ await consider("DIRSTACK", true);
86118
+ if (state.functionNames?.length) await consider("FUNCNAME", true);
85432
86119
  for (const name2 in state.variables) if (Object.hasOwn(state.variables, name2)) await consider(name2, state.variables[name2] !== void 0);
85433
86120
  if (store) for (const [name2, entry] of store.bindings) await consider(name2, entry.binding.assigned);
85434
86121
  for (const frame of state.locals) for (const [name2, saved] of frame) {
@@ -85495,7 +86182,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
85495
86182
  setArraySelector(resolved2, { kind: "element", index: { decimal: (0, value_exports.shellValueText)(value2), word: { offset: word.offset, parts: [{ kind: "text", value: (0, value_exports.shellValueText)(value2), quoted: true, ...typeof value2 === "string" ? {} : { byteValue: value2 } }] } } });
85496
86183
  return resolved2;
85497
86184
  }
85498
- const maximum = binding?.maximum ?? (state.variables[part.name] === void 0 ? -1 : 0);
86185
+ const maximum = binding?.maximum ?? (part.name === "FUNCNAME" && state.variables.FUNCNAME === void 0 ? (state.functionNames?.length ?? 0) - 1 : state.variables[part.name] === void 0 ? -1 : 0);
85499
86186
  const index = await this.arrayIndex(binding, selector.index, state, io, store.owner, false, maximum);
85500
86187
  const resolved = { ...part };
85501
86188
  copyArraySelector(part, resolved);
@@ -85553,8 +86240,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
85553
86240
  const selector2 = getArraySelector(part);
85554
86241
  if (selector2?.kind === "members" || part.name === "@" || part.name === "*") {
85555
86242
  const members = selector2 ? await this.arrayMembers(part.name, state, io, part.keys) : this.positionalValues(state);
85556
- const ifs = state.variables.IFS ?? " ";
85557
- const separator = selector2?.kind === "members" && !split3 && (selector2.separator === "@" || !part.quoted) ? " " : ifs.length ? String.fromCodePoint(ifs.codePointAt(0)) : "";
86243
+ const separator = !split3 && (selector2?.kind === "members" ? selector2.separator === "@" : part.name === "@") ? " " : this.ifsSeparator(state, io);
85558
86244
  const fragments2 = [];
85559
86245
  let bytes3 = 0;
85560
86246
  for (const member of members) {
@@ -85932,7 +86618,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
85932
86618
  }
85933
86619
  if (part.length) return String(binding?.values.size ?? (part.name === "FUNCNAME" && state.variables.FUNCNAME === void 0 ? state.functionNames?.length ?? 0 : state.variables[part.name] === void 0 ? 0 : 1));
85934
86620
  const values = await this.arrayMembers(part.name, state, io, selector.kind === "keys" || part.keys === true, part.substring);
85935
- const space = (selector.kind === "keys" || part.keys === true) && state.extensions?.syntax?.arrayKeys ? Boolean(hereDocument || (selector.separator === "@" ? !part.quoted && !split3 || state.variables.IFS === "" : !part.quoted && split3 && state.variables.IFS === "")) : !split3 && (selector.separator === "@" || !part.quoted);
86621
+ const space = selector.kind === "keys" || part.keys === true ? Boolean(hereDocument || (selector.separator === "@" ? !part.quoted && !split3 || state.variables.IFS === "" : !part.quoted && split3 && state.variables.IFS === "")) : !split3 && selector.separator === "@";
85936
86622
  return this.arrayJoin(store.owner, values, space ? " " : this.ifsSeparator(state, io));
85937
86623
  }
85938
86624
  if (part.substring && (part.name === "@" || part.name === "*")) {
@@ -85941,7 +86627,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
85941
86627
  return (0, value_exports.concatShellValues)(values.flatMap((entry, index) => index ? [separator, entry] : [entry]), io[valueScope]);
85942
86628
  }
85943
86629
  const namerefName = part.indirect && state.variableAttributes?.get(part.name)?.includes("n");
85944
- let value2 = namerefName ? state.variables[part.name] === void 0 ? void 0 : this.referenceName(state, part.name) : part.specialParameter ? specialValue === void 0 ? void 0 : (0, value_exports.shellValueText)(specialValue) : part.name === "?" ? String(state.status) : part.name === "-" ? `${state.allexport ? "a" : ""}${state.errexit ? "e" : ""}${state.noglob ? "f" : ""}${state.noexec ? "n" : ""}${state.nounset ? "u" : ""}${state.braceexpand !== false ? "B" : ""}${state.noclobber ? "C" : ""}` : part.name === "#" ? String(state.positional.length) : part.name === "@" || part.name === "*" ? state.positional.join(hereString && (part.name === "@" || !part.quoted) ? " " : Array.from(state.variables.IFS ?? " ")[0] ?? "") : /^0+$/u.test(part.name) ? state.arg0 ?? "virtual-bash" : /^\d+$/u.test(part.name) ? state.positional[Number(part.name) - 1] : part.name === "LINENO" ? state.extensions ? String(io.diagnosticLine ?? part.line ?? 1) : state.variables.LINENO ?? String(io.diagnosticLine ?? part.line ?? 1) : this.variable(state, part.name);
86630
+ let value2 = namerefName ? state.variables[part.name] === void 0 ? void 0 : this.referenceName(state, part.name) : part.specialParameter ? specialValue === void 0 ? void 0 : (0, value_exports.shellValueText)(specialValue) : part.name === "?" ? String(state.status) : part.name === "-" ? `${state.allexport ? "a" : ""}${state.errexit ? "e" : ""}${state.noglob ? "f" : ""}${state.noexec ? "n" : ""}${state.nounset ? "u" : ""}${state.braceexpand !== false ? "B" : ""}${state.noclobber ? "C" : ""}` : part.name === "#" ? String(state.positional.length) : part.name === "@" || part.name === "*" ? state.positional.join(part.name === "@" && !split3 || hereString && (part.name === "@" || !part.quoted) ? " " : Array.from(state.variables.IFS ?? " ")[0] ?? "") : /^0+$/u.test(part.name) ? state.arg0 ?? "virtual-bash" : /^\d+$/u.test(part.name) ? state.positional[Number(part.name) - 1] : part.name === "LINENO" ? state.extensions ? String(io.diagnosticLine ?? part.line ?? 1) : state.variables.LINENO ?? String(io.diagnosticLine ?? part.line ?? 1) : this.variable(state, part.name);
85945
86631
  let retained = part.specialParameter ? specialValue : value2;
85946
86632
  if (value2 !== void 0 && !namerefName) {
85947
86633
  if (/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(part.name)) {
@@ -85952,7 +86638,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
85952
86638
  } else if (/^0+$/u.test(part.name)) retained = stateMonitor(state)?.positionals.get(zeroPositionKey, value2) ?? value2;
85953
86639
  else if (/^[0-9]+$/u.test(part.name)) retained = stateMonitor(state)?.positionals.get(String(Number(part.name) - 1), value2) ?? value2;
85954
86640
  else if (part.name === "@" || part.name === "*") {
85955
- const separator = hereString && (part.name === "@" || !part.quoted) ? " " : this.ifsSeparator(state, io);
86641
+ const separator = part.name === "@" && !split3 || hereString && (part.name === "@" || !part.quoted) ? " " : this.ifsSeparator(state, io);
85956
86642
  const values = this.positionalValues(state);
85957
86643
  retained = (0, value_exports.concatShellValues)(values.flatMap((entry, index) => index ? [separator, entry] : [entry]), io[valueScope]);
85958
86644
  }
@@ -86273,14 +86959,14 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86273
86959
  fastValueWord(word, state, io, split3, pattern, hereDocument, braces, assignmentStart, overrideDiagnosticLine) {
86274
86960
  const monitor = stateMonitor(state);
86275
86961
  const rawState = monitor ? monitor.raw : state;
86276
- if (pattern || word.parts.length === 0 || rawState.depth + (io.parameterDepth ?? 0) >= 32 || hasActiveVariableAttributes(rawState)) return void 0;
86962
+ if (pattern || word.parts.length === 0 || rawState.depth + (io.parameterDepth ?? 0) >= 32 || hasNonNamerefAttributes(rawState)) return void 0;
86277
86963
  if (guestArrays(state) && word.parts.some((part) => part.kind === "arithmetic" && !part.expression.error && !isSafeSmiProgram(part.expression))) return void 0;
86278
86964
  const activeArrayStore = arrayStore(state);
86279
86965
  const rawVars = rawState.variables;
86280
86966
  this.signal.throwIfAborted();
86281
86967
  let out = "";
86282
86968
  for (let i = 0; i < word.parts.length; i++) {
86283
- const part = word.parts[i];
86969
+ let part = word.parts[i];
86284
86970
  if (part.kind === "text") {
86285
86971
  if (part.byteValue || invokedValues.has(part)) return void 0;
86286
86972
  if (hereDocument && part.quoted && part.value.includes("$")) return void 0;
@@ -86291,7 +86977,14 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86291
86977
  }
86292
86978
  out += part.value;
86293
86979
  } else if (part.kind === "variable") {
86294
- if (rawState.variableAttributes?.get(part.name)?.includes("n")) return void 0;
86980
+ if (rawState.variableAttributes?.get(part.name)?.includes("n")) {
86981
+ if (part.indirect) return void 0;
86982
+ const resolvedName = resolveSyncNameref(rawState, part.name);
86983
+ if (resolvedName === part.name) return void 0;
86984
+ const origSel = getArraySelector(part);
86985
+ part = { ...part, name: resolvedName };
86986
+ if (origSel) setArraySelector(part, origSel);
86987
+ }
86295
86988
  if (split3 && !part.quoted && (rawVars.IFS !== void 0 && rawVars.IFS !== " \n")) return void 0;
86296
86989
  if (!part.indirect && !part.prefixNames && !part.length && !part.substring && !part.transform && part.operator === void 0 && getArraySelector(part) === void 0 && (part.name === "?" || part.name === "#" || part.name.length === 1 && part.name >= "1" && part.name <= "9")) {
86297
86990
  let val2;
@@ -86315,7 +87008,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86315
87008
  const refRaw = rawVars[part.name];
86316
87009
  const refName = refRaw === void 0 ? void 0 : this._syncArithRawWriteOnly && this._syncArithTouched?.has(part.name) ? refRaw : monitor?.values.get(part.name, refRaw) ?? refRaw;
86317
87010
  if (typeof refName !== "string" || !isShellIdentifier(refName)) return void 0;
86318
- if (activeArrayStore?.get(refName) || rawState.variableAttributes?.get(refName) || refName === "PIPESTATUS" || refName === "LINENO" || refName === "_" || refName === "FUNCNAME") {
87011
+ if (activeArrayStore?.get(refName) || rawState.variableAttributes?.get(refName) || refName === "PIPESTATUS" || refName === "LINENO" || refName === "_" || refName === "FUNCNAME" || refName === "DIRSTACK") {
86319
87012
  return void 0;
86320
87013
  }
86321
87014
  const targetRaw = rawVars[refName];
@@ -86328,7 +87021,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86328
87021
  continue;
86329
87022
  }
86330
87023
  if (part.indirect || part.prefixNames || part.specialParameter || part.transform) return void 0;
86331
- if (part.name === "@" || part.name === "*" || part.name === "PIPESTATUS" || part.name === "LINENO" || part.name === "_" || part.name === "FUNCNAME") return void 0;
87024
+ if (part.name === "@" || part.name === "*" || part.name === "PIPESTATUS" || part.name === "LINENO" || part.name === "_" || part.name === "FUNCNAME" || part.name === "DIRSTACK") return void 0;
86332
87025
  if (!isShellIdentifier(part.name)) return void 0;
86333
87026
  const selector = getArraySelector(part);
86334
87027
  const arrayBinding = activeArrayStore?.get(part.name);
@@ -86395,10 +87088,11 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86395
87088
  }
86396
87089
  const ifsVal = monitor?.values.get("IFS", rawVars.IFS ?? " ") ?? rawVars.IFS ?? " ";
86397
87090
  if (validElemOp && typeof ifsVal === "string" && (ifsVal.length === 0 || ifsVal.charCodeAt(0) < 128)) {
86398
- const sep = selector.separator === "@" ? " " : ifsVal.length > 0 ? ifsVal[0] : "";
87091
+ const sep = selector.separator === "@" && (!isKeys || ifsVal.length === 0) ? " " : ifsVal.length > 0 ? ifsVal[0] : "";
87092
+ const parameterLine = part.line ?? overrideDiagnosticLine;
86399
87093
  const evalSliceInt = (w) => {
86400
87094
  if (w.parts.length === 0) return 0;
86401
- const expanded = this.fastValueWord(w, rawState, io, false, false, false, false, void 0, part.line ?? overrideDiagnosticLine);
87095
+ const expanded = this.fastValueWord(w, rawState, io, false, false, false, false, void 0, parameterLine);
86402
87096
  if (typeof expanded !== "string") return void 0;
86403
87097
  const trimmed = expanded.trim();
86404
87098
  if (trimmed.length === 0) return 0;
@@ -86578,9 +87272,10 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86578
87272
  if (part.length || part.operator !== void 0 || this.budget.limits.maxExpansionBytes !== Infinity || rawState.depth + (io.parameterDepth ?? 0) >= 60 || !part.substring.offset.parts.every((p) => p.kind === "text" || p.kind === "arithmetic" || p.kind === "variable" && !p.operator && !p.substring) || part.substring.length && !part.substring.length.parts.every((p) => p.kind === "text" || p.kind === "arithmetic" || p.kind === "variable" && !p.operator && !p.substring) || ValueScope.prototype.reserve !== defaultValueScopeReserve || String.prototype.codePointAt !== defaultStringCodePointAt || globalThis.Float64Array !== defaultFloat64Array || !part.substring.offset.parts.length && !part.substring.length) {
86579
87273
  return void 0;
86580
87274
  }
87275
+ const parameterLine = part.line ?? overrideDiagnosticLine;
86581
87276
  const evalSubInt = (w) => {
86582
87277
  if (w.parts.length === 0) return 0;
86583
- const expanded = this.fastValueWord(w, rawState, io, false, false, false, false, void 0, part.line ?? overrideDiagnosticLine);
87278
+ const expanded = this.fastValueWord(w, rawState, io, false, false, false, false, void 0, parameterLine);
86584
87279
  if (typeof expanded !== "string") return void 0;
86585
87280
  const trimmed = expanded.trim();
86586
87281
  if (trimmed.length === 0) return 0;
@@ -86638,7 +87333,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86638
87333
  }
86639
87334
  if (part.operator !== void 0) {
86640
87335
  if (this.budget.limits.maxExpansionBytes !== Infinity || rawState.depth + (io.parameterDepth ?? 0) >= 60 || ValueScope.prototype.reserve !== defaultValueScopeReserve || String.prototype.codePointAt !== defaultStringCodePointAt || globalThis.Float64Array !== defaultFloat64Array) return void 0;
86641
- if (!rawState.nocasematch && (part.operator === "/" || part.operator === "//" || part.operator === "/#" || part.operator === "/%") && part.alternate && part.alternate.parts.length >= 1 && part.alternate.parts.every((p) => p.quoted === part.alternate.parts[0].quoted && (p.kind === "text" && !p.byteValue || p.kind === "variable" && !p.operator && !p.substring && !p.length && !p.indirect && !p.prefixNames && !p.specialParameter && !p.transform && getArraySelector(p) === void 0 && isShellIdentifier(p.name))) && (!part.replacement || part.replacement.parts.length === 0 || part.replacement.parts.every((p) => p.kind === "text" && !p.byteValue || p.kind === "variable" && !p.operator && !p.substring && !p.length && !p.indirect && !p.prefixNames && !p.specialParameter && !p.transform && getArraySelector(p) === void 0 && isShellIdentifier(p.name)))) {
87336
+ const patternQuoted = part.alternate?.parts[0]?.quoted;
87337
+ if (!rawState.nocasematch && (part.operator === "/" || part.operator === "//" || part.operator === "/#" || part.operator === "/%") && part.alternate && part.alternate.parts.length >= 1 && part.alternate.parts.every((p) => p.quoted === patternQuoted && (p.kind === "text" && !p.byteValue || p.kind === "variable" && !p.operator && !p.substring && !p.length && !p.indirect && !p.prefixNames && !p.specialParameter && !p.transform && getArraySelector(p) === void 0 && isShellIdentifier(p.name))) && (!part.replacement || part.replacement.parts.length === 0 || part.replacement.parts.every((p) => p.kind === "text" && !p.byteValue || p.kind === "variable" && !p.operator && !p.substring && !p.length && !p.indirect && !p.prefixNames && !p.specialParameter && !p.transform && getArraySelector(p) === void 0 && isShellIdentifier(p.name)))) {
86642
87338
  const patQuoted = part.alternate.parts[0].quoted;
86643
87339
  const pat = part.alternate.parts.length === 1 && part.alternate.parts[0].kind === "text" ? part.alternate.parts[0].value : this.fastValueWord(part.alternate, rawState, io, false, false, false, false, void 0, part.line ?? overrideDiagnosticLine);
86644
87340
  if (typeof pat !== "string" || pat.length === 0) return void 0;
@@ -86693,7 +87389,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86693
87389
  out += replaced;
86694
87390
  continue;
86695
87391
  }
86696
- if ((part.operator === "#" || part.operator === "##" || part.operator === "%" || part.operator === "%%") && part.alternate && part.alternate.parts.length >= 1 && part.alternate.parts.every((p) => p.quoted === part.alternate.parts[0].quoted && (p.kind === "text" && !p.byteValue || p.kind === "variable" && !p.operator && !p.substring && !p.length && !p.indirect && !p.prefixNames && !p.specialParameter && !p.transform && getArraySelector(p) === void 0 && isShellIdentifier(p.name)))) {
87392
+ if ((part.operator === "#" || part.operator === "##" || part.operator === "%" || part.operator === "%%") && part.alternate && part.alternate.parts.length >= 1 && part.alternate.parts.every((p) => p.quoted === patternQuoted && (p.kind === "text" && !p.byteValue || p.kind === "variable" && !p.operator && !p.substring && !p.length && !p.indirect && !p.prefixNames && !p.specialParameter && !p.transform && getArraySelector(p) === void 0 && isShellIdentifier(p.name)))) {
86697
87393
  const patQuoted = part.alternate.parts[0].quoted;
86698
87394
  const pat = part.alternate.parts.length === 1 && part.alternate.parts[0].kind === "text" ? part.alternate.parts[0].value : this.fastValueWord(part.alternate, rawState, io, false, false, false, false, void 0, part.line ?? overrideDiagnosticLine);
86699
87395
  if (typeof pat !== "string") return void 0;
@@ -86767,7 +87463,9 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86767
87463
  out += converted;
86768
87464
  continue;
86769
87465
  }
86770
- if ((part.operator === "-" || part.operator === ":-" || part.operator === "+" || part.operator === ":+") && part.alternate && !rawState.nounset && part.alternate.parts.every((p) => p.kind === "text" || p.kind === "arithmetic" || p.kind === "variable" && !p.operator && !p.substring)) {
87466
+ if ((part.operator === "-" || part.operator === ":-" || part.operator === "+" || part.operator === ":+" || part.operator === "=" || part.operator === ":=") && part.alternate && !rawState.nounset && part.alternate.parts.every((p) => p.kind === "text" || p.kind === "arithmetic" || p.kind === "variable" && !p.operator && !p.substring)) {
87467
+ const isAssignOp = part.operator === "=" || part.operator === ":=";
87468
+ if (isAssignOp && (!isShellIdentifier(part.name) || part.name === "OPTIND" || part.name === "PIPESTATUS" || part.name === "_" || rawState.readonlyVariables?.has(part.name) || rawState.variableAttributes?.get(part.name) || activeArrayStore?.get(part.name) || monitor?.hasOverlay(part.name) || i < word.parts.length - 1 && !this.isPureSyncValueWord({ offset: 0, parts: word.parts.slice(i + 1) }, rawState, false))) return void 0;
86771
87469
  const raw2 = rawVars[part.name];
86772
87470
  const cur = raw2 === void 0 ? void 0 : this._syncArithRawWriteOnly && this._syncArithTouched?.has(part.name) ? raw2 : monitor?.values.get(part.name, raw2) ?? raw2;
86773
87471
  if (cur !== void 0 && typeof cur !== "string") return void 0;
@@ -86780,10 +87478,21 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86780
87478
  resolvedScalar = altVal;
86781
87479
  } else resolvedScalar = "";
86782
87480
  } else {
86783
- const isMissing = cur === void 0 || part.operator === ":-" && cur === "";
87481
+ const isMissing = cur === void 0 || (part.operator === ":-" || part.operator === ":=") && cur === "";
86784
87482
  if (isMissing) {
86785
87483
  const altVal = this.fastValueWord(part.alternate, rawState, io, false, false, false, false, void 0, part.line ?? overrideDiagnosticLine);
86786
87484
  if (typeof altVal !== "string") return void 0;
87485
+ if (isAssignOp) {
87486
+ if (this._syncArithRawWriteOnly && this._syncArithTouched) {
87487
+ rawState.variables[part.name] = altVal;
87488
+ this._syncArithTouched.add(part.name);
87489
+ } else if (monitor) {
87490
+ monitor.publishStringVariable(part.name, altVal);
87491
+ } else {
87492
+ rawState.variables[part.name] = altVal;
87493
+ }
87494
+ if (rawState.allexport) (monitor ? monitor.proxy.exported : rawState.exported).add(part.name);
87495
+ }
86787
87496
  resolvedScalar = altVal;
86788
87497
  } else resolvedScalar = cur;
86789
87498
  }
@@ -86882,7 +87591,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
86882
87591
  if (rawState.nounset && p.name >= "1" && p.name <= "9" && activePos[p.name.charCodeAt(0) - 49] === void 0) return false;
86883
87592
  continue;
86884
87593
  }
86885
- if (p.prefixNames || p.specialParameter || p.transform || p.name === "@" || p.name === "*" || p.name === "PIPESTATUS" || p.name === "LINENO" || p.name === "_" || p.name === "FUNCNAME" || !isShellIdentifier(p.name)) {
87594
+ if (p.prefixNames || p.specialParameter || p.transform || p.name === "@" || p.name === "*" || p.name === "PIPESTATUS" || p.name === "LINENO" || p.name === "_" || p.name === "FUNCNAME" || p.name === "DIRSTACK" || !isShellIdentifier(p.name)) {
86886
87595
  return false;
86887
87596
  }
86888
87597
  if (p.operator !== void 0 && (p.operator === "=" || p.operator === ":=" || p.operator === "?" || p.operator === ":?")) return false;
@@ -87770,7 +88479,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
87770
88479
  const binding = arrayStore(state)?.get(part.name);
87771
88480
  const index2 = binding?.associative ? await this.arrayIndex(binding, selector.index, state, partIO, requireArrays(state).owner) : numericIndex(selector.index, 4294967295);
87772
88481
  if (index2 === void 0 && !binding?.associative) throw new ArrayFailure("index outside 0..4294967295");
87773
- value2 = binding ? index2 === void 0 ? void 0 : binding.getValue(index2) : index2 === 0 ? value2 : void 0;
88482
+ value2 = binding ? index2 === void 0 ? void 0 : binding.getValue(index2) : part.name === "FUNCNAME" && state.variables.FUNCNAME === void 0 ? index2 === void 0 ? void 0 : state.functionNames?.[index2] : index2 === 0 ? value2 : void 0;
87774
88483
  }
87775
88484
  const missing = value2 === void 0 || part.operator.startsWith(":") && shellValueByteLength(value2) === 0;
87776
88485
  if (part.operator.endsWith("+") ? !missing : missing) {
@@ -88070,7 +88779,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
88070
88779
  return this.arithmeticValue(prepareArithmetic(source2 || "0", this.budget.parsing), state, io);
88071
88780
  };
88072
88781
  offset = await evaluate(substring.offset);
88073
- if (offset < 0n) offset += BigInt((binding?.maximum ?? (state.variables[name2] === void 0 ? -1 : 0)) + 1);
88782
+ const maximum = binding?.maximum ?? (name2 === "FUNCNAME" && state.variables.FUNCNAME === void 0 ? (state.functionNames?.length ?? 0) - 1 : state.variables[name2] === void 0 ? -1 : 0);
88783
+ if (offset < 0n) offset += BigInt(maximum + 1);
88074
88784
  if (substring.length) {
88075
88785
  count2 = await evaluate(substring.length);
88076
88786
  if (count2 < 0n) throw new ExpansionFailure("substring expression < 0", io.diagnosticLine);
@@ -88081,7 +88791,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
88081
88791
  if (!binding) {
88082
88792
  if (name2 === "FUNCNAME" && state.variables.FUNCNAME === void 0) {
88083
88793
  const stack = state.functionNames ?? [];
88084
- const start = offset < 0n ? Math.max(0, stack.length + Number(offset)) : Number(offset);
88794
+ const start = Number(offset);
88085
88795
  const end = count2 === void 0 ? stack.length : start + Number(count2);
88086
88796
  const sliced = stack.slice(start, end);
88087
88797
  return keys2 ? sliced.map((_v, idx) => String(start + idx)) : sliced;