@actual-app/api 26.2.0-nightly.20260114 → 26.2.0-nightly.20260115

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.
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _g, _Stack_constructing, _LRUCache_instances, _LRUCache_max, _LRUCache_maxSize, _LRUCache_dispose, _LRUCache_onInsert, _LRUCache_disposeAfter, _LRUCache_fetchMethod, _LRUCache_memoMethod, _LRUCache_perf, _LRUCache_size, _LRUCache_calculatedSize, _LRUCache_keyMap, _LRUCache_keyList, _LRUCache_valList, _LRUCache_next, _LRUCache_prev, _LRUCache_head, _LRUCache_tail, _LRUCache_free, _LRUCache_disposed, _LRUCache_sizes, _LRUCache_starts, _LRUCache_ttls, _LRUCache_hasDispose, _LRUCache_hasFetchMethod, _LRUCache_hasDisposeAfter, _LRUCache_hasOnInsert, _LRUCache_initializeTTLTracking, _LRUCache_updateItemAge, _LRUCache_statusTTL, _LRUCache_setItemTTL, _LRUCache_isStale, _LRUCache_initializeSizeTracking, _LRUCache_removeItemSize, _LRUCache_addItemSize, _LRUCache_requireSize, _LRUCache_indexes, _LRUCache_rindexes, _LRUCache_isValidIndex, _LRUCache_evict, _LRUCache_backgroundFetch, _LRUCache_isBackgroundFetch, _LRUCache_connect, _LRUCache_moveToTail, _LRUCache_delete, _LRUCache_clear, _h;
13
+ var _g, _Stack_constructing, _LRUCache_instances, _LRUCache_max, _LRUCache_maxSize, _LRUCache_dispose, _LRUCache_onInsert, _LRUCache_disposeAfter, _LRUCache_fetchMethod, _LRUCache_memoMethod, _LRUCache_perf, _LRUCache_size, _LRUCache_calculatedSize, _LRUCache_keyMap, _LRUCache_keyList, _LRUCache_valList, _LRUCache_next, _LRUCache_prev, _LRUCache_head, _LRUCache_tail, _LRUCache_free, _LRUCache_disposed, _LRUCache_sizes, _LRUCache_starts, _LRUCache_ttls, _LRUCache_autopurgeTimers, _LRUCache_hasDispose, _LRUCache_hasFetchMethod, _LRUCache_hasDisposeAfter, _LRUCache_hasOnInsert, _LRUCache_initializeTTLTracking, _LRUCache_updateItemAge, _LRUCache_statusTTL, _LRUCache_setItemTTL, _LRUCache_isStale, _LRUCache_initializeSizeTracking, _LRUCache_removeItemSize, _LRUCache_addItemSize, _LRUCache_requireSize, _LRUCache_indexes, _LRUCache_rindexes, _LRUCache_isValidIndex, _LRUCache_evict, _LRUCache_backgroundFetch, _LRUCache_isBackgroundFetch, _LRUCache_connect, _LRUCache_moveToTail, _LRUCache_delete, _LRUCache_clear, _h;
14
14
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
15
15
  const fs$1 = require("fs");
16
16
  const path = require("path");
@@ -4272,6 +4272,7 @@ class LRUCache {
4272
4272
  // properties
4273
4273
  starts: __classPrivateFieldGet(c, _LRUCache_starts, "f"),
4274
4274
  ttls: __classPrivateFieldGet(c, _LRUCache_ttls, "f"),
4275
+ autopurgeTimers: __classPrivateFieldGet(c, _LRUCache_autopurgeTimers, "f"),
4275
4276
  sizes: __classPrivateFieldGet(c, _LRUCache_sizes, "f"),
4276
4277
  keyMap: __classPrivateFieldGet(c, _LRUCache_keyMap, "f"),
4277
4278
  keyList: __classPrivateFieldGet(c, _LRUCache_keyList, "f"),
@@ -4372,6 +4373,7 @@ class LRUCache {
4372
4373
  _LRUCache_sizes.set(this, void 0);
4373
4374
  _LRUCache_starts.set(this, void 0);
4374
4375
  _LRUCache_ttls.set(this, void 0);
4376
+ _LRUCache_autopurgeTimers.set(this, void 0);
4375
4377
  _LRUCache_hasDispose.set(this, void 0);
4376
4378
  _LRUCache_hasFetchMethod.set(this, void 0);
4377
4379
  _LRUCache_hasDisposeAfter.set(this, void 0);
@@ -4592,15 +4594,21 @@ class LRUCache {
4592
4594
  * Iterating over the cache itself yields the same results as
4593
4595
  * {@link LRUCache.entries}
4594
4596
  */
4595
- [(_LRUCache_max = new WeakMap(), _LRUCache_maxSize = new WeakMap(), _LRUCache_dispose = new WeakMap(), _LRUCache_onInsert = new WeakMap(), _LRUCache_disposeAfter = new WeakMap(), _LRUCache_fetchMethod = new WeakMap(), _LRUCache_memoMethod = new WeakMap(), _LRUCache_perf = new WeakMap(), _LRUCache_size = new WeakMap(), _LRUCache_calculatedSize = new WeakMap(), _LRUCache_keyMap = new WeakMap(), _LRUCache_keyList = new WeakMap(), _LRUCache_valList = new WeakMap(), _LRUCache_next = new WeakMap(), _LRUCache_prev = new WeakMap(), _LRUCache_head = new WeakMap(), _LRUCache_tail = new WeakMap(), _LRUCache_free = new WeakMap(), _LRUCache_disposed = new WeakMap(), _LRUCache_sizes = new WeakMap(), _LRUCache_starts = new WeakMap(), _LRUCache_ttls = new WeakMap(), _LRUCache_hasDispose = new WeakMap(), _LRUCache_hasFetchMethod = new WeakMap(), _LRUCache_hasDisposeAfter = new WeakMap(), _LRUCache_hasOnInsert = new WeakMap(), _LRUCache_updateItemAge = new WeakMap(), _LRUCache_statusTTL = new WeakMap(), _LRUCache_setItemTTL = new WeakMap(), _LRUCache_isStale = new WeakMap(), _LRUCache_removeItemSize = new WeakMap(), _LRUCache_addItemSize = new WeakMap(), _LRUCache_requireSize = new WeakMap(), _LRUCache_instances = new WeakSet(), _LRUCache_initializeTTLTracking = function _LRUCache_initializeTTLTracking() {
4597
+ [(_LRUCache_max = new WeakMap(), _LRUCache_maxSize = new WeakMap(), _LRUCache_dispose = new WeakMap(), _LRUCache_onInsert = new WeakMap(), _LRUCache_disposeAfter = new WeakMap(), _LRUCache_fetchMethod = new WeakMap(), _LRUCache_memoMethod = new WeakMap(), _LRUCache_perf = new WeakMap(), _LRUCache_size = new WeakMap(), _LRUCache_calculatedSize = new WeakMap(), _LRUCache_keyMap = new WeakMap(), _LRUCache_keyList = new WeakMap(), _LRUCache_valList = new WeakMap(), _LRUCache_next = new WeakMap(), _LRUCache_prev = new WeakMap(), _LRUCache_head = new WeakMap(), _LRUCache_tail = new WeakMap(), _LRUCache_free = new WeakMap(), _LRUCache_disposed = new WeakMap(), _LRUCache_sizes = new WeakMap(), _LRUCache_starts = new WeakMap(), _LRUCache_ttls = new WeakMap(), _LRUCache_autopurgeTimers = new WeakMap(), _LRUCache_hasDispose = new WeakMap(), _LRUCache_hasFetchMethod = new WeakMap(), _LRUCache_hasDisposeAfter = new WeakMap(), _LRUCache_hasOnInsert = new WeakMap(), _LRUCache_updateItemAge = new WeakMap(), _LRUCache_statusTTL = new WeakMap(), _LRUCache_setItemTTL = new WeakMap(), _LRUCache_isStale = new WeakMap(), _LRUCache_removeItemSize = new WeakMap(), _LRUCache_addItemSize = new WeakMap(), _LRUCache_requireSize = new WeakMap(), _LRUCache_instances = new WeakSet(), _LRUCache_initializeTTLTracking = function _LRUCache_initializeTTLTracking() {
4596
4598
  const ttls = new ZeroArray(__classPrivateFieldGet(this, _LRUCache_max, "f"));
4597
4599
  const starts = new ZeroArray(__classPrivateFieldGet(this, _LRUCache_max, "f"));
4598
4600
  __classPrivateFieldSet(this, _LRUCache_ttls, ttls, "f");
4599
4601
  __classPrivateFieldSet(this, _LRUCache_starts, starts, "f");
4602
+ const purgeTimers = this.ttlAutopurge ? new Array(__classPrivateFieldGet(this, _LRUCache_max, "f")) : void 0;
4603
+ __classPrivateFieldSet(this, _LRUCache_autopurgeTimers, purgeTimers, "f");
4600
4604
  __classPrivateFieldSet(this, _LRUCache_setItemTTL, (index, ttl, start = __classPrivateFieldGet(this, _LRUCache_perf, "f").now()) => {
4601
4605
  starts[index] = ttl !== 0 ? start : 0;
4602
4606
  ttls[index] = ttl;
4603
- if (ttl !== 0 && this.ttlAutopurge) {
4607
+ if (purgeTimers?.[index]) {
4608
+ clearTimeout(purgeTimers[index]);
4609
+ purgeTimers[index] = void 0;
4610
+ }
4611
+ if (ttl !== 0 && purgeTimers) {
4604
4612
  const t2 = setTimeout(() => {
4605
4613
  if (__classPrivateFieldGet(this, _LRUCache_isStale, "f").call(this, index)) {
4606
4614
  __classPrivateFieldGet(this, _LRUCache_instances, "m", _LRUCache_delete).call(this, __classPrivateFieldGet(this, _LRUCache_keyList, "f")[index], "expire");
@@ -4609,6 +4617,7 @@ class LRUCache {
4609
4617
  if (t2.unref) {
4610
4618
  t2.unref();
4611
4619
  }
4620
+ purgeTimers[index] = t2;
4612
4621
  }
4613
4622
  }, "f");
4614
4623
  __classPrivateFieldSet(this, _LRUCache_updateItemAge, (index) => {
@@ -5280,6 +5289,10 @@ _h = Symbol.toStringTag, _LRUCache_evict = function _LRUCache_evict(free) {
5280
5289
  }
5281
5290
  }
5282
5291
  __classPrivateFieldGet(this, _LRUCache_removeItemSize, "f").call(this, head);
5292
+ if (__classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")?.[head]) {
5293
+ clearTimeout(__classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")[head]);
5294
+ __classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")[head] = void 0;
5295
+ }
5283
5296
  if (free) {
5284
5297
  __classPrivateFieldGet(this, _LRUCache_keyList, "f")[head] = void 0;
5285
5298
  __classPrivateFieldGet(this, _LRUCache_valList, "f")[head] = void 0;
@@ -5433,6 +5446,10 @@ _h = Symbol.toStringTag, _LRUCache_evict = function _LRUCache_evict(free) {
5433
5446
  if (__classPrivateFieldGet(this, _LRUCache_size, "f") !== 0) {
5434
5447
  const index = __classPrivateFieldGet(this, _LRUCache_keyMap, "f").get(k);
5435
5448
  if (index !== void 0) {
5449
+ if (__classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")?.[index]) {
5450
+ clearTimeout(__classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")?.[index]);
5451
+ __classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")[index] = void 0;
5452
+ }
5436
5453
  deleted = true;
5437
5454
  if (__classPrivateFieldGet(this, _LRUCache_size, "f") === 1) {
5438
5455
  __classPrivateFieldGet(this, _LRUCache_instances, "m", _LRUCache_clear).call(this, reason);
@@ -5501,6 +5518,11 @@ _h = Symbol.toStringTag, _LRUCache_evict = function _LRUCache_evict(free) {
5501
5518
  if (__classPrivateFieldGet(this, _LRUCache_ttls, "f") && __classPrivateFieldGet(this, _LRUCache_starts, "f")) {
5502
5519
  __classPrivateFieldGet(this, _LRUCache_ttls, "f").fill(0);
5503
5520
  __classPrivateFieldGet(this, _LRUCache_starts, "f").fill(0);
5521
+ for (const t2 of __classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f") ?? []) {
5522
+ if (t2 !== void 0)
5523
+ clearTimeout(t2);
5524
+ }
5525
+ __classPrivateFieldGet(this, _LRUCache_autopurgeTimers, "f")?.fill(void 0);
5504
5526
  }
5505
5527
  if (__classPrivateFieldGet(this, _LRUCache_sizes, "f")) {
5506
5528
  __classPrivateFieldGet(this, _LRUCache_sizes, "f").fill(0);
@@ -5725,7 +5747,7 @@ const millisecondsInDay = 864e5;
5725
5747
  const millisecondsInMinute = 6e4;
5726
5748
  const millisecondsInHour = 36e5;
5727
5749
  const millisecondsInSecond = 1e3;
5728
- const constructFromSymbol = Symbol.for("constructDateFrom");
5750
+ const constructFromSymbol = /* @__PURE__ */ Symbol.for("constructDateFrom");
5729
5751
  function constructFrom(date, value) {
5730
5752
  if (typeof date === "function")
5731
5753
  return date(value);
@@ -9879,7 +9901,7 @@ var postProcessor = {
9879
9901
  return value;
9880
9902
  }
9881
9903
  };
9882
- const PATH_KEY = Symbol("i18next/PATH_KEY");
9904
+ const PATH_KEY = /* @__PURE__ */ Symbol("i18next/PATH_KEY");
9883
9905
  function createProxy() {
9884
9906
  const state = [];
9885
9907
  const handler = /* @__PURE__ */ Object.create(null);
@@ -10520,9 +10542,6 @@ class PluralResolver {
10520
10542
  this.logger = baseLogger.create("pluralResolver");
10521
10543
  this.pluralRulesCache = {};
10522
10544
  }
10523
- addRule(lng, obj) {
10524
- this.rules[lng] = obj;
10525
- }
10526
10545
  clearCache() {
10527
10546
  this.pluralRulesCache = {};
10528
10547
  }
@@ -11302,6 +11321,9 @@ class I18n extends EventEmitter {
11302
11321
  if (options.nsSeparator !== void 0) {
11303
11322
  this.options.userDefinedNsSeparator = options.nsSeparator;
11304
11323
  }
11324
+ if (typeof this.options.overloadTranslationOptionHandler !== "function") {
11325
+ this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
11326
+ }
11305
11327
  const createClassOnDemand = (ClassOrObject) => {
11306
11328
  if (!ClassOrObject)
11307
11329
  return null;
@@ -11780,6 +11802,19 @@ class I18n extends EventEmitter {
11780
11802
  clone.store = new ResourceStore(clonedData, mergedOptions);
11781
11803
  clone.services.resourceStore = clone.store;
11782
11804
  }
11805
+ if (options.interpolation) {
11806
+ const defOpts = get$4();
11807
+ const mergedInterpolation = {
11808
+ ...defOpts.interpolation,
11809
+ ...this.options.interpolation,
11810
+ ...options.interpolation
11811
+ };
11812
+ const mergedForInterpolator = {
11813
+ ...mergedOptions,
11814
+ interpolation: mergedInterpolation
11815
+ };
11816
+ clone.services.interpolator = new Interpolator(mergedForInterpolator);
11817
+ }
11783
11818
  clone.translator = new Translator(clone.services, mergedOptions);
11784
11819
  clone.translator.on("*", (event, ...args) => {
11785
11820
  clone.emit(event, ...args);
@@ -66138,7 +66173,7 @@ class CellAddress {
66138
66173
  return new CellAddress(this.col, this.row, this.type, sheet);
66139
66174
  }
66140
66175
  isInvalid(baseAddress) {
66141
- return invalidSimpleCellAddress(this.toSimpleCellAddress(baseAddress));
66176
+ return isColOrRowInvalid(this.toSimpleCellAddress(baseAddress));
66142
66177
  }
66143
66178
  shiftRelativeDimensions(toRight, toBottom) {
66144
66179
  const col = this.isColumnAbsolute() ? this.col : this.col + toRight;
@@ -66169,7 +66204,7 @@ class CellAddress {
66169
66204
  }
66170
66205
  unparse(baseAddress) {
66171
66206
  const simpleAddress = this.toSimpleCellAddress(baseAddress);
66172
- if (invalidSimpleCellAddress(simpleAddress)) {
66207
+ if (isColOrRowInvalid(simpleAddress)) {
66173
66208
  return void 0;
66174
66209
  }
66175
66210
  const column = columnIndexToLabel(simpleAddress.col);
@@ -66202,17 +66237,18 @@ const addressRegex = new RegExp(`^(${SHEET_NAME_PATTERN})?(\\${ABSOLUTE_OPERATOR
66202
66237
  const columnRegex = new RegExp(`^(${SHEET_NAME_PATTERN})?(\\${ABSOLUTE_OPERATOR}?)([A-Za-z]+)$`);
66203
66238
  const rowRegex = new RegExp(`^(${SHEET_NAME_PATTERN})?(\\${ABSOLUTE_OPERATOR}?)([0-9]+)$`);
66204
66239
  const simpleSheetNameRegex = new RegExp(`^${UNQUOTED_SHEET_NAME_PATTERN}$`);
66205
- const cellAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
66240
+ const cellAddressFromString = (stringAddress, baseAddress, resolveSheetReference) => {
66206
66241
  const result = addressRegex.exec(stringAddress);
66207
- const col = columnLabelToIndex(result[6]);
66208
- let sheet = extractSheetNumber(result, sheetMapping);
66209
- if (sheet === void 0) {
66242
+ if (!result) {
66210
66243
  return void 0;
66211
66244
  }
66245
+ const col = columnLabelToIndex(result[6]);
66246
+ const row = Number(result[8]) - 1;
66247
+ const sheetName = extractSheetName(result);
66248
+ const sheet = sheetNameToId(sheetName, resolveSheetReference);
66212
66249
  if (sheet === null) {
66213
- sheet = void 0;
66250
+ return void 0;
66214
66251
  }
66215
- const row = Number(result[8]) - 1;
66216
66252
  if (result[5] === ABSOLUTE_OPERATOR && result[7] === ABSOLUTE_OPERATOR) {
66217
66253
  return CellAddress.absolute(col, row, sheet);
66218
66254
  }
@@ -66226,16 +66262,17 @@ const cellAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
66226
66262
  return CellAddress.relative(col - baseAddress.col, row - baseAddress.row, sheet);
66227
66263
  }
66228
66264
  };
66229
- const columnAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
66265
+ const columnAddressFromString = (stringAddress, baseAddress, resolveSheetReference) => {
66230
66266
  const result = columnRegex.exec(stringAddress);
66231
- let sheet = extractSheetNumber(result, sheetMapping);
66232
- if (sheet === void 0) {
66267
+ if (!result) {
66233
66268
  return void 0;
66234
66269
  }
66270
+ const col = columnLabelToIndex(result[6]);
66271
+ const sheetName = extractSheetName(result);
66272
+ const sheet = sheetNameToId(sheetName, resolveSheetReference);
66235
66273
  if (sheet === null) {
66236
- sheet = void 0;
66274
+ return void 0;
66237
66275
  }
66238
- const col = columnLabelToIndex(result[6]);
66239
66276
  if (result[5] === ABSOLUTE_OPERATOR) {
66240
66277
  return ColumnAddress.absolute(col, sheet);
66241
66278
  }
@@ -66243,16 +66280,17 @@ const columnAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
66243
66280
  return ColumnAddress.relative(col - baseAddress.col, sheet);
66244
66281
  }
66245
66282
  };
66246
- const rowAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
66283
+ const rowAddressFromString = (stringAddress, baseAddress, resolveSheetReference) => {
66247
66284
  const result = rowRegex.exec(stringAddress);
66248
- let sheet = extractSheetNumber(result, sheetMapping);
66249
- if (sheet === void 0) {
66285
+ if (!result) {
66250
66286
  return void 0;
66251
66287
  }
66288
+ const row = Number(result[6]) - 1;
66289
+ const sheetName = extractSheetName(result);
66290
+ const sheet = sheetNameToId(sheetName, resolveSheetReference);
66252
66291
  if (sheet === null) {
66253
- sheet = void 0;
66292
+ return void 0;
66254
66293
  }
66255
- const row = Number(result[6]) - 1;
66256
66294
  if (result[5] === ABSOLUTE_OPERATOR) {
66257
66295
  return RowAddress.absolute(row, sheet);
66258
66296
  }
@@ -66260,33 +66298,32 @@ const rowAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
66260
66298
  return RowAddress.relative(row - baseAddress.row, sheet);
66261
66299
  }
66262
66300
  };
66263
- const simpleCellAddressFromString = (sheetMapping, stringAddress, contextSheetId) => {
66301
+ const simpleCellAddressFromString = (resolveSheetReference, stringAddress, contextSheetId) => {
66264
66302
  const regExpExecArray = addressRegex.exec(stringAddress);
66265
66303
  if (!regExpExecArray) {
66266
66304
  return void 0;
66267
66305
  }
66268
66306
  const col = columnLabelToIndex(regExpExecArray[6]);
66269
- let sheet = extractSheetNumber(regExpExecArray, sheetMapping);
66270
- if (sheet === void 0) {
66271
- return void 0;
66272
- }
66307
+ const row = Number(regExpExecArray[8]) - 1;
66308
+ const sheetName = extractSheetName(regExpExecArray);
66309
+ const sheet = sheetNameToId(sheetName, resolveSheetReference);
66273
66310
  if (sheet === null) {
66274
- sheet = contextSheetId;
66311
+ return void 0;
66275
66312
  }
66276
- const row = Number(regExpExecArray[8]) - 1;
66277
- return simpleCellAddress(sheet, col, row);
66313
+ const effectiveSheet = sheet === void 0 ? contextSheetId : sheet;
66314
+ return simpleCellAddress(effectiveSheet, col, row);
66278
66315
  };
66279
- const simpleCellRangeFromString = (sheetMapping, stringAddress, contextSheetId) => {
66316
+ const simpleCellRangeFromString = (resolveSheetReference, stringAddress, contextSheetId) => {
66280
66317
  const split2 = stringAddress.split(RANGE_OPERATOR);
66281
66318
  if (split2.length !== 2) {
66282
66319
  return void 0;
66283
66320
  }
66284
66321
  const [startString, endString] = split2;
66285
- const start = simpleCellAddressFromString(sheetMapping, startString, contextSheetId);
66322
+ const start = simpleCellAddressFromString(resolveSheetReference, startString, contextSheetId);
66286
66323
  if (start === void 0) {
66287
66324
  return void 0;
66288
66325
  }
66289
- const end = simpleCellAddressFromString(sheetMapping, endString, start.sheet);
66326
+ const end = simpleCellAddressFromString(resolveSheetReference, endString, start.sheet);
66290
66327
  if (end === void 0) {
66291
66328
  return void 0;
66292
66329
  }
@@ -66349,16 +66386,17 @@ function sheetIndexToString(sheetId, sheetMappingFn) {
66349
66386
  return `'${sheetName}'`;
66350
66387
  }
66351
66388
  }
66352
- function extractSheetNumber(regexResult, sheetMapping) {
66389
+ function extractSheetName(regexResult) {
66353
66390
  var _a;
66354
- let maybeSheetName = (_a = regexResult[3]) !== null && _a !== void 0 ? _a : regexResult[2];
66355
- if (maybeSheetName) {
66356
- maybeSheetName = maybeSheetName.replace(/''/g, "'");
66357
- return sheetMapping(maybeSheetName);
66358
- }
66359
- else {
66360
- return null;
66391
+ const maybeSheetName = (_a = regexResult[3]) !== null && _a !== void 0 ? _a : regexResult[2];
66392
+ return maybeSheetName ? maybeSheetName.replace(/''/g, "'") : null;
66393
+ }
66394
+ function sheetNameToId(sheetName, resolveSheetReference) {
66395
+ if (!sheetName) {
66396
+ return void 0;
66361
66397
  }
66398
+ const sheetId = resolveSheetReference(sheetName);
66399
+ return sheetId === void 0 ? null : sheetId;
66362
66400
  }
66363
66401
  function isEmpty(arr) {
66364
66402
  return arr && arr.length === 0;
@@ -74847,11 +74885,12 @@ const buildLexerConfig = (config2) => {
74847
74885
  };
74848
74886
  };
74849
74887
  class FormulaParser extends EmbeddedActionsParser {
74850
- constructor(lexerConfig, sheetMapping) {
74888
+ constructor(lexerConfig, resolveSheetReference) {
74851
74889
  super(lexerConfig.allTokens, {
74852
74890
  outputCst: false,
74853
74891
  maxLookahead: 7
74854
74892
  });
74893
+ this.resolveSheetReference = resolveSheetReference;
74855
74894
  this.booleanExpressionOrEmpty = this.RULE("booleanExpressionOrEmpty", () => {
74856
74895
  return this.OR([{
74857
74896
  ALT: () => this.SUBRULE(this.booleanExpression)
@@ -74902,8 +74941,8 @@ class FormulaParser extends EmbeddedActionsParser {
74902
74941
  this.columnRangeExpression = this.RULE("columnRangeExpression", () => {
74903
74942
  const range2 = this.CONSUME(ColumnRange);
74904
74943
  const [startImage, endImage] = range2.image.split(":");
74905
- const firstAddress = this.ACTION(() => columnAddressFromString(this.sheetMapping, startImage, this.formulaAddress));
74906
- const secondAddress = this.ACTION(() => columnAddressFromString(this.sheetMapping, endImage, this.formulaAddress));
74944
+ const firstAddress = this.ACTION(() => columnAddressFromString(startImage, this.formulaAddress, this.resolveSheetReference));
74945
+ const secondAddress = this.ACTION(() => columnAddressFromString(endImage, this.formulaAddress, this.resolveSheetReference));
74907
74946
  if (firstAddress === void 0 || secondAddress === void 0) {
74908
74947
  return buildCellErrorAst(new CellError(ErrorType.REF));
74909
74948
  }
@@ -74919,8 +74958,8 @@ class FormulaParser extends EmbeddedActionsParser {
74919
74958
  this.rowRangeExpression = this.RULE("rowRangeExpression", () => {
74920
74959
  const range2 = this.CONSUME(RowRange);
74921
74960
  const [startImage, endImage] = range2.image.split(":");
74922
- const firstAddress = this.ACTION(() => rowAddressFromString(this.sheetMapping, startImage, this.formulaAddress));
74923
- const secondAddress = this.ACTION(() => rowAddressFromString(this.sheetMapping, endImage, this.formulaAddress));
74961
+ const firstAddress = this.ACTION(() => rowAddressFromString(startImage, this.formulaAddress, this.resolveSheetReference));
74962
+ const secondAddress = this.ACTION(() => rowAddressFromString(endImage, this.formulaAddress, this.resolveSheetReference));
74924
74963
  if (firstAddress === void 0 || secondAddress === void 0) {
74925
74964
  return buildCellErrorAst(new CellError(ErrorType.REF));
74926
74965
  }
@@ -74936,7 +74975,7 @@ class FormulaParser extends EmbeddedActionsParser {
74936
74975
  this.cellReference = this.RULE("cellReference", () => {
74937
74976
  const cell = this.CONSUME(CellReference);
74938
74977
  const address = this.ACTION(() => {
74939
- return cellAddressFromString(this.sheetMapping, cell.image, this.formulaAddress);
74978
+ return cellAddressFromString(cell.image, this.formulaAddress, this.resolveSheetReference);
74940
74979
  });
74941
74980
  if (address === void 0) {
74942
74981
  return buildErrorWithRawInputAst(cell.image, new CellError(ErrorType.REF), cell.leadingWhitespace);
@@ -74952,10 +74991,10 @@ class FormulaParser extends EmbeddedActionsParser {
74952
74991
  var _a;
74953
74992
  const end = this.CONSUME(CellReference);
74954
74993
  const startAddress = this.ACTION(() => {
74955
- return cellAddressFromString(this.sheetMapping, start.image, this.formulaAddress);
74994
+ return cellAddressFromString(start.image, this.formulaAddress, this.resolveSheetReference);
74956
74995
  });
74957
74996
  const endAddress = this.ACTION(() => {
74958
- return cellAddressFromString(this.sheetMapping, end.image, this.formulaAddress);
74997
+ return cellAddressFromString(end.image, this.formulaAddress, this.resolveSheetReference);
74959
74998
  });
74960
74999
  if (startAddress === void 0 || endAddress === void 0) {
74961
75000
  return this.ACTION(() => {
@@ -74981,7 +75020,7 @@ class FormulaParser extends EmbeddedActionsParser {
74981
75020
  var _a;
74982
75021
  const offsetProcedure = this.SUBRULE(this.offsetProcedureExpression);
74983
75022
  const startAddress = this.ACTION(() => {
74984
- return cellAddressFromString(this.sheetMapping, start.image, this.formulaAddress);
75023
+ return cellAddressFromString(start.image, this.formulaAddress, this.resolveSheetReference);
74985
75024
  });
74986
75025
  if (startAddress === void 0) {
74987
75026
  return buildCellErrorAst(new CellError(ErrorType.REF));
@@ -75005,7 +75044,7 @@ class FormulaParser extends EmbeddedActionsParser {
75005
75044
  this.endRangeWithOffsetStartReference = this.RULE("endRangeWithOffsetStartReference", (start) => {
75006
75045
  const end = this.CONSUME(CellReference);
75007
75046
  const endAddress = this.ACTION(() => {
75008
- return cellAddressFromString(this.sheetMapping, end.image, this.formulaAddress);
75047
+ return cellAddressFromString(end.image, this.formulaAddress, this.resolveSheetReference);
75009
75048
  });
75010
75049
  if (endAddress === void 0) {
75011
75050
  return this.ACTION(() => {
@@ -75264,7 +75303,6 @@ class FormulaParser extends EmbeddedActionsParser {
75264
75303
  return this.SUBRULE(this.booleanExpression);
75265
75304
  });
75266
75305
  this.lexerConfig = lexerConfig;
75267
- this.sheetMapping = sheetMapping;
75268
75306
  this.formulaAddress = simpleCellAddress(0, 0, 0);
75269
75307
  this.performSelfAnalysis();
75270
75308
  }
@@ -75486,10 +75524,9 @@ class FormulaLexer {
75486
75524
  }
75487
75525
  }
75488
75526
  class Unparser {
75489
- constructor(config2, lexerConfig, sheetMappingFn, namedExpressions) {
75527
+ constructor(config2, sheetMapping, namedExpressions) {
75490
75528
  this.config = config2;
75491
- this.lexerConfig = lexerConfig;
75492
- this.sheetMappingFn = sheetMappingFn;
75529
+ this.sheetMapping = sheetMapping;
75493
75530
  this.namedExpressions = namedExpressions;
75494
75531
  }
75495
75532
  unparse(ast, address) {
@@ -75567,8 +75604,15 @@ class Unparser {
75567
75604
  }
75568
75605
  }
75569
75606
  }
75607
+ /**
75608
+ * Unparses a sheet name.
75609
+ * @param {number} sheetId - the ID of the sheet
75610
+ * @returns {string} the unparsed sheet name
75611
+ */
75570
75612
  unparseSheetName(sheetId) {
75571
- const sheetName = sheetIndexToString(sheetId, this.sheetMappingFn);
75613
+ const sheetName = sheetIndexToString(sheetId, (id2) => this.sheetMapping.getSheetNameOrThrowError(id2, {
75614
+ includePlaceholders: true
75615
+ }));
75572
75616
  if (sheetName === void 0) {
75573
75617
  throw new NoSheetWithIdError(sheetId);
75574
75618
  }
@@ -75596,14 +75640,14 @@ function formatNumber(number2, decimalSeparator) {
75596
75640
  return numericString.replace(".", decimalSeparator);
75597
75641
  }
75598
75642
  class ParserWithCaching {
75599
- constructor(config2, functionRegistry, sheetMapping) {
75643
+ constructor(config2, functionRegistry, resolveSheetReference) {
75600
75644
  this.config = config2;
75601
75645
  this.functionRegistry = functionRegistry;
75602
- this.sheetMapping = sheetMapping;
75646
+ this.resolveSheetReference = resolveSheetReference;
75603
75647
  this.statsCacheUsed = 0;
75604
75648
  this.lexerConfig = buildLexerConfig(config2);
75605
75649
  this.lexer = new FormulaLexer(this.lexerConfig);
75606
- this.formulaParser = new FormulaParser(this.lexerConfig, this.sheetMapping);
75650
+ this.formulaParser = new FormulaParser(this.lexerConfig, this.resolveSheetReference);
75607
75651
  this.cache = new Cache(this.functionRegistry);
75608
75652
  }
75609
75653
  /**
@@ -75799,7 +75843,7 @@ class ParserWithCaching {
75799
75843
  while (idx < tokens.length) {
75800
75844
  const token = tokens[idx];
75801
75845
  if (tokenMatcher(token, CellReference)) {
75802
- const cellAddress = cellAddressFromString(this.sheetMapping, token.image, baseAddress);
75846
+ const cellAddress = cellAddressFromString(token.image, baseAddress, this.resolveSheetReference);
75803
75847
  if (cellAddress === void 0) {
75804
75848
  hash = hash.concat(token.image);
75805
75849
  }
@@ -75814,8 +75858,8 @@ class ParserWithCaching {
75814
75858
  }
75815
75859
  else if (tokenMatcher(token, ColumnRange)) {
75816
75860
  const [start, end] = token.image.split(":");
75817
- const startAddress = columnAddressFromString(this.sheetMapping, start, baseAddress);
75818
- const endAddress = columnAddressFromString(this.sheetMapping, end, baseAddress);
75861
+ const startAddress = columnAddressFromString(start, baseAddress, this.resolveSheetReference);
75862
+ const endAddress = columnAddressFromString(end, baseAddress, this.resolveSheetReference);
75819
75863
  if (startAddress === void 0 || endAddress === void 0) {
75820
75864
  hash = hash.concat("!REF");
75821
75865
  }
@@ -75825,8 +75869,8 @@ class ParserWithCaching {
75825
75869
  }
75826
75870
  else if (tokenMatcher(token, RowRange)) {
75827
75871
  const [start, end] = token.image.split(":");
75828
- const startAddress = rowAddressFromString(this.sheetMapping, start, baseAddress);
75829
- const endAddress = rowAddressFromString(this.sheetMapping, end, baseAddress);
75872
+ const startAddress = rowAddressFromString(start, baseAddress, this.resolveSheetReference);
75873
+ const endAddress = rowAddressFromString(end, baseAddress, this.resolveSheetReference);
75830
75874
  if (startAddress === void 0 || endAddress === void 0) {
75831
75875
  hash = hash.concat("!REF");
75832
75876
  }
@@ -76059,14 +76103,14 @@ const filterDependenciesOutOfScope = (deps) => {
76059
76103
  return true;
76060
76104
  }
76061
76105
  if (dep instanceof AbsoluteCellRange) {
76062
- return !(invalidSimpleCellAddress(dep.start) || invalidSimpleCellAddress(dep.end));
76106
+ return !(isColOrRowInvalid(dep.start) || isColOrRowInvalid(dep.end));
76063
76107
  }
76064
76108
  else {
76065
- return !invalidSimpleCellAddress(dep);
76109
+ return !isColOrRowInvalid(dep);
76066
76110
  }
76067
76111
  });
76068
76112
  };
76069
- const EmptyValue = Symbol("Empty value");
76113
+ const EmptyValue = /* @__PURE__ */ Symbol("Empty value");
76070
76114
  function getRawValue(num2) {
76071
76115
  if (num2 instanceof RichNumber) {
76072
76116
  return num2.val;
@@ -76393,6 +76437,299 @@ class ContentChanges {
76393
76437
  });
76394
76438
  }
76395
76439
  }
76440
+ class InternalNamedExpression {
76441
+ constructor(displayName, address, added, options) {
76442
+ this.displayName = displayName;
76443
+ this.address = address;
76444
+ this.added = added;
76445
+ this.options = options;
76446
+ }
76447
+ normalizeExpressionName() {
76448
+ return this.displayName.toLowerCase();
76449
+ }
76450
+ copy() {
76451
+ return new InternalNamedExpression(this.displayName, this.address, this.added, this.options);
76452
+ }
76453
+ }
76454
+ class WorkbookStore {
76455
+ constructor() {
76456
+ this.mapping = /* @__PURE__ */ new Map();
76457
+ }
76458
+ has(expressionName) {
76459
+ return this.mapping.has(this.normalizeExpressionName(expressionName));
76460
+ }
76461
+ isNameAvailable(expressionName) {
76462
+ const normalizedExpressionName = this.normalizeExpressionName(expressionName);
76463
+ const namedExpression = this.mapping.get(normalizedExpressionName);
76464
+ return !(namedExpression && namedExpression.added);
76465
+ }
76466
+ add(namedExpression) {
76467
+ this.mapping.set(namedExpression.normalizeExpressionName(), namedExpression);
76468
+ }
76469
+ get(expressionName) {
76470
+ return this.mapping.get(this.normalizeExpressionName(expressionName));
76471
+ }
76472
+ getExisting(expressionName) {
76473
+ const namedExpression = this.mapping.get(this.normalizeExpressionName(expressionName));
76474
+ if (namedExpression && namedExpression.added) {
76475
+ return namedExpression;
76476
+ }
76477
+ else {
76478
+ return void 0;
76479
+ }
76480
+ }
76481
+ remove(expressionName) {
76482
+ const normalizedExpressionName = this.normalizeExpressionName(expressionName);
76483
+ const namedExpression = this.mapping.get(normalizedExpressionName);
76484
+ if (namedExpression) {
76485
+ namedExpression.added = false;
76486
+ }
76487
+ }
76488
+ getAllNamedExpressions() {
76489
+ return Array.from(this.mapping.values()).filter((ne) => ne.added);
76490
+ }
76491
+ normalizeExpressionName(expressionName) {
76492
+ return expressionName.toLowerCase();
76493
+ }
76494
+ }
76495
+ class WorksheetStore {
76496
+ constructor() {
76497
+ this.mapping = /* @__PURE__ */ new Map();
76498
+ }
76499
+ add(namedExpression) {
76500
+ this.mapping.set(this.normalizeExpressionName(namedExpression.displayName), namedExpression);
76501
+ }
76502
+ get(expressionName) {
76503
+ return this.mapping.get(this.normalizeExpressionName(expressionName));
76504
+ }
76505
+ has(expressionName) {
76506
+ return this.mapping.has(this.normalizeExpressionName(expressionName));
76507
+ }
76508
+ getAllNamedExpressions() {
76509
+ return Array.from(this.mapping.values()).filter((ne) => ne.added);
76510
+ }
76511
+ isNameAvailable(expressionName) {
76512
+ const normalizedExpressionName = this.normalizeExpressionName(expressionName);
76513
+ return !this.mapping.has(normalizedExpressionName);
76514
+ }
76515
+ remove(expressionName) {
76516
+ const normalizedExpressionName = this.normalizeExpressionName(expressionName);
76517
+ const namedExpression = this.mapping.get(normalizedExpressionName);
76518
+ if (namedExpression) {
76519
+ this.mapping.delete(normalizedExpressionName);
76520
+ }
76521
+ }
76522
+ normalizeExpressionName(expressionName) {
76523
+ return expressionName.toLowerCase();
76524
+ }
76525
+ }
76526
+ class NamedExpressions {
76527
+ constructor() {
76528
+ this.nextNamedExpressionRow = 0;
76529
+ this.workbookStore = new WorkbookStore();
76530
+ this.worksheetStores = /* @__PURE__ */ new Map();
76531
+ this.addressCache = /* @__PURE__ */ new Map();
76532
+ }
76533
+ isNameAvailable(expressionName, sheetId) {
76534
+ var _a, _b;
76535
+ if (sheetId === void 0) {
76536
+ return this.workbookStore.isNameAvailable(expressionName);
76537
+ }
76538
+ else {
76539
+ return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.isNameAvailable(expressionName)) !== null && _b !== void 0 ? _b : true;
76540
+ }
76541
+ }
76542
+ namedExpressionInAddress(row) {
76543
+ const namedExpression = this.addressCache.get(row);
76544
+ if (namedExpression && namedExpression.added) {
76545
+ return namedExpression;
76546
+ }
76547
+ else {
76548
+ return void 0;
76549
+ }
76550
+ }
76551
+ namedExpressionForScope(expressionName, sheetId) {
76552
+ var _a;
76553
+ if (sheetId === void 0) {
76554
+ return this.workbookStore.getExisting(expressionName);
76555
+ }
76556
+ else {
76557
+ return (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.get(expressionName);
76558
+ }
76559
+ }
76560
+ nearestNamedExpression(expressionName, sheetId) {
76561
+ var _a, _b;
76562
+ return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.get(expressionName)) !== null && _b !== void 0 ? _b : this.workbookStore.getExisting(expressionName);
76563
+ }
76564
+ isExpressionInScope(expressionName, sheetId) {
76565
+ var _a, _b;
76566
+ return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.has(expressionName)) !== null && _b !== void 0 ? _b : false;
76567
+ }
76568
+ /**
76569
+ * Checks the validity of a named-expression's name.
76570
+ *
76571
+ * The name:
76572
+ * - Must start with a Unicode letter or with an underscore (`_`).
76573
+ * - Can contain only Unicode letters, numbers, underscores, and periods (`.`).
76574
+ * - Can't be the same as any possible reference in the A1 notation (`[A-Za-z]+[0-9]+`).
76575
+ * - Can't be the same as any possible reference in the R1C1 notation (`[rR][0-9]*[cC][0-9]*`).
76576
+ *
76577
+ * The naming rules follow the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#__RefHeading__1017964_715980110) standard.
76578
+ */
76579
+ isNameValid(expressionName) {
76580
+ const a1CellRefRegexp = new RegExp(`^${CELL_REFERENCE_PATTERN}$`);
76581
+ const r1c1CellRefRegexp = new RegExp(`^${R1C1_CELL_REFERENCE_PATTERN}$`);
76582
+ const namedExpRegexp = new RegExp(`^${NAMED_EXPRESSION_PATTERN}$`);
76583
+ if (a1CellRefRegexp.test(expressionName) || r1c1CellRefRegexp.test(expressionName)) {
76584
+ return false;
76585
+ }
76586
+ return namedExpRegexp.test(expressionName);
76587
+ }
76588
+ addNamedExpression(expressionName, sheetId, options) {
76589
+ const store2 = sheetId === void 0 ? this.workbookStore : this.worksheetStoreOrCreate(sheetId);
76590
+ let namedExpression = store2.get(expressionName);
76591
+ if (namedExpression !== void 0) {
76592
+ namedExpression.added = true;
76593
+ namedExpression.displayName = expressionName;
76594
+ namedExpression.options = options;
76595
+ }
76596
+ else {
76597
+ namedExpression = new InternalNamedExpression(expressionName, this.nextAddress(), true, options);
76598
+ store2.add(namedExpression);
76599
+ }
76600
+ this.addressCache.set(namedExpression.address.row, namedExpression);
76601
+ return namedExpression;
76602
+ }
76603
+ restoreNamedExpression(namedExpression, sheetId) {
76604
+ const store2 = sheetId === void 0 ? this.workbookStore : this.worksheetStoreOrCreate(sheetId);
76605
+ namedExpression.added = true;
76606
+ store2.add(namedExpression);
76607
+ this.addressCache.set(namedExpression.address.row, namedExpression);
76608
+ return namedExpression;
76609
+ }
76610
+ namedExpressionOrPlaceholder(expressionName, sheetId) {
76611
+ var _a;
76612
+ return (_a = this.worksheetStoreOrCreate(sheetId).get(expressionName)) !== null && _a !== void 0 ? _a : this.workbookNamedExpressionOrPlaceholder(expressionName);
76613
+ }
76614
+ workbookNamedExpressionOrPlaceholder(expressionName) {
76615
+ let namedExpression = this.workbookStore.get(expressionName);
76616
+ if (namedExpression === void 0) {
76617
+ namedExpression = new InternalNamedExpression(expressionName, this.nextAddress(), false);
76618
+ this.workbookStore.add(namedExpression);
76619
+ }
76620
+ return namedExpression;
76621
+ }
76622
+ remove(expressionName, sheetId) {
76623
+ let store2;
76624
+ if (sheetId === void 0) {
76625
+ store2 = this.workbookStore;
76626
+ }
76627
+ else {
76628
+ store2 = this.worksheetStore(sheetId);
76629
+ }
76630
+ const namedExpression = store2 === null || store2 === void 0 ? void 0 : store2.get(expressionName);
76631
+ if (store2 === void 0 || namedExpression === void 0 || !namedExpression.added) {
76632
+ throw Error("Named expression does not exist");
76633
+ }
76634
+ store2.remove(expressionName);
76635
+ if (store2 instanceof WorksheetStore && store2.mapping.size === 0) {
76636
+ this.worksheetStores.delete(sheetId);
76637
+ }
76638
+ this.addressCache.delete(namedExpression.address.row);
76639
+ }
76640
+ getAllNamedExpressionsNamesInScope(sheetId) {
76641
+ return this.getAllNamedExpressions().filter(({ scope }) => scope === sheetId).map((ne) => ne.expression.displayName);
76642
+ }
76643
+ getAllNamedExpressionsNames() {
76644
+ return this.getAllNamedExpressions().map((ne) => ne.expression.displayName);
76645
+ }
76646
+ getAllNamedExpressions() {
76647
+ const storedNamedExpressions = [];
76648
+ this.workbookStore.getAllNamedExpressions().forEach((expr) => {
76649
+ storedNamedExpressions.push({
76650
+ expression: expr,
76651
+ scope: void 0
76652
+ });
76653
+ });
76654
+ this.worksheetStores.forEach((store2, sheetNum) => {
76655
+ store2.getAllNamedExpressions().forEach((expr) => {
76656
+ storedNamedExpressions.push({
76657
+ expression: expr,
76658
+ scope: sheetNum
76659
+ });
76660
+ });
76661
+ });
76662
+ return storedNamedExpressions;
76663
+ }
76664
+ getAllNamedExpressionsForScope(scope) {
76665
+ var _a, _b;
76666
+ if (scope === void 0) {
76667
+ return this.workbookStore.getAllNamedExpressions();
76668
+ }
76669
+ else {
76670
+ return (_b = (_a = this.worksheetStores.get(scope)) === null || _a === void 0 ? void 0 : _a.getAllNamedExpressions()) !== null && _b !== void 0 ? _b : [];
76671
+ }
76672
+ }
76673
+ worksheetStoreOrCreate(sheetId) {
76674
+ let store2 = this.worksheetStores.get(sheetId);
76675
+ if (!store2) {
76676
+ store2 = new WorksheetStore();
76677
+ this.worksheetStores.set(sheetId, store2);
76678
+ }
76679
+ return store2;
76680
+ }
76681
+ worksheetStore(sheetId) {
76682
+ return this.worksheetStores.get(sheetId);
76683
+ }
76684
+ nextAddress() {
76685
+ return simpleCellAddress(NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS, 0, this.nextNamedExpressionRow++);
76686
+ }
76687
+ }
76688
+ NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS = -1;
76689
+ const doesContainRelativeReferences = (ast) => {
76690
+ switch (ast.type) {
76691
+ case AstNodeType.EMPTY:
76692
+ case AstNodeType.NUMBER:
76693
+ case AstNodeType.STRING:
76694
+ case AstNodeType.ERROR:
76695
+ case AstNodeType.ERROR_WITH_RAW_INPUT:
76696
+ return false;
76697
+ case AstNodeType.CELL_REFERENCE:
76698
+ return !ast.reference.isAbsolute();
76699
+ case AstNodeType.CELL_RANGE:
76700
+ case AstNodeType.COLUMN_RANGE:
76701
+ case AstNodeType.ROW_RANGE:
76702
+ return !ast.start.isAbsolute();
76703
+ case AstNodeType.NAMED_EXPRESSION:
76704
+ return false;
76705
+ case AstNodeType.PERCENT_OP:
76706
+ case AstNodeType.PLUS_UNARY_OP:
76707
+ case AstNodeType.MINUS_UNARY_OP: {
76708
+ return doesContainRelativeReferences(ast.value);
76709
+ }
76710
+ case AstNodeType.CONCATENATE_OP:
76711
+ case AstNodeType.EQUALS_OP:
76712
+ case AstNodeType.NOT_EQUAL_OP:
76713
+ case AstNodeType.LESS_THAN_OP:
76714
+ case AstNodeType.GREATER_THAN_OP:
76715
+ case AstNodeType.LESS_THAN_OR_EQUAL_OP:
76716
+ case AstNodeType.GREATER_THAN_OR_EQUAL_OP:
76717
+ case AstNodeType.MINUS_OP:
76718
+ case AstNodeType.PLUS_OP:
76719
+ case AstNodeType.TIMES_OP:
76720
+ case AstNodeType.DIV_OP:
76721
+ case AstNodeType.POWER_OP:
76722
+ return doesContainRelativeReferences(ast.left) || doesContainRelativeReferences(ast.right);
76723
+ case AstNodeType.PARENTHESIS:
76724
+ return doesContainRelativeReferences(ast.expression);
76725
+ case AstNodeType.FUNCTION_CALL: {
76726
+ return ast.args.some((arg) => doesContainRelativeReferences(arg));
76727
+ }
76728
+ case AstNodeType.ARRAY: {
76729
+ return ast.args.some((row) => row.some((arg) => doesContainRelativeReferences(arg)));
76730
+ }
76731
+ }
76732
+ };
76396
76733
  class RowsSpan {
76397
76734
  constructor(sheet, rowStart, rowEnd) {
76398
76735
  this.sheet = sheet;
@@ -76784,68 +77121,164 @@ class AddressMapping {
76784
77121
  this.policy = policy;
76785
77122
  this.mapping = /* @__PURE__ */ new Map();
76786
77123
  }
76787
- /** @inheritDoc */
76788
- getCell(address) {
77124
+ /**
77125
+ * Gets the cell vertex at the specified address.
77126
+ */
77127
+ getCell(address, options = {}) {
76789
77128
  const sheetMapping = this.mapping.get(address.sheet);
76790
- if (sheetMapping === void 0) {
76791
- throw new NoSheetWithIdError(address.sheet);
77129
+ if (!sheetMapping) {
77130
+ if (options.throwIfSheetNotExists) {
77131
+ throw new NoSheetWithIdError(address.sheet);
77132
+ }
77133
+ return void 0;
77134
+ }
77135
+ const cell = sheetMapping.getCell(address);
77136
+ if (!cell && options.throwIfCellNotExists) {
77137
+ throw Error("Vertex for address missing in AddressMapping");
76792
77138
  }
76793
- return sheetMapping.getCell(address);
77139
+ return cell;
76794
77140
  }
76795
- fetchCell(address) {
77141
+ /**
77142
+ * Gets the cell vertex at the specified address or throws if it doesn't exist.
77143
+ * @throws {NoSheetWithIdError} if sheet doesn't exist
77144
+ * @throws {Error} if cell doesn't exist
77145
+ */
77146
+ getCellOrThrow(address) {
76796
77147
  const sheetMapping = this.mapping.get(address.sheet);
76797
- if (sheetMapping === void 0) {
77148
+ if (!sheetMapping) {
76798
77149
  throw new NoSheetWithIdError(address.sheet);
76799
77150
  }
76800
- const vertex = sheetMapping.getCell(address);
76801
- if (!vertex) {
77151
+ const cell = sheetMapping.getCell(address);
77152
+ if (!cell) {
76802
77153
  throw Error("Vertex for address missing in AddressMapping");
76803
77154
  }
76804
- return vertex;
77155
+ return cell;
76805
77156
  }
76806
- strategyFor(sheetId) {
77157
+ /**
77158
+ * Gets the address mapping strategy for the specified sheet.
77159
+ * @throws {NoSheetWithIdError} if sheet doesn't exist
77160
+ */
77161
+ getStrategyForSheetOrThrow(sheetId) {
76807
77162
  const strategy = this.mapping.get(sheetId);
76808
77163
  if (strategy === void 0) {
76809
77164
  throw new NoSheetWithIdError(sheetId);
76810
77165
  }
76811
77166
  return strategy;
76812
77167
  }
76813
- addSheet(sheetId, strategy) {
76814
- if (this.mapping.has(sheetId)) {
76815
- throw Error("Sheet already added");
77168
+ /**
77169
+ * Adds a new sheet with the specified strategy.
77170
+ * @throws {Error} if sheet is already added and throwIfSheetAlreadyExists is true
77171
+ */
77172
+ addSheetWithStrategy(sheetId, strategy, options = {
77173
+ throwIfSheetAlreadyExists: true
77174
+ }) {
77175
+ const strategyFound = this.mapping.get(sheetId);
77176
+ if (strategyFound) {
77177
+ if (options.throwIfSheetAlreadyExists) {
77178
+ throw Error("Sheet already added");
77179
+ }
77180
+ return strategyFound;
76816
77181
  }
76817
77182
  this.mapping.set(sheetId, strategy);
77183
+ return strategy;
77184
+ }
77185
+ /**
77186
+ * Adds a sheet or changes the strategy for an existing sheet.
77187
+ * Designed for the purpose of exchanging the placeholder strategy for a real strategy.
77188
+ */
77189
+ addSheetOrChangeStrategy(sheetId, sheetBoundaries) {
77190
+ const newStrategy = this.createStrategyBasedOnBoundaries(sheetBoundaries);
77191
+ const strategyPlaceholder = this.mapping.get(sheetId);
77192
+ if (!strategyPlaceholder) {
77193
+ this.mapping.set(sheetId, newStrategy);
77194
+ return newStrategy;
77195
+ }
77196
+ if (newStrategy instanceof DenseStrategy) {
77197
+ return strategyPlaceholder;
77198
+ }
77199
+ this.moveStrategyContent(strategyPlaceholder, newStrategy, sheetId);
77200
+ this.mapping.set(sheetId, newStrategy);
77201
+ return newStrategy;
76818
77202
  }
76819
- autoAddSheet(sheetId, sheetBoundaries) {
77203
+ /**
77204
+ * Moves the content of the source strategy to the target strategy.
77205
+ */
77206
+ moveStrategyContent(sourceStrategy, targetStrategy, sheetContext) {
77207
+ const sourceVertices = sourceStrategy.getEntries(sheetContext);
77208
+ for (const [address, vertex] of sourceVertices) {
77209
+ targetStrategy.setCell(address, vertex);
77210
+ }
77211
+ }
77212
+ /**
77213
+ * Adds a sheet and sets the strategy based on the sheet boundaries.
77214
+ * @throws {Error} if sheet already exists and throwIfSheetAlreadyExists is true
77215
+ */
77216
+ addSheetAndSetStrategyBasedOnBoundaries(sheetId, sheetBoundaries, options = {
77217
+ throwIfSheetAlreadyExists: true
77218
+ }) {
77219
+ this.addSheetWithStrategy(sheetId, this.createStrategyBasedOnBoundaries(sheetBoundaries), options);
77220
+ }
77221
+ /**
77222
+ * Creates a strategy based on the sheet boundaries.
77223
+ */
77224
+ createStrategyBasedOnBoundaries(sheetBoundaries) {
76820
77225
  const { height, width, fill } = sheetBoundaries;
76821
77226
  const strategyConstructor = this.policy.call(fill);
76822
- this.addSheet(sheetId, new strategyConstructor(width, height));
77227
+ return new strategyConstructor(width, height);
76823
77228
  }
77229
+ /**
77230
+ * Adds a placeholder strategy (DenseStrategy) for a sheet. If the sheet already exists, does nothing.
77231
+ */
77232
+ addSheetStrategyPlaceholderIfNotExists(sheetId) {
77233
+ if (this.mapping.has(sheetId)) {
77234
+ return;
77235
+ }
77236
+ this.mapping.set(sheetId, new DenseStrategy(0, 0));
77237
+ }
77238
+ /**
77239
+ * Removes a sheet from the address mapping.
77240
+ * If sheet does not exist, does nothing.
77241
+ * @returns {boolean} true if sheet was removed, false if it did not exist.
77242
+ */
77243
+ removeSheetIfExists(sheetId) {
77244
+ return this.mapping.delete(sheetId);
77245
+ }
77246
+ /**
77247
+ * Gets the interpreter value of a cell at the specified address.
77248
+ * @returns {InterpreterValue} The interpreter value (returns EmptyValue if cell doesn't exist)
77249
+ */
76824
77250
  getCellValue(address) {
76825
77251
  const vertex = this.getCell(address);
76826
77252
  if (vertex === void 0) {
76827
77253
  return EmptyValue;
76828
77254
  }
76829
- else if (vertex instanceof ArrayVertex) {
77255
+ else if (vertex instanceof ArrayFormulaVertex) {
76830
77256
  return vertex.getArrayCellValue(address);
76831
77257
  }
76832
77258
  else {
76833
77259
  return vertex.getCellValue();
76834
77260
  }
76835
77261
  }
77262
+ /**
77263
+ * Gets the raw cell content at the specified address.
77264
+ * @returns {RawCellContent} The raw cell content or null if cell doesn't exist or is not a value cell
77265
+ */
76836
77266
  getRawValue(address) {
76837
77267
  const vertex = this.getCell(address);
76838
77268
  if (vertex instanceof ValueCellVertex) {
76839
77269
  return vertex.getValues().rawValue;
76840
77270
  }
76841
- else if (vertex instanceof ArrayVertex) {
77271
+ else if (vertex instanceof ArrayFormulaVertex) {
76842
77272
  return vertex.getArrayCellRawValue(address);
76843
77273
  }
76844
77274
  else {
76845
77275
  return null;
76846
77276
  }
76847
77277
  }
76848
- /** @inheritDoc */
77278
+ /**
77279
+ * Sets a cell vertex at the specified address.
77280
+ * @throws {Error} if sheet not initialized
77281
+ */
76849
77282
  setCell(address, newVertex) {
76850
77283
  const sheetMapping = this.mapping.get(address.sheet);
76851
77284
  if (!sheetMapping) {
@@ -76853,15 +77286,19 @@ class AddressMapping {
76853
77286
  }
76854
77287
  sheetMapping.setCell(address, newVertex);
76855
77288
  }
77289
+ /**
77290
+ * Moves a cell from source address to destination address.
77291
+ * Supports cross-sheet moves (used for placeholder sheet merging).
77292
+ * @throws {Error} if source sheet not initialized
77293
+ * @throws {Error} if destination occupied
77294
+ * @throws {Error} if source cell doesn't exist
77295
+ */
76856
77296
  moveCell(source, destination) {
76857
77297
  const sheetMapping = this.mapping.get(source.sheet);
76858
77298
  if (!sheetMapping) {
76859
77299
  throw Error("Sheet not initialized.");
76860
77300
  }
76861
- if (source.sheet !== destination.sheet) {
76862
- throw Error("Cannot move cells between sheets.");
76863
- }
76864
- if (sheetMapping.has(destination)) {
77301
+ if (this.has(destination)) {
76865
77302
  throw new Error("Cannot move cell. Destination already occupied.");
76866
77303
  }
76867
77304
  const vertex = sheetMapping.getCell(source);
@@ -76871,6 +77308,10 @@ class AddressMapping {
76871
77308
  this.setCell(destination, vertex);
76872
77309
  this.removeCell(source);
76873
77310
  }
77311
+ /**
77312
+ * Removes a cell at the specified address.
77313
+ * @throws Error if sheet not initialized
77314
+ */
76874
77315
  removeCell(address) {
76875
77316
  const sheetMapping = this.mapping.get(address.sheet);
76876
77317
  if (!sheetMapping) {
@@ -76878,7 +77319,9 @@ class AddressMapping {
76878
77319
  }
76879
77320
  sheetMapping.removeCell(address);
76880
77321
  }
76881
- /** @inheritDoc */
77322
+ /**
77323
+ * Checks if a cell exists at the specified address.
77324
+ */
76882
77325
  has(address) {
76883
77326
  const sheetMapping = this.mapping.get(address.sheet);
76884
77327
  if (sheetMapping === void 0) {
@@ -76886,78 +77329,99 @@ class AddressMapping {
76886
77329
  }
76887
77330
  return sheetMapping.has(address);
76888
77331
  }
76889
- /** @inheritDoc */
76890
- getHeight(sheetId) {
76891
- const sheetMapping = this.mapping.get(sheetId);
76892
- if (sheetMapping === void 0) {
76893
- throw new NoSheetWithIdError(sheetId);
76894
- }
77332
+ /**
77333
+ * Gets the height of the specified sheet.
77334
+ */
77335
+ getSheetHeight(sheetId) {
77336
+ const sheetMapping = this.getStrategyForSheetOrThrow(sheetId);
76895
77337
  return sheetMapping.getHeight();
76896
77338
  }
76897
- /** @inheritDoc */
76898
- getWidth(sheetId) {
76899
- const sheetMapping = this.mapping.get(sheetId);
76900
- if (!sheetMapping) {
76901
- throw new NoSheetWithIdError(sheetId);
76902
- }
77339
+ /**
77340
+ * Gets the width of the specified sheet.
77341
+ */
77342
+ getSheetWidth(sheetId) {
77343
+ const sheetMapping = this.getStrategyForSheetOrThrow(sheetId);
76903
77344
  return sheetMapping.getWidth();
76904
77345
  }
76905
- addRows(sheet, row, numberOfRows) {
76906
- const sheetMapping = this.mapping.get(sheet);
76907
- if (sheetMapping === void 0) {
76908
- throw new NoSheetWithIdError(sheet);
76909
- }
77346
+ /**
77347
+ * Adds rows to a sheet.
77348
+ */
77349
+ addRows(sheetId, row, numberOfRows) {
77350
+ const sheetMapping = this.getStrategyForSheetOrThrow(sheetId);
76910
77351
  sheetMapping.addRows(row, numberOfRows);
76911
77352
  }
77353
+ /**
77354
+ * Removes rows from a sheet.
77355
+ */
76912
77356
  removeRows(removedRows) {
76913
- const sheetMapping = this.mapping.get(removedRows.sheet);
76914
- if (sheetMapping === void 0) {
76915
- throw new NoSheetWithIdError(removedRows.sheet);
76916
- }
77357
+ const sheetMapping = this.getStrategyForSheetOrThrow(removedRows.sheet);
76917
77358
  sheetMapping.removeRows(removedRows);
76918
77359
  }
76919
- removeSheet(sheetId) {
76920
- this.mapping.delete(sheetId);
76921
- }
76922
- addColumns(sheet, column, numberOfColumns) {
76923
- const sheetMapping = this.mapping.get(sheet);
76924
- if (sheetMapping === void 0) {
76925
- throw new NoSheetWithIdError(sheet);
76926
- }
77360
+ /**
77361
+ * Adds columns to a sheet starting at the specified column index.
77362
+ */
77363
+ addColumns(sheetId, column, numberOfColumns) {
77364
+ const sheetMapping = this.getStrategyForSheetOrThrow(sheetId);
76927
77365
  sheetMapping.addColumns(column, numberOfColumns);
76928
77366
  }
77367
+ /**
77368
+ * Removes columns from a sheet.
77369
+ */
76929
77370
  removeColumns(removedColumns) {
76930
- const sheetMapping = this.mapping.get(removedColumns.sheet);
76931
- if (sheetMapping === void 0) {
76932
- throw new NoSheetWithIdError(removedColumns.sheet);
76933
- }
77371
+ const sheetMapping = this.getStrategyForSheetOrThrow(removedColumns.sheet);
76934
77372
  sheetMapping.removeColumns(removedColumns);
76935
77373
  }
77374
+ /**
77375
+ * Returns an iterator of cell vertices within the specified rows span.
77376
+ */
76936
77377
  *verticesFromRowsSpan(rowsSpan) {
76937
77378
  yield* this.mapping.get(rowsSpan.sheet).verticesFromRowsSpan(rowsSpan);
76938
77379
  }
77380
+ /**
77381
+ * Returns an iterator of cell vertices within the specified columns span.
77382
+ */
76939
77383
  *verticesFromColumnsSpan(columnsSpan) {
76940
77384
  yield* this.mapping.get(columnsSpan.sheet).verticesFromColumnsSpan(columnsSpan);
76941
77385
  }
77386
+ /**
77387
+ * Returns an iterator of address-vertex pairs within the specified rows span.
77388
+ */
76942
77389
  *entriesFromRowsSpan(rowsSpan) {
76943
- yield* this.mapping.get(rowsSpan.sheet).entriesFromRowsSpan(rowsSpan);
77390
+ const sheetMapping = this.getStrategyForSheetOrThrow(rowsSpan.sheet);
77391
+ yield* sheetMapping.entriesFromRowsSpan(rowsSpan);
76944
77392
  }
77393
+ /**
77394
+ * Returns an iterator of address-vertex pairs within the specified columns span.
77395
+ */
76945
77396
  *entriesFromColumnsSpan(columnsSpan) {
76946
- yield* this.mapping.get(columnsSpan.sheet).entriesFromColumnsSpan(columnsSpan);
77397
+ const sheetMapping = this.getStrategyForSheetOrThrow(columnsSpan.sheet);
77398
+ yield* sheetMapping.entriesFromColumnsSpan(columnsSpan);
76947
77399
  }
77400
+ /**
77401
+ * Returns an iterator of all address-vertex pairs across all sheets.
77402
+ * @returns {IterableIterator<[SimpleCellAddress, Maybe<CellVertex>]>} Iterator of [address, vertex] tuples
77403
+ */
76948
77404
  *entries() {
76949
77405
  for (const [sheet, mapping] of this.mapping.entries()) {
76950
77406
  yield* mapping.getEntries(sheet);
76951
77407
  }
76952
77408
  }
76953
- *sheetEntries(sheet) {
76954
- const sheetMapping = this.mapping.get(sheet);
76955
- if (sheetMapping !== void 0) {
76956
- yield* sheetMapping.getEntries(sheet);
76957
- }
76958
- else {
76959
- throw new NoSheetWithIdError(sheet);
76960
- }
77409
+ /**
77410
+ * Returns an iterator of address-vertex pairs for a specific sheet.
77411
+ * @returns {IterableIterator<[SimpleCellAddress, CellVertex]>} Iterator of [address, vertex] tuples
77412
+ * @throws {NoSheetWithIdError} if sheet doesn't exist
77413
+ */
77414
+ *sheetEntries(sheetId) {
77415
+ const sheetMapping = this.getStrategyForSheetOrThrow(sheetId);
77416
+ yield* sheetMapping.getEntries(sheetId);
77417
+ }
77418
+ /**
77419
+ * Checks if a sheet has any entries.
77420
+ * @throws {NoSheetWithIdError} if sheet doesn't exist
77421
+ */
77422
+ hasAnyEntries(sheetId) {
77423
+ const iterator = this.sheetEntries(sheetId);
77424
+ return !iterator.next().done;
76961
77425
  }
76962
77426
  }
76963
77427
  class ArrayMapping {
@@ -77225,10 +77689,10 @@ class FormulaVertex {
77225
77689
  }
77226
77690
  static fromAst(formula, address, size2, version) {
77227
77691
  if (size2.isScalar()) {
77228
- return new FormulaCellVertex(formula, address, version);
77692
+ return new ScalarFormulaVertex(formula, address, version);
77229
77693
  }
77230
77694
  else {
77231
- return new ArrayVertex(formula, address, size2, version);
77695
+ return new ArrayFormulaVertex(formula, address, size2, version);
77232
77696
  }
77233
77697
  }
77234
77698
  /**
@@ -77254,7 +77718,7 @@ class FormulaVertex {
77254
77718
  return this.cellAddress;
77255
77719
  }
77256
77720
  }
77257
- class ArrayVertex extends FormulaVertex {
77721
+ class ArrayFormulaVertex extends FormulaVertex {
77258
77722
  constructor(formula, cellAddress, size2, version = 0) {
77259
77723
  super(formula, cellAddress, version);
77260
77724
  if (size2.isRef) {
@@ -77367,7 +77831,7 @@ class ArrayVertex extends FormulaVertex {
77367
77831
  this.array = new ErroredArray(error, this.array.size);
77368
77832
  }
77369
77833
  }
77370
- class FormulaCellVertex extends FormulaVertex {
77834
+ class ScalarFormulaVertex extends FormulaVertex {
77371
77835
  constructor(formula, address, version) {
77372
77836
  super(formula, address, version);
77373
77837
  }
@@ -77472,18 +77936,6 @@ class RangeVertex {
77472
77936
  this.dependentCacheRanges.forEach((range2) => range2.criterionFunctionCache.clear());
77473
77937
  this.dependentCacheRanges.clear();
77474
77938
  }
77475
- /**
77476
- * Returns start of the range (it's top-left corner)
77477
- */
77478
- getStart() {
77479
- return this.start;
77480
- }
77481
- /**
77482
- * Returns end of the range (it's bottom-right corner)
77483
- */
77484
- getEnd() {
77485
- return this.end;
77486
- }
77487
77939
  }
77488
77940
  const collectAddressesDependentToRange = (functionRegistry, vertex, range2, lazilyTransformingAstService, dependencyGraph) => {
77489
77941
  if (vertex instanceof RangeVertex) {
@@ -77964,38 +78416,42 @@ class Graph {
77964
78416
  * Returns error for missing node.
77965
78417
  */
77966
78418
  missingNodeError(node2) {
77967
- return new Error(`Unknown node ${node2}`);
78419
+ return new Error(`Unknown node ${JSON.stringify(node2)}`);
77968
78420
  }
77969
78421
  }
77970
78422
  class RangeMapping {
77971
78423
  constructor() {
77972
78424
  this.rangeMapping = /* @__PURE__ */ new Map();
77973
78425
  }
77974
- getMappingSize(sheet) {
78426
+ /**
78427
+ * Returns number of ranges in the sheet or 0 if the sheet does not exist
78428
+ */
78429
+ getNumberOfRangesInSheet(sheet) {
77975
78430
  var _a, _b;
77976
78431
  return (_b = (_a = this.rangeMapping.get(sheet)) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0;
77977
78432
  }
77978
78433
  /**
77979
- * Saves range vertex
77980
- *
77981
- * @param vertex - vertex to save
78434
+ * Adds or updates vertex in the mapping
77982
78435
  */
77983
- setRange(vertex) {
77984
- let sheetMap = this.rangeMapping.get(vertex.getStart().sheet);
78436
+ addOrUpdateVertex(vertex) {
78437
+ let sheetMap = this.rangeMapping.get(vertex.sheet);
77985
78438
  if (sheetMap === void 0) {
77986
78439
  sheetMap = /* @__PURE__ */ new Map();
77987
- this.rangeMapping.set(vertex.getStart().sheet, sheetMap);
78440
+ this.rangeMapping.set(vertex.sheet, sheetMap);
77988
78441
  }
77989
- const key = keyFromAddresses(vertex.getStart(), vertex.getEnd());
78442
+ const key = RangeMapping.calculateRangeKey(vertex.start, vertex.end);
77990
78443
  sheetMap.set(key, vertex);
77991
78444
  }
77992
- removeRange(vertex) {
77993
- const sheet = vertex.getStart().sheet;
78445
+ /**
78446
+ * Removes vertex from the mapping if it exists
78447
+ */
78448
+ removeVertexIfExists(vertex) {
78449
+ const sheet = vertex.sheet;
77994
78450
  const sheetMap = this.rangeMapping.get(sheet);
77995
78451
  if (sheetMap === void 0) {
77996
78452
  return;
77997
78453
  }
77998
- const key = keyFromAddresses(vertex.getStart(), vertex.getEnd());
78454
+ const key = RangeMapping.calculateRangeKey(vertex.start, vertex.end);
77999
78455
  sheetMap.delete(key);
78000
78456
  if (sheetMap.size === 0) {
78001
78457
  this.rangeMapping.delete(sheet);
@@ -78003,17 +78459,17 @@ class RangeMapping {
78003
78459
  }
78004
78460
  /**
78005
78461
  * Returns associated vertex for given range
78006
- *
78007
- * @param start - top-left corner of the range
78008
- * @param end - bottom-right corner of the range
78009
78462
  */
78010
- getRange(start, end) {
78463
+ getRangeVertex(start, end) {
78011
78464
  const sheetMap = this.rangeMapping.get(start.sheet);
78012
- const key = keyFromAddresses(start, end);
78465
+ const key = RangeMapping.calculateRangeKey(start, end);
78013
78466
  return sheetMap === null || sheetMap === void 0 ? void 0 : sheetMap.get(key);
78014
78467
  }
78015
- fetchRange(start, end) {
78016
- const maybeRange = this.getRange(start, end);
78468
+ /**
78469
+ * Returns associated vertex for given range or throws an error if not found
78470
+ */
78471
+ getVertexOrThrow(start, end) {
78472
+ const maybeRange = this.getRangeVertex(start, end);
78017
78473
  if (!maybeRange) {
78018
78474
  throw Error("Range does not exist");
78019
78475
  }
@@ -78039,9 +78495,9 @@ class RangeMapping {
78039
78495
  }
78040
78496
  }
78041
78497
  const verticesToMerge = [];
78042
- updated.sort((left, right) => compareBy(left[1], right[1], coordinate));
78498
+ updated.sort((left, right) => RangeMapping.compareBy(left[1], right[1], coordinate));
78043
78499
  for (const [oldKey, vertex] of updated) {
78044
- const newKey = keyFromRange(vertex.range);
78500
+ const newKey = RangeMapping.calculateRangeKey(vertex.range.start, vertex.range.end);
78045
78501
  if (newKey === oldKey) {
78046
78502
  continue;
78047
78503
  }
@@ -78051,7 +78507,7 @@ class RangeMapping {
78051
78507
  verticesToMerge.push([existingVertex, vertex]);
78052
78508
  }
78053
78509
  else {
78054
- this.setRange(vertex);
78510
+ this.addOrUpdateVertex(vertex);
78055
78511
  }
78056
78512
  }
78057
78513
  return {
@@ -78060,7 +78516,7 @@ class RangeMapping {
78060
78516
  verticesWithChangedSize
78061
78517
  };
78062
78518
  }
78063
- moveAllRangesInSheetAfterRowByRows(sheet, row, numberOfRows) {
78519
+ moveAllRangesInSheetAfterAddingRows(sheet, row, numberOfRows) {
78064
78520
  return this.updateVerticesFromSheet(sheet, (key, vertex) => {
78065
78521
  if (row <= vertex.start.row) {
78066
78522
  vertex.range.shiftByRows(numberOfRows);
@@ -78081,7 +78537,7 @@ class RangeMapping {
78081
78537
  }
78082
78538
  });
78083
78539
  }
78084
- moveAllRangesInSheetAfterColumnByColumns(sheet, column, numberOfColumns) {
78540
+ moveAllRangesInSheetAfterAddingColumns(sheet, column, numberOfColumns) {
78085
78541
  return this.updateVerticesFromSheet(sheet, (key, vertex) => {
78086
78542
  if (column <= vertex.start.col) {
78087
78543
  vertex.range.shiftByColumns(numberOfColumns);
@@ -78118,14 +78574,6 @@ class RangeMapping {
78118
78574
  }
78119
78575
  });
78120
78576
  }
78121
- removeRangesInSheet(sheet) {
78122
- if (this.rangeMapping.has(sheet)) {
78123
- const ranges = this.rangeMapping.get(sheet).values();
78124
- this.rangeMapping.delete(sheet);
78125
- return ranges;
78126
- }
78127
- return [][Symbol.iterator]();
78128
- }
78129
78577
  *rangesInSheet(sheet) {
78130
78578
  const sheetMap = this.rangeMapping.get(sheet);
78131
78579
  if (!sheetMap) {
@@ -78141,14 +78589,12 @@ class RangeMapping {
78141
78589
  }
78142
78590
  }
78143
78591
  /**
78144
- * Finds smaller range does have own vertex.
78145
- *
78146
- * @param range
78592
+ * Finds smaller range if exists.
78147
78593
  */
78148
78594
  findSmallerRange(range2) {
78149
78595
  if (range2.height() > 1 && Number.isFinite(range2.height())) {
78150
78596
  const valuesRangeEndRowLess = simpleCellAddress(range2.end.sheet, range2.end.col, range2.end.row - 1);
78151
- const rowLessVertex = this.getRange(range2.start, valuesRangeEndRowLess);
78597
+ const rowLessVertex = this.getRangeVertex(range2.start, valuesRangeEndRowLess);
78152
78598
  if (rowLessVertex !== void 0) {
78153
78599
  const restRange = AbsoluteCellRange.fromSimpleCellAddresses(simpleCellAddress(range2.start.sheet, range2.start.col, range2.end.row), range2.end);
78154
78600
  return {
@@ -78161,6 +78607,27 @@ class RangeMapping {
78161
78607
  restRange: range2
78162
78608
  };
78163
78609
  }
78610
+ /**
78611
+ * Calculates a string key from start and end addresses
78612
+ */
78613
+ static calculateRangeKey(start, end) {
78614
+ return `${start.col},${start.row},${end.col},${end.row}`;
78615
+ }
78616
+ /**
78617
+ * Compares two range vertices by their start and end addresses using the provided coordinate function
78618
+ */
78619
+ static compareBy(left, right, coordinate) {
78620
+ const leftStart = coordinate(left.range.start);
78621
+ const rightStart = coordinate(right.range.start);
78622
+ if (leftStart === rightStart) {
78623
+ const leftEnd = coordinate(left.range.end);
78624
+ const rightEnd = coordinate(right.range.end);
78625
+ return leftEnd - rightEnd;
78626
+ }
78627
+ else {
78628
+ return leftStart - rightStart;
78629
+ }
78630
+ }
78164
78631
  *entriesFromSheet(sheet) {
78165
78632
  const sheetMap = this.rangeMapping.get(sheet);
78166
78633
  if (!sheetMap) {
@@ -78169,7 +78636,11 @@ class RangeMapping {
78169
78636
  yield* sheetMap.entries();
78170
78637
  }
78171
78638
  removeByKey(sheet, key) {
78172
- this.rangeMapping.get(sheet).delete(key);
78639
+ const sheetMap = this.rangeMapping.get(sheet);
78640
+ if (!sheetMap) {
78641
+ throw new Error(`Sheet ${sheet} not found`);
78642
+ }
78643
+ sheetMap.delete(key);
78173
78644
  }
78174
78645
  getByKey(sheet, key) {
78175
78646
  var _a;
@@ -78185,31 +78656,13 @@ class RangeMapping {
78185
78656
  }
78186
78657
  }
78187
78658
  updated.forEach((entry) => {
78188
- this.setRange(entry.vertex);
78659
+ this.addOrUpdateVertex(entry.vertex);
78189
78660
  });
78190
78661
  return {
78191
78662
  verticesWithChangedSize: updated.filter((entry) => entry.changedSize).map((entry) => entry.vertex)
78192
78663
  };
78193
78664
  }
78194
78665
  }
78195
- function keyFromAddresses(start, end) {
78196
- return `${start.col},${start.row},${end.col},${end.row}`;
78197
- }
78198
- function keyFromRange(range2) {
78199
- return keyFromAddresses(range2.start, range2.end);
78200
- }
78201
- const compareBy = (left, right, coordinate) => {
78202
- const leftStart = coordinate(left.range.start);
78203
- const rightStart = coordinate(left.range.start);
78204
- if (leftStart === rightStart) {
78205
- const leftEnd = coordinate(left.range.end);
78206
- const rightEnd = coordinate(right.range.end);
78207
- return leftEnd - rightEnd;
78208
- }
78209
- else {
78210
- return leftStart - rightStart;
78211
- }
78212
- };
78213
78666
  class TranslationPackage {
78214
78667
  constructor(functions, errors2, ui) {
78215
78668
  this.functions = functions;
@@ -78314,107 +78767,361 @@ var UIElement;
78314
78767
  (function (UIElement2) {
78315
78768
  UIElement2["NEW_SHEET_PREFIX"] = "NEW_SHEET_PREFIX";
78316
78769
  })(UIElement || (UIElement = {}));
78317
- function canonicalize(sheetDisplayName) {
78318
- return sheetDisplayName.toLowerCase();
78319
- }
78320
78770
  class Sheet {
78321
- constructor(id2, displayName) {
78771
+ constructor(id2, displayName, isPlaceholder = false) {
78322
78772
  this.id = id2;
78323
78773
  this.displayName = displayName;
78774
+ this.isPlaceholder = isPlaceholder;
78324
78775
  }
78776
+ /**
78777
+ * Returns the canonical (normalized) name of the sheet.
78778
+ */
78325
78779
  get canonicalName() {
78326
- return canonicalize(this.displayName);
78780
+ return SheetMapping.canonicalizeSheetName(this.displayName);
78327
78781
  }
78328
78782
  }
78329
78783
  class SheetMapping {
78330
78784
  constructor(languages) {
78331
- this.languages = languages;
78332
- this.mappingFromCanonicalName = /* @__PURE__ */ new Map();
78333
- this.mappingFromId = /* @__PURE__ */ new Map();
78334
78785
  this.lastSheetId = -1;
78335
- this.fetch = (sheetName) => {
78336
- const sheet = this.mappingFromCanonicalName.get(canonicalize(sheetName));
78337
- if (sheet === void 0) {
78338
- throw new NoSheetWithNameError(sheetName);
78339
- }
78340
- return sheet.id;
78341
- };
78342
- this.get = (sheetName) => {
78343
- var _a;
78344
- return (_a = this.mappingFromCanonicalName.get(canonicalize(sheetName))) === null || _a === void 0 ? void 0 : _a.id;
78345
- };
78346
- this.fetchDisplayName = (sheetId) => {
78347
- return this.fetchSheetById(sheetId).displayName;
78348
- };
78786
+ this.mappingFromCanonicalNameToId = /* @__PURE__ */ new Map();
78787
+ this.allSheets = /* @__PURE__ */ new Map();
78349
78788
  this.sheetNamePrefix = languages.getUITranslation(UIElement.NEW_SHEET_PREFIX);
78350
78789
  }
78790
+ /**
78791
+ * Converts sheet name to canonical/normalized form.
78792
+ * @static
78793
+ */
78794
+ static canonicalizeSheetName(sheetDisplayName) {
78795
+ return sheetDisplayName.toLowerCase();
78796
+ }
78797
+ /**
78798
+ * Returns sheet ID for the given name. By default excludes placeholders.
78799
+ */
78800
+ getSheetId(sheetName, options = {}) {
78801
+ var _a;
78802
+ return (_a = this._getSheetByName(sheetName, options)) === null || _a === void 0 ? void 0 : _a.id;
78803
+ }
78804
+ /**
78805
+ * Returns sheet ID for the given name. Excludes placeholders.
78806
+ *
78807
+ * @throws {NoSheetWithNameError} if the sheet with the given name does not exist.
78808
+ */
78809
+ getSheetIdOrThrowError(sheetName) {
78810
+ const sheet = this._getSheetByName(sheetName, {});
78811
+ if (sheet === void 0) {
78812
+ throw new NoSheetWithNameError(sheetName);
78813
+ }
78814
+ return sheet.id;
78815
+ }
78816
+ /**
78817
+ * Returns display name for the given sheet ID. Excludes placeholders.
78818
+ *
78819
+ * @returns {Maybe<string>} the display name, or undefined if the sheet with the given ID does not exist.
78820
+ */
78821
+ getSheetName(sheetId) {
78822
+ var _a;
78823
+ return (_a = this._getSheet(sheetId, {})) === null || _a === void 0 ? void 0 : _a.displayName;
78824
+ }
78825
+ /**
78826
+ * Returns display name for the given sheet ID. Excludes placeholders.
78827
+ *
78828
+ * @throws {NoSheetWithIdError} if the sheet with the given ID does not exist.
78829
+ */
78830
+ getSheetNameOrThrowError(sheetId, options = {}) {
78831
+ return this._getSheetOrThrowError(sheetId, options).displayName;
78832
+ }
78833
+ /**
78834
+ * Iterates over all sheet display names. By default excludes placeholders.
78835
+ */
78836
+ *iterateSheetNames(options = {}) {
78837
+ for (const sheet of this.allSheets.values()) {
78838
+ if (options.includePlaceholders || !sheet.isPlaceholder) {
78839
+ yield sheet.displayName;
78840
+ }
78841
+ }
78842
+ }
78843
+ /**
78844
+ * Returns array of all sheet display names. By default excludes placeholders.
78845
+ */
78846
+ getSheetNames(options = {}) {
78847
+ return Array.from(this.iterateSheetNames(options));
78848
+ }
78849
+ /**
78850
+ * Returns total count of sheets. By default excludes placeholders.
78851
+ */
78852
+ numberOfSheets(options = {}) {
78853
+ return this.getSheetNames(options).length;
78854
+ }
78855
+ /**
78856
+ * Checks if sheet with given ID exists. By default excludes placeholders.
78857
+ */
78858
+ hasSheetWithId(sheetId, options = {}) {
78859
+ return this._getSheet(sheetId, options) !== void 0;
78860
+ }
78861
+ /**
78862
+ * Checks if sheet with given name exists (case-insensitive). Excludes placeholders.
78863
+ */
78864
+ hasSheetWithName(sheetName) {
78865
+ return this._getSheetByName(sheetName, {}) !== void 0;
78866
+ }
78867
+ /**
78868
+ * Adds new sheet with optional name and returns its ID.
78869
+ * If called with a name of an existing placeholder sheet, converts the placeholder sheet to a real sheet.
78870
+ *
78871
+ * @throws {SheetNameAlreadyTakenError} if the sheet with the given name already exists.
78872
+ */
78351
78873
  addSheet(newSheetDisplayName = `${this.sheetNamePrefix}${this.lastSheetId + 2}`) {
78352
- const newSheetCanonicalName = canonicalize(newSheetDisplayName);
78353
- if (this.mappingFromCanonicalName.has(newSheetCanonicalName)) {
78354
- throw new SheetNameAlreadyTakenError(newSheetDisplayName);
78874
+ const sheetWithConflictingName = this._getSheetByName(newSheetDisplayName, {
78875
+ includePlaceholders: true
78876
+ });
78877
+ if (sheetWithConflictingName) {
78878
+ if (!sheetWithConflictingName.isPlaceholder) {
78879
+ throw new SheetNameAlreadyTakenError(newSheetDisplayName);
78880
+ }
78881
+ sheetWithConflictingName.isPlaceholder = false;
78882
+ return sheetWithConflictingName.id;
78355
78883
  }
78356
78884
  this.lastSheetId++;
78357
78885
  const sheet = new Sheet(this.lastSheetId, newSheetDisplayName);
78358
- this.store(sheet);
78886
+ this._storeSheetInMappings(sheet);
78359
78887
  return sheet.id;
78360
78888
  }
78361
- removeSheet(sheetId) {
78362
- const sheet = this.fetchSheetById(sheetId);
78363
- if (sheetId == this.lastSheetId) {
78364
- --this.lastSheetId;
78889
+ /**
78890
+ * Adds a sheet with a specific ID and name. Used for redo operations.
78891
+ * If called with a name of an existing placeholder sheet, converts the placeholder sheet to a real sheet.
78892
+ *
78893
+ * @throws {SheetNameAlreadyTakenError} if the sheet with the given name already exists.
78894
+ */
78895
+ addSheetWithId(sheetId, sheetDisplayName) {
78896
+ const sheetWithConflictingName = this._getSheetByName(sheetDisplayName, {
78897
+ includePlaceholders: true
78898
+ });
78899
+ if (sheetWithConflictingName) {
78900
+ if (sheetWithConflictingName.id !== sheetId) {
78901
+ throw new SheetNameAlreadyTakenError(sheetDisplayName);
78902
+ }
78903
+ if (!sheetWithConflictingName.isPlaceholder) {
78904
+ throw new SheetNameAlreadyTakenError(sheetDisplayName);
78905
+ }
78906
+ sheetWithConflictingName.isPlaceholder = false;
78907
+ return;
78365
78908
  }
78366
- this.mappingFromCanonicalName.delete(sheet.canonicalName);
78367
- this.mappingFromId.delete(sheet.id);
78368
- }
78369
- getDisplayName(sheetId) {
78370
- var _a;
78371
- return (_a = this.mappingFromId.get(sheetId)) === null || _a === void 0 ? void 0 : _a.displayName;
78909
+ if (sheetId > this.lastSheetId) {
78910
+ this.lastSheetId = sheetId;
78911
+ }
78912
+ const sheet = new Sheet(sheetId, sheetDisplayName);
78913
+ this._storeSheetInMappings(sheet);
78372
78914
  }
78373
- *displayNames() {
78374
- for (const sheet of this.mappingFromCanonicalName.values()) {
78375
- yield sheet.displayName;
78915
+ /**
78916
+ * Adds a placeholder sheet with the given name if it does not exist yet
78917
+ */
78918
+ addPlaceholderIfNotExists(sheetName) {
78919
+ const sheetWithConflictingName = this._getSheetByName(sheetName, {
78920
+ includePlaceholders: true
78921
+ });
78922
+ if (sheetWithConflictingName) {
78923
+ return sheetWithConflictingName.id;
78376
78924
  }
78925
+ this.lastSheetId++;
78926
+ const sheet = new Sheet(this.lastSheetId, sheetName, true);
78927
+ this._storeSheetInMappings(sheet);
78928
+ return sheet.id;
78377
78929
  }
78378
- numberOfSheets() {
78379
- return this.mappingFromCanonicalName.size;
78930
+ /**
78931
+ * Adds a placeholder sheet with a specific ID and name.
78932
+ * Used for undo operations to restore previously merged placeholder sheets.
78933
+ *
78934
+ * @throws {SheetNameAlreadyTakenError} if the sheet with the given name already exists.
78935
+ */
78936
+ addPlaceholderWithId(sheetId, sheetDisplayName) {
78937
+ const sheetWithConflictingName = this._getSheetByName(sheetDisplayName, {
78938
+ includePlaceholders: true
78939
+ });
78940
+ if (sheetWithConflictingName) {
78941
+ throw new SheetNameAlreadyTakenError(sheetDisplayName);
78942
+ }
78943
+ if (this.hasSheetWithId(sheetId, {
78944
+ includePlaceholders: true
78945
+ })) {
78946
+ throw new Error(`Sheet with id ${sheetId} already exists`);
78947
+ }
78948
+ if (sheetId > this.lastSheetId) {
78949
+ this.lastSheetId = sheetId;
78950
+ }
78951
+ const sheet = new Sheet(sheetId, sheetDisplayName, true);
78952
+ this._storeSheetInMappings(sheet);
78380
78953
  }
78381
- hasSheetWithId(sheetId) {
78382
- return this.mappingFromId.has(sheetId);
78954
+ /**
78955
+ *
78956
+ * Removes sheet with given ID.
78957
+ * If sheet does not exist, does nothing.
78958
+ * @returns {boolean} true if sheet was removed, false if it did not exist.
78959
+ */
78960
+ removeSheetIfExists(sheetId, options = {}) {
78961
+ const sheet = this._getSheet(sheetId, options);
78962
+ if (!sheet) {
78963
+ return false;
78964
+ }
78965
+ this.allSheets.delete(sheetId);
78966
+ this.mappingFromCanonicalNameToId.delete(sheet.canonicalName);
78967
+ if (sheetId === this.lastSheetId) {
78968
+ this.lastSheetId--;
78969
+ }
78970
+ return true;
78383
78971
  }
78384
- hasSheetWithName(sheetName) {
78385
- return this.mappingFromCanonicalName.has(canonicalize(sheetName));
78972
+ /**
78973
+ * Marks sheet with given ID as a placeholder.
78974
+ * @throws {NoSheetWithIdError} if the sheet with the given ID does not exist
78975
+ */
78976
+ markSheetAsPlaceholder(sheetId) {
78977
+ const sheet = this._getSheetOrThrowError(sheetId, {});
78978
+ sheet.isPlaceholder = true;
78386
78979
  }
78980
+ /**
78981
+ * Renames sheet.
78982
+ * - If called with sheetId of a placeholder sheet, throws {NoSheetWithIdError}.
78983
+ * - If newDisplayName is conflicting with an existing sheet, throws {SheetNameAlreadyTakenError}.
78984
+ * - If newDisplayName is conflicting with a placeholder sheet name, deletes the placeholder sheet and returns its id as mergedWithPlaceholderSheet.
78985
+ *
78986
+ * @throws {SheetNameAlreadyTakenError} if the sheet with the given name already exists.
78987
+ * @throws {NoSheetWithIdError} if the sheet with the given ID does not exist.
78988
+ */
78387
78989
  renameSheet(sheetId, newDisplayName) {
78388
- const sheet = this.fetchSheetById(sheetId);
78990
+ const sheet = this._getSheetOrThrowError(sheetId, {});
78389
78991
  const currentDisplayName = sheet.displayName;
78390
78992
  if (currentDisplayName === newDisplayName) {
78391
- return void 0;
78993
+ return {
78994
+ previousDisplayName: void 0
78995
+ };
78392
78996
  }
78393
- const sheetWithThisCanonicalName = this.mappingFromCanonicalName.get(canonicalize(newDisplayName));
78394
- if (sheetWithThisCanonicalName !== void 0 && sheetWithThisCanonicalName.id !== sheet.id) {
78395
- throw new SheetNameAlreadyTakenError(newDisplayName);
78997
+ const sheetWithConflictingName = this._getSheetByName(newDisplayName, {
78998
+ includePlaceholders: true
78999
+ });
79000
+ let mergedWithPlaceholderSheet = void 0;
79001
+ if (sheetWithConflictingName !== void 0 && sheetWithConflictingName.id !== sheet.id) {
79002
+ if (!sheetWithConflictingName.isPlaceholder) {
79003
+ throw new SheetNameAlreadyTakenError(newDisplayName);
79004
+ }
79005
+ else {
79006
+ this.mappingFromCanonicalNameToId.delete(sheetWithConflictingName.canonicalName);
79007
+ this.allSheets.delete(sheetWithConflictingName.id);
79008
+ if (sheetWithConflictingName.id === this.lastSheetId) {
79009
+ this.lastSheetId--;
79010
+ }
79011
+ mergedWithPlaceholderSheet = sheetWithConflictingName.id;
79012
+ }
78396
79013
  }
78397
79014
  const currentCanonicalName = sheet.canonicalName;
78398
- this.mappingFromCanonicalName.delete(currentCanonicalName);
79015
+ this.mappingFromCanonicalNameToId.delete(currentCanonicalName);
78399
79016
  sheet.displayName = newDisplayName;
78400
- this.store(sheet);
78401
- return currentDisplayName;
79017
+ this._storeSheetInMappings(sheet);
79018
+ return {
79019
+ previousDisplayName: currentDisplayName,
79020
+ mergedWithPlaceholderSheet
79021
+ };
79022
+ }
79023
+ /**
79024
+ * Stores sheet in both internal mappings.
79025
+ * - If ID exists, it is updated. If not, it is added.
79026
+ * - If canonical name exists, it is updated. If not, it is added.
79027
+ *
79028
+ * @internal
79029
+ */
79030
+ _storeSheetInMappings(sheet) {
79031
+ this.allSheets.set(sheet.id, sheet);
79032
+ this.mappingFromCanonicalNameToId.set(sheet.canonicalName, sheet.id);
78402
79033
  }
78403
- sheetNames() {
78404
- return Array.from(this.mappingFromId.values()).map((s) => s.displayName);
79034
+ /**
79035
+ * Returns sheet by ID
79036
+ *
79037
+ * @returns {Maybe<Sheet>} the sheet, or undefined if not found.
79038
+ * @internal
79039
+ */
79040
+ _getSheet(sheetId, options) {
79041
+ const retrievedSheet = this.allSheets.get(sheetId);
79042
+ if (retrievedSheet === void 0) {
79043
+ return void 0;
79044
+ }
79045
+ return options.includePlaceholders || !retrievedSheet.isPlaceholder ? retrievedSheet : void 0;
78405
79046
  }
78406
- store(sheet) {
78407
- this.mappingFromId.set(sheet.id, sheet);
78408
- this.mappingFromCanonicalName.set(sheet.canonicalName, sheet);
79047
+ /**
79048
+ * Returns sheet by name
79049
+ *
79050
+ * @returns {Maybe<Sheet>} the sheet, or undefined if not found.
79051
+ * @internal
79052
+ */
79053
+ _getSheetByName(sheetName, options) {
79054
+ const sheetId = this.mappingFromCanonicalNameToId.get(SheetMapping.canonicalizeSheetName(sheetName));
79055
+ if (sheetId === void 0) {
79056
+ return void 0;
79057
+ }
79058
+ return this._getSheet(sheetId, options);
78409
79059
  }
78410
- fetchSheetById(sheetId) {
78411
- const sheet = this.mappingFromId.get(sheetId);
79060
+ /**
79061
+ * Returns sheet by ID
79062
+ *
79063
+ * @throws {NoSheetWithIdError} if the sheet with the given ID does not exist.
79064
+ * @internal
79065
+ */
79066
+ _getSheetOrThrowError(sheetId, options) {
79067
+ const sheet = this._getSheet(sheetId, options);
78412
79068
  if (sheet === void 0) {
78413
79069
  throw new NoSheetWithIdError(sheetId);
78414
79070
  }
78415
79071
  return sheet;
78416
79072
  }
78417
79073
  }
79074
+ class SheetReferenceRegistrar {
79075
+ constructor(sheetMapping, addressMapping) {
79076
+ this.sheetMapping = sheetMapping;
79077
+ this.addressMapping = addressMapping;
79078
+ }
79079
+ /**
79080
+ * Adds placeholder sheet if it doesn't exist and adds placeholder strategy to address mapping.
79081
+ * @returns {number} sheet id
79082
+ */
79083
+ ensureSheetRegistered(sheetName) {
79084
+ const sheetId = this.sheetMapping.addPlaceholderIfNotExists(sheetName);
79085
+ this.addressMapping.addSheetStrategyPlaceholderIfNotExists(sheetId);
79086
+ return sheetId;
79087
+ }
79088
+ }
79089
+ function validateAsSheet(sheet) {
79090
+ if (!Array.isArray(sheet)) {
79091
+ throw new InvalidArgumentsError("an array of arrays.");
79092
+ }
79093
+ for (let i = 0; i < sheet.length; i++) {
79094
+ if (!Array.isArray(sheet[i])) {
79095
+ throw new InvalidArgumentsError("an array of arrays.");
79096
+ }
79097
+ }
79098
+ }
79099
+ function findBoundaries(sheet) {
79100
+ let width = 0;
79101
+ let height = 0;
79102
+ let cellsCount = 0;
79103
+ for (let currentRow = 0; currentRow < sheet.length; currentRow++) {
79104
+ let currentRowWidth = 0;
79105
+ for (let currentCol = 0; currentCol < sheet[currentRow].length; currentCol++) {
79106
+ const currentValue = sheet[currentRow][currentCol];
79107
+ if (currentValue === void 0 || currentValue === null) {
79108
+ continue;
79109
+ }
79110
+ currentRowWidth = currentCol + 1;
79111
+ ++cellsCount;
79112
+ }
79113
+ width = Math.max(width, currentRowWidth);
79114
+ if (currentRowWidth > 0) {
79115
+ height = currentRow + 1;
79116
+ }
79117
+ }
79118
+ const sheetSize = width * height;
79119
+ return {
79120
+ height,
79121
+ width,
79122
+ fill: sheetSize === 0 ? 0 : cellsCount / sheetSize
79123
+ };
79124
+ }
78418
79125
  class DependencyGraph {
78419
79126
  constructor(addressMapping, rangeMapping, sheetMapping, arrayMapping, stats, lazilyTransformingAstService, functionRegistry, namedExpressions) {
78420
79127
  this.addressMapping = addressMapping;
@@ -78461,14 +79168,14 @@ class DependencyGraph {
78461
79168
  const [address, dependencies] = dependenciesResult;
78462
79169
  return dependencies.map((dependency) => {
78463
79170
  if (dependency instanceof AbsoluteCellRange) {
78464
- return [dependency.start, this.rangeMapping.fetchRange(dependency.start, dependency.end)];
79171
+ return [dependency.start, this.rangeMapping.getVertexOrThrow(dependency.start, dependency.end)];
78465
79172
  }
78466
79173
  else if (dependency instanceof NamedExpressionDependency) {
78467
79174
  const namedExpression = this.namedExpressions.namedExpressionOrPlaceholder(dependency.name, address.sheet);
78468
- return [namedExpression.address, this.addressMapping.fetchCell(namedExpression.address)];
79175
+ return [namedExpression.address, this.addressMapping.getCellOrThrow(namedExpression.address)];
78469
79176
  }
78470
79177
  else {
78471
- return [dependency, this.addressMapping.fetchCell(dependency)];
79178
+ return [dependency, this.addressMapping.getCellOrThrow(dependency)];
78472
79179
  }
78473
79180
  });
78474
79181
  }
@@ -78510,6 +79217,7 @@ class DependencyGraph {
78510
79217
  return [address, absolutizeDependencies(deps, address)];
78511
79218
  };
78512
79219
  this.graph = new Graph(this.dependencyQueryVertices);
79220
+ this.sheetReferenceRegistrar = new SheetReferenceRegistrar(sheetMapping, addressMapping);
78513
79221
  }
78514
79222
  /**
78515
79223
  * Invariants:
@@ -78542,7 +79250,7 @@ class DependencyGraph {
78542
79250
  }
78543
79251
  setValueToCell(address, value) {
78544
79252
  const vertex = this.shrinkPossibleArrayAndGetCell(address);
78545
- if (vertex instanceof ArrayVertex) {
79253
+ if (vertex instanceof ArrayFormulaVertex) {
78546
79254
  this.arrayMapping.removeArray(vertex.getRange());
78547
79255
  }
78548
79256
  if (vertex instanceof ValueCellVertex) {
@@ -78561,6 +79269,11 @@ class DependencyGraph {
78561
79269
  this.correctInfiniteRangesDependency(address);
78562
79270
  return this.getAndClearContentChanges();
78563
79271
  }
79272
+ /**
79273
+ * Sets a cell empty.
79274
+ * - if vertex has no dependents, removes it from graph, address mapping and range mapping and cleans up its dependencies
79275
+ * - if vertex has dependents, exchanges it for an EmptyCellVertex and marks it as dirty
79276
+ */
78564
79277
  setCellEmpty(address) {
78565
79278
  const vertex = this.shrinkPossibleArrayAndGetCell(address);
78566
79279
  if (vertex === void 0) {
@@ -78592,16 +79305,22 @@ class DependencyGraph {
78592
79305
  }
78593
79306
  processCellDependencies(cellDependencies, endVertex) {
78594
79307
  const endVertexId = this.graph.getNodeId(endVertex);
79308
+ if (endVertexId === void 0) {
79309
+ throw new Error("End vertex not found");
79310
+ }
78595
79311
  cellDependencies.forEach((dep) => {
78596
79312
  if (dep instanceof AbsoluteCellRange) {
78597
79313
  const range2 = dep;
78598
79314
  let rangeVertex = this.getRange(range2.start, range2.end);
78599
79315
  if (rangeVertex === void 0) {
78600
79316
  rangeVertex = new RangeVertex(range2);
78601
- this.rangeMapping.setRange(rangeVertex);
79317
+ this.rangeMapping.addOrUpdateVertex(rangeVertex);
78602
79318
  }
78603
79319
  this.graph.addNodeAndReturnId(rangeVertex);
78604
79320
  const rangeVertexId = this.graph.getNodeId(rangeVertex);
79321
+ if (rangeVertexId === void 0) {
79322
+ throw new Error("Range vertex not found");
79323
+ }
78605
79324
  if (!range2.isFinite()) {
78606
79325
  this.graph.markNodeAsInfiniteRange(rangeVertexId);
78607
79326
  }
@@ -78676,7 +79395,7 @@ class DependencyGraph {
78676
79395
  for (const adjacentNode of this.graph.adjacentNodes(vertex)) {
78677
79396
  this.graph.markNodeAsDirty(adjacentNode);
78678
79397
  }
78679
- if (vertex instanceof ArrayVertex) {
79398
+ if (vertex instanceof ArrayFormulaVertex) {
78680
79399
  if (vertex.isLeftCorner(address)) {
78681
79400
  this.shrinkArrayToCorner(vertex);
78682
79401
  this.arrayMapping.removeArray(vertex.getRange());
@@ -78704,29 +79423,64 @@ class DependencyGraph {
78704
79423
  contentChanges: this.getAndClearContentChanges()
78705
79424
  };
78706
79425
  }
78707
- removeSheet(removedSheetId) {
78708
- this.clearSheet(removedSheetId);
78709
- for (const [adr, vertex] of this.addressMapping.sheetEntries(removedSheetId)) {
78710
- for (const adjacentNode of this.graph.adjacentNodes(vertex)) {
78711
- this.graph.markNodeAsDirty(adjacentNode);
78712
- }
78713
- this.removeVertex(vertex);
78714
- this.addressMapping.removeCell(adr);
78715
- }
79426
+ /**
79427
+ * Adds a new sheet to the graph.
79428
+ * If the sheetId was a placeholder sheet, marks its vertices as dirty.
79429
+ */
79430
+ addSheet(sheetId) {
79431
+ this.addressMapping.addSheetOrChangeStrategy(sheetId, findBoundaries([]));
79432
+ this.stats.measure(StatType.ADJUSTING_ADDRESS_MAPPING, () => {
79433
+ this.markAllCellsAsDirtyInSheet(sheetId);
79434
+ });
78716
79435
  this.stats.measure(StatType.ADJUSTING_RANGES, () => {
78717
- const rangesToRemove = this.rangeMapping.removeRangesInSheet(removedSheetId);
78718
- for (const range2 of rangesToRemove) {
78719
- this.removeVertex(range2);
78720
- }
78721
- this.stats.measure(StatType.ADJUSTING_ADDRESS_MAPPING, () => {
78722
- this.addressMapping.removeSheet(removedSheetId);
78723
- });
79436
+ this.markAllRangesAsDirtyInSheet(sheetId);
78724
79437
  });
78725
79438
  }
79439
+ /**
79440
+ * Removes all vertices without dependents in other sheets from address mapping, range mapping and array mapping.
79441
+ * - If nothing is left, removes the sheet from sheet mapping and address mapping.
79442
+ * - Otherwise, marks it as placeholder.
79443
+ */
79444
+ removeSheet(sheetId) {
79445
+ this.clearSheet(sheetId);
79446
+ const addressMappingCleared = !this.addressMapping.hasAnyEntries(sheetId);
79447
+ const rangeMappingCleared = this.rangeMapping.getNumberOfRangesInSheet(sheetId) === 0;
79448
+ if (addressMappingCleared && rangeMappingCleared) {
79449
+ this.sheetMapping.removeSheetIfExists(sheetId);
79450
+ this.addressMapping.removeSheetIfExists(sheetId);
79451
+ }
79452
+ else {
79453
+ this.sheetMapping.markSheetAsPlaceholder(sheetId);
79454
+ }
79455
+ }
79456
+ /**
79457
+ * Removes placeholderSheetToDelete and reroutes edges to the corresponding vertices in sheetToKeep
79458
+ *
79459
+ * Assumptions about placeholderSheetToDelete:
79460
+ * - is empty (contains only empty cell vertices and range vertices),
79461
+ * - empty cell vertices have no dependencies,
79462
+ * - range vertices have dependencies only in placeholderSheetToDelete,
79463
+ * - vertices may have dependents in placeholderSheetToDelete and other sheets,
79464
+ */
79465
+ mergeSheets(sheetToKeep, placeholderSheetToDelete) {
79466
+ if (!this.isPlaceholder(placeholderSheetToDelete)) {
79467
+ throw new Error(`Cannot merge sheets: sheet ${placeholderSheetToDelete} is not a placeholder`);
79468
+ }
79469
+ this.mergeRangeVertices(sheetToKeep, placeholderSheetToDelete);
79470
+ this.mergeCellVertices(sheetToKeep, placeholderSheetToDelete);
79471
+ this.addressMapping.removeSheetIfExists(placeholderSheetToDelete);
79472
+ this.addStructuralNodesToChangeSet();
79473
+ }
79474
+ /**
79475
+ * Clears the sheet content.
79476
+ * - removes all cell vertices without dependents
79477
+ * - removes all array vertices
79478
+ * - for vertices with dependents, exchanges them for EmptyCellVertex and marks them as dirty
79479
+ */
78726
79480
  clearSheet(sheetId) {
78727
79481
  const arrays = /* @__PURE__ */ new Set();
78728
79482
  for (const [address, vertex] of this.addressMapping.sheetEntries(sheetId)) {
78729
- if (vertex instanceof ArrayVertex) {
79483
+ if (vertex instanceof ArrayFormulaVertex) {
78730
79484
  arrays.add(vertex);
78731
79485
  }
78732
79486
  else {
@@ -78744,7 +79498,7 @@ class DependencyGraph {
78744
79498
  for (const adjacentNode of this.graph.adjacentNodes(vertex)) {
78745
79499
  this.graph.markNodeAsDirty(adjacentNode);
78746
79500
  }
78747
- if (vertex instanceof ArrayVertex) {
79501
+ if (vertex instanceof ArrayFormulaVertex) {
78748
79502
  if (vertex.isLeftCorner(address)) {
78749
79503
  this.shrinkArrayToCorner(vertex);
78750
79504
  this.arrayMapping.removeArray(vertex.getRange());
@@ -78777,7 +79531,7 @@ class DependencyGraph {
78777
79531
  this.addressMapping.addRows(addedRows.sheet, addedRows.rowStart, addedRows.numberOfRows);
78778
79532
  });
78779
79533
  const affectedArrays = this.stats.measure(StatType.ADJUSTING_RANGES, () => {
78780
- const result = this.rangeMapping.moveAllRangesInSheetAfterRowByRows(addedRows.sheet, addedRows.rowStart, addedRows.numberOfRows);
79534
+ const result = this.rangeMapping.moveAllRangesInSheetAfterAddingRows(addedRows.sheet, addedRows.rowStart, addedRows.numberOfRows);
78781
79535
  this.fixRangesWhenAddingRows(addedRows.sheet, addedRows.rowStart, addedRows.numberOfRows);
78782
79536
  return this.getArrayVerticesRelatedToRanges(result.verticesWithChangedSize);
78783
79537
  });
@@ -78797,7 +79551,7 @@ class DependencyGraph {
78797
79551
  this.addressMapping.addColumns(addedColumns.sheet, addedColumns.columnStart, addedColumns.numberOfColumns);
78798
79552
  });
78799
79553
  const affectedArrays = this.stats.measure(StatType.ADJUSTING_RANGES, () => {
78800
- const result = this.rangeMapping.moveAllRangesInSheetAfterColumnByColumns(addedColumns.sheet, addedColumns.columnStart, addedColumns.numberOfColumns);
79554
+ const result = this.rangeMapping.moveAllRangesInSheetAfterAddingColumns(addedColumns.sheet, addedColumns.columnStart, addedColumns.numberOfColumns);
78801
79555
  this.fixRangesWhenAddingColumns(addedColumns.sheet, addedColumns.columnStart, addedColumns.numberOfColumns);
78802
79556
  return this.getArrayVerticesRelatedToRanges(result.verticesWithChangedSize);
78803
79557
  });
@@ -78875,13 +79629,20 @@ class DependencyGraph {
78875
79629
  }
78876
79630
  this.rangeMapping.moveRangesInsideSourceRange(sourceRange, toRight, toBottom, toSheet);
78877
79631
  }
79632
+ /**
79633
+ * Sets an array empty.
79634
+ * - removes all corresponding entries from address mapping
79635
+ * - reroutes the edges
79636
+ * - removes vertex from graph and cleans up its dependencies
79637
+ * - removes vertex from range mapping and array mapping
79638
+ */
78878
79639
  setArrayEmpty(arrayVertex) {
78879
79640
  const arrayRange = AbsoluteCellRange.spanFrom(arrayVertex.getAddress(this.lazilyTransformingAstService), arrayVertex.width, arrayVertex.height);
78880
- const adjacentNodes = this.graph.adjacentNodes(arrayVertex);
79641
+ const dependentVertices = this.graph.adjacentNodes(arrayVertex);
78881
79642
  for (const address of arrayRange.addresses(this)) {
78882
79643
  this.addressMapping.removeCell(address);
78883
79644
  }
78884
- for (const adjacentNode of adjacentNodes.values()) {
79645
+ for (const adjacentNode of dependentVertices.values()) {
78885
79646
  const nodeDependencies = collectAddressesDependentToRange(this.functionRegistry, adjacentNode, arrayVertex.getRange(), this.lazilyTransformingAstService, this);
78886
79647
  for (const address of nodeDependencies) {
78887
79648
  const { vertex, id: id2 } = this.fetchCellOrCreateEmpty(address);
@@ -78902,9 +79663,12 @@ class DependencyGraph {
78902
79663
  this.graph.addNodeAndReturnId(vertex);
78903
79664
  this.setAddressMappingForArrayVertex(vertex, address);
78904
79665
  }
79666
+ /**
79667
+ * Iterator over all array formula nodes in the graph.
79668
+ */
78905
79669
  *arrayFormulaNodes() {
78906
79670
  for (const vertex of this.graph.getNodes()) {
78907
- if (vertex instanceof ArrayVertex) {
79671
+ if (vertex instanceof ArrayFormulaVertex) {
78908
79672
  yield vertex;
78909
79673
  }
78910
79674
  }
@@ -78916,18 +79680,33 @@ class DependencyGraph {
78916
79680
  yield* this.addressMapping.entriesFromColumnsSpan(columnsSpan);
78917
79681
  }
78918
79682
  fetchCell(address) {
78919
- return this.addressMapping.fetchCell(address);
79683
+ return this.addressMapping.getCellOrThrow(address);
78920
79684
  }
79685
+ /**
79686
+ * Gets the cell vertex at the specified address.
79687
+ * @throws {NoSheetWithIdError} if sheet doesn't exist
79688
+ */
78921
79689
  getCell(address) {
78922
- return this.addressMapping.getCell(address);
79690
+ return this.addressMapping.getCell(address, {
79691
+ throwIfSheetNotExists: true
79692
+ });
78923
79693
  }
78924
79694
  getCellValue(address) {
79695
+ if (this.isPlaceholder(address.sheet)) {
79696
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
79697
+ }
78925
79698
  return this.addressMapping.getCellValue(address);
78926
79699
  }
78927
79700
  getRawValue(address) {
79701
+ if (this.isPlaceholder(address.sheet)) {
79702
+ return null;
79703
+ }
78928
79704
  return this.addressMapping.getRawValue(address);
78929
79705
  }
78930
79706
  getScalarValue(address) {
79707
+ if (this.isPlaceholder(address.sheet)) {
79708
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
79709
+ }
78931
79710
  const value = this.addressMapping.getCellValue(address);
78932
79711
  if (value instanceof SimpleRangeValue) {
78933
79712
  return new CellError(ErrorType.VALUE, ErrorMessage.ScalarExpected);
@@ -78938,19 +79717,19 @@ class DependencyGraph {
78938
79717
  return this.graph.existsEdge(fromNode, toNode);
78939
79718
  }
78940
79719
  getSheetId(sheetName) {
78941
- return this.sheetMapping.fetch(sheetName);
79720
+ return this.sheetMapping.getSheetIdOrThrowError(sheetName);
78942
79721
  }
78943
79722
  getSheetHeight(sheet) {
78944
- return this.addressMapping.getHeight(sheet);
79723
+ return this.addressMapping.getSheetHeight(sheet);
78945
79724
  }
78946
79725
  getSheetWidth(sheet) {
78947
- return this.addressMapping.getWidth(sheet);
79726
+ return this.addressMapping.getSheetWidth(sheet);
78948
79727
  }
78949
79728
  getArray(range2) {
78950
79729
  return this.arrayMapping.getArray(range2);
78951
79730
  }
78952
79731
  getRange(start, end) {
78953
- return this.rangeMapping.getRange(start, end);
79732
+ return this.rangeMapping.getRangeVertex(start, end);
78954
79733
  }
78955
79734
  topSortWithScc() {
78956
79735
  return this.graph.topSortWithScc();
@@ -78963,7 +79742,7 @@ class DependencyGraph {
78963
79742
  }
78964
79743
  forceApplyPostponedTransformations() {
78965
79744
  for (const vertex of this.graph.getNodes()) {
78966
- if (vertex instanceof FormulaCellVertex) {
79745
+ if (vertex instanceof ScalarFormulaVertex) {
78967
79746
  vertex.ensureRecentData(this.lazilyTransformingAstService);
78968
79747
  }
78969
79748
  }
@@ -79010,7 +79789,7 @@ class DependencyGraph {
79010
79789
  }
79011
79790
  isArrayInternalCell(address) {
79012
79791
  const vertex = this.getCell(address);
79013
- return vertex instanceof ArrayVertex && !vertex.isLeftCorner(address);
79792
+ return vertex instanceof ArrayFormulaVertex && !vertex.isLeftCorner(address);
79014
79793
  }
79015
79794
  getAndClearContentChanges() {
79016
79795
  const changes = this.changes;
@@ -79021,16 +79800,98 @@ class DependencyGraph {
79021
79800
  const deps = this.graph.adjacentNodes(inputVertex);
79022
79801
  const ret = [];
79023
79802
  deps.forEach((vertex) => {
79024
- const castVertex = vertex;
79025
- if (castVertex instanceof RangeVertex) {
79026
- ret.push(simpleCellRange(castVertex.start, castVertex.end));
79803
+ if (vertex instanceof RangeVertex) {
79804
+ ret.push(simpleCellRange(vertex.start, vertex.end));
79027
79805
  }
79028
- else {
79029
- ret.push(castVertex.getAddress(this.lazilyTransformingAstService));
79806
+ else if (vertex instanceof FormulaVertex) {
79807
+ ret.push(vertex.getAddress(this.lazilyTransformingAstService));
79030
79808
  }
79031
79809
  });
79032
79810
  return ret;
79033
79811
  }
79812
+ /**
79813
+ * Marks all cell vertices in the sheet as dirty.
79814
+ */
79815
+ markAllCellsAsDirtyInSheet(sheetId) {
79816
+ const sheetCells = this.addressMapping.sheetEntries(sheetId);
79817
+ for (const [, vertex] of sheetCells) {
79818
+ this.graph.markNodeAsDirty(vertex);
79819
+ }
79820
+ }
79821
+ /**
79822
+ * Marks all range vertices in the sheet as dirty.
79823
+ */
79824
+ markAllRangesAsDirtyInSheet(sheetId) {
79825
+ const sheetRanges = this.rangeMapping.rangesInSheet(sheetId);
79826
+ for (const vertex of sheetRanges) {
79827
+ this.graph.markNodeAsDirty(vertex);
79828
+ }
79829
+ }
79830
+ /**
79831
+ * For each range vertex in placeholderSheetToDelete:
79832
+ * - reroutes dependencies and dependents of range vertex to the corresponding vertex in sheetToKeep
79833
+ * - removes range vertex from graph and range mapping
79834
+ * - cleans up dependencies of the removed vertex
79835
+ */
79836
+ mergeRangeVertices(sheetToKeep, placeholderSheetToDelete) {
79837
+ const rangeVertices = Array.from(this.rangeMapping.rangesInSheet(placeholderSheetToDelete));
79838
+ for (const vertexToDelete of rangeVertices) {
79839
+ if (!this.graph.hasNode(vertexToDelete)) {
79840
+ continue;
79841
+ }
79842
+ const start = vertexToDelete.start;
79843
+ const end = vertexToDelete.end;
79844
+ if (start.sheet !== placeholderSheetToDelete && end.sheet !== placeholderSheetToDelete) {
79845
+ continue;
79846
+ }
79847
+ const targetStart = simpleCellAddress(sheetToKeep, start.col, start.row);
79848
+ const targetEnd = simpleCellAddress(sheetToKeep, end.col, end.row);
79849
+ const vertexToKeep = this.rangeMapping.getRangeVertex(targetStart, targetEnd);
79850
+ if (vertexToKeep) {
79851
+ this.rerouteDependents(vertexToDelete, vertexToKeep);
79852
+ this.removeVertexAndRerouteDependencies(vertexToDelete, vertexToKeep);
79853
+ this.rangeMapping.removeVertexIfExists(vertexToDelete);
79854
+ this.graph.markNodeAsDirty(vertexToKeep);
79855
+ }
79856
+ else {
79857
+ this.rangeMapping.removeVertexIfExists(vertexToDelete);
79858
+ vertexToDelete.range.moveToSheet(sheetToKeep);
79859
+ this.rangeMapping.addOrUpdateVertex(vertexToDelete);
79860
+ this.graph.markNodeAsDirty(vertexToDelete);
79861
+ }
79862
+ }
79863
+ }
79864
+ /**
79865
+ * For each cell vertex in placeholderSheetToDelete:
79866
+ * - reroutes dependents of cell vertex to the corresponding vertex in sheetToKeep
79867
+ * - removes cell vertex from graph and address mapping
79868
+ * - cleans up dependencies of the removed vertex
79869
+ */
79870
+ mergeCellVertices(sheetToKeep, placeholderSheetToDelete) {
79871
+ const cellVertices = Array.from(this.addressMapping.sheetEntries(placeholderSheetToDelete));
79872
+ for (const [addressToDelete, vertexToDelete] of cellVertices) {
79873
+ const addressToKeep = simpleCellAddress(sheetToKeep, addressToDelete.col, addressToDelete.row);
79874
+ const vertexToKeep = this.getCell(addressToKeep);
79875
+ if (vertexToKeep) {
79876
+ this.rerouteDependents(vertexToDelete, vertexToKeep);
79877
+ this.removeVertexAndCleanupDependencies(vertexToDelete);
79878
+ this.addressMapping.removeCell(addressToDelete);
79879
+ this.graph.markNodeAsDirty(vertexToKeep);
79880
+ }
79881
+ else {
79882
+ this.addressMapping.moveCell(addressToDelete, addressToKeep);
79883
+ this.graph.markNodeAsDirty(vertexToDelete);
79884
+ }
79885
+ }
79886
+ }
79887
+ /**
79888
+ * Checks if the given sheet ID refers to a placeholder sheet (doesn't exist but is referenced by other sheets)
79889
+ */
79890
+ isPlaceholder(sheetId) {
79891
+ return sheetId !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(sheetId, {
79892
+ includePlaceholders: false
79893
+ });
79894
+ }
79034
79895
  exchangeGraphNode(oldNode, newNode) {
79035
79896
  this.graph.addNodeAndReturnId(newNode);
79036
79897
  const adjNodesStored = this.graph.adjacentNodes(oldNode);
@@ -79051,6 +79912,9 @@ class DependencyGraph {
79051
79912
  }
79052
79913
  const { vertex, id: maybeVertexId } = this.fetchCellOrCreateEmpty(address);
79053
79914
  const vertexId = maybeVertexId !== null && maybeVertexId !== void 0 ? maybeVertexId : this.graph.getNodeId(vertex);
79915
+ if (vertexId === void 0) {
79916
+ throw new Error("Vertex not found");
79917
+ }
79054
79918
  relevantInfiniteRanges.forEach(({ id: id2 }) => {
79055
79919
  this.graph.addEdge(vertexId, id2);
79056
79920
  });
@@ -79070,7 +79934,7 @@ class DependencyGraph {
79070
79934
  return;
79071
79935
  }
79072
79936
  this.graph.adjacentNodes(range2).forEach((adjacentVertex) => {
79073
- if (adjacentVertex instanceof ArrayVertex) {
79937
+ if (adjacentVertex instanceof ArrayFormulaVertex) {
79074
79938
  arrayVertices.add(adjacentVertex);
79075
79939
  }
79076
79940
  });
@@ -79162,7 +80026,7 @@ class DependencyGraph {
79162
80026
  }
79163
80027
  while (find2.smallerRangeVertex === void 0) {
79164
80028
  const newRangeVertex = new RangeVertex(AbsoluteCellRange.spanFrom(currentRangeVertex.range.start, currentRangeVertex.range.width(), currentRangeVertex.range.height() - 1));
79165
- this.rangeMapping.setRange(newRangeVertex);
80029
+ this.rangeMapping.addOrUpdateVertex(newRangeVertex);
79166
80030
  this.graph.addNodeAndReturnId(newRangeVertex);
79167
80031
  const restRange = new AbsoluteCellRange(simpleCellAddress(currentRangeVertex.range.start.sheet, currentRangeVertex.range.start.col, currentRangeVertex.range.end.row), currentRangeVertex.range.end);
79168
80032
  this.addAllFromRange(restRange, currentRangeVertex);
@@ -79204,12 +80068,12 @@ class DependencyGraph {
79204
80068
  const address = vertex.getAddress(this.lazilyTransformingAstService);
79205
80069
  const range2 = AbsoluteCellRange.spanFrom(address, vertex.width, vertex.height);
79206
80070
  const oldNode = this.shrinkPossibleArrayAndGetCell(address);
79207
- if (vertex instanceof ArrayVertex) {
80071
+ if (vertex instanceof ArrayFormulaVertex) {
79208
80072
  this.setArray(range2, vertex);
79209
80073
  }
79210
80074
  this.exchangeOrAddGraphNode(oldNode, vertex);
79211
80075
  this.addressMapping.setCell(address, vertex);
79212
- if (vertex instanceof ArrayVertex) {
80076
+ if (vertex instanceof ArrayFormulaVertex) {
79213
80077
  if (!this.isThereSpaceForArray(vertex)) {
79214
80078
  return;
79215
80079
  }
@@ -79227,7 +80091,7 @@ class DependencyGraph {
79227
80091
  }
79228
80092
  setAddressMappingForArrayVertex(vertex, formulaAddress) {
79229
80093
  this.addressMapping.setCell(formulaAddress, vertex);
79230
- if (!(vertex instanceof ArrayVertex)) {
80094
+ if (!(vertex instanceof ArrayFormulaVertex)) {
79231
80095
  return;
79232
80096
  }
79233
80097
  const range2 = AbsoluteCellRange.spanFromOrUndef(formulaAddress, vertex.width, vertex.height);
@@ -79245,7 +80109,8 @@ class DependencyGraph {
79245
80109
  truncateRanges(span, coordinate) {
79246
80110
  const { verticesToRemove, verticesToMerge, verticesWithChangedSize } = this.rangeMapping.truncateRanges(span, coordinate);
79247
80111
  for (const [existingVertex, mergedVertex] of verticesToMerge) {
79248
- this.mergeRangeVertices(existingVertex, mergedVertex);
80112
+ this.rerouteDependents(mergedVertex, existingVertex);
80113
+ this.removeVertexAndCleanupDependencies(mergedVertex);
79249
80114
  }
79250
80115
  for (const rangeVertex of verticesToRemove) {
79251
80116
  this.removeVertexAndCleanupDependencies(rangeVertex);
@@ -79322,36 +80187,59 @@ class DependencyGraph {
79322
80187
  }
79323
80188
  shrinkPossibleArrayAndGetCell(address) {
79324
80189
  const vertex = this.getCell(address);
79325
- if (!(vertex instanceof ArrayVertex)) {
80190
+ if (!(vertex instanceof ArrayFormulaVertex)) {
79326
80191
  return vertex;
79327
80192
  }
79328
80193
  this.setNoSpaceIfArray(vertex);
79329
80194
  return this.getCell(address);
79330
80195
  }
79331
80196
  setNoSpaceIfArray(vertex) {
79332
- if (vertex instanceof ArrayVertex) {
80197
+ if (vertex instanceof ArrayFormulaVertex) {
79333
80198
  this.shrinkArrayToCorner(vertex);
79334
80199
  vertex.setNoSpace();
79335
80200
  }
79336
80201
  }
80202
+ /**
80203
+ * Removes a vertex from the graph and range mapping and cleans up its dependencies.
80204
+ */
79337
80205
  removeVertex(vertex) {
79338
80206
  this.removeVertexAndCleanupDependencies(vertex);
79339
80207
  if (vertex instanceof RangeVertex) {
79340
- this.rangeMapping.removeRange(vertex);
80208
+ this.rangeMapping.removeVertexIfExists(vertex);
79341
80209
  }
79342
80210
  }
79343
- mergeRangeVertices(existingVertex, newVertex) {
79344
- const adjNodesStored = this.graph.adjacentNodes(newVertex);
79345
- this.removeVertexAndCleanupDependencies(newVertex);
79346
- this.graph.removeEdgeIfExists(existingVertex, newVertex);
79347
- adjNodesStored.forEach((adjacentNode) => {
80211
+ /**
80212
+ * Reroutes dependent vertices of source to target. Also removes the edge target -> source if it exists.
80213
+ */
80214
+ rerouteDependents(source, target) {
80215
+ const dependents = this.graph.adjacentNodes(source);
80216
+ this.graph.removeEdgeIfExists(target, source);
80217
+ dependents.forEach((adjacentNode) => {
79348
80218
  if (this.graph.hasNode(adjacentNode)) {
79349
- this.graph.addEdge(existingVertex, adjacentNode);
80219
+ this.graph.addEdge(target, adjacentNode);
80220
+ }
80221
+ });
80222
+ }
80223
+ /**
80224
+ * Removes a vertex from graph and reroutes its dependencies to other vertex. Also removes the edge vertexToKeep -> vertexToDelete if it exists.
80225
+ */
80226
+ removeVertexAndRerouteDependencies(vertexToDelete, vertexToKeep) {
80227
+ const dependencies = this.graph.removeNode(vertexToDelete);
80228
+ this.graph.removeEdgeIfExists(vertexToKeep, vertexToDelete);
80229
+ dependencies.forEach(([_, dependency]) => {
80230
+ if (this.graph.hasNode(dependency)) {
80231
+ this.graph.addEdge(dependency, vertexToKeep);
79350
80232
  }
79351
80233
  });
79352
80234
  }
80235
+ /**
80236
+ * Removes a vertex from graph and cleans up its dependencies.
80237
+ * Dependency clean up = remove all RangeVertex and EmptyCellVertex dependencies if no other vertex depends on them.
80238
+ * Also cleans up placeholder sheets that have no remaining vertices (not needed anymore)
80239
+ */
79353
80240
  removeVertexAndCleanupDependencies(inputVertex) {
79354
80241
  const dependencies = new Set(this.graph.removeNode(inputVertex));
80242
+ const affectedSheets = /* @__PURE__ */ new Set();
79355
80243
  while (dependencies.size > 0) {
79356
80244
  const dependency = dependencies.values().next().value;
79357
80245
  dependencies.delete(dependency);
@@ -79361,13 +80249,29 @@ class DependencyGraph {
79361
80249
  this.graph.removeNode(vertex).forEach((candidate) => dependencies.add(candidate));
79362
80250
  }
79363
80251
  if (vertex instanceof RangeVertex) {
79364
- this.rangeMapping.removeRange(vertex);
80252
+ this.rangeMapping.removeVertexIfExists(vertex);
80253
+ affectedSheets.add(vertex.sheet);
79365
80254
  }
79366
- else if (vertex instanceof EmptyCellVertex) {
80255
+ else if (vertex instanceof EmptyCellVertex && isSimpleCellAddress(address)) {
79367
80256
  this.addressMapping.removeCell(address);
80257
+ affectedSheets.add(address.sheet);
79368
80258
  }
79369
80259
  }
79370
80260
  }
80261
+ this.cleanupPlaceholderSheets(affectedSheets);
80262
+ }
80263
+ /**
80264
+ * Removes placeholder sheets that have no remaining vertices.
80265
+ */
80266
+ cleanupPlaceholderSheets(sheetIds) {
80267
+ for (const sheetId of sheetIds) {
80268
+ if (this.isPlaceholder(sheetId) && !this.addressMapping.hasAnyEntries(sheetId) && this.rangeMapping.getNumberOfRangesInSheet(sheetId) === 0) {
80269
+ this.sheetMapping.removeSheetIfExists(sheetId, {
80270
+ includePlaceholders: true
80271
+ });
80272
+ this.addressMapping.removeSheetIfExists(sheetId);
80273
+ }
80274
+ }
79371
80275
  }
79372
80276
  }
79373
80277
  class EmptyCellVertex {
@@ -79786,7 +80690,7 @@ var CellType;
79786
80690
  CellType2["ARRAYFORMULA"] = "ARRAYFORMULA";
79787
80691
  })(CellType || (CellType = {}));
79788
80692
  const getCellType = (vertex, address) => {
79789
- if (vertex instanceof ArrayVertex) {
80693
+ if (vertex instanceof ArrayFormulaVertex) {
79790
80694
  if (vertex.isLeftCorner(address)) {
79791
80695
  return CellType.ARRAYFORMULA;
79792
80696
  }
@@ -79794,7 +80698,7 @@ const getCellType = (vertex, address) => {
79794
80698
  return CellType.ARRAY;
79795
80699
  }
79796
80700
  }
79797
- if (vertex instanceof FormulaCellVertex || vertex instanceof ParsingErrorVertex) {
80701
+ if (vertex instanceof ScalarFormulaVertex || vertex instanceof ParsingErrorVertex) {
79798
80702
  return CellType.FORMULA;
79799
80703
  }
79800
80704
  if (vertex instanceof ValueCellVertex) {
@@ -79902,7 +80806,7 @@ const simpleCellAddress = (sheet, col, row) => ({
79902
80806
  col,
79903
80807
  row
79904
80808
  });
79905
- const invalidSimpleCellAddress = (address) => address.col < 0 || address.row < 0;
80809
+ const isColOrRowInvalid = (address) => address.col < 0 || address.row < 0;
79906
80810
  const movedSimpleCellAddress = (address, toSheet, toRight, toBottom) => {
79907
80811
  return simpleCellAddress(toSheet, address.col + toRight, address.row + toBottom);
79908
80812
  };
@@ -82438,7 +83342,7 @@ function checkLicenseKeyValidity(licenseKey) {
82438
83342
  messageDescriptor.template = "valid";
82439
83343
  }
82440
83344
  else if (typeof licenseKey === "string" && checkKeySchema(licenseKey)) {
82441
- const [day, month, year] = "14/10/2025".split("/");
83345
+ const [day, month, year] = "18/12/2025".split("/");
82442
83346
  const releaseDays = Math.floor(( /* @__PURE__ */new Date(`${month}/${day}/${year}`)).getTime() / 864e5);
82443
83347
  const keyValidityDays = extractTime(licenseKey);
82444
83348
  messageDescriptor.vars.keyValidityDate = formatDate(new Date((keyValidityDays + 1) * 864e5));
@@ -82696,7 +83600,7 @@ class ClipboardOperations {
82696
83600
  if (this.clipboard === void 0) {
82697
83601
  return;
82698
83602
  }
82699
- if (invalidSimpleCellAddress(destinationLeftCorner) || !this.dependencyGraph.sheetMapping.hasSheetWithId(destinationLeftCorner.sheet)) {
83603
+ if (isColOrRowInvalid(destinationLeftCorner) || !this.dependencyGraph.sheetMapping.hasSheetWithId(destinationLeftCorner.sheet)) {
82700
83604
  throw new InvalidArgumentsError("a valid target address.");
82701
83605
  }
82702
83606
  const targetRange = AbsoluteCellRange.spanFrom(destinationLeftCorner, this.clipboard.width, this.clipboard.height);
@@ -82714,299 +83618,6 @@ class ClipboardOperations {
82714
83618
  return this.clipboard !== void 0 && this.clipboard.type === ClipboardOperationType.COPY;
82715
83619
  }
82716
83620
  }
82717
- class InternalNamedExpression {
82718
- constructor(displayName, address, added, options) {
82719
- this.displayName = displayName;
82720
- this.address = address;
82721
- this.added = added;
82722
- this.options = options;
82723
- }
82724
- normalizeExpressionName() {
82725
- return this.displayName.toLowerCase();
82726
- }
82727
- copy() {
82728
- return new InternalNamedExpression(this.displayName, this.address, this.added, this.options);
82729
- }
82730
- }
82731
- class WorkbookStore {
82732
- constructor() {
82733
- this.mapping = /* @__PURE__ */ new Map();
82734
- }
82735
- has(expressionName) {
82736
- return this.mapping.has(this.normalizeExpressionName(expressionName));
82737
- }
82738
- isNameAvailable(expressionName) {
82739
- const normalizedExpressionName = this.normalizeExpressionName(expressionName);
82740
- const namedExpression = this.mapping.get(normalizedExpressionName);
82741
- return !(namedExpression && namedExpression.added);
82742
- }
82743
- add(namedExpression) {
82744
- this.mapping.set(namedExpression.normalizeExpressionName(), namedExpression);
82745
- }
82746
- get(expressionName) {
82747
- return this.mapping.get(this.normalizeExpressionName(expressionName));
82748
- }
82749
- getExisting(expressionName) {
82750
- const namedExpression = this.mapping.get(this.normalizeExpressionName(expressionName));
82751
- if (namedExpression && namedExpression.added) {
82752
- return namedExpression;
82753
- }
82754
- else {
82755
- return void 0;
82756
- }
82757
- }
82758
- remove(expressionName) {
82759
- const normalizedExpressionName = this.normalizeExpressionName(expressionName);
82760
- const namedExpression = this.mapping.get(normalizedExpressionName);
82761
- if (namedExpression) {
82762
- namedExpression.added = false;
82763
- }
82764
- }
82765
- getAllNamedExpressions() {
82766
- return Array.from(this.mapping.values()).filter((ne) => ne.added);
82767
- }
82768
- normalizeExpressionName(expressionName) {
82769
- return expressionName.toLowerCase();
82770
- }
82771
- }
82772
- class WorksheetStore {
82773
- constructor() {
82774
- this.mapping = /* @__PURE__ */ new Map();
82775
- }
82776
- add(namedExpression) {
82777
- this.mapping.set(this.normalizeExpressionName(namedExpression.displayName), namedExpression);
82778
- }
82779
- get(expressionName) {
82780
- return this.mapping.get(this.normalizeExpressionName(expressionName));
82781
- }
82782
- has(expressionName) {
82783
- return this.mapping.has(this.normalizeExpressionName(expressionName));
82784
- }
82785
- getAllNamedExpressions() {
82786
- return Array.from(this.mapping.values()).filter((ne) => ne.added);
82787
- }
82788
- isNameAvailable(expressionName) {
82789
- const normalizedExpressionName = this.normalizeExpressionName(expressionName);
82790
- return !this.mapping.has(normalizedExpressionName);
82791
- }
82792
- remove(expressionName) {
82793
- const normalizedExpressionName = this.normalizeExpressionName(expressionName);
82794
- const namedExpression = this.mapping.get(normalizedExpressionName);
82795
- if (namedExpression) {
82796
- this.mapping.delete(normalizedExpressionName);
82797
- }
82798
- }
82799
- normalizeExpressionName(expressionName) {
82800
- return expressionName.toLowerCase();
82801
- }
82802
- }
82803
- class NamedExpressions {
82804
- constructor() {
82805
- this.nextNamedExpressionRow = 0;
82806
- this.workbookStore = new WorkbookStore();
82807
- this.worksheetStores = /* @__PURE__ */ new Map();
82808
- this.addressCache = /* @__PURE__ */ new Map();
82809
- }
82810
- isNameAvailable(expressionName, sheetId) {
82811
- var _a, _b;
82812
- if (sheetId === void 0) {
82813
- return this.workbookStore.isNameAvailable(expressionName);
82814
- }
82815
- else {
82816
- return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.isNameAvailable(expressionName)) !== null && _b !== void 0 ? _b : true;
82817
- }
82818
- }
82819
- namedExpressionInAddress(row) {
82820
- const namedExpression = this.addressCache.get(row);
82821
- if (namedExpression && namedExpression.added) {
82822
- return namedExpression;
82823
- }
82824
- else {
82825
- return void 0;
82826
- }
82827
- }
82828
- namedExpressionForScope(expressionName, sheetId) {
82829
- var _a;
82830
- if (sheetId === void 0) {
82831
- return this.workbookStore.getExisting(expressionName);
82832
- }
82833
- else {
82834
- return (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.get(expressionName);
82835
- }
82836
- }
82837
- nearestNamedExpression(expressionName, sheetId) {
82838
- var _a, _b;
82839
- return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.get(expressionName)) !== null && _b !== void 0 ? _b : this.workbookStore.getExisting(expressionName);
82840
- }
82841
- isExpressionInScope(expressionName, sheetId) {
82842
- var _a, _b;
82843
- return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.has(expressionName)) !== null && _b !== void 0 ? _b : false;
82844
- }
82845
- /**
82846
- * Checks the validity of a named-expression's name.
82847
- *
82848
- * The name:
82849
- * - Must start with a Unicode letter or with an underscore (`_`).
82850
- * - Can contain only Unicode letters, numbers, underscores, and periods (`.`).
82851
- * - Can't be the same as any possible reference in the A1 notation (`[A-Za-z]+[0-9]+`).
82852
- * - Can't be the same as any possible reference in the R1C1 notation (`[rR][0-9]*[cC][0-9]*`).
82853
- *
82854
- * The naming rules follow the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#__RefHeading__1017964_715980110) standard.
82855
- */
82856
- isNameValid(expressionName) {
82857
- const a1CellRefRegexp = new RegExp(`^${CELL_REFERENCE_PATTERN}$`);
82858
- const r1c1CellRefRegexp = new RegExp(`^${R1C1_CELL_REFERENCE_PATTERN}$`);
82859
- const namedExpRegexp = new RegExp(`^${NAMED_EXPRESSION_PATTERN}$`);
82860
- if (a1CellRefRegexp.test(expressionName) || r1c1CellRefRegexp.test(expressionName)) {
82861
- return false;
82862
- }
82863
- return namedExpRegexp.test(expressionName);
82864
- }
82865
- addNamedExpression(expressionName, sheetId, options) {
82866
- const store2 = sheetId === void 0 ? this.workbookStore : this.worksheetStoreOrCreate(sheetId);
82867
- let namedExpression = store2.get(expressionName);
82868
- if (namedExpression !== void 0) {
82869
- namedExpression.added = true;
82870
- namedExpression.displayName = expressionName;
82871
- namedExpression.options = options;
82872
- }
82873
- else {
82874
- namedExpression = new InternalNamedExpression(expressionName, this.nextAddress(), true, options);
82875
- store2.add(namedExpression);
82876
- }
82877
- this.addressCache.set(namedExpression.address.row, namedExpression);
82878
- return namedExpression;
82879
- }
82880
- restoreNamedExpression(namedExpression, sheetId) {
82881
- const store2 = sheetId === void 0 ? this.workbookStore : this.worksheetStoreOrCreate(sheetId);
82882
- namedExpression.added = true;
82883
- store2.add(namedExpression);
82884
- this.addressCache.set(namedExpression.address.row, namedExpression);
82885
- return namedExpression;
82886
- }
82887
- namedExpressionOrPlaceholder(expressionName, sheetId) {
82888
- var _a;
82889
- return (_a = this.worksheetStoreOrCreate(sheetId).get(expressionName)) !== null && _a !== void 0 ? _a : this.workbookNamedExpressionOrPlaceholder(expressionName);
82890
- }
82891
- workbookNamedExpressionOrPlaceholder(expressionName) {
82892
- let namedExpression = this.workbookStore.get(expressionName);
82893
- if (namedExpression === void 0) {
82894
- namedExpression = new InternalNamedExpression(expressionName, this.nextAddress(), false);
82895
- this.workbookStore.add(namedExpression);
82896
- }
82897
- return namedExpression;
82898
- }
82899
- remove(expressionName, sheetId) {
82900
- let store2;
82901
- if (sheetId === void 0) {
82902
- store2 = this.workbookStore;
82903
- }
82904
- else {
82905
- store2 = this.worksheetStore(sheetId);
82906
- }
82907
- const namedExpression = store2 === null || store2 === void 0 ? void 0 : store2.get(expressionName);
82908
- if (store2 === void 0 || namedExpression === void 0 || !namedExpression.added) {
82909
- throw Error("Named expression does not exist");
82910
- }
82911
- store2.remove(expressionName);
82912
- if (store2 instanceof WorksheetStore && store2.mapping.size === 0) {
82913
- this.worksheetStores.delete(sheetId);
82914
- }
82915
- this.addressCache.delete(namedExpression.address.row);
82916
- }
82917
- getAllNamedExpressionsNamesInScope(sheetId) {
82918
- return this.getAllNamedExpressions().filter(({ scope }) => scope === sheetId).map((ne) => ne.expression.displayName);
82919
- }
82920
- getAllNamedExpressionsNames() {
82921
- return this.getAllNamedExpressions().map((ne) => ne.expression.displayName);
82922
- }
82923
- getAllNamedExpressions() {
82924
- const storedNamedExpressions = [];
82925
- this.workbookStore.getAllNamedExpressions().forEach((expr) => {
82926
- storedNamedExpressions.push({
82927
- expression: expr,
82928
- scope: void 0
82929
- });
82930
- });
82931
- this.worksheetStores.forEach((store2, sheetNum) => {
82932
- store2.getAllNamedExpressions().forEach((expr) => {
82933
- storedNamedExpressions.push({
82934
- expression: expr,
82935
- scope: sheetNum
82936
- });
82937
- });
82938
- });
82939
- return storedNamedExpressions;
82940
- }
82941
- getAllNamedExpressionsForScope(scope) {
82942
- var _a, _b;
82943
- if (scope === void 0) {
82944
- return this.workbookStore.getAllNamedExpressions();
82945
- }
82946
- else {
82947
- return (_b = (_a = this.worksheetStores.get(scope)) === null || _a === void 0 ? void 0 : _a.getAllNamedExpressions()) !== null && _b !== void 0 ? _b : [];
82948
- }
82949
- }
82950
- worksheetStoreOrCreate(sheetId) {
82951
- let store2 = this.worksheetStores.get(sheetId);
82952
- if (!store2) {
82953
- store2 = new WorksheetStore();
82954
- this.worksheetStores.set(sheetId, store2);
82955
- }
82956
- return store2;
82957
- }
82958
- worksheetStore(sheetId) {
82959
- return this.worksheetStores.get(sheetId);
82960
- }
82961
- nextAddress() {
82962
- return simpleCellAddress(NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS, 0, this.nextNamedExpressionRow++);
82963
- }
82964
- }
82965
- NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS = -1;
82966
- const doesContainRelativeReferences = (ast) => {
82967
- switch (ast.type) {
82968
- case AstNodeType.EMPTY:
82969
- case AstNodeType.NUMBER:
82970
- case AstNodeType.STRING:
82971
- case AstNodeType.ERROR:
82972
- case AstNodeType.ERROR_WITH_RAW_INPUT:
82973
- return false;
82974
- case AstNodeType.CELL_REFERENCE:
82975
- return !ast.reference.isAbsolute();
82976
- case AstNodeType.CELL_RANGE:
82977
- case AstNodeType.COLUMN_RANGE:
82978
- case AstNodeType.ROW_RANGE:
82979
- return !ast.start.isAbsolute();
82980
- case AstNodeType.NAMED_EXPRESSION:
82981
- return false;
82982
- case AstNodeType.PERCENT_OP:
82983
- case AstNodeType.PLUS_UNARY_OP:
82984
- case AstNodeType.MINUS_UNARY_OP: {
82985
- return doesContainRelativeReferences(ast.value);
82986
- }
82987
- case AstNodeType.CONCATENATE_OP:
82988
- case AstNodeType.EQUALS_OP:
82989
- case AstNodeType.NOT_EQUAL_OP:
82990
- case AstNodeType.LESS_THAN_OP:
82991
- case AstNodeType.GREATER_THAN_OP:
82992
- case AstNodeType.LESS_THAN_OR_EQUAL_OP:
82993
- case AstNodeType.GREATER_THAN_OR_EQUAL_OP:
82994
- case AstNodeType.MINUS_OP:
82995
- case AstNodeType.PLUS_OP:
82996
- case AstNodeType.TIMES_OP:
82997
- case AstNodeType.DIV_OP:
82998
- case AstNodeType.POWER_OP:
82999
- return doesContainRelativeReferences(ast.left) || doesContainRelativeReferences(ast.right);
83000
- case AstNodeType.PARENTHESIS:
83001
- return doesContainRelativeReferences(ast.expression);
83002
- case AstNodeType.FUNCTION_CALL: {
83003
- return ast.args.some((arg) => doesContainRelativeReferences(arg));
83004
- }
83005
- case AstNodeType.ARRAY: {
83006
- return ast.args.some((row) => row.some((arg) => doesContainRelativeReferences(arg)));
83007
- }
83008
- }
83009
- };
83010
83621
  class Transformer {
83011
83622
  performEagerTransformations(graph, parser2) {
83012
83623
  for (const node2 of graph.arrayFormulaNodes()) {
@@ -83708,77 +84319,107 @@ class RemoveRowsTransformer extends Transformer {
83708
84319
  }
83709
84320
  }
83710
84321
  }
83711
- class RemoveSheetTransformer extends Transformer {
83712
- constructor(sheet) {
84322
+ class RenameSheetTransformer extends Transformer {
84323
+ constructor(sheetIdToKeep, sheetBeingMerged) {
83713
84324
  super();
83714
- this.sheet = sheet;
84325
+ this.sheetIdToKeep = sheetIdToKeep;
84326
+ this.sheetBeingMerged = sheetBeingMerged;
84327
+ }
84328
+ /**
84329
+ * Returns id of sheet that survives merge operation.
84330
+ *
84331
+ * @returns {number} sheet identifier.
84332
+ */
84333
+ get sheet() {
84334
+ return this.sheetIdToKeep;
83715
84335
  }
84336
+ /**
84337
+ * Sheet merge cannot be undone because original sheet id is lost.
84338
+ *
84339
+ * @returns {boolean} always true to indicate transformation irreversibility.
84340
+ */
83716
84341
  isIrreversible() {
83717
84342
  return true;
83718
84343
  }
83719
- performEagerTransformations(graph, _parser) {
83720
- for (const node2 of graph.arrayFormulaNodes()) {
83721
- const [newAst] = this.transformSingleAst(node2.getFormula(graph.lazilyTransformingAstService), node2.getAddress(graph.lazilyTransformingAstService));
83722
- node2.setFormula(newAst);
83723
- }
83724
- }
83725
- fixNodeAddress(address) {
83726
- return address;
83727
- }
84344
+ /**
84345
+ * Updates cell address sheet when it points to merged sheet.
84346
+ *
84347
+ * @param {T} dependencyAddress - dependency address needing sheet update.
84348
+ * @param {SimpleCellAddress} _formulaAddress - location of formula (unused but required by base class).
84349
+ * @returns {T | false} updated address or false when nothing changes.
84350
+ */
83728
84351
  transformCellAddress(dependencyAddress, _formulaAddress) {
83729
- return this.transformAddress(dependencyAddress);
84352
+ return this.updateSheetInAddress(dependencyAddress);
83730
84353
  }
83731
- transformCellRange(start, _end, _formulaAddress) {
83732
- return this.transformAddress(start);
83733
- }
83734
- transformColumnRange(start, _end, _formulaAddress) {
83735
- return this.transformAddress(start);
84354
+ /**
84355
+ * Updates sheet for both ends of cell range.
84356
+ *
84357
+ * @param {CellAddress} start - start address of range.
84358
+ * @param {CellAddress} end - end address of range.
84359
+ * @param {SimpleCellAddress} _formulaAddress - formula location (unused).
84360
+ * @returns {[CellAddress, CellAddress] | false} updated range tuple or false when unchanged.
84361
+ */
84362
+ transformCellRange(start, end, _formulaAddress) {
84363
+ return this.transformRange(start, end);
83736
84364
  }
83737
- transformRowRange(start, _end, _formulaAddress) {
83738
- return this.transformAddress(start);
84365
+ /**
84366
+ * Updates sheet for both ends of column range.
84367
+ *
84368
+ * @param {ColumnAddress} start - beginning column of range.
84369
+ * @param {ColumnAddress} end - ending column of range.
84370
+ * @param {SimpleCellAddress} _formulaAddress - formula location (unused).
84371
+ * @returns {[ColumnAddress, ColumnAddress] | false} updated column range or false.
84372
+ */
84373
+ transformColumnRange(start, end, _formulaAddress) {
84374
+ return this.transformRange(start, end);
83739
84375
  }
83740
- transformAddress(address) {
83741
- if (address.sheet === this.sheet) {
83742
- return ErrorType.REF;
83743
- }
83744
- return false;
84376
+ /**
84377
+ * Updates sheet for both ends of row range.
84378
+ *
84379
+ * @param {RowAddress} start - beginning row address.
84380
+ * @param {RowAddress} end - ending row address.
84381
+ * @param {SimpleCellAddress} _formulaAddress - formula location (unused).
84382
+ * @returns {[RowAddress, RowAddress] | false} updated row range or false.
84383
+ */
84384
+ transformRowRange(start, end, _formulaAddress) {
84385
+ return this.transformRange(start, end);
83745
84386
  }
83746
- }
83747
- function validateAsSheet(sheet) {
83748
- if (!Array.isArray(sheet)) {
83749
- throw new InvalidArgumentsError("an array of arrays.");
84387
+ /**
84388
+ * Node addresses are already absolute, so no change is needed.
84389
+ *
84390
+ * @param {SimpleCellAddress} address - node address to inspect.
84391
+ * @returns {SimpleCellAddress} original address unchanged.
84392
+ */
84393
+ fixNodeAddress(address) {
84394
+ return address;
83750
84395
  }
83751
- for (let i = 0; i < sheet.length; i++) {
83752
- if (!Array.isArray(sheet[i])) {
83753
- throw new InvalidArgumentsError("an array of arrays.");
84396
+ /**
84397
+ * Updates sheet identifier for both range ends if needed.
84398
+ *
84399
+ * @param {T} start - range start address.
84400
+ * @param {T} end - range end address.
84401
+ * @returns {[T, T] | false} tuple with updated addresses or false when no updates happen.
84402
+ */
84403
+ transformRange(start, end) {
84404
+ const newStart = this.updateSheetInAddress(start);
84405
+ const newEnd = this.updateSheetInAddress(end);
84406
+ if (newStart || newEnd) {
84407
+ return [newStart || start, newEnd || end];
83754
84408
  }
84409
+ return false;
83755
84410
  }
83756
- }
83757
- function findBoundaries(sheet) {
83758
- let width = 0;
83759
- let height = 0;
83760
- let cellsCount = 0;
83761
- for (let currentRow = 0; currentRow < sheet.length; currentRow++) {
83762
- let currentRowWidth = 0;
83763
- for (let currentCol = 0; currentCol < sheet[currentRow].length; currentCol++) {
83764
- const currentValue = sheet[currentRow][currentCol];
83765
- if (currentValue === void 0 || currentValue === null) {
83766
- continue;
83767
- }
83768
- currentRowWidth = currentCol + 1;
83769
- ++cellsCount;
83770
- }
83771
- width = Math.max(width, currentRowWidth);
83772
- if (currentRowWidth > 0) {
83773
- height = currentRow + 1;
84411
+ /**
84412
+ * Replaces sheet id in address when it points to merged sheet.
84413
+ *
84414
+ * @param {T} address - address to update.
84415
+ * @returns {T | false} address with new sheet id or false when no change occurs.
84416
+ */
84417
+ updateSheetInAddress(address) {
84418
+ if (address.sheet === this.sheetBeingMerged) {
84419
+ return address.withSheet(this.sheetIdToKeep);
83774
84420
  }
84421
+ return false;
83775
84422
  }
83776
- const sheetSize = width * height;
83777
- return {
83778
- height,
83779
- width,
83780
- fill: sheetSize === 0 ? 0 : cellsCount / sheetSize
83781
- };
83782
84423
  }
83783
84424
  class RemoveRowsCommand {
83784
84425
  constructor(sheet, indexes) {
@@ -83879,38 +84520,78 @@ class Operations {
83879
84520
  }
83880
84521
  return columnsRemovals;
83881
84522
  }
83882
- removeSheet(sheetId) {
83883
- this.dependencyGraph.removeSheet(sheetId);
83884
- let version = 0;
83885
- this.stats.measure(StatType.TRANSFORM_ASTS, () => {
83886
- const transformation = new RemoveSheetTransformer(sheetId);
83887
- transformation.performEagerTransformations(this.dependencyGraph, this.parser);
83888
- version = this.lazilyTransformingAstService.addTransformation(transformation);
83889
- });
83890
- this.sheetMapping.removeSheet(sheetId);
84523
+ /**
84524
+ * Clears the sheet content.
84525
+ */
84526
+ clearSheet(sheetId) {
84527
+ this.dependencyGraph.clearSheet(sheetId);
83891
84528
  this.columnSearch.removeSheet(sheetId);
83892
- const scopedNamedExpressions = this.namedExpressions.getAllNamedExpressionsForScope(sheetId).map((namedExpression) => this.removeNamedExpression(namedExpression.normalizeExpressionName(), sheetId));
84529
+ }
84530
+ /**
84531
+ * Adds a new sheet to the workbook.
84532
+ */
84533
+ addSheet(name) {
84534
+ const sheetId = this.sheetMapping.addSheet(name);
84535
+ this.dependencyGraph.addSheet(sheetId);
83893
84536
  return {
83894
- version,
83895
- scopedNamedExpressions
84537
+ sheetName: this.sheetMapping.getSheetNameOrThrowError(sheetId),
84538
+ sheetId
83896
84539
  };
83897
84540
  }
83898
- removeSheetByName(sheetName) {
83899
- const sheetId = this.sheetMapping.fetch(sheetName);
83900
- return this.removeSheet(sheetId);
84541
+ /**
84542
+ * Adds a sheet with a specific ID for redo operations.
84543
+ */
84544
+ addSheetWithId(sheetId, name) {
84545
+ this.sheetMapping.addSheetWithId(sheetId, name);
84546
+ this.dependencyGraph.addSheet(sheetId);
83901
84547
  }
83902
- clearSheet(sheetId) {
83903
- this.dependencyGraph.clearSheet(sheetId);
84548
+ /**
84549
+ * Adds a placeholder sheet with a specific ID for undo operations.
84550
+ * Used to restore previously merged placeholder sheets.
84551
+ *
84552
+ * Note: Unlike `addSheetWithId`, this does NOT call `dependencyGraph.addSheet()`
84553
+ * because placeholders don't need dirty marking or strategy changes - they only
84554
+ * need to exist in the mappings so formulas can reference them again.
84555
+ */
84556
+ addPlaceholderSheetWithId(sheetId, name) {
84557
+ this.sheetMapping.addPlaceholderWithId(sheetId, name);
84558
+ this.addressMapping.addSheetStrategyPlaceholderIfNotExists(sheetId);
84559
+ }
84560
+ /**
84561
+ * Removes a sheet from the workbook.
84562
+ */
84563
+ removeSheet(sheetId) {
84564
+ this.dependencyGraph.removeSheet(sheetId);
83904
84565
  this.columnSearch.removeSheet(sheetId);
84566
+ const scopedNamedExpressions = this.namedExpressions.getAllNamedExpressionsForScope(sheetId).map((namedExpression) => this.removeNamedExpression(namedExpression.normalizeExpressionName(), sheetId));
84567
+ return scopedNamedExpressions;
83905
84568
  }
83906
- addSheet(name) {
83907
- const sheetId = this.sheetMapping.addSheet(name);
83908
- const sheet = [];
83909
- this.dependencyGraph.addressMapping.autoAddSheet(sheetId, findBoundaries(sheet));
83910
- return this.sheetMapping.fetchDisplayName(sheetId);
84569
+ /**
84570
+ * Removes a sheet from the workbook by name.
84571
+ */
84572
+ removeSheetByName(sheetName) {
84573
+ const sheetId = this.sheetMapping.getSheetIdOrThrowError(sheetName);
84574
+ return this.removeSheet(sheetId);
83911
84575
  }
84576
+ /**
84577
+ * Renames a sheet in the workbook.
84578
+ */
83912
84579
  renameSheet(sheetId, newName) {
83913
- return this.sheetMapping.renameSheet(sheetId, newName);
84580
+ const { previousDisplayName, mergedWithPlaceholderSheet } = this.sheetMapping.renameSheet(sheetId, newName);
84581
+ let version;
84582
+ if (mergedWithPlaceholderSheet !== void 0) {
84583
+ this.dependencyGraph.mergeSheets(sheetId, mergedWithPlaceholderSheet);
84584
+ this.stats.measure(StatType.TRANSFORM_ASTS, () => {
84585
+ const transformation = new RenameSheetTransformer(sheetId, mergedWithPlaceholderSheet);
84586
+ transformation.performEagerTransformations(this.dependencyGraph, this.parser);
84587
+ version = this.lazilyTransformingAstService.addTransformation(transformation);
84588
+ });
84589
+ }
84590
+ return {
84591
+ previousDisplayName,
84592
+ version,
84593
+ mergedPlaceholderSheetId: mergedWithPlaceholderSheet
84594
+ };
83914
84595
  }
83915
84596
  moveRows(sheet, startRow, numberOfRows, targetRow) {
83916
84597
  const rowsToAdd = RowsSpan.fromNumberOfRows(sheet, targetRow, numberOfRows);
@@ -84049,7 +84730,7 @@ class Operations {
84049
84730
  return [namedExpression, content];
84050
84731
  }
84051
84732
  ensureItIsPossibleToMoveCells(sourceLeftCorner, width, height, destinationLeftCorner) {
84052
- if (invalidSimpleCellAddress(sourceLeftCorner) || !(isPositiveInteger$1(width) && isPositiveInteger$1(height) || isRowOrColumnRange(sourceLeftCorner, width, height)) || invalidSimpleCellAddress(destinationLeftCorner) || !this.sheetMapping.hasSheetWithId(sourceLeftCorner.sheet) || !this.sheetMapping.hasSheetWithId(destinationLeftCorner.sheet)) {
84733
+ if (isColOrRowInvalid(sourceLeftCorner) || !(isPositiveInteger$1(width) && isPositiveInteger$1(height) || isRowOrColumnRange(sourceLeftCorner, width, height)) || isColOrRowInvalid(destinationLeftCorner) || !this.sheetMapping.hasSheetWithId(sourceLeftCorner.sheet) || !this.sheetMapping.hasSheetWithId(destinationLeftCorner.sheet)) {
84053
84734
  throw new InvalidArgumentsError("a valid range of cells to move.");
84054
84735
  }
84055
84736
  const sourceRange = AbsoluteCellRange.spanFrom(sourceLeftCorner, width, height);
@@ -84077,8 +84758,6 @@ class Operations {
84077
84758
  }
84078
84759
  /**
84079
84760
  * Restores a single cell.
84080
- * @param {SimpleCellAddress} address
84081
- * @param {ClipboardCell} clipboardCell
84082
84761
  */
84083
84762
  restoreCell(address, clipboardCell) {
84084
84763
  switch (clipboardCell.type) {
@@ -84139,7 +84818,7 @@ class Operations {
84139
84818
  type: ClipboardCellType.VALUE
84140
84819
  }, vertex.getValues());
84141
84820
  }
84142
- else if (vertex instanceof ArrayVertex) {
84821
+ else if (vertex instanceof ArrayFormulaVertex) {
84143
84822
  const val2 = vertex.getArrayCellValue(address);
84144
84823
  if (val2 === EmptyValue) {
84145
84824
  return {
@@ -84152,7 +84831,7 @@ class Operations {
84152
84831
  rawValue: vertex.getArrayCellRawValue(address)
84153
84832
  };
84154
84833
  }
84155
- else if (vertex instanceof FormulaCellVertex) {
84834
+ else if (vertex instanceof ScalarFormulaVertex) {
84156
84835
  return {
84157
84836
  type: ClipboardCellType.FORMULA,
84158
84837
  hash: this.parser.computeHashFromAst(vertex.getFormula(this.lazilyTransformingAstService))
@@ -84236,37 +84915,49 @@ class Operations {
84236
84915
  }
84237
84916
  }
84238
84917
  }
84918
+ /**
84919
+ * Sets cell content to an instance of parsing error.
84920
+ * Creates a ParsingErrorVertex and updates the dependency graph and column search index.
84921
+ */
84239
84922
  setParsingErrorToCell(rawInput, errors2, address) {
84240
- const oldValue = this.dependencyGraph.getCellValue(address);
84923
+ this.removeCellValueFromColumnSearch(address);
84241
84924
  const vertex = new ParsingErrorVertex(errors2, rawInput);
84242
84925
  const arrayChanges = this.dependencyGraph.setParsingErrorToCell(address, vertex);
84243
- this.columnSearch.remove(getRawValue(oldValue), address);
84244
84926
  this.columnSearch.applyChanges(arrayChanges.getChanges());
84245
84927
  this.changes.addAll(arrayChanges);
84246
84928
  this.changes.addChange(vertex.getCellValue(), address);
84247
84929
  }
84930
+ /**
84931
+ * Sets cell content to a formula.
84932
+ * Creates a ScalarFormulaVertex and updates the dependency graph and column search index.
84933
+ */
84248
84934
  setFormulaToCell(address, size2, { ast, hasVolatileFunction, hasStructuralChangeFunction, dependencies }) {
84249
- const oldValue = this.dependencyGraph.getCellValue(address);
84935
+ this.removeCellValueFromColumnSearch(address);
84250
84936
  const arrayChanges = this.dependencyGraph.setFormulaToCell(address, ast, absolutizeDependencies(dependencies, address), size2, hasVolatileFunction, hasStructuralChangeFunction);
84251
- this.columnSearch.remove(getRawValue(oldValue), address);
84252
84937
  this.columnSearch.applyChanges(arrayChanges.getChanges());
84253
84938
  this.changes.addAll(arrayChanges);
84254
84939
  }
84940
+ /**
84941
+ * Sets cell content to a value.
84942
+ * Creates a ValueCellVertex and updates the dependency graph and column search index.
84943
+ */
84255
84944
  setValueToCell(value, address) {
84256
- const oldValue = this.dependencyGraph.getCellValue(address);
84945
+ this.changeCellValueInColumnSearch(address, value.parsedValue);
84257
84946
  const arrayChanges = this.dependencyGraph.setValueToCell(address, value);
84258
- this.columnSearch.change(getRawValue(oldValue), getRawValue(value.parsedValue), address);
84259
84947
  this.columnSearch.applyChanges(arrayChanges.getChanges().filter((change) => !equalSimpleCellAddress(change.address, address)));
84260
84948
  this.changes.addAll(arrayChanges);
84261
84949
  this.changes.addChange(value.parsedValue, address);
84262
84950
  }
84951
+ /**
84952
+ * Sets cell content to an empty value.
84953
+ * Creates an EmptyCellVertex and updates the dependency graph and column search index.
84954
+ */
84263
84955
  setCellEmpty(address) {
84264
84956
  if (this.dependencyGraph.isArrayInternalCell(address)) {
84265
84957
  return;
84266
84958
  }
84267
- const oldValue = this.dependencyGraph.getCellValue(address);
84959
+ this.removeCellValueFromColumnSearch(address);
84268
84960
  const arrayChanges = this.dependencyGraph.setCellEmpty(address);
84269
- this.columnSearch.remove(getRawValue(oldValue), address);
84270
84961
  this.columnSearch.applyChanges(arrayChanges.getChanges());
84271
84962
  this.changes.addAll(arrayChanges);
84272
84963
  this.changes.addChange(EmptyValue, address);
@@ -84286,7 +84977,7 @@ class Operations {
84286
84977
  * @param {number} sheet - sheet ID number
84287
84978
  */
84288
84979
  rowEffectivelyNotInSheet(row, sheet) {
84289
- const height = this.dependencyGraph.addressMapping.getHeight(sheet);
84980
+ const height = this.dependencyGraph.addressMapping.getSheetHeight(sheet);
84290
84981
  return row >= height;
84291
84982
  }
84292
84983
  getAndClearContentChanges() {
@@ -84415,7 +85106,7 @@ class Operations {
84415
85106
  * @param {number} sheet - sheet ID number
84416
85107
  */
84417
85108
  columnEffectivelyNotInSheet(column, sheet) {
84418
- const width = this.dependencyGraph.addressMapping.getWidth(sheet);
85109
+ const width = this.dependencyGraph.addressMapping.getSheetWidth(sheet);
84419
85110
  return column >= width;
84420
85111
  }
84421
85112
  adjustNamedExpressionEdges(namedExpression, expressionName, sheetId) {
@@ -84428,7 +85119,7 @@ class Operations {
84428
85119
  const { vertex: globalVertex, id: maybeGlobalVertexId } = this.dependencyGraph.fetchCellOrCreateEmpty(globalNamedExpression.address);
84429
85120
  const globalVertexId = maybeGlobalVertexId !== null && maybeGlobalVertexId !== void 0 ? maybeGlobalVertexId : this.dependencyGraph.graph.getNodeId(globalVertex);
84430
85121
  for (const adjacentNode of this.dependencyGraph.graph.adjacentNodes(globalVertex)) {
84431
- if (adjacentNode instanceof FormulaCellVertex && adjacentNode.getAddress(this.lazilyTransformingAstService).sheet === sheetId) {
85122
+ if (adjacentNode instanceof ScalarFormulaVertex && adjacentNode.getAddress(this.lazilyTransformingAstService).sheet === sheetId) {
84432
85123
  const ast = adjacentNode.getFormula(this.lazilyTransformingAstService);
84433
85124
  const formulaAddress = adjacentNode.getAddress(this.lazilyTransformingAstService);
84434
85125
  const { dependencies } = this.parser.fetchCachedResultForAst(ast);
@@ -84468,8 +85159,10 @@ class Operations {
84468
85159
  const addedGlobalNamedExpressions = [];
84469
85160
  const targetRange = AbsoluteCellRange.spanFrom(destinationLeftCorner, width, height);
84470
85161
  for (const formulaAddress of targetRange.addresses(this.dependencyGraph)) {
84471
- const vertex = this.addressMapping.fetchCell(formulaAddress);
84472
- if (vertex instanceof FormulaCellVertex && formulaAddress.sheet !== sourceLeftCorner.sheet) {
85162
+ const vertex = this.addressMapping.getCell(formulaAddress, {
85163
+ throwIfCellNotExists: true
85164
+ });
85165
+ if (vertex instanceof ScalarFormulaVertex && formulaAddress.sheet !== sourceLeftCorner.sheet) {
84473
85166
  const ast = vertex.getFormula(this.lazilyTransformingAstService);
84474
85167
  const { dependencies } = this.parser.fetchCachedResultForAst(ast);
84475
85168
  addedGlobalNamedExpressions.push(...this.updateNamedExpressionsForTargetAddress(sourceLeftCorner.sheet, formulaAddress, dependencies));
@@ -84482,7 +85175,7 @@ class Operations {
84482
85175
  return [];
84483
85176
  }
84484
85177
  const addedGlobalNamedExpressions = [];
84485
- const vertex = this.addressMapping.fetchCell(targetAddress);
85178
+ const vertex = this.addressMapping.getCellOrThrow(targetAddress);
84486
85179
  for (const namedExpressionDependency of absolutizeDependencies(dependencies, targetAddress)) {
84487
85180
  if (!(namedExpressionDependency instanceof NamedExpressionDependency)) {
84488
85181
  continue;
@@ -84499,14 +85192,14 @@ class Operations {
84499
85192
  return addedGlobalNamedExpressions;
84500
85193
  }
84501
85194
  allocateNamedExpressionAddressSpace() {
84502
- this.dependencyGraph.addressMapping.addSheet(NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS, new SparseStrategy(0, 0));
85195
+ this.dependencyGraph.addressMapping.addSheetWithStrategy(NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS, new SparseStrategy(0, 0));
84503
85196
  }
84504
85197
  copyOrFetchGlobalNamedExpressionVertex(expressionName, sourceVertex, addedNamedExpressions) {
84505
85198
  let expression = this.namedExpressions.namedExpressionForScope(expressionName);
84506
85199
  if (expression === void 0) {
84507
85200
  expression = this.namedExpressions.addNamedExpression(expressionName);
84508
85201
  addedNamedExpressions.push(expression.normalizeExpressionName());
84509
- if (sourceVertex instanceof FormulaCellVertex) {
85202
+ if (sourceVertex instanceof ScalarFormulaVertex) {
84510
85203
  const parsingResult = this.parser.fetchCachedResultForAst(sourceVertex.getFormula(this.lazilyTransformingAstService));
84511
85204
  const { ast, hasVolatileFunction, hasStructuralChangeFunction, dependencies } = parsingResult;
84512
85205
  this.dependencyGraph.setFormulaToCell(expression.address, ast, absolutizeDependencies(dependencies, expression.address), ArraySize.scalar(), hasVolatileFunction, hasStructuralChangeFunction);
@@ -84520,6 +85213,38 @@ class Operations {
84520
85213
  }
84521
85214
  return this.dependencyGraph.fetchCellOrCreateEmpty(expression.address).vertex;
84522
85215
  }
85216
+ /**
85217
+ * Removes a cell value from the columnSearch index.
85218
+ * Ignores the non-computed formula vertices.
85219
+ */
85220
+ removeCellValueFromColumnSearch(address) {
85221
+ if (this.isNotComputed(address)) {
85222
+ return;
85223
+ }
85224
+ const oldValue = this.dependencyGraph.getCellValue(address);
85225
+ this.columnSearch.remove(getRawValue(oldValue), address);
85226
+ }
85227
+ /**
85228
+ * Changes a cell value in the columnSearch index.
85229
+ * Ignores the non-computed formula vertices.
85230
+ */
85231
+ changeCellValueInColumnSearch(address, newValue) {
85232
+ if (this.isNotComputed(address)) {
85233
+ return;
85234
+ }
85235
+ const oldValue = this.dependencyGraph.getCellValue(address);
85236
+ this.columnSearch.change(getRawValue(oldValue), getRawValue(newValue), address);
85237
+ }
85238
+ /**
85239
+ * Checks if the ScalarFormulaVertex or ArrayFormulaVertex at the given address is not computed.
85240
+ */
85241
+ isNotComputed(address) {
85242
+ const vertex = this.dependencyGraph.getCell(address);
85243
+ if (!vertex) {
85244
+ return false;
85245
+ }
85246
+ return "isComputed" in vertex && !vertex.isComputed();
85247
+ }
84523
85248
  }
84524
85249
  function normalizeRemovedIndexes(indexes) {
84525
85250
  if (indexes.length <= 1) {
@@ -84721,9 +85446,10 @@ class RemoveColumnsUndoEntry extends BaseUndoEntry {
84721
85446
  }
84722
85447
  }
84723
85448
  class AddSheetUndoEntry extends BaseUndoEntry {
84724
- constructor(sheetName) {
85449
+ constructor(sheetName, sheetId) {
84725
85450
  super();
84726
85451
  this.sheetName = sheetName;
85452
+ this.sheetId = sheetId;
84727
85453
  }
84728
85454
  doUndo(undoRedo) {
84729
85455
  undoRedo.undoAddSheet(this);
@@ -84733,13 +85459,12 @@ class AddSheetUndoEntry extends BaseUndoEntry {
84733
85459
  }
84734
85460
  }
84735
85461
  class RemoveSheetUndoEntry extends BaseUndoEntry {
84736
- constructor(sheetName, sheetId, oldSheetContent, scopedNamedExpressions, version) {
85462
+ constructor(sheetName, sheetId, oldSheetContent, scopedNamedExpressions) {
84737
85463
  super();
84738
85464
  this.sheetName = sheetName;
84739
85465
  this.sheetId = sheetId;
84740
85466
  this.oldSheetContent = oldSheetContent;
84741
85467
  this.scopedNamedExpressions = scopedNamedExpressions;
84742
- this.version = version;
84743
85468
  }
84744
85469
  doUndo(undoRedo) {
84745
85470
  undoRedo.undoRemoveSheet(this);
@@ -84749,11 +85474,13 @@ class RemoveSheetUndoEntry extends BaseUndoEntry {
84749
85474
  }
84750
85475
  }
84751
85476
  class RenameSheetUndoEntry extends BaseUndoEntry {
84752
- constructor(sheetId, oldName, newName) {
85477
+ constructor(sheetId, oldName, newName, version, mergedPlaceholderSheetId) {
84753
85478
  super();
84754
85479
  this.sheetId = sheetId;
84755
85480
  this.oldName = oldName;
84756
85481
  this.newName = newName;
85482
+ this.version = version;
85483
+ this.mergedPlaceholderSheetId = mergedPlaceholderSheetId;
84757
85484
  }
84758
85485
  doUndo(undoRedo) {
84759
85486
  undoRedo.undoRenameSheet(this);
@@ -85004,8 +85731,8 @@ class UndoRedo {
85004
85731
  }
85005
85732
  undoRemoveSheet(operation) {
85006
85733
  this.operations.forceApplyPostponedTransformations();
85007
- const { oldSheetContent, sheetId } = operation;
85008
- this.operations.addSheet(operation.sheetName);
85734
+ const { oldSheetContent, sheetId, scopedNamedExpressions, sheetName } = operation;
85735
+ this.operations.addSheetWithId(sheetId, sheetName);
85009
85736
  for (let rowIndex = 0; rowIndex < oldSheetContent.length; rowIndex++) {
85010
85737
  const row = oldSheetContent[rowIndex];
85011
85738
  for (let col = 0; col < row.length; col++) {
@@ -85014,13 +85741,17 @@ class UndoRedo {
85014
85741
  this.operations.restoreCell(address, cellType);
85015
85742
  }
85016
85743
  }
85017
- for (const [namedexpression, content] of operation.scopedNamedExpressions) {
85744
+ for (const [namedexpression, content] of scopedNamedExpressions) {
85018
85745
  this.operations.restoreNamedExpression(namedexpression, content, sheetId);
85019
85746
  }
85020
- this.restoreOldDataFromVersion(operation.version - 1);
85021
85747
  }
85022
85748
  undoRenameSheet(operation) {
85749
+ this.operations.forceApplyPostponedTransformations();
85023
85750
  this.operations.renameSheet(operation.sheetId, operation.oldName);
85751
+ if (operation.mergedPlaceholderSheetId !== void 0 && operation.version !== void 0) {
85752
+ this.operations.addPlaceholderSheetWithId(operation.mergedPlaceholderSheetId, operation.newName);
85753
+ this.restoreOldDataFromVersion(operation.version - 1);
85754
+ }
85024
85755
  }
85025
85756
  undoClearSheet(operation) {
85026
85757
  const { oldSheetContent, sheetId } = operation;
@@ -85108,7 +85839,7 @@ class UndoRedo {
85108
85839
  this.operations.removeSheetByName(operation.sheetName);
85109
85840
  }
85110
85841
  redoAddSheet(operation) {
85111
- this.operations.addSheet(operation.sheetName);
85842
+ this.operations.addSheetWithId(operation.sheetId, operation.sheetName);
85112
85843
  }
85113
85844
  redoRenameSheet(operation) {
85114
85845
  this.operations.renameSheet(operation.sheetId, operation.newName);
@@ -85281,27 +86012,27 @@ class CrudOperations {
85281
86012
  this.ensureItIsPossibleToAddSheet(name);
85282
86013
  }
85283
86014
  this.undoRedo.clearRedoStack();
85284
- const addedSheetName = this.operations.addSheet(name);
85285
- this.undoRedo.saveOperation(new AddSheetUndoEntry(addedSheetName));
85286
- return addedSheetName;
86015
+ const { sheetName, sheetId } = this.operations.addSheet(name);
86016
+ this.undoRedo.saveOperation(new AddSheetUndoEntry(sheetName, sheetId));
86017
+ return sheetName;
85287
86018
  }
85288
86019
  removeSheet(sheetId) {
85289
86020
  this.ensureScopeIdIsValid(sheetId);
85290
86021
  this.undoRedo.clearRedoStack();
85291
86022
  this.clipboardOperations.abortCut();
85292
- const originalName = this.sheetMapping.fetchDisplayName(sheetId);
86023
+ const originalName = this.sheetMapping.getSheetNameOrThrowError(sheetId);
85293
86024
  const oldSheetContent = this.operations.getSheetClipboardCells(sheetId);
85294
- const { version, scopedNamedExpressions } = this.operations.removeSheet(sheetId);
85295
- this.undoRedo.saveOperation(new RemoveSheetUndoEntry(originalName, sheetId, oldSheetContent, scopedNamedExpressions, version));
86025
+ const scopedNamedExpressions = this.operations.removeSheet(sheetId);
86026
+ this.undoRedo.saveOperation(new RemoveSheetUndoEntry(originalName, sheetId, oldSheetContent, scopedNamedExpressions));
85296
86027
  }
85297
86028
  renameSheet(sheetId, newName) {
85298
86029
  this.ensureItIsPossibleToRenameSheet(sheetId, newName);
85299
- const oldName = this.operations.renameSheet(sheetId, newName);
85300
- if (oldName !== void 0) {
86030
+ const { previousDisplayName, version, mergedPlaceholderSheetId } = this.operations.renameSheet(sheetId, newName);
86031
+ if (previousDisplayName !== void 0) {
85301
86032
  this.undoRedo.clearRedoStack();
85302
- this.undoRedo.saveOperation(new RenameSheetUndoEntry(sheetId, oldName, newName));
86033
+ this.undoRedo.saveOperation(new RenameSheetUndoEntry(sheetId, previousDisplayName, newName, version, mergedPlaceholderSheetId));
85303
86034
  }
85304
- return oldName;
86035
+ return previousDisplayName;
85305
86036
  }
85306
86037
  clearSheet(sheetId) {
85307
86038
  this.ensureScopeIdIsValid(sheetId);
@@ -85542,7 +86273,7 @@ class CrudOperations {
85542
86273
  this.ensureItIsPossibleToAddRows(sheet, [targetRow, numberOfRows]);
85543
86274
  const sourceStart = simpleCellAddress(sheet, 0, startRow);
85544
86275
  const targetStart = simpleCellAddress(sheet, 0, targetRow);
85545
- if (!this.sheetMapping.hasSheetWithId(sheet) || invalidSimpleCellAddress(sourceStart) || invalidSimpleCellAddress(targetStart) || !isPositiveInteger(numberOfRows) || targetRow <= startRow + numberOfRows && targetRow >= startRow) {
86276
+ if (!this.sheetMapping.hasSheetWithId(sheet) || isColOrRowInvalid(sourceStart) || isColOrRowInvalid(targetStart) || !isPositiveInteger(numberOfRows) || targetRow <= startRow + numberOfRows && targetRow >= startRow) {
85546
86277
  throw new InvalidArgumentsError("a valid range of rows to move.");
85547
86278
  }
85548
86279
  const width = this.dependencyGraph.getSheetWidth(sheet);
@@ -85558,7 +86289,7 @@ class CrudOperations {
85558
86289
  this.ensureItIsPossibleToAddColumns(sheet, [targetColumn, numberOfColumns]);
85559
86290
  const sourceStart = simpleCellAddress(sheet, startColumn, 0);
85560
86291
  const targetStart = simpleCellAddress(sheet, targetColumn, 0);
85561
- if (!this.sheetMapping.hasSheetWithId(sheet) || invalidSimpleCellAddress(sourceStart) || invalidSimpleCellAddress(targetStart) || !isPositiveInteger(numberOfColumns) || targetColumn <= startColumn + numberOfColumns && targetColumn >= startColumn) {
86292
+ if (!this.sheetMapping.hasSheetWithId(sheet) || isColOrRowInvalid(sourceStart) || isColOrRowInvalid(targetStart) || !isPositiveInteger(numberOfColumns) || targetColumn <= startColumn + numberOfColumns && targetColumn >= startColumn) {
85562
86293
  throw new InvalidArgumentsError("a valid range of columns to move.");
85563
86294
  }
85564
86295
  const sheetHeight = this.dependencyGraph.getSheetHeight(sheet);
@@ -85579,13 +86310,13 @@ class CrudOperations {
85579
86310
  if (!this.sheetMapping.hasSheetWithId(sheetId)) {
85580
86311
  throw new NoSheetWithIdError(sheetId);
85581
86312
  }
85582
- const existingSheetId = this.sheetMapping.get(name);
86313
+ const existingSheetId = this.sheetMapping.getSheetId(name);
85583
86314
  if (existingSheetId !== void 0 && existingSheetId !== sheetId) {
85584
86315
  throw new SheetNameAlreadyTakenError(name);
85585
86316
  }
85586
86317
  }
85587
86318
  ensureItIsPossibleToChangeContent(address) {
85588
- if (invalidSimpleCellAddress(address)) {
86319
+ if (isColOrRowInvalid(address)) {
85589
86320
  throw new InvalidAddressError(address);
85590
86321
  }
85591
86322
  if (!this.sheetMapping.hasSheetWithId(address.sheet)) {
@@ -85684,37 +86415,7 @@ class Evaluator {
85684
86415
  partialRun(vertices) {
85685
86416
  const changes = ContentChanges.empty();
85686
86417
  this.stats.measure(StatType.EVALUATION, () => {
85687
- this.dependencyGraph.graph.getTopSortedWithSccSubgraphFrom(vertices, (vertex) => {
85688
- if (vertex instanceof FormulaVertex) {
85689
- const currentValue = vertex.isComputed() ? vertex.getCellValue() : void 0;
85690
- const newCellValue = this.recomputeFormulaVertexValue(vertex);
85691
- if (newCellValue !== currentValue) {
85692
- const address = vertex.getAddress(this.lazilyTransformingAstService);
85693
- changes.addChange(newCellValue, address);
85694
- this.columnSearch.change(getRawValue(currentValue), getRawValue(newCellValue), address);
85695
- return true;
85696
- }
85697
- return false;
85698
- }
85699
- else if (vertex instanceof RangeVertex) {
85700
- vertex.clearCache();
85701
- return true;
85702
- }
85703
- else {
85704
- return true;
85705
- }
85706
- }, (vertex) => {
85707
- if (vertex instanceof RangeVertex) {
85708
- vertex.clearCache();
85709
- }
85710
- else if (vertex instanceof FormulaVertex) {
85711
- const address = vertex.getAddress(this.lazilyTransformingAstService);
85712
- this.columnSearch.remove(getRawValue(vertex.valueOrUndef()), address);
85713
- const error = new CellError(ErrorType.CYCLE, void 0, vertex);
85714
- vertex.setCellValue(error);
85715
- changes.addChange(error, address);
85716
- }
85717
- });
86418
+ this.dependencyGraph.graph.getTopSortedWithSccSubgraphFrom(vertices, (vertex) => this.recomputeVertex(vertex, changes), (vertex) => this.processVertexOnCycle(vertex, changes));
85718
86419
  });
85719
86420
  return changes;
85720
86421
  }
@@ -85725,17 +86426,55 @@ class Evaluator {
85725
86426
  const range2 = dep;
85726
86427
  if (this.dependencyGraph.getRange(range2.start, range2.end) === void 0) {
85727
86428
  const rangeVertex = new RangeVertex(range2);
85728
- this.dependencyGraph.rangeMapping.setRange(rangeVertex);
86429
+ this.dependencyGraph.rangeMapping.addOrUpdateVertex(rangeVertex);
85729
86430
  tmpRanges.push(rangeVertex);
85730
86431
  }
85731
86432
  }
85732
86433
  }
85733
86434
  const ret = this.evaluateAstToCellValue(ast, new InterpreterState(address, this.config.useArrayArithmetic));
85734
86435
  tmpRanges.forEach((rangeVertex) => {
85735
- this.dependencyGraph.rangeMapping.removeRange(rangeVertex);
86436
+ this.dependencyGraph.rangeMapping.removeVertexIfExists(rangeVertex);
85736
86437
  });
85737
86438
  return ret;
85738
86439
  }
86440
+ /**
86441
+ * Recalculates the value of a single vertex assuming its dependencies have already been recalculated
86442
+ */
86443
+ recomputeVertex(vertex, changes) {
86444
+ if (vertex instanceof FormulaVertex) {
86445
+ const currentValue = vertex.isComputed() ? vertex.getCellValue() : void 0;
86446
+ const newCellValue = this.recomputeFormulaVertexValue(vertex);
86447
+ if (newCellValue !== currentValue) {
86448
+ const address = vertex.getAddress(this.lazilyTransformingAstService);
86449
+ changes.addChange(newCellValue, address);
86450
+ this.columnSearch.change(getRawValue(currentValue), getRawValue(newCellValue), address);
86451
+ return true;
86452
+ }
86453
+ return false;
86454
+ }
86455
+ else if (vertex instanceof RangeVertex) {
86456
+ vertex.clearCache();
86457
+ return true;
86458
+ }
86459
+ else {
86460
+ return true;
86461
+ }
86462
+ }
86463
+ /**
86464
+ * Processes a vertex that is part of a cycle in dependency graph
86465
+ */
86466
+ processVertexOnCycle(vertex, changes) {
86467
+ if (vertex instanceof RangeVertex) {
86468
+ vertex.clearCache();
86469
+ }
86470
+ else if (vertex instanceof FormulaVertex) {
86471
+ const address = vertex.getAddress(this.lazilyTransformingAstService);
86472
+ this.columnSearch.remove(getRawValue(vertex.valueOrUndef()), address);
86473
+ const error = new CellError(ErrorType.CYCLE, void 0, vertex);
86474
+ vertex.setCellValue(error);
86475
+ changes.addChange(error, address);
86476
+ }
86477
+ }
85739
86478
  /**
85740
86479
  * Recalculates formulas in the topological sort order
85741
86480
  */
@@ -85758,7 +86497,7 @@ class Evaluator {
85758
86497
  }
85759
86498
  recomputeFormulaVertexValue(vertex) {
85760
86499
  const address = vertex.getAddress(this.lazilyTransformingAstService);
85761
- if (vertex instanceof ArrayVertex && (vertex.array.size.isRef || !this.dependencyGraph.isThereSpaceForArray(vertex))) {
86500
+ if (vertex instanceof ArrayFormulaVertex && (vertex.array.size.isRef || !this.dependencyGraph.isThereSpaceForArray(vertex))) {
85762
86501
  return vertex.setNoSpace();
85763
86502
  }
85764
86503
  else {
@@ -85805,10 +86544,10 @@ class ExportedNamedExpressionChange {
85805
86544
  }
85806
86545
  }
85807
86546
  class Exporter {
85808
- constructor(config2, namedExpressions, sheetIndexMapping, lazilyTransformingService) {
86547
+ constructor(config2, namedExpressions, sheetMapping, lazilyTransformingService) {
85809
86548
  this.config = config2;
85810
86549
  this.namedExpressions = namedExpressions;
85811
- this.sheetIndexMapping = sheetIndexMapping;
86550
+ this.sheetMapping = sheetMapping;
85812
86551
  this.lazilyTransformingService = lazilyTransformingService;
85813
86552
  }
85814
86553
  exportChange(change) {
@@ -85866,7 +86605,7 @@ class Exporter {
85866
86605
  address = (_b = this.namedExpressions.namedExpressionInAddress(originAddress.row)) === null || _b === void 0 ? void 0 : _b.displayName;
85867
86606
  }
85868
86607
  else {
85869
- address = simpleCellAddressToString(this.sheetIndexMapping, originAddress, -1);
86608
+ address = simpleCellAddressToString(this.sheetMapping.getSheetNameOrThrowError.bind(this.sheetMapping), originAddress, -1);
85870
86609
  }
85871
86610
  }
85872
86611
  return new DetailedCellError(error, this.config.translationPackage.getErrorTranslation(error.type), address);
@@ -85943,7 +86682,7 @@ class SimpleStrategy {
85943
86682
  this.shrinkArrayIfNeeded(address);
85944
86683
  const size2 = this.arraySizePredictor.checkArraySize(parseResult.ast, address);
85945
86684
  if (size2.isScalar()) {
85946
- const vertex = new FormulaCellVertex(parseResult.ast, address, 0);
86685
+ const vertex = new ScalarFormulaVertex(parseResult.ast, address, 0);
85947
86686
  dependencies.set(vertex, absolutizeDependencies(parseResult.dependencies, address));
85948
86687
  this.dependencyGraph.addVertex(address, vertex);
85949
86688
  if (parseResult.hasVolatileFunction) {
@@ -85954,7 +86693,7 @@ class SimpleStrategy {
85954
86693
  }
85955
86694
  }
85956
86695
  else {
85957
- const vertex = new ArrayVertex(parseResult.ast, address, new ArraySize(size2.width, size2.height));
86696
+ const vertex = new ArrayFormulaVertex(parseResult.ast, address, new ArraySize(size2.width, size2.height));
85958
86697
  dependencies.set(vertex, absolutizeDependencies(parseResult.dependencies, address));
85959
86698
  this.dependencyGraph.addArrayVertex(address, vertex);
85960
86699
  }
@@ -85975,7 +86714,7 @@ class SimpleStrategy {
85975
86714
  }
85976
86715
  shrinkArrayIfNeeded(address) {
85977
86716
  const vertex = this.dependencyGraph.getCell(address);
85978
- if (vertex instanceof ArrayVertex) {
86717
+ if (vertex instanceof ArrayFormulaVertex) {
85979
86718
  this.dependencyGraph.shrinkArrayToCorner(vertex);
85980
86719
  }
85981
86720
  }
@@ -86476,8 +87215,8 @@ class Interpreter {
86476
87215
  /**
86477
87216
  * Calculates cell value from formula abstract syntax tree
86478
87217
  *
86479
- * @param formula - abstract syntax tree of formula
86480
- * @param formulaAddress - address of the cell in which formula is located
87218
+ * @param {Ast} ast - abstract syntax tree of formula
87219
+ * @param {InterpreterState} state - interpreter state
86481
87220
  */
86482
87221
  evaluateAstWithoutPostprocessing(ast, state) {
86483
87222
  switch (ast.type) {
@@ -86486,9 +87225,12 @@ class Interpreter {
86486
87225
  }
86487
87226
  case AstNodeType.CELL_REFERENCE: {
86488
87227
  const address = ast.reference.toSimpleCellAddress(state.formulaAddress);
86489
- if (invalidSimpleCellAddress(address)) {
87228
+ if (isColOrRowInvalid(address)) {
86490
87229
  return new CellError(ErrorType.REF, ErrorMessage.BadRef);
86491
87230
  }
87231
+ if (!this.isSheetValid(ast.reference)) {
87232
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
87233
+ }
86492
87234
  return this.dependencyGraph.getCellValue(address);
86493
87235
  }
86494
87236
  case AstNodeType.NUMBER:
@@ -86589,6 +87331,9 @@ class Interpreter {
86589
87331
  }
86590
87332
  }
86591
87333
  case AstNodeType.CELL_RANGE: {
87334
+ if (!this.isSheetValid(ast.start) || !this.isSheetValid(ast.end)) {
87335
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
87336
+ }
86592
87337
  if (!this.rangeSpansOneSheet(ast)) {
86593
87338
  return new CellError(ErrorType.REF, ErrorMessage.RangeManySheets);
86594
87339
  }
@@ -86609,11 +87354,12 @@ class Interpreter {
86609
87354
  throw new Error("Unknown array");
86610
87355
  }
86611
87356
  }
86612
- else {
86613
- return SimpleRangeValue.onlyRange(range2, this.dependencyGraph);
86614
- }
87357
+ return SimpleRangeValue.onlyRange(range2, this.dependencyGraph);
86615
87358
  }
86616
87359
  case AstNodeType.COLUMN_RANGE: {
87360
+ if (!this.isSheetValid(ast.start) || !this.isSheetValid(ast.end)) {
87361
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
87362
+ }
86617
87363
  if (!this.rangeSpansOneSheet(ast)) {
86618
87364
  return new CellError(ErrorType.REF, ErrorMessage.RangeManySheets);
86619
87365
  }
@@ -86621,6 +87367,9 @@ class Interpreter {
86621
87367
  return SimpleRangeValue.onlyRange(range2, this.dependencyGraph);
86622
87368
  }
86623
87369
  case AstNodeType.ROW_RANGE: {
87370
+ if (!this.isSheetValid(ast.start) || !this.isSheetValid(ast.end)) {
87371
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
87372
+ }
86624
87373
  if (!this.rangeSpansOneSheet(ast)) {
86625
87374
  return new CellError(ErrorType.REF, ErrorMessage.RangeManySheets);
86626
87375
  }
@@ -86672,6 +87421,18 @@ class Interpreter {
86672
87421
  }
86673
87422
  }
86674
87423
  }
87424
+ /**
87425
+ * Sheet is valid if:
87426
+ * - sheet is undefined OR
87427
+ * - sheet is a named expressions store OR
87428
+ * - sheet exists in sheet mapping
87429
+ * - sheet is not a placeholder
87430
+ */
87431
+ isSheetValid(address) {
87432
+ return address.sheet === void 0 || address.sheet === NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS || this.dependencyGraph.sheetMapping.hasSheetWithId(address.sheet, {
87433
+ includePlaceholders: false
87434
+ });
87435
+ }
86675
87436
  rangeSpansOneSheet(ast) {
86676
87437
  return ast.start.sheet === ast.end.sheet;
86677
87438
  }
@@ -87357,7 +88118,7 @@ class Serialization {
87357
88118
  }
87358
88119
  getCellHyperlink(address) {
87359
88120
  const formulaVertex = this.dependencyGraph.getCell(address);
87360
- if (formulaVertex instanceof FormulaCellVertex) {
88121
+ if (formulaVertex instanceof ScalarFormulaVertex) {
87361
88122
  const formula = formulaVertex.getFormula(this.dependencyGraph.lazilyTransformingAstService);
87362
88123
  if ("HYPERLINK" === formula.procedureName) {
87363
88124
  return formula.hyperlink;
@@ -87367,12 +88128,12 @@ class Serialization {
87367
88128
  }
87368
88129
  getCellFormula(address, targetAddress) {
87369
88130
  const formulaVertex = this.dependencyGraph.getCell(address);
87370
- if (formulaVertex instanceof FormulaCellVertex) {
88131
+ if (formulaVertex instanceof ScalarFormulaVertex) {
87371
88132
  const formula = formulaVertex.getFormula(this.dependencyGraph.lazilyTransformingAstService);
87372
88133
  targetAddress = targetAddress !== null && targetAddress !== void 0 ? targetAddress : address;
87373
88134
  return this.unparser.unparse(formula, targetAddress);
87374
88135
  }
87375
- else if (formulaVertex instanceof ArrayVertex) {
88136
+ else if (formulaVertex instanceof ArrayFormulaVertex) {
87376
88137
  const arrayVertexAddress = formulaVertex.getAddress(this.dependencyGraph.lazilyTransformingAstService);
87377
88138
  if (arrayVertexAddress.row !== address.row || arrayVertexAddress.col !== address.col || arrayVertexAddress.sheet !== address.sheet) {
87378
88139
  return void 0;
@@ -87435,8 +88196,8 @@ class Serialization {
87435
88196
  }
87436
88197
  genericAllSheetsGetter(sheetGetter) {
87437
88198
  const result = {};
87438
- for (const sheetName of this.dependencyGraph.sheetMapping.displayNames()) {
87439
- const sheetId = this.dependencyGraph.sheetMapping.fetch(sheetName);
88199
+ for (const sheetName of this.dependencyGraph.sheetMapping.iterateSheetNames()) {
88200
+ const sheetId = this.dependencyGraph.sheetMapping.getSheetIdOrThrowError(sheetName);
87440
88201
  result[sheetName] = sheetGetter(sheetId);
87441
88202
  }
87442
88203
  return result;
@@ -87456,8 +88217,8 @@ class Serialization {
87456
88217
  getAllNamedExpressionsSerialized() {
87457
88218
  const idMap = [];
87458
88219
  let id2 = 0;
87459
- for (const sheetName of this.dependencyGraph.sheetMapping.displayNames()) {
87460
- const sheetId = this.dependencyGraph.sheetMapping.fetch(sheetName);
88220
+ for (const sheetName of this.dependencyGraph.sheetMapping.iterateSheetNames()) {
88221
+ const sheetId = this.dependencyGraph.sheetMapping.getSheetIdOrThrowError(sheetName);
87461
88222
  idMap[sheetId] = id2;
87462
88223
  id2++;
87463
88224
  }
@@ -87471,7 +88232,7 @@ class Serialization {
87471
88232
  });
87472
88233
  }
87473
88234
  withNewConfig(newConfig, namedExpressions) {
87474
- const newUnparser = new Unparser(newConfig, buildLexerConfig(newConfig), this.dependencyGraph.sheetMapping.fetchDisplayName, namedExpressions);
88235
+ const newUnparser = new Unparser(newConfig, this.dependencyGraph.sheetMapping, namedExpressions);
87475
88236
  return new Serialization(this.dependencyGraph, newUnparser, this.exporter);
87476
88237
  }
87477
88238
  }
@@ -87511,12 +88272,14 @@ class BuildEngineFactory {
87511
88272
  throw new SheetSizeLimitExceededError();
87512
88273
  }
87513
88274
  const sheetId = sheetMapping.addSheet(sheetName);
87514
- addressMapping.autoAddSheet(sheetId, boundaries);
88275
+ addressMapping.addSheetAndSetStrategyBasedOnBoundaries(sheetId, boundaries, {
88276
+ throwIfSheetAlreadyExists: true
88277
+ });
87515
88278
  }
87516
88279
  }
87517
- const parser2 = new ParserWithCaching(config2, functionRegistry, sheetMapping.get);
88280
+ const parser2 = new ParserWithCaching(config2, functionRegistry, dependencyGraph.sheetReferenceRegistrar.ensureSheetRegistered.bind(dependencyGraph.sheetReferenceRegistrar));
87518
88281
  lazilyTransformingAstService.parser = parser2;
87519
- const unparser = new Unparser(config2, buildLexerConfig(config2), sheetMapping.fetchDisplayName, namedExpressions);
88282
+ const unparser = new Unparser(config2, sheetMapping, namedExpressions);
87520
88283
  const dateTimeHelper = new DateTimeHelper(config2);
87521
88284
  const numberLiteralHelper = new NumberLiteralHelper(config2);
87522
88285
  const arithmeticHelper = new ArithmeticHelper(config2, dateTimeHelper, numberLiteralHelper);
@@ -87527,7 +88290,7 @@ class BuildEngineFactory {
87527
88290
  lazilyTransformingAstService.undoRedo = undoRedo;
87528
88291
  const clipboardOperations = new ClipboardOperations(config2, dependencyGraph, operations);
87529
88292
  const crudOperations = new CrudOperations(config2, operations, undoRedo, clipboardOperations, dependencyGraph, columnSearch, parser2, cellContentParser, lazilyTransformingAstService, namedExpressions);
87530
- const exporter = new Exporter(config2, namedExpressions, sheetMapping.fetchDisplayName, lazilyTransformingAstService);
88293
+ const exporter = new Exporter(config2, namedExpressions, sheetMapping, lazilyTransformingAstService);
87531
88294
  const serialization = new Serialization(dependencyGraph, unparser, exporter);
87532
88295
  const interpreter = new Interpreter(config2, dependencyGraph, columnSearch, stats, arithmeticHelper, functionRegistry, namedExpressions, serialization, arraySizePredictor, dateTimeHelper);
87533
88296
  stats.measure(StatType.GRAPH_BUILD, () => {
@@ -90040,6 +90803,8 @@ class HyperFormula {
90040
90803
  /**
90041
90804
  * Adds a new sheet to the HyperFormula instance. Returns given or autogenerated name of a new sheet.
90042
90805
  *
90806
+ * Note that this method may trigger dependency graph recalculation.
90807
+ *
90043
90808
  * @param {string} [sheetName] - if not specified, name is autogenerated
90044
90809
  *
90045
90810
  * @fires [[sheetAdded]] after the sheet was added
@@ -90069,6 +90834,7 @@ class HyperFormula {
90069
90834
  validateArgToType(sheetName, "string", "sheetName");
90070
90835
  }
90071
90836
  const addedSheetName = this._crudOperations.addSheet(sheetName);
90837
+ this.recomputeIfDependencyGraphNeedsIt();
90072
90838
  this._emitter.emit(Events.SheetAdded, addedSheetName);
90073
90839
  return addedSheetName;
90074
90840
  }
@@ -90139,7 +90905,7 @@ class HyperFormula {
90139
90905
  */
90140
90906
  removeSheet(sheetId) {
90141
90907
  validateArgToType(sheetId, "number", "sheetId");
90142
- const displayName = this.sheetMapping.getDisplayName(sheetId);
90908
+ const displayName = this.sheetMapping.getSheetName(sheetId);
90143
90909
  this._crudOperations.removeSheet(sheetId);
90144
90910
  const changes = this.recomputeIfDependencyGraphNeedsIt();
90145
90911
  this._emitter.emit(Events.SheetRemoved, displayName, changes);
@@ -90315,7 +91081,7 @@ class HyperFormula {
90315
91081
  simpleCellAddressFromString(cellAddress, contextSheetId) {
90316
91082
  validateArgToType(cellAddress, "string", "cellAddress");
90317
91083
  validateArgToType(contextSheetId, "number", "sheetId");
90318
- return simpleCellAddressFromString(this.sheetMapping.get, cellAddress, contextSheetId);
91084
+ return simpleCellAddressFromString(this.sheetMapping.getSheetId.bind(this.sheetMapping), cellAddress, contextSheetId);
90319
91085
  }
90320
91086
  /**
90321
91087
  * Computes simple (absolute) address of a cell range based on its string representation.
@@ -90343,7 +91109,7 @@ class HyperFormula {
90343
91109
  simpleCellRangeFromString(cellRange, contextSheetId) {
90344
91110
  validateArgToType(cellRange, "string", "cellRange");
90345
91111
  validateArgToType(contextSheetId, "number", "sheetId");
90346
- return simpleCellRangeFromString(this.sheetMapping.get, cellRange, contextSheetId);
91112
+ return simpleCellRangeFromString(this.sheetMapping.getSheetId.bind(this.sheetMapping), cellRange, contextSheetId);
90347
91113
  }
90348
91114
  /**
90349
91115
  * Computes string representation of an absolute address in A1 notation. If `cellAddress.sheet` is not present in the engine, returns `undefined`.
@@ -90384,7 +91150,7 @@ class HyperFormula {
90384
91150
  throw new ExpectedValueOfTypeError("SimpleCellAddress", "cellAddress");
90385
91151
  }
90386
91152
  const contextSheetId = typeof optionsOrContextSheetId === "number" ? optionsOrContextSheetId : optionsOrContextSheetId.includeSheetName ? cellAddress.sheet + 1 : cellAddress.sheet;
90387
- return simpleCellAddressToString(this.sheetMapping.fetchDisplayName, cellAddress, contextSheetId);
91153
+ return simpleCellAddressToString(this.sheetMapping.getSheetNameOrThrowError.bind(this.sheetMapping), cellAddress, contextSheetId);
90388
91154
  }
90389
91155
  /**
90390
91156
  * Computes string representation of an absolute range in A1 notation.
@@ -90432,7 +91198,7 @@ class HyperFormula {
90432
91198
  throw new ExpectedValueOfTypeError("SimpleCellRange", "cellRange");
90433
91199
  }
90434
91200
  const contextSheetId = typeof optionsOrContextSheetId === "number" ? optionsOrContextSheetId : optionsOrContextSheetId.includeSheetName ? cellRange.start.sheet + cellRange.end.sheet + 1 : cellRange.start.sheet;
90435
- return simpleCellRangeToString(this.sheetMapping.fetchDisplayName, cellRange, contextSheetId);
91201
+ return simpleCellRangeToString(this.sheetMapping.getSheetNameOrThrowError.bind(this.sheetMapping), cellRange, contextSheetId);
90436
91202
  }
90437
91203
  /**
90438
91204
  * Returns all the out-neighbors in the [dependency graph](../../guide/dependency-graph.md) for a given cell address or range. Including:
@@ -90465,7 +91231,7 @@ class HyperFormula {
90465
91231
  vertex = this._dependencyGraph.addressMapping.getCell(address);
90466
91232
  }
90467
91233
  else if (isSimpleCellRange(address)) {
90468
- vertex = this._dependencyGraph.rangeMapping.getRange(address.start, address.end);
91234
+ vertex = this._dependencyGraph.rangeMapping.getRangeVertex(address.start, address.end);
90469
91235
  }
90470
91236
  else {
90471
91237
  throw new ExpectedValueOfTypeError("SimpleCellAddress | SimpleCellRange", address);
@@ -90504,7 +91270,7 @@ class HyperFormula {
90504
91270
  vertex = this._dependencyGraph.addressMapping.getCell(address);
90505
91271
  }
90506
91272
  else if (isSimpleCellRange(address)) {
90507
- vertex = this._dependencyGraph.rangeMapping.getRange(address.start, address.end);
91273
+ vertex = this._dependencyGraph.rangeMapping.getRangeVertex(address.start, address.end);
90508
91274
  }
90509
91275
  else {
90510
91276
  throw new ExpectedValueOfTypeError("SimpleCellAddress | SimpleCellRange", address);
@@ -90536,7 +91302,7 @@ class HyperFormula {
90536
91302
  */
90537
91303
  getSheetName(sheetId) {
90538
91304
  validateArgToType(sheetId, "number", "sheetId");
90539
- return this.sheetMapping.getDisplayName(sheetId);
91305
+ return this.sheetMapping.getSheetName(sheetId);
90540
91306
  }
90541
91307
  /**
90542
91308
  * List all sheet names.
@@ -90556,7 +91322,7 @@ class HyperFormula {
90556
91322
  * @category Sheets
90557
91323
  */
90558
91324
  getSheetNames() {
90559
- return this.sheetMapping.sheetNames();
91325
+ return this.sheetMapping.getSheetNames();
90560
91326
  }
90561
91327
  /**
90562
91328
  * Returns a unique sheet ID assigned to the sheet with a given name or `undefined` if the sheet does not exist.
@@ -90580,7 +91346,7 @@ class HyperFormula {
90580
91346
  */
90581
91347
  getSheetId(sheetName) {
90582
91348
  validateArgToType(sheetName, "string", "sheetName");
90583
- return this.sheetMapping.get(sheetName);
91349
+ return this.sheetMapping.getSheetId(sheetName);
90584
91350
  }
90585
91351
  /**
90586
91352
  * Returns `true` whether sheet with a given name exists. The method accepts sheet name to be checked.
@@ -90914,6 +91680,8 @@ class HyperFormula {
90914
91680
  /**
90915
91681
  * Renames a specified sheet.
90916
91682
  *
91683
+ * Note that this method may trigger dependency graph recalculation.
91684
+ *
90917
91685
  * @param {number} sheetId - a sheet ID
90918
91686
  * @param {string} newName - a name of the sheet to be given, if is the same as the old one the method does nothing
90919
91687
  *
@@ -90940,6 +91708,7 @@ class HyperFormula {
90940
91708
  validateArgToType(sheetId, "number", "sheetId");
90941
91709
  validateArgToType(newName, "string", "newName");
90942
91710
  const oldName = this._crudOperations.renameSheet(sheetId, newName);
91711
+ this.recomputeIfDependencyGraphNeedsIt();
90943
91712
  if (oldName !== void 0) {
90944
91713
  this._emitter.emit(Events.SheetRenamed, oldName, newName);
90945
91714
  }
@@ -91999,9 +92768,9 @@ class HyperFormula {
91999
92768
  }
92000
92769
  }
92001
92770
  }
92002
- HyperFormula.version = "3.1.0";
92003
- HyperFormula.buildDate = "14/10/2025 09:41:56";
92004
- HyperFormula.releaseDate = "14/10/2025";
92771
+ HyperFormula.version = "3.1.1";
92772
+ HyperFormula.buildDate = "18/12/2025 11:47:25";
92773
+ HyperFormula.releaseDate = "18/12/2025";
92005
92774
  HyperFormula.languages = {};
92006
92775
  HyperFormula.registeredLanguages = /* @__PURE__ */ new Map();
92007
92776
  const privatePool = /* @__PURE__ */ new WeakMap();
@@ -95240,7 +96009,7 @@ class InformationPlugin extends FunctionPlugin {
95240
96009
  */
95241
96010
  sheet(ast, state) {
95242
96011
  return this.runFunctionWithReferenceArgument(ast.args, state, this.metadata("SHEET"), () => state.formulaAddress.sheet + 1, (reference) => reference.sheet + 1, (value) => {
95243
- const sheetNumber = this.dependencyGraph.sheetMapping.get(value);
96012
+ const sheetNumber = this.dependencyGraph.sheetMapping.getSheetId(value);
95244
96013
  if (sheetNumber !== void 0) {
95245
96014
  return sheetNumber + 1;
95246
96015
  }
@@ -96216,13 +96985,13 @@ class NumericAggregationPlugin extends FunctionPlugin {
96216
96985
  /**
96217
96986
  * Performs range operation on given range
96218
96987
  *
96219
- * @param ast - cell range ast
96220
- * @param state
96221
- * @param initialAccValue - initial accumulator value for reducing function
96222
- * @param functionName - function name to use as cache key
96223
- * @param reducingFunction - reducing function
96224
- * @param mapFunction
96225
- * @param coercionFunction
96988
+ * @param {CellRangeAst | ColumnRangeAst | RowRangeAst} ast - cell range ast
96989
+ * @param {InterpreterState} state - interpreter state
96990
+ * @param {T} initialAccValue - initial accumulator value for reducing function
96991
+ * @param {string} functionName - function name to use as cache key
96992
+ * @param {BinaryOperation<T>} reducingFunction - reducing function
96993
+ * @param {MapOperation<T>} mapFunction - mapper transforming coerced scalar
96994
+ * @param {coercionOperation} coercionFunction - scalar-to-number coercer
96226
96995
  */
96227
96996
  evaluateRange(ast, state, initialAccValue, functionName2, reducingFunction, mapFunction, coercionFunction) {
96228
96997
  let range2;
@@ -96237,6 +97006,9 @@ class NumericAggregationPlugin extends FunctionPlugin {
96237
97006
  throw err;
96238
97007
  }
96239
97008
  }
97009
+ if (!this.isSheetValid(range2)) {
97010
+ return new CellError(ErrorType.REF, ErrorMessage.SheetRef);
97011
+ }
96240
97012
  const rangeVertex = this.dependencyGraph.getRange(range2.start, range2.end);
96241
97013
  if (rangeVertex === void 0) {
96242
97014
  throw new Error("Range does not exists in graph");
@@ -96259,6 +97031,16 @@ class NumericAggregationPlugin extends FunctionPlugin {
96259
97031
  }
96260
97032
  return value;
96261
97033
  }
97034
+ /**
97035
+ * Checks whether both ends of a range point to existing sheets (placeholders excluded).
97036
+ */
97037
+ isSheetValid(range2) {
97038
+ return this.dependencyGraph.sheetMapping.hasSheetWithId(range2.start.sheet, {
97039
+ includePlaceholders: false
97040
+ }) && this.dependencyGraph.sheetMapping.hasSheetWithId(range2.end.sheet, {
97041
+ includePlaceholders: false
97042
+ });
97043
+ }
96262
97044
  /**
96263
97045
  * Returns list of values for given range and function name
96264
97046
  *
@@ -111665,7 +112447,7 @@ function requireDefineProperties() {
111665
112447
  return defineProperties_1;
111666
112448
  hasRequiredDefineProperties = 1;
111667
112449
  var keys2 = requireObjectKeys();
111668
- var hasSymbols2 = typeof Symbol === "function" && typeof Symbol("foo") === "symbol";
112450
+ var hasSymbols2 = typeof Symbol === "function" && typeof /* @__PURE__ */ Symbol("foo") === "symbol";
111669
112451
  var toStr = Object.prototype.toString;
111670
112452
  var concat = Array.prototype.concat;
111671
112453
  var defineDataProperty2 = /* @__PURE__ */ requireDefineDataProperty();
@@ -111854,7 +112636,7 @@ function requireShams$1() {
111854
112636
  return true;
111855
112637
  }
111856
112638
  var obj = {};
111857
- var sym = Symbol("test");
112639
+ var sym = /* @__PURE__ */ Symbol("test");
111858
112640
  var symObj = Object(sym);
111859
112641
  if (typeof sym === "string") {
111860
112642
  return false;
@@ -111913,7 +112695,7 @@ function requireHasSymbols() {
111913
112695
  if (typeof origSymbol("foo") !== "symbol") {
111914
112696
  return false;
111915
112697
  }
111916
- if (typeof Symbol("bar") !== "symbol") {
112698
+ if (typeof /* @__PURE__ */ Symbol("bar") !== "symbol") {
111917
112699
  return false;
111918
112700
  }
111919
112701
  return hasSymbolSham();
@@ -134315,7 +135097,21 @@ async function init(config2) {
134315
135097
  _setDocumentDir(dataDir || process.cwd());
134316
135098
  if (serverURL) {
134317
135099
  setServer(serverURL);
134318
- if (config2.password) {
135100
+ if ("sessionToken" in config2 && config2.sessionToken) {
135101
+ await runHandler(exports.handlers["subscribe-set-token"], {
135102
+ token: config2.sessionToken
135103
+ });
135104
+ const user = await runHandler(exports.handlers["subscribe-get-user"], void 0);
135105
+ if (!user || user.tokenExpired === true) {
135106
+ await runHandler(exports.handlers["subscribe-set-token"], { token: "" });
135107
+ throw new Error("Authentication failed: invalid or expired session token");
135108
+ }
135109
+ if (user.offline === true) {
135110
+ await runHandler(exports.handlers["subscribe-set-token"], { token: "" });
135111
+ throw new Error("Authentication failed: server offline or unreachable");
135112
+ }
135113
+ }
135114
+ else if ("password" in config2 && config2.password) {
134319
135115
  const result = await runHandler(exports.handlers["subscribe-sign-in"], {
134320
135116
  password: config2.password
134321
135117
  });