@univerjs/engine-formula 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/lib/cjs/{en-US-DrAfIiBE.js → en-US-BYMYuEpp.js} +15 -15
  2. package/lib/cjs/facade.js +3 -18
  3. package/lib/cjs/index.js +479 -165
  4. package/lib/cjs/locale/en-US.js +1 -1
  5. package/lib/cjs/locale/fa-IR.js +1 -1
  6. package/lib/cjs/locale/zh-HK.js +1 -1
  7. package/lib/cjs/locale/zh-TW.js +1 -1
  8. package/lib/cjs/{zh-TW-CvMudVQy.js → zh-TW-B5pYt-NJ.js} +15 -15
  9. package/lib/es/facade.js +3 -18
  10. package/lib/es/index.js +453 -139
  11. package/lib/facade.js +3 -18
  12. package/lib/index.js +453 -139
  13. package/lib/types/basics/common.d.ts +8 -2
  14. package/lib/types/commands/mutations/set-formula-calculation.mutation.d.ts +4 -2
  15. package/lib/types/config/config.d.ts +0 -2
  16. package/lib/types/engine/dependency/dependency-groups.d.ts +21 -0
  17. package/lib/types/engine/dependency/dependency-tree.d.ts +1 -0
  18. package/lib/types/engine/dependency/formula-dependency.d.ts +1 -1
  19. package/lib/types/facade/f-formula.d.ts +0 -13
  20. package/lib/types/functions/lookup/xlookup/index.d.ts +2 -4
  21. package/lib/types/index.d.ts +4 -2
  22. package/lib/types/models/formula-data.model.d.ts +5 -0
  23. package/lib/types/services/active-dirty-manager.service.d.ts +1 -0
  24. package/lib/types/services/calculate-formula.service.d.ts +34 -2
  25. package/lib/types/services/current-data.service.d.ts +4 -2
  26. package/lib/types/services/formula-calculation-trigger.service.d.ts +5 -0
  27. package/lib/types/services/formula-changeset-calculation.service.d.ts +34 -0
  28. package/lib/types/services/runtime.service.d.ts +40 -3
  29. package/lib/umd/facade.js +1 -1
  30. package/lib/umd/index.js +4 -4
  31. package/package.json +5 -5
package/lib/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import IntervalTree from "@flatten-js/interval-tree";
2
- import { AbsoluteRefType, AsyncLock, BooleanNumber, BuildTextUtils, CellValueType, CommandType, DataStreamTreeTokenType, DateSystem, Disposable, DisposableCollection, EXCEL_1904_OFFSET, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LRUMap, LifecycleService, LifecycleStages, LocaleService, LocaleType, MAX_COLUMN_COUNT, MAX_ROW_COUNT, ObjectMatrix, Optional, Plugin, RANGE_TYPE, RTree, Rectangle, RichTextBuilder, Styles, Tools, UniverInstanceType, cellToRange, columnLabelToNumber, createBaseFormulaTableNameMap, createIdentifier, excelDateSerial, excelDateTimePartsToSerial, excelDateTimeSerial, excelSerialToDate, excelSerialToDateTime, excelSerialToDateTimeParts, generateRandomId, getBaseFormulaTableName, getDateSystemMaxSerial, getNumfmtParseValueFilter, hashAlgorithm, isFormulaId, isFormulaString, isNodeEnv, isNullCell, isRealNum, isTextFormat, isValidRange, merge, moveRangeByOffset, numfmt, regexp, requestImmediateMacroTask, sortRules, toDisposable, touchDependencies } from "@univerjs/core";
2
+ import { AbsoluteRefType, AsyncLock, BooleanNumber, BuildTextUtils, CellValueType, CommandType, DataStreamTreeTokenType, DateSystem, Disposable, DisposableCollection, EXCEL_1904_OFFSET, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LRUMap, LifecycleService, LifecycleStages, LocaleService, LocaleType, MAX_COLUMN_COUNT, MAX_ROW_COUNT, ObjectMatrix, Optional, Plugin, RANGE_TYPE, RTree, Rectangle, RichTextBuilder, Styles, Tools, UniverInstanceType, cellToRange, columnLabelToNumber, createBaseFormulaTableNameMap, createIdentifier, excelDateSerial, excelDateTimePartsToSerial, excelDateTimeSerial, excelSerialToDate, excelSerialToDateTime, excelSerialToDateTimeParts, generateRandomId, getBaseFormulaTableName, getDateSystemMaxSerial, getNumfmtParseValueFilter, hashAlgorithm, isFormulaId, isFormulaString, isNodeEnv, isNullCell, isRealNum, isTextFormat, isValidRange, merge, moveRangeByOffset, normalizeWorkbookCalculationSettings, numfmt, regexp, requestImmediateMacroTask, sortRules, toDisposable, touchDependencies } from "@univerjs/core";
3
3
  import { BehaviorSubject, Observable, Subject, combineLatest, distinctUntilChanged, filter, map, shareReplay, take } from "rxjs";
4
4
  import Decimal from "decimal.js";
5
5
  import { DataSyncPrimaryController } from "@univerjs/rpc";
@@ -328,7 +328,7 @@ function getSearchModeValue(searchModeValue) {
328
328
  }
329
329
 
330
330
  //#endregion
331
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
331
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/typeof.js
332
332
  function _typeof(o) {
333
333
  "@babel/helpers - typeof";
334
334
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -339,7 +339,7 @@ function _typeof(o) {
339
339
  }
340
340
 
341
341
  //#endregion
342
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
342
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPrimitive.js
343
343
  function toPrimitive(t, r) {
344
344
  if ("object" != _typeof(t) || !t) return t;
345
345
  var e = t[Symbol.toPrimitive];
@@ -352,14 +352,14 @@ function toPrimitive(t, r) {
352
352
  }
353
353
 
354
354
  //#endregion
355
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
355
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPropertyKey.js
356
356
  function toPropertyKey(t) {
357
357
  var i = toPrimitive(t, "string");
358
358
  return "symbol" == _typeof(i) ? i : i + "";
359
359
  }
360
360
 
361
361
  //#endregion
362
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
362
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/defineProperty.js
363
363
  function _defineProperty(e, r, t) {
364
364
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
365
365
  value: t,
@@ -1186,7 +1186,7 @@ function splitTableStructuredRef(ref) {
1186
1186
  }
1187
1187
 
1188
1188
  //#endregion
1189
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
1189
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateParam.js
1190
1190
  function __decorateParam(paramIndex, decorator) {
1191
1191
  return function(target, key) {
1192
1192
  decorator(target, key, paramIndex);
@@ -1194,7 +1194,7 @@ function __decorateParam(paramIndex, decorator) {
1194
1194
  }
1195
1195
 
1196
1196
  //#endregion
1197
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
1197
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorate.js
1198
1198
  function __decorate(decorators, target, key, desc) {
1199
1199
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1200
1200
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1672,8 +1672,6 @@ const SetSuperTableOptionMutation = {
1672
1672
  //#endregion
1673
1673
  //#region src/config/config.ts
1674
1674
  const ENGINE_FORMULA_PLUGIN_CONFIG_KEY = "engine-formula.config";
1675
- const DEFAULT_CYCLE_REFERENCE_COUNT = 1;
1676
- const ENGINE_FORMULA_CYCLE_REFERENCE_COUNT = "CYCLE_REFERENCE_COUNT";
1677
1675
  const ENGINE_FORMULA_RETURN_DEPENDENCY_TREE = "RETURN_DEPENDENCY_TREE";
1678
1676
  const configSymbol = Symbol(ENGINE_FORMULA_PLUGIN_CONFIG_KEY);
1679
1677
  const defaultPluginConfig = {};
@@ -3094,9 +3092,8 @@ var LexerTreeBuilder = class extends Disposable {
3094
3092
  const isCacheable = !/\b(?:LET|LAMBDA)\s*\(/iu.test(formulaString);
3095
3093
  const cacheKey = injectDefinedNameParam == null ? formulaString : `${injectDefinedNameParam.unitId ?? ""}\0${injectDefinedNameParam.sheetId ?? ""}\0${injectDefinedNameParam.refOffsetX}\0${injectDefinedNameParam.refOffsetY}\0${formulaString}`;
3096
3094
  if (transformSuffix === true && isCacheable) {
3097
- var _this$_simpleCheckDef;
3098
3095
  const lexerNode = FormulaLexerNodeCache.get(cacheKey);
3099
- const simpleCheckDefinedNameResult = injectDefinedNameParam && ((_this$_simpleCheckDef = this._simpleCheckDefinedName) === null || _this$_simpleCheckDef === void 0 ? void 0 : _this$_simpleCheckDef.call(this, formulaString, injectDefinedNameParam));
3096
+ const simpleCheckDefinedNameResult = injectDefinedNameParam && this._simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode);
3100
3097
  if (lexerNode && !simpleCheckDefinedNameResult) return lexerNode;
3101
3098
  }
3102
3099
  this._resetCurrentLexerNode();
@@ -3163,13 +3160,13 @@ var LexerTreeBuilder = class extends Disposable {
3163
3160
  const definedNameToken = token.trim();
3164
3161
  const definedContent = getValueByName(unitId, definedNameToken, sheetId);
3165
3162
  if (definedContent) {
3163
+ definedNames.push(definedContent.name);
3166
3164
  const refOffsetX = definedContent.localSheetId === "AllDefaultWorkbook" ? param.refOffsetX - 1 : param.refOffsetX;
3167
3165
  const refString = definedContent.formulaOrRefString.startsWith("=") ? definedContent.formulaOrRefString : this._moveDefinedNameRefOffset(definedContent.formulaOrRefString, refOffsetX, param.refOffsetY);
3168
3166
  const nestedDefinedNameParam = this._handleNestedDefinedName(refString, param);
3169
3167
  if (nestedDefinedNameParam == null || typeof nestedDefinedNameParam !== "object") {
3170
3168
  sequenceString += nestedDefinedNameParam || "#NAME?";
3171
3169
  hasDefinedName = true;
3172
- definedNames.push(definedNameToken);
3173
3170
  } else if (typeof nestedDefinedNameParam === "object") {
3174
3171
  const { sequenceString: nestedSequenceString, definedNames: nestedDefinedNames } = nestedDefinedNameParam;
3175
3172
  sequenceString += nestedSequenceString;
@@ -3234,7 +3231,7 @@ var LexerTreeBuilder = class extends Disposable {
3234
3231
  if (state === "#VALUE!" || sequenceArray.length === 0) return state;
3235
3232
  return this._handleDefinedName(sequenceArray, param);
3236
3233
  }
3237
- _simpleCheckDefinedName(formulaString, injectDefinedNameParam) {
3234
+ _simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode) {
3238
3235
  const { getDirtyDefinedNameMap, unitId } = injectDefinedNameParam;
3239
3236
  const definedNameMap = getDirtyDefinedNameMap();
3240
3237
  const executeUnitId = unitId;
@@ -3242,7 +3239,7 @@ var LexerTreeBuilder = class extends Disposable {
3242
3239
  const names = Object.keys(definedNameMap[executeUnitId]);
3243
3240
  for (let i = 0, len = names.length; i < len; i++) {
3244
3241
  const name = names[i];
3245
- if (formulaString.indexOf(name) > -1) return true;
3242
+ if (formulaString.indexOf(name) > -1 || (lexerNode === null || lexerNode === void 0 ? void 0 : lexerNode.getDefinedNames().includes(name))) return true;
3246
3243
  }
3247
3244
  }
3248
3245
  return false;
@@ -4301,18 +4298,43 @@ let FormulaDataModel = class FormulaDataModel extends Disposable {
4301
4298
  super();
4302
4299
  this._univerInstanceService = _univerInstanceService;
4303
4300
  this._lexerTreeBuilder = _lexerTreeBuilder;
4301
+ _defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
4304
4302
  _defineProperty(this, "_formulaIdMapData", Object.create(null));
4305
4303
  _defineProperty(this, "_arrayFormulaRange", Object.create(null));
4306
4304
  _defineProperty(this, "_arrayFormulaCellData", Object.create(null));
4307
4305
  _defineProperty(this, "_unitImageFormulaData", Object.create(null));
4306
+ this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
4307
+ for (const [key, cell] of this._circularReferences) if (cell.unitId === workbook.getUnitId()) this._circularReferences.delete(key);
4308
+ }));
4308
4309
  }
4309
4310
  dispose() {
4310
4311
  super.dispose();
4312
+ this._circularReferences.clear();
4311
4313
  this._formulaIdMapData = Object.create(null);
4312
4314
  this._arrayFormulaRange = Object.create(null);
4313
4315
  this._arrayFormulaCellData = Object.create(null);
4314
4316
  this._unitImageFormulaData = Object.create(null);
4315
4317
  }
4318
+ setCircularReferences(cells) {
4319
+ this._circularReferences.clear();
4320
+ for (const cell of cells) this._circularReferences.set(JSON.stringify([
4321
+ cell.unitId,
4322
+ cell.sheetId,
4323
+ cell.row,
4324
+ cell.column
4325
+ ]), { ...cell });
4326
+ }
4327
+ getCircularReferences(unitId) {
4328
+ return Array.from(this._circularReferences.values()).filter((cell) => cell.unitId === unitId).map((cell) => ({ ...cell }));
4329
+ }
4330
+ isCircularReference(unitId, sheetId, row, column) {
4331
+ return this._circularReferences.has(JSON.stringify([
4332
+ unitId,
4333
+ sheetId,
4334
+ row,
4335
+ column
4336
+ ]));
4337
+ }
4316
4338
  clearPreviousArrayFormulaCellData(clearArrayFormulaCellData) {
4317
4339
  Object.keys(clearArrayFormulaCellData).forEach((unitId) => {
4318
4340
  const clearSheetData = clearArrayFormulaCellData[unitId];
@@ -5151,6 +5173,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5151
5173
  this._localeService = _localeService;
5152
5174
  this._formulaDataModel = _formulaDataModel;
5153
5175
  this._sheetRowFilteredService = _sheetRowFilteredService;
5176
+ _defineProperty(this, "_dirtyIterationUnits", []);
5154
5177
  _defineProperty(this, "_unitData", Object.create(null));
5155
5178
  _defineProperty(this, "_unitStylesData", Object.create(null));
5156
5179
  _defineProperty(this, "_arrayFormulaCellData", Object.create(null));
@@ -5331,6 +5354,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5331
5354
  }
5332
5355
  if (config.rowData) this._applyUnitRowData(config.rowData);
5333
5356
  this._formulaData = config.formulaData;
5357
+ this._dirtyIterationUnits = config.dirtyIterationUnits ?? [];
5334
5358
  this._arrayFormulaCellData = convertUnitDataToRuntime(config.arrayFormulaCellData);
5335
5359
  this._arrayFormulaRange = config.arrayFormulaRange;
5336
5360
  this._forceCalculate = config.forceCalculate;
@@ -5358,6 +5382,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5358
5382
  }
5359
5383
  getDirtyData() {
5360
5384
  return {
5385
+ dirtyIterationUnits: this._dirtyIterationUnits,
5361
5386
  forceCalculation: this._forceCalculate,
5362
5387
  dirtyRanges: this._dirtyRanges,
5363
5388
  dirtyNameMap: this._dirtyNameMap,
@@ -5370,6 +5395,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5370
5395
  };
5371
5396
  }
5372
5397
  loadDirtyRangesAndExcludedCell(dirtyRanges, excludedCell) {
5398
+ this._dirtyIterationUnits = [];
5373
5399
  this._dirtyRanges = dirtyRanges;
5374
5400
  this._excludedCell = excludedCell;
5375
5401
  /**
@@ -10029,11 +10055,14 @@ let FormulaExecutedStateType = /* @__PURE__ */ function(FormulaExecutedStateType
10029
10055
  return FormulaExecutedStateType;
10030
10056
  }({});
10031
10057
  let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10032
- constructor(_currentConfigService, _hyperlinkEngineFormulaService) {
10058
+ constructor(_currentConfigService, _hyperlinkEngineFormulaService, _univerInstanceService) {
10033
10059
  super();
10034
10060
  this._currentConfigService = _currentConfigService;
10035
10061
  this._hyperlinkEngineFormulaService = _hyperlinkEngineFormulaService;
10062
+ this._univerInstanceService = _univerInstanceService;
10036
10063
  _defineProperty(this, "_formulaExecuteStage", 0);
10064
+ _defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
10065
+ _defineProperty(this, "_pendingCircularReferences", /* @__PURE__ */ new Map());
10037
10066
  _defineProperty(this, "_stopState", false);
10038
10067
  _defineProperty(this, "_externalReferenceUnavailable", false);
10039
10068
  _defineProperty(this, "_currentRow", -1);
@@ -10044,6 +10073,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10044
10073
  _defineProperty(this, "_currentSubUnitId", "");
10045
10074
  _defineProperty(this, "_currentUnitId", "");
10046
10075
  _defineProperty(this, "_runtimeData", Object.create(null));
10076
+ _defineProperty(this, "_sourceFormulaData", Object.create(null));
10077
+ _defineProperty(this, "_currentSourceFormula", void 0);
10047
10078
  _defineProperty(this, "_runtimeOtherData", Object.create(null));
10048
10079
  _defineProperty(this, "_unitArrayFormulaRange", Object.create(null));
10049
10080
  _defineProperty(this, "_unitArrayFormulaEmbeddedMap", Object.create(null));
@@ -10061,6 +10092,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10061
10092
  _defineProperty(this, "_formulaCycleIndex", 0);
10062
10093
  _defineProperty(this, "_isCycleDependency", false);
10063
10094
  _defineProperty(this, "_dependencyTreeModelData", []);
10095
+ this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
10096
+ for (const references of [this._circularReferences, this._pendingCircularReferences]) for (const [key, cell] of references) if (cell.unitId === workbook.getUnitId()) references.delete(key);
10097
+ }));
10064
10098
  }
10065
10099
  get currentRow() {
10066
10100
  return this._currentRow;
@@ -10085,6 +10119,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10085
10119
  dispose() {
10086
10120
  super.dispose();
10087
10121
  this.reset();
10122
+ this._circularReferences.clear();
10123
+ this._pendingCircularReferences.clear();
10088
10124
  this._runtimeFeatureCellData = Object.create(null);
10089
10125
  this._runtimeFeatureRange = Object.create(null);
10090
10126
  this.clearReferenceAndNumberformatCache();
@@ -10156,6 +10192,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10156
10192
  reset() {
10157
10193
  this._formulaExecuteStage = 0;
10158
10194
  this._runtimeData = Object.create(null);
10195
+ this._sourceFormulaData = Object.create(null);
10196
+ this._currentSourceFormula = void 0;
10159
10197
  this._runtimeOtherData = Object.create(null);
10160
10198
  this._unitArrayFormulaRange = Object.create(null);
10161
10199
  this._unitArrayFormulaEmbeddedMap = Object.create(null);
@@ -10176,7 +10214,60 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10176
10214
  clearStringToNumberPatternCache();
10177
10215
  clearReferenceToRangeCache();
10178
10216
  }
10217
+ beginCircularReferences() {
10218
+ this._pendingCircularReferences = new Map(this._circularReferences);
10219
+ const formulaData = this._currentConfigService.getFormulaData();
10220
+ for (const [key, cell] of this._pendingCircularReferences) {
10221
+ var _formulaData$cell$uni;
10222
+ if (!((_formulaData$cell$uni = formulaData[cell.unitId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.sheetId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.row]) === null || _formulaData$cell$uni === void 0 ? void 0 : _formulaData$cell$uni[cell.column])) this._pendingCircularReferences.delete(key);
10223
+ }
10224
+ }
10225
+ clearCircularReferenceCells(cells) {
10226
+ if (this._pendingCircularReferences.size === 0) return;
10227
+ for (const cell of cells) {
10228
+ this._pendingCircularReferences.delete(JSON.stringify([
10229
+ cell.unitId,
10230
+ cell.subUnitId,
10231
+ cell.row,
10232
+ cell.column
10233
+ ]));
10234
+ if (this._pendingCircularReferences.size === 0) return;
10235
+ }
10236
+ }
10237
+ recordCircularReferences(cells) {
10238
+ for (const cell of cells) {
10239
+ if (cell.row < 0 || cell.column < 0) continue;
10240
+ this._pendingCircularReferences.set(JSON.stringify([
10241
+ cell.unitId,
10242
+ cell.sheetId,
10243
+ cell.row,
10244
+ cell.column
10245
+ ]), { ...cell });
10246
+ }
10247
+ }
10248
+ completeCircularReferences() {
10249
+ if (!this.isStopExecution()) this._circularReferences = new Map(this._pendingCircularReferences);
10250
+ }
10251
+ preserveCurrentCellData() {
10252
+ var _this$_currentConfigS;
10253
+ const unitId = this.currentUnitId;
10254
+ const sheetId = this.currentSubUnitId;
10255
+ const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[sheetId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(this.currentRow, this.currentColumn);
10256
+ if ((cell === null || cell === void 0 ? void 0 : cell.v) != null) return;
10257
+ const sheets = this._runtimeData[unitId] ??= {};
10258
+ (sheets[sheetId] ??= new ObjectMatrix()).setValue(this.currentRow, this.currentColumn, {
10259
+ v: (cell === null || cell === void 0 ? void 0 : cell.v) ?? 0,
10260
+ t: (cell === null || cell === void 0 ? void 0 : cell.v) == null ? CellValueType.NUMBER : cell.t
10261
+ });
10262
+ if (this._currentSourceFormula) {
10263
+ const formulas = this._sourceFormulaData[unitId] ??= {};
10264
+ const sheet = formulas[sheetId] ??= {};
10265
+ const row = sheet[this.currentRow] ??= {};
10266
+ row[this.currentColumn] = { ...this._currentSourceFormula };
10267
+ }
10268
+ }
10179
10269
  setCurrent(row, column, rowCount, columnCount, sheetId, unitId) {
10270
+ var _this$_currentConfigS2, _this$_currentConfigS3;
10180
10271
  this._externalReferenceUnavailable = false;
10181
10272
  this._currentRow = row;
10182
10273
  this._currentColumn = column;
@@ -10184,6 +10275,18 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10184
10275
  this._currentColumnCount = columnCount;
10185
10276
  this._currentSubUnitId = sheetId;
10186
10277
  this._currentUnitId = unitId;
10278
+ const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[sheetId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(row, column);
10279
+ const formula = (_this$_currentConfigS3 = this._currentConfigService.getFormulaData()[unitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[sheetId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[row]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[column];
10280
+ if (formula) {
10281
+ const isSharedFollower = (formula.x ?? 0) !== 0 || (formula.y ?? 0) !== 0;
10282
+ this._currentSourceFormula = {
10283
+ f: isSharedFollower ? "" : formula.f,
10284
+ si: formula.si
10285
+ };
10286
+ } else this._currentSourceFormula = (cell === null || cell === void 0 ? void 0 : cell.f) || (cell === null || cell === void 0 ? void 0 : cell.si) ? {
10287
+ f: cell.f ?? "",
10288
+ si: cell.si ?? void 0
10289
+ } : void 0;
10187
10290
  }
10188
10291
  setFunctionRefInfoOverride(rowCount, columnCount) {
10189
10292
  this._functionRefInfoOverrideStack.push({
@@ -10234,9 +10337,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10234
10337
  }
10235
10338
  setRuntimeData(functionVariant) {
10236
10339
  if (this._externalReferenceUnavailable) {
10237
- var _this$_currentConfigS, _this$_currentConfigS2;
10238
- const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[this._currentSubUnitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(this._currentRow, this._currentColumn);
10239
- const formula = (_this$_currentConfigS2 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[this._currentSubUnitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[this._currentRow]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[this._currentColumn]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.f;
10340
+ var _this$_currentConfigS4, _this$_currentConfigS5;
10341
+ const cell = (_this$_currentConfigS4 = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentSubUnitId]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4.cellData.getValue(this._currentRow, this._currentColumn);
10342
+ const formula = (_this$_currentConfigS5 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentSubUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentRow]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentColumn]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5.f;
10240
10343
  if ((cell === null || cell === void 0 ? void 0 : cell.f) && cell.v != null && (formula == null || formula === cell.f)) return;
10241
10344
  }
10242
10345
  const row = this._currentRow;
@@ -10295,7 +10398,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10295
10398
  const hasDataInArrayFormulaRange = this._checkIfArrayFormulaRangeHasData(unitId, sheetId, row, column, arrayRange);
10296
10399
  const isArrayFormulaExceeded = this._checkIfArrayFormulaExceeded(rowCount, columnCount, arrayRange);
10297
10400
  if (hasDataInArrayFormulaRange || isArrayFormulaExceeded) {
10298
- var _this$_currentConfigS3;
10401
+ var _this$_currentConfigS6;
10299
10402
  const errorObject = this._getValueObjectOfRuntimeData(ErrorValueObject.create("#SPILL!"));
10300
10403
  sheetData.setValue(row, column, errorObject);
10301
10404
  clearArrayUnitData.setValue(row, column, errorObject);
@@ -10306,7 +10409,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10306
10409
  */
10307
10410
  const unitData = this._currentConfigService.getUnitData();
10308
10411
  const arrayData = this._currentConfigService.getArrayFormulaCellData();
10309
- const previousArrayFormulaRange = (_this$_currentConfigS3 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[sheetId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[row]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[column];
10412
+ const previousArrayFormulaRange = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[sheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[row]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[column];
10310
10413
  objectValueRefOrArray.iterator((_, rowIndex, columnIndex) => {
10311
10414
  var _unitData$unitId, _arrayData$unitId;
10312
10415
  const currentRow = rowIndex - startRow + row;
@@ -10346,6 +10449,12 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10346
10449
  } else {
10347
10450
  const valueObject = this._getValueObjectOfRuntimeData(functionVariant);
10348
10451
  sheetData.setValue(row, column, valueObject);
10452
+ if (this._currentSourceFormula != null) {
10453
+ const unitFormulas = this._sourceFormulaData[unitId] ??= {};
10454
+ const sheetFormulas = unitFormulas[sheetId] ??= {};
10455
+ const rowFormulas = sheetFormulas[row] ??= {};
10456
+ rowFormulas[column] = { ...this._currentSourceFormula };
10457
+ }
10349
10458
  if (functionVariant.isString() && functionVariant.isImage()) {
10350
10459
  const imageInfo = functionVariant.getImageInfo();
10351
10460
  if (imageInfo) this._runtimeImageFormulaData.push({
@@ -10417,6 +10526,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10417
10526
  getAllRuntimeData() {
10418
10527
  return {
10419
10528
  unitData: this.getUnitData(),
10529
+ circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
10530
+ sourceFormulaData: this._sourceFormulaData,
10420
10531
  arrayFormulaRange: this.getUnitArrayFormula(),
10421
10532
  arrayFormulaEmbedded: this.getUnitArrayFormulaEmbeddedMap(),
10422
10533
  unitOtherData: this.getRuntimeOtherData(),
@@ -10436,6 +10547,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10436
10547
  totalArrayFormulasToCalculate: this.getTotalArrayFormulasToCalculate(),
10437
10548
  completedArrayFormulasCount: this.getCompletedArrayFormulasCount(),
10438
10549
  stage: this.getFormulaExecuteStage(),
10550
+ circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
10439
10551
  formulaCycleIndex: this.getFormulaCycleIndex()
10440
10552
  };
10441
10553
  }
@@ -10443,11 +10555,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10443
10555
  FORMULA_REF_TO_ARRAY_CACHE.clear();
10444
10556
  }
10445
10557
  _checkIfArrayFormulaRangeHasData(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, arrayRange) {
10446
- var _this$_currentConfigS4;
10558
+ var _this$_currentConfigS7;
10447
10559
  const { startRow, startColumn, endRow, endColumn } = arrayRange;
10448
10560
  const unitData = this._currentConfigService.getUnitData();
10449
10561
  const arrayData = this._currentConfigService.getArrayFormulaCellData();
10450
- const previousArrayFormulaRange = (_this$_currentConfigS4 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[formulaSheetId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[formulaRow]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4[formulaColumn];
10562
+ const previousArrayFormulaRange = (_this$_currentConfigS7 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaSheetId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaRow]) === null || _this$_currentConfigS7 === void 0 ? void 0 : _this$_currentConfigS7[formulaColumn];
10451
10563
  for (let r = startRow; r <= endRow; r++) for (let c = startColumn; c <= endColumn; c++) {
10452
10564
  var _this$_runtimeData, _arrayData$formulaUni, _unitData$formulaUnit;
10453
10565
  if (r === formulaRow && formulaColumn === c) continue;
@@ -10483,8 +10595,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10483
10595
  * @returns
10484
10596
  */
10485
10597
  _isInOtherArrayFormulaRange(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, r, c) {
10486
- var _this$_currentConfigS5;
10487
- const arrayFormulaRange = (_this$_currentConfigS5 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5[formulaSheetId];
10598
+ var _this$_currentConfigS8;
10599
+ const arrayFormulaRange = (_this$_currentConfigS8 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS8 === void 0 ? void 0 : _this$_currentConfigS8[formulaSheetId];
10488
10600
  if (arrayFormulaRange == null) return false;
10489
10601
  let isCellOverlapping = false;
10490
10602
  new ObjectMatrix(arrayFormulaRange).forValue((rangeRow, rangeCol, range) => {
@@ -10497,8 +10609,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10497
10609
  return isCellOverlapping;
10498
10610
  }
10499
10611
  _isCurrentSingleCellArrayFormulaRange(unitId, sheetId, row, column) {
10500
- var _this$_currentConfigS6;
10501
- const range = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[sheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[row]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[column];
10612
+ var _this$_currentConfigS9;
10613
+ const range = (_this$_currentConfigS9 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[sheetId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[row]) === null || _this$_currentConfigS9 === void 0 ? void 0 : _this$_currentConfigS9[column];
10502
10614
  return range != null && range.startRow === range.endRow && range.startColumn === range.endColumn;
10503
10615
  }
10504
10616
  _isInArrayFormulaRange(range, r, c) {
@@ -10522,7 +10634,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10522
10634
  return isInDirtyRange(dirtyRanges, unitId, sheetId, row, column);
10523
10635
  }
10524
10636
  };
10525
- FormulaRuntimeService = __decorate([__decorateParam(0, IFormulaCurrentConfigService), __decorateParam(1, IHyperlinkEngineFormulaService)], FormulaRuntimeService);
10637
+ FormulaRuntimeService = __decorate([
10638
+ __decorateParam(0, IFormulaCurrentConfigService),
10639
+ __decorateParam(1, IHyperlinkEngineFormulaService),
10640
+ __decorateParam(2, IUniverInstanceService)
10641
+ ], FormulaRuntimeService);
10526
10642
  const IFormulaRuntimeService = createIdentifier("univer.formula.runtime.service");
10527
10643
 
10528
10644
  //#endregion
@@ -13526,6 +13642,90 @@ var OtherFormulaManagerService = class extends Disposable {
13526
13642
  };
13527
13643
  const IOtherFormulaManagerService = createIdentifier("univer.formula.other-formula-manager.service");
13528
13644
 
13645
+ //#endregion
13646
+ //#region src/engine/dependency/dependency-groups.ts
13647
+ /**
13648
+ * Copyright 2023-present DreamNum Co., Ltd.
13649
+ *
13650
+ * Licensed under the Apache License, Version 2.0 (the "License");
13651
+ * you may not use this file except in compliance with the License.
13652
+ * You may obtain a copy of the License at
13653
+ *
13654
+ * http://www.apache.org/licenses/LICENSE-2.0
13655
+ *
13656
+ * Unless required by applicable law or agreed to in writing, software
13657
+ * distributed under the License is distributed on an "AS IS" BASIS,
13658
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13659
+ * See the License for the specific language governing permissions and
13660
+ * limitations under the License.
13661
+ */
13662
+ /**
13663
+ * Returns strongly connected components in dependency order: precedents before their dependents.
13664
+ * Mutually dependent nodes stay together so only their group needs iterative calculation.
13665
+ * Uses iterative Kosaraju traversal to avoid overflowing the call stack on large dependency graphs.
13666
+ */
13667
+ function getDependencyGroups(nodes, getId, getDependents) {
13668
+ const byId = new Map(nodes.map((node) => [getId(node), node]));
13669
+ const edges = /* @__PURE__ */ new Map();
13670
+ const reverse = /* @__PURE__ */ new Map();
13671
+ for (const node of nodes) {
13672
+ const id = getId(node);
13673
+ const dependents = Array.from(getDependents(node)).filter((dependent) => byId.has(dependent));
13674
+ edges.set(id, dependents);
13675
+ for (const dependent of dependents) {
13676
+ const incoming = reverse.get(dependent) ?? [];
13677
+ incoming.push(id);
13678
+ reverse.set(dependent, incoming);
13679
+ }
13680
+ }
13681
+ const visited = /* @__PURE__ */ new Set();
13682
+ const order = [];
13683
+ for (const id of byId.keys()) {
13684
+ if (visited.has(id)) continue;
13685
+ visited.add(id);
13686
+ const stack = [{
13687
+ id,
13688
+ next: 0
13689
+ }];
13690
+ while (stack.length) {
13691
+ const frame = stack[stack.length - 1];
13692
+ const children = edges.get(frame.id);
13693
+ if (frame.next === children.length) {
13694
+ order.push(frame.id);
13695
+ stack.pop();
13696
+ continue;
13697
+ }
13698
+ const child = children[frame.next++];
13699
+ if (!visited.has(child)) {
13700
+ visited.add(child);
13701
+ stack.push({
13702
+ id: child,
13703
+ next: 0
13704
+ });
13705
+ }
13706
+ }
13707
+ }
13708
+ visited.clear();
13709
+ const groups = [];
13710
+ for (let i = order.length - 1; i >= 0; i--) {
13711
+ const id = order[i];
13712
+ if (visited.has(id)) continue;
13713
+ const group = [];
13714
+ const stack = [id];
13715
+ visited.add(id);
13716
+ while (stack.length) {
13717
+ const current = stack.pop();
13718
+ group.push(byId.get(current));
13719
+ for (const parent of reverse.get(current) ?? []) if (!visited.has(parent)) {
13720
+ visited.add(parent);
13721
+ stack.push(parent);
13722
+ }
13723
+ }
13724
+ groups.push(group);
13725
+ }
13726
+ return groups;
13727
+ }
13728
+
13529
13729
  //#endregion
13530
13730
  //#region src/engine/dependency/dependency-tree.ts
13531
13731
  let FormulaDependencyTreeType = /* @__PURE__ */ function(FormulaDependencyTreeType) {
@@ -13538,6 +13738,7 @@ var FormulaDependencyTreeCalculator = class {
13538
13738
  constructor() {
13539
13739
  _defineProperty(this, "_state", 0);
13540
13740
  _defineProperty(this, "type", 0);
13741
+ _defineProperty(this, "cycleGroup", void 0);
13541
13742
  _defineProperty(this, "treeId", void 0);
13542
13743
  _defineProperty(this, "children", /* @__PURE__ */ new Set());
13543
13744
  _defineProperty(this, "parents", /* @__PURE__ */ new Set());
@@ -13959,7 +14160,28 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
13959
14160
  await this._generateTreeList(formulaData, otherFormulaData, unitData);
13960
14161
  this._dependencyManagerService.openKdTree();
13961
14162
  const updateTreeList = this._getUpdateTreeListAndMakeDependency();
13962
- const finalTreeList = this._calculateRunList(updateTreeList);
14163
+ const runList = this._calculateRunList(updateTreeList);
14164
+ const selfReferences = /* @__PURE__ */ new Set();
14165
+ const groups = getDependencyGroups(runList, (tree) => tree.treeId, (tree) => {
14166
+ const dependents = this._dependencyManagerService.searchDependency(tree.toRTreeItem());
14167
+ const addressDependents = this._dependencyRTreeCacheForAddressFunction.bulkSearch(tree.toRTreeItem());
14168
+ for (const dependent of addressDependents) dependents.add(dependent);
14169
+ if (dependents.has(tree.treeId)) selfReferences.add(tree.treeId);
14170
+ return dependents;
14171
+ });
14172
+ this._runtimeService.clearCircularReferenceCells(runList);
14173
+ for (const group of groups) {
14174
+ const cyclic = group.length > 1 || selfReferences.has(group[0].treeId);
14175
+ const groupId = cyclic ? group.map((tree) => tree.treeId).sort((a, b) => a - b).join(",") : void 0;
14176
+ for (const tree of group) {
14177
+ tree.cycleGroup = groupId;
14178
+ if (cyclic) {
14179
+ var _this$_runtimeService;
14180
+ (_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 || _this$_runtimeService.realDeleteValue(tree.row, tree.column);
14181
+ }
14182
+ }
14183
+ }
14184
+ const finalTreeList = groups.flat().reverse();
13963
14185
  if (this._checkIsCycleDependency(finalTreeList)) this._runtimeService.enableCycleDependency();
13964
14186
  if (isCalculateTreeModel) this._runtimeService.setDependencyTreeModelData(this._getAllDependencyJson(Array.from(this._dependencyTreeCache.values())));
13965
14187
  this._dependencyTreeCache.clear();
@@ -13968,41 +14190,8 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
13968
14190
  this._runtimeService.clearArrayObjectCache();
13969
14191
  return Promise.resolve(finalTreeList);
13970
14192
  }
13971
- _isCyclicUtilMap(treeId, colorMap) {
13972
- const WHITE = 0;
13973
- const GRAY = 1;
13974
- const BLACK = 2;
13975
- const stack = [treeId];
13976
- while (stack.length > 0) {
13977
- const currentTreeId = stack[stack.length - 1];
13978
- if ((colorMap.get(currentTreeId) || WHITE) === WHITE) {
13979
- colorMap.set(currentTreeId, GRAY);
13980
- const node = this._dependencyTreeCache.get(currentTreeId);
13981
- if (node == null) {
13982
- colorMap.set(currentTreeId, BLACK);
13983
- stack.pop();
13984
- continue;
13985
- }
13986
- const parents = this._dependencyManagerService.searchDependency(node.toRTreeItem());
13987
- for (const parentTreeId of parents) {
13988
- const parentColor = colorMap.get(parentTreeId) || WHITE;
13989
- if (parentColor === GRAY) return true;
13990
- else if (parentColor === WHITE) stack.push(parentTreeId);
13991
- }
13992
- } else {
13993
- colorMap.set(currentTreeId, BLACK);
13994
- stack.pop();
13995
- }
13996
- }
13997
- return false;
13998
- }
13999
14193
  _checkIsCycleDependency(treeList) {
14000
- const colorMap = /* @__PURE__ */ new Map();
14001
- for (const tree of treeList) if (!colorMap.has(tree.treeId)) {
14002
- if (this._isCyclicUtilMap(tree.treeId, colorMap)) return true;
14003
- }
14004
- colorMap.clear();
14005
- return false;
14194
+ return treeList.some((tree) => tree.cycleGroup != null);
14006
14195
  }
14007
14196
  _getFeatureFormulaTree(featureId, treeId, params) {
14008
14197
  const { unitId, subUnitId, dependencyRanges, getDirtyData } = params;
@@ -14386,11 +14575,17 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
14386
14575
  if (node.nodeType === 12 && node.getToken() === "#") return true;
14387
14576
  return false;
14388
14577
  }
14578
+ _isStaticReference(node) {
14579
+ return node.nodeType === 1 || node.nodeType === 10 && node.getChildren().every((child) => this._isStaticReference(child));
14580
+ }
14389
14581
  _nodeTraversalRef(node, result) {
14390
14582
  const children = node.getChildren();
14391
14583
  const childrenCount = children.length;
14584
+ const token = node.getToken();
14585
+ const readsReferenceMetadata = node.nodeType === 4 && (token === "ROW" || token === "ROWS" || token === "COLUMN" || token === "COLUMNS");
14392
14586
  for (let i = 0; i < childrenCount; i++) {
14393
14587
  const item = children[i];
14588
+ if (readsReferenceMetadata && this._isStaticReference(item)) continue;
14394
14589
  if (this._isPreCalculateNode(item)) {
14395
14590
  result.push(item);
14396
14591
  if (item.nodeType === 10) {
@@ -14634,9 +14829,10 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
14634
14829
  * @param tree
14635
14830
  */
14636
14831
  _includeTree(tree, node) {
14637
- var _this$_currentConfigS, _this$_currentConfigS2;
14832
+ var _this$_currentConfigS, _this$_currentConfigS2, _this$_currentConfigS3;
14638
14833
  const unitId = tree.unitId;
14639
14834
  const subUnitId = tree.subUnitId;
14835
+ if ((_this$_currentConfigS = this._currentConfigService.getDirtyData().dirtyIterationUnits) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.includes(unitId)) return true;
14640
14836
  /**
14641
14837
  * RAND, RANDBETWEEN, NOW, TODAY are volatile functions that are marked dirty and recalculated every time a calculation occurs.
14642
14838
  */
@@ -14644,13 +14840,13 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
14644
14840
  if (this._includeTreeFeature(tree) === true) return true;
14645
14841
  if (this._includeOtherFormula(tree) === true) return true;
14646
14842
  if (includeDefinedName(tree, node, this._currentConfigService) === true) return true;
14647
- const excludedCell = (_this$_currentConfigS = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[unitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS[subUnitId];
14843
+ const excludedCell = (_this$_currentConfigS2 = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId];
14648
14844
  if ((excludedCell === null || excludedCell === void 0 ? void 0 : excludedCell.getValue(tree.row, tree.column)) != null) return false;
14649
14845
  /**
14650
14846
  * When a worksheet is inserted or deleted,
14651
14847
  * the formulas within it need to be calculated.
14652
14848
  */
14653
- if (((_this$_currentConfigS2 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId]) != null) return true;
14849
+ if (((_this$_currentConfigS3 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[subUnitId]) != null) return true;
14654
14850
  if (!this._updateRangeFlattenCache.has(unitId)) return false;
14655
14851
  const sheetRangeMap = this._updateRangeFlattenCache.get(unitId);
14656
14852
  if (!sheetRangeMap.has(subUnitId)) return false;
@@ -14813,6 +15009,105 @@ FormulaDependencyGenerator = __decorate([
14813
15009
  const DEFAULT_INTERVAL_COUNT = 500;
14814
15010
  const ICalculateFormulaService = createIdentifier("engine-formula.calculate-formula.service");
14815
15011
  let CalculateFormulaService = class CalculateFormulaService extends Disposable {
15012
+ _loadCalculationSettings(settings) {
15013
+ this._workbookCalculationSettings = settings ?? {};
15014
+ this._normalizedCalculationSettings.clear();
15015
+ }
15016
+ _getCalculationSettings(unitId) {
15017
+ let settings = this._normalizedCalculationSettings.get(unitId);
15018
+ if (settings == null) {
15019
+ settings = normalizeWorkbookCalculationSettings(this._workbookCalculationSettings[unitId]);
15020
+ this._normalizedCalculationSettings.set(unitId, settings);
15021
+ }
15022
+ return settings;
15023
+ }
15024
+ _getIterationCell(tree) {
15025
+ var _this$_runtimeService, _this$_currentConfigS;
15026
+ const cell = ((_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 ? void 0 : _this$_runtimeService.getValue(tree.row, tree.column)) ?? ((_this$_currentConfigS = this._currentConfigService.getUnitData()[tree.unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[tree.subUnitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(tree.row, tree.column)) ?? { v: 0 };
15027
+ return cell.v == null ? {
15028
+ v: 0,
15029
+ t: CellValueType.NUMBER
15030
+ } : cell;
15031
+ }
15032
+ async *_iterateCalculationGroup(group, groupId) {
15033
+ const settings = group.map((item) => this._getCalculationSettings(item.unitId));
15034
+ if (group.every((item, i) => {
15035
+ var _this$_currentConfigS2;
15036
+ const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[item.unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[item.subUnitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(item.row, item.column);
15037
+ const formula = (item.formula ?? (cell === null || cell === void 0 ? void 0 : cell.f) ?? "").toUpperCase();
15038
+ const requiresRecalculation = formula.includes(`${"INDEX"}(`) && !(formula.includes(`${"LOOKUP"}(`) && !formula.includes(`${"XLOOKUP"}(`));
15039
+ return settings[i].iterativeCalculation && this._preserveCircularUnits.has(item.unitId) && (cell === null || cell === void 0 ? void 0 : cell.v) != null && !requiresRecalculation;
15040
+ })) {
15041
+ for (const tree of group) yield {
15042
+ tree,
15043
+ preserve: true,
15044
+ iteration: 0
15045
+ };
15046
+ this._runtimeService.recordCircularReferences(group.map((item) => ({
15047
+ unitId: item.unitId,
15048
+ sheetId: item.subUnitId,
15049
+ row: item.row,
15050
+ column: item.column,
15051
+ groupId,
15052
+ iterations: 0
15053
+ })));
15054
+ return;
15055
+ }
15056
+ const limit = settings.reduce((limit, setting) => Math.max(limit, setting.iterativeCalculation ? setting.maxIterations : 0), 1);
15057
+ let converged = false;
15058
+ let iterations = 0;
15059
+ const beforeValues = [];
15060
+ const beforeTypes = [];
15061
+ for (let iteration = 0; iteration < limit; iteration++) {
15062
+ for (let i = 0; i < group.length; i++) if (settings[i].iterativeCalculation) {
15063
+ const before = this._getIterationCell(group[i]);
15064
+ beforeValues[i] = before.v;
15065
+ beforeTypes[i] = before.t;
15066
+ }
15067
+ for (let i = 0; i < group.length; i++) if (iteration < (settings[i].iterativeCalculation ? settings[i].maxIterations : 1)) {
15068
+ FORMULA_REF_TO_ARRAY_CACHE.clear();
15069
+ yield {
15070
+ tree: group[i],
15071
+ preserve: !settings[i].iterativeCalculation,
15072
+ iteration
15073
+ };
15074
+ }
15075
+ iterations = iteration + 1;
15076
+ converged = group.every((item, i) => {
15077
+ if (!settings[i].iterativeCalculation) return true;
15078
+ const after = this._getIterationCell(item);
15079
+ const previousValue = beforeValues[i];
15080
+ return typeof after.v === "number" && typeof previousValue === "number" && (after.t == null || after.t === CellValueType.NUMBER) && (beforeTypes[i] == null || beforeTypes[i] === CellValueType.NUMBER) ? Number.isFinite(after.v) && Math.abs(after.v - previousValue) <= settings[i].maxChange : after.t === beforeTypes[i] && after.v === previousValue;
15081
+ });
15082
+ if (converged) break;
15083
+ }
15084
+ FORMULA_REF_TO_ARRAY_CACHE.clear();
15085
+ this._runtimeService.recordCircularReferences(group.map((item, i) => ({
15086
+ unitId: item.unitId,
15087
+ sheetId: item.subUnitId,
15088
+ row: item.row,
15089
+ column: item.column,
15090
+ groupId,
15091
+ iterations: settings[i].iterativeCalculation ? Math.min(iterations, settings[i].maxIterations) : 0,
15092
+ converged: settings[i].iterativeCalculation ? converged : void 0
15093
+ })));
15094
+ }
15095
+ async *_getCalculationSteps(trees) {
15096
+ while (trees.length) {
15097
+ const tree = trees.pop();
15098
+ if (tree.cycleGroup == null) {
15099
+ yield {
15100
+ tree,
15101
+ preserve: false,
15102
+ iteration: 0
15103
+ };
15104
+ continue;
15105
+ }
15106
+ const group = [tree];
15107
+ while (trees.length && trees[trees.length - 1].cycleGroup === tree.cycleGroup) group.push(trees.pop());
15108
+ yield* this._iterateCalculationGroup(group, tree.cycleGroup);
15109
+ }
15110
+ }
14816
15111
  constructor(_configService, _lexer, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _interpreter, _astTreeBuilder) {
14817
15112
  super();
14818
15113
  this._configService = _configService;
@@ -14828,6 +15123,9 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14828
15123
  _defineProperty(this, "executionCompleteListener$", this._executionCompleteListener$.asObservable());
14829
15124
  _defineProperty(this, "_executeLock", new AsyncLock());
14830
15125
  _defineProperty(this, "_isCalculateTreeModel", false);
15126
+ _defineProperty(this, "_workbookCalculationSettings", {});
15127
+ _defineProperty(this, "_preserveCircularUnits", /* @__PURE__ */ new Set());
15128
+ _defineProperty(this, "_normalizedCalculationSettings", /* @__PURE__ */ new Map());
14831
15129
  }
14832
15130
  dispose() {
14833
15131
  super.dispose();
@@ -14858,20 +15156,17 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14858
15156
  this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
14859
15157
  }
14860
15158
  async execute(formulaDatasetConfig) {
14861
- this._runtimeService.setFormulaExecuteStage(1);
14862
- this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14863
- this._currentConfigService.load(formulaDatasetConfig);
14864
- this._runtimeService.reset();
14865
- const cycleReferenceCount = formulaDatasetConfig.maxIteration || 1;
14866
- this._isCalculateTreeModel = formulaDatasetConfig.isCalculateTreeModel || false;
14867
- this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
14868
- for (let i = 0; i < cycleReferenceCount; i++) {
14869
- this._runtimeService.setFormulaCycleIndex(i);
14870
- const executed = await this._executeStep();
14871
- FORMULA_REF_TO_ARRAY_CACHE.clear();
14872
- const isCycleDependency = this._runtimeService.isCycleDependency();
14873
- if (!executed || !isCycleDependency) break;
14874
- }
15159
+ return this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
15160
+ this._runtimeService.setFormulaExecuteStage(1);
15161
+ this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
15162
+ this._currentConfigService.load(formulaDatasetConfig);
15163
+ this._runtimeService.reset();
15164
+ this._loadCalculationSettings(formulaDatasetConfig.calculationSettings);
15165
+ this._preserveCircularUnits = new Set(formulaDatasetConfig.preserveCircularUnits);
15166
+ this._runtimeService.beginCircularReferences();
15167
+ this._isCalculateTreeModel = formulaDatasetConfig.isCalculateTreeModel || false;
15168
+ await this._executeStep();
15169
+ this._runtimeService.completeCircularReferences();
14875
15170
  this._runtimeService.setFormulaExecuteStage(8);
14876
15171
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14877
15172
  this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData());
@@ -14952,15 +15247,9 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14952
15247
  const intervalCount = (config === null || config === void 0 ? void 0 : config.intervalCount) || 500;
14953
15248
  let i = 0;
14954
15249
  const treeCount = treeList.length;
14955
- while (treeList.length > 0) {
14956
- const tree = treeList.pop();
15250
+ for await (const { tree, preserve, iteration } of this._getCalculationSteps(treeList)) {
15251
+ this._runtimeService.setFormulaCycleIndex(iteration);
14957
15252
  this._runtimeService.setCurrent(tree.row, tree.column, tree.rowCount, tree.columnCount, tree.subUnitId, tree.unitId);
14958
- const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
14959
- const nodeData = {
14960
- node,
14961
- refOffsetX: tree.refOffsetX,
14962
- refOffsetY: tree.refOffsetY
14963
- };
14964
15253
  const getDirtyData = tree.getDirtyData;
14965
15254
  if (i % intervalCount === 0) {
14966
15255
  /**
@@ -14978,12 +15267,23 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14978
15267
  this._runtimeService.setCompletedFormulasCount(i + 1);
14979
15268
  }
14980
15269
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14981
- if (this._runtimeService.isStopExecution() || nodeData == null && getDirtyData == null) {
15270
+ if (this._runtimeService.isStopExecution()) {
14982
15271
  this._runtimeService.setFormulaExecuteStage(0);
14983
15272
  this._runtimeService.markedAsStopFunctionsExecuted();
14984
15273
  return;
14985
15274
  }
14986
15275
  }
15276
+ if (preserve) {
15277
+ this._runtimeService.preserveCurrentCellData();
15278
+ i++;
15279
+ continue;
15280
+ }
15281
+ const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
15282
+ const nodeData = {
15283
+ node,
15284
+ refOffsetX: tree.refOffsetX,
15285
+ refOffsetY: tree.refOffsetY
15286
+ };
14987
15287
  let value;
14988
15288
  if (getDirtyData != null && tree.featureId != null) {
14989
15289
  /**
@@ -15159,11 +15459,12 @@ let CalculateController = class CalculateController extends Disposable {
15159
15459
  }));
15160
15460
  }
15161
15461
  async _calculate(formulaDirtyData) {
15162
- const { forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, maxIteration = 1, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
15462
+ const { dirtyIterationUnits, forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, calculationSettings, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
15163
15463
  const formulaData = this._formulaDataModel.getFormulaData();
15164
15464
  const arrayFormulaCellData = this._formulaDataModel.getArrayFormulaCellData();
15165
15465
  const arrayFormulaRange = this._formulaDataModel.getArrayFormulaRange();
15166
15466
  this._calculateFormulaService.execute({
15467
+ dirtyIterationUnits,
15167
15468
  formulaData,
15168
15469
  arrayFormulaCellData,
15169
15470
  arrayFormulaRange,
@@ -15175,7 +15476,7 @@ let CalculateController = class CalculateController extends Disposable {
15175
15476
  dirtyUnitFeatureMap,
15176
15477
  dirtyUnitOtherFormulaMap,
15177
15478
  clearDependencyTreeCache,
15178
- maxIteration,
15479
+ calculationSettings,
15179
15480
  isCalculateTreeModel,
15180
15481
  rowData,
15181
15482
  externalReferences
@@ -15223,7 +15524,10 @@ let CalculateController = class CalculateController extends Disposable {
15223
15524
  break;
15224
15525
  case 0:
15225
15526
  }
15226
- this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, { functionsExecutedState }, { onlyLocal: true });
15527
+ this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, {
15528
+ functionsExecutedState,
15529
+ circularReferences: data.circularReferences
15530
+ }, { onlyLocal: true });
15227
15531
  });
15228
15532
  /**
15229
15533
  * Assignment operation after formula calculation.
@@ -15237,7 +15541,7 @@ let CalculateController = class CalculateController extends Disposable {
15237
15541
  if (dependencyTreeModelData.length > 0) this._commandService.executeCommand(SetFormulaDependencyCalculationResultMutation.id, { result: dependencyTreeModelData }, { onlyLocal: true });
15238
15542
  }
15239
15543
  async _applyResult(data) {
15240
- const { unitData, unitOtherData, arrayFormulaRange, arrayFormulaCellData, clearArrayFormulaCellData, arrayFormulaEmbedded, imageFormulaData } = data;
15544
+ const { unitData, sourceFormulaData, unitOtherData, arrayFormulaRange, arrayFormulaCellData, clearArrayFormulaCellData, arrayFormulaEmbedded, imageFormulaData } = data;
15241
15545
  if (!unitData) {
15242
15546
  this._applyTreeResult(data);
15243
15547
  console.error("No sheetData from Formula Engine!");
@@ -15257,6 +15561,7 @@ let CalculateController = class CalculateController extends Disposable {
15257
15561
  this._applyTreeResult(data);
15258
15562
  this._commandService.executeCommand(SetFormulaCalculationResultMutation.id, {
15259
15563
  unitData: convertRuntimeToUnitData(unitData),
15564
+ sourceFormulaData,
15260
15565
  unitOtherData
15261
15566
  }, { onlyLocal: true });
15262
15567
  }
@@ -21300,13 +21605,13 @@ const weekendNumberMap = {
21300
21605
  17: [6]
21301
21606
  };
21302
21607
  function isValidWeekend(weekend) {
21303
- if (typeof weekend === "string" && /^[0|1]{7}/.test(weekend)) return true;
21608
+ if (typeof weekend === "string") return weekend.length === 7 && /^[01]{7}$/.test(weekend);
21304
21609
  if (weekendNumberMap[Number(weekend)]) return true;
21305
21610
  return false;
21306
21611
  }
21307
21612
  function getWeekendArray(weekend) {
21308
21613
  if (!isValidWeekend(weekend)) return [];
21309
- if (typeof weekend === "string" && /^[0|1]{7}/.test(weekend)) {
21614
+ if (typeof weekend === "string") {
21310
21615
  const result = [];
21311
21616
  for (let i = 1; i <= weekend.length; i++) if (`${weekend[i - 1]}` === "1") {
21312
21617
  if (i === weekend.length) result.push(0);
@@ -32681,7 +32986,7 @@ var Sort = class extends BaseFunction {
32681
32986
  _getResult(array, sortIndexValue, sortOrderValue, byColValue, arrayRowCount, arrayColumnCount) {
32682
32987
  if (!byColValue) {
32683
32988
  if (sortIndexValue > arrayColumnCount) return ErrorValueObject.create("#VALUE!");
32684
- const arrayValue = array.getArrayValue();
32989
+ const arrayValue = array.getArrayValue().slice();
32685
32990
  arrayValue.sort(this._sort(sortIndexValue - 1, sortOrderValue));
32686
32991
  return ArrayValueObject.create({
32687
32992
  calculateValueList: arrayValue,
@@ -33613,30 +33918,18 @@ var Xlookup = class extends BaseFunction {
33613
33918
  else resultArray = returnArray.slice(void 0, [0, 1]);
33614
33919
  if (resultArray == null) return ErrorValueObject.create("#N/A");
33615
33920
  return lookupValue.map((value) => {
33616
- const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33617
- if (checkErrorCombination) return checkErrorCombination;
33618
- const result = this._handleSingleObject(value, lookupArray, resultArray, matchModeValue, searchModeValue);
33619
- if (result.isError()) return ifNotFound;
33620
- return this._blankResultAsZero(result);
33921
+ return this._getLookupResult(value, lookupArray, resultArray, ifNotFound, matchModeValue, searchModeValue);
33621
33922
  });
33622
33923
  }
33623
33924
  const _lookupValue = lookupValue.isArray() ? lookupValue.get(0, 0) : lookupValue;
33624
- if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) {
33625
- const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33626
- if (checkErrorCombination) return checkErrorCombination;
33627
- const result = this._handleSingleObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue);
33628
- if (result.isError()) return ifNotFound;
33629
- return this._blankResultAsZero(result);
33630
- }
33925
+ if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue);
33631
33926
  let axis = 0;
33632
33927
  /**
33633
33928
  * 0 for rows
33634
33929
  * 1 for columns
33635
33930
  */
33636
33931
  if (columnCountLookup === columnCountReturn) axis = 1;
33637
- const resultArray = this._handleExpandObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue, axis);
33638
- if (resultArray == null) return ErrorValueObject.create("#N/A");
33639
- return resultArray;
33932
+ return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue, axis);
33640
33933
  }
33641
33934
  _legacyImplicitLookupValue(lookupValue) {
33642
33935
  if (!lookupValue.isArray()) return lookupValue;
@@ -33664,35 +33957,37 @@ var Xlookup = class extends BaseFunction {
33664
33957
  if (rowIndex < 0 || rowIndex >= rowCount || columnIndex < 0 || columnIndex >= columnCount) return ErrorValueObject.create("#VALUE!");
33665
33958
  return array.get(rowIndex, columnIndex) || ErrorValueObject.create("#VALUE!");
33666
33959
  }
33667
- _handleExpandObject(value, searchArray, resultArray, matchModeValue, searchModeValue, axis = 0) {
33960
+ _getLookupResult(value, searchArray, resultArray, ifNotFound, matchModeValue, searchModeValue, axis) {
33961
+ if (value.isError()) return value;
33962
+ const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33963
+ if (checkErrorCombination) return checkErrorCombination;
33964
+ const position = this._findPosition(value, searchArray, matchModeValue, searchModeValue);
33965
+ if (position == null) return ifNotFound;
33966
+ if (axis === 0) return resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A");
33967
+ if (axis === 1) return resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
33968
+ const result = resultArray.get(position.row, position.column) ?? NullValueObject.create();
33969
+ return this._blankResultAsZero(result);
33970
+ }
33971
+ _findPosition(value, searchArray, matchModeValue, searchModeValue) {
33668
33972
  if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
33669
33973
  const searchType = getSearchModeValue(searchModeValue);
33670
33974
  const matchType = getMatchModeValue(matchModeValue);
33671
- return this.binarySearchExpand(value, searchArray, resultArray, axis, searchType, matchType);
33975
+ const rowOrColumn = searchArray.binarySearch(value, searchType, matchType);
33976
+ if (rowOrColumn == null) return null;
33977
+ return searchArray.getRowCount() === 1 ? {
33978
+ row: 0,
33979
+ column: rowOrColumn
33980
+ } : {
33981
+ row: rowOrColumn,
33982
+ column: 0
33983
+ };
33672
33984
  }
33673
- if (matchModeValue === 2) return this.fuzzySearchExpand(value, searchArray, resultArray, searchModeValue !== -1, axis);
33674
- if (matchModeValue === -1 || matchModeValue === 1) return this.orderSearchExpand(value, searchArray, resultArray, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, axis, true);
33675
- return this._exactSearchExpand(value, searchArray, resultArray, searchModeValue !== -1, axis);
33676
- }
33677
- _handleSingleObject(value, searchArray, resultArray, matchModeValue, searchModeValue) {
33678
- if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
33679
- const searchType = getSearchModeValue(searchModeValue);
33680
- const matchType = getMatchModeValue(matchModeValue);
33681
- return this.binarySearch(value, searchArray, resultArray, searchType, matchType);
33985
+ if (matchModeValue === 2) {
33986
+ const matches = searchArray.compare(value, "=");
33987
+ return searchModeValue === -1 ? matches.getLastTruePosition() : matches.getFirstTruePosition();
33682
33988
  }
33683
- if (matchModeValue === 2) return this.fuzzySearch(value, searchArray, resultArray, searchModeValue !== -1);
33684
- if (matchModeValue === -1 || matchModeValue === 1) return this.orderSearch(value, searchArray, resultArray, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, true);
33685
- return this._exactSearch(value, searchArray, resultArray, searchModeValue !== -1);
33686
- }
33687
- _exactSearch(value, searchArray, resultArray, isFirst) {
33688
- const position = this._findExactPosition(value, searchArray, isFirst);
33689
- if (position == null) return ErrorValueObject.create("#N/A");
33690
- return resultArray.get(position.row, position.column) ?? ErrorValueObject.create("#N/A");
33691
- }
33692
- _exactSearchExpand(value, searchArray, resultArray, isFirst, axis) {
33693
- const position = this._findExactPosition(value, searchArray, isFirst);
33694
- if (position == null) return ErrorValueObject.create("#N/A");
33695
- return axis === 0 ? resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A") : resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
33989
+ if (matchModeValue === -1 || matchModeValue === 1) return searchArray.orderSearch(value, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, false, true);
33990
+ return this._findExactPosition(value, searchArray, searchModeValue !== -1);
33696
33991
  }
33697
33992
  _findExactPosition(value, searchArray, isFirst) {
33698
33993
  let position;
@@ -43719,7 +44014,7 @@ function getObjectValue(result, isUseStrip = false) {
43719
44014
  //#endregion
43720
44015
  //#region package.json
43721
44016
  var name = "@univerjs/engine-formula";
43722
- var version = "1.0.3";
44017
+ var version = "1.1.0";
43723
44018
 
43724
44019
  //#endregion
43725
44020
  //#region src/services/global-computing-status.service.ts
@@ -43805,6 +44100,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43805
44100
  _defineProperty(this, "_executionInProgress", false);
43806
44101
  _defineProperty(this, "_hasPendingCalculation", false);
43807
44102
  _defineProperty(this, "_stopRequested", false);
44103
+ _defineProperty(this, "_suppressed", false);
43808
44104
  this._registerGenericDirtyConversions();
43809
44105
  this._initialize();
43810
44106
  }
@@ -43813,6 +44109,16 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43813
44109
  this._started = true;
43814
44110
  this._scheduleFlush();
43815
44111
  }
44112
+ /** Snapshot reconstruction calculates these synchronous mutations in its isolated runtime. */
44113
+ runWithoutTriggering(operation) {
44114
+ const previous = this._suppressed;
44115
+ this._suppressed = true;
44116
+ try {
44117
+ return operation();
44118
+ } finally {
44119
+ this._suppressed = previous;
44120
+ }
44121
+ }
43816
44122
  dispose() {
43817
44123
  clearTimeout(this._timer);
43818
44124
  this._waitingCommandQueue = [];
@@ -43832,7 +44138,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43832
44138
  return;
43833
44139
  }
43834
44140
  const conversion = this._activeDirtyManagerService.get(command.id);
43835
- if (!conversion) return;
44141
+ if (!conversion || this._suppressed) return;
43836
44142
  if (((_conversion$shouldTri = conversion.shouldTrigger) === null || _conversion$shouldTri === void 0 ? void 0 : _conversion$shouldTri.call(conversion, command, options)) === false) return;
43837
44143
  this._waitingCommandQueue.push(command);
43838
44144
  this._scheduleFlush();
@@ -43921,6 +44227,8 @@ function mergeDirtyData(left, right) {
43921
44227
  return result;
43922
44228
  }
43923
44229
  function appendDirtyData(target, source, rangeKeys) {
44230
+ var _source$dirtyIteratio;
44231
+ if ((_source$dirtyIteratio = source.dirtyIterationUnits) === null || _source$dirtyIteratio === void 0 ? void 0 : _source$dirtyIteratio.length) target.dirtyIterationUnits = Array.from(/* @__PURE__ */ new Set([...target.dirtyIterationUnits ?? [], ...source.dirtyIterationUnits]));
43924
44232
  mergeDirtyRanges(target.dirtyRanges, source.dirtyRanges ?? [], rangeKeys);
43925
44233
  mergeDirtyUnitStringMap(target.dirtyNameMap, source.dirtyNameMap);
43926
44234
  mergeDirtyUnitStringMap(target.dirtyDefinedNameMap, source.dirtyDefinedNameMap);
@@ -43964,7 +44272,8 @@ function mergeDirtyUnitNestedMap(target, right) {
43964
44272
  });
43965
44273
  }
43966
44274
  function hasDirtyData(dirtyData) {
43967
- return dirtyData.forceCalculation || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
44275
+ var _dirtyData$dirtyItera;
44276
+ return dirtyData.forceCalculation || Boolean((_dirtyData$dirtyItera = dirtyData.dirtyIterationUnits) === null || _dirtyData$dirtyItera === void 0 ? void 0 : _dirtyData$dirtyItera.length) || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
43968
44277
  }
43969
44278
  function hasNestedValue(value) {
43970
44279
  if (value == null) return false;
@@ -43972,7 +44281,8 @@ function hasNestedValue(value) {
43972
44281
  return Object.values(value).some(hasNestedValue);
43973
44282
  }
43974
44283
  function dirtyDataIntersects(left, right) {
43975
- if (left.forceCalculation || right.forceCalculation) return true;
44284
+ var _left$dirtyIterationU, _right$dirtyIteration;
44285
+ if (left.forceCalculation || right.forceCalculation || ((_left$dirtyIterationU = left.dirtyIterationUnits) === null || _left$dirtyIterationU === void 0 ? void 0 : _left$dirtyIterationU.length) || ((_right$dirtyIteration = right.dirtyIterationUnits) === null || _right$dirtyIteration === void 0 ? void 0 : _right$dirtyIteration.length)) return true;
43976
44286
  if (left.dirtyRanges.some((leftRange) => right.dirtyRanges.some((rightRange) => leftRange.unitId === rightRange.unitId && leftRange.sheetId === rightRange.sheetId && Rectangle.intersects(leftRange.range, rightRange.range))) || clearedSheetIntersects(left, right) || clearedSheetIntersects(right, left)) return true;
43977
44287
  return [
43978
44288
  [left.dirtyNameMap, right.dirtyNameMap],
@@ -57421,4 +57731,8 @@ _defineProperty(UniverFormulaEnginePlugin, "version", version);
57421
57731
  UniverFormulaEnginePlugin = __decorate([__decorateParam(1, Inject(Injector)), __decorateParam(2, IConfigService)], UniverFormulaEnginePlugin);
57422
57732
 
57423
57733
  //#endregion
57424
- export { ALL_IMPLEMENTED_FUNCTIONS, ALL_IMPLEMENTED_FUNCTIONS_SET, ActiveDirtyManagerService, ArrayValueObject, AstRootNodeFactory, AstTreeBuilder, AsyncArrayObject, AsyncCustomFunction, AsyncObject, BaseFunction, BaseReferenceObject, BaseValueObject, BooleanValue, BooleanValueObject, CELL_INVERTED_INDEX_CACHE, CalculateController, CalculateFormulaService, CustomFunction, DEFAULT_CYCLE_REFERENCE_COUNT, DEFAULT_INTERVAL_COUNT, DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME, DEFAULT_TOKEN_LET_FUNCTION_NAME, DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER, DEFAULT_TOKEN_TYPE_PARAMETER, DEFAULT_TOKEN_TYPE_ROOT, DefinedNamesService, DependencyManagerBaseService, DependencyManagerService, DescriptionService, ENGINE_FORMULA_CYCLE_REFERENCE_COUNT, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, ENGINE_FORMULA_RETURN_DEPENDENCY_TREE, ERROR_TYPE_SET, ErrorType, ErrorValueObject, FORMULA_REF_TO_ARRAY_CACHE, FUNCTION_LIST, FUNCTION_LIST_ARRAY, FUNCTION_LIST_COMPATIBILITY, FUNCTION_LIST_CUBE, FUNCTION_LIST_DATABASE, FUNCTION_LIST_DATE, FUNCTION_LIST_ENGINEERING, FUNCTION_LIST_FINANCIAL, FUNCTION_LIST_INFORMATION, FUNCTION_LIST_LOGICAL, FUNCTION_LIST_LOOKUP, FUNCTION_LIST_MATH, FUNCTION_LIST_STATISTICAL, FUNCTION_LIST_TEXT, FUNCTION_LIST_UNIVER, FUNCTION_LIST_WEB, FUNCTION_NAMES_ARRAY, FUNCTION_NAMES_COMPATIBILITY, FUNCTION_NAMES_CUBE, FUNCTION_NAMES_DATABASE, FUNCTION_NAMES_DATE, FUNCTION_NAMES_ENGINEERING, FUNCTION_NAMES_FINANCIAL, FUNCTION_NAMES_INFORMATION, FUNCTION_NAMES_LOGICAL, FUNCTION_NAMES_LOOKUP, FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT, FUNCTION_NAMES_UNIVER, FUNCTION_NAMES_WEB, FeatureCalculationManagerService, FormulaCalculationSessionController, FormulaCalculationSessionService, FormulaCalculationTriggerService, FormulaCurrentConfigService, FormulaDataModel, FormulaDependencyGenerator, FormulaDependencyTree, FormulaDependencyTreeModel, FormulaDependencyTreeType, FormulaDependencyTreeVirtual, FormulaExecuteStageType, FormulaExecutedStateType, FormulaResultApplicationType, FormulaResultStatus, FormulaRuntimeService, FormulaUnitReferenceResolver, FunctionNodeFactory, FunctionService, FunctionType, GlobalComputingStatusService, HyperlinkEngineFormulaService, IActiveDirtyManagerService, ICalculateFormulaService, IDefinedNamesService, IDependencyManagerService, IDescriptionService, IFeatureCalculationManagerService, IFormulaCurrentConfigService, IFormulaDependencyGenerator, IFormulaExternalReferenceDataLoader, IFormulaRuntimeService, IFormulaUnitReferenceResolver, IFunctionService, IHyperlinkEngineFormulaService, IOtherFormulaManagerService, IRegisterFunctionService, ISheetRowFilteredService, ISuperTableService, Interpreter, LambdaNodeFactory, LambdaParameterNodeFactory, LambdaValueObjectObject, Lexer, LexerNode, LexerTreeBuilder, NEW_EXCEL_FUNCTIONS, NoopFormulaExternalReferenceDataLoader, NullValueObject, NumberValueObject, OPERATOR_TOKEN_SET, OperatorNodeFactory, OtherFormulaBizType, OtherFormulaManagerService, OtherFormulaMarkDirty, PrefixNodeFactory, RangeReferenceObject, ReferenceNodeFactory, RegisterFunctionMutation, RegisterFunctionService, RegisterOtherFormulaService, RemoveDefinedNameMutation, RemoveFeatureCalculationMutation, RemoveOtherFormulaMutation, RemoveSuperTableMutation, SUFFIX_TOKEN_SET, SetArrayFormulaDataMutation, SetCellFormulaDependencyCalculationMutation, SetCellFormulaDependencyCalculationResultMutation, SetDefinedNameMutation, SetDefinedNameMutationFactory, SetFeatureCalculationMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, SetFormulaDataMutation, SetFormulaDependencyCalculationMutation, SetFormulaDependencyCalculationResultMutation, SetFormulaStringBatchCalculationMutation, SetFormulaStringBatchCalculationResultMutation, SetImageFormulaDataMutation, SetOtherFormulaMutation, SetQueryFormulaDependencyAllMutation, SetQueryFormulaDependencyAllResultMutation, SetQueryFormulaDependencyMutation, SetQueryFormulaDependencyResultMutation, SetSuperTableMutation, SetSuperTableOptionMutation, SetTriggerFormulaCalculationStartMutation, SheetRowFilteredService, StringValueObject, SuffixNodeFactory, SuperTableActiveDirtyController, SuperTableService, UnionNodeFactory, UniverFormulaEnginePlugin, ValueNodeFactory, ValueObjectFactory, buildFormulaTextRuns, compareToken, convertUnitDataToRuntime, deserializeRangeForR1C1, deserializeRangeWithSheet, deserializeRangeWithSheetWithCache, extractFormulaError, findFormulaStructuredReferences, functionArray, functionCompatibility, functionCube, functionDatabase, functionDate, functionEngineering, functionFinancial, functionInformation, functionLogical, functionLookup, functionMath, functionMeta, functionStatistical, functionText, functionUniver, functionWeb, generateAstNode, generateExecuteAstNodeData, generateParam, generateRandomDependencyTreeId, generateStringWithSequence, getAbsoluteRefTypeWitString, getAbsoluteRefTypeWithSingleString, getFormulaHighlightDataStream, getFormulaReferenceIndex, getFormulaReplaceResult, getFormulaSequenceCharacterAtOffset, getFormulaSequenceNodeIndex, getFunctionName, getObjectValue, getRangeWithRefsString, handleNumfmtInCell, handleRefStringInfo, includeFormulaLexerToken, isFormulaLexerToken, isFormulaReferenceAddingContext, isFormulaReferenceAddingTextContext, isInDirtyRange, isReferenceString, isReferenceStringWithEffectiveColumn, isReferenceStrings, matchRefDrawToken, matchToken, needsQuoting, normalizeFormulaUnitName, normalizeSheetName, operatorToken, prefixToken, quoteSheetName, refactorFormulaUnitQualifier, resolveFormulaReferenceEditingContext, searchFormulaFunctions, sequenceNodeType, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, splitTableStructuredRef, strip, stripErrorMargin, unquoteSheetName };
57734
+ //#region src/services/formula-changeset-calculation.service.ts
57735
+ const IFormulaChangesetCalculationService = createIdentifier("engine-formula.changeset-calculation.service");
57736
+
57737
+ //#endregion
57738
+ export { ALL_IMPLEMENTED_FUNCTIONS, ALL_IMPLEMENTED_FUNCTIONS_SET, ActiveDirtyManagerService, ArrayValueObject, AstRootNodeFactory, AstTreeBuilder, AsyncArrayObject, AsyncCustomFunction, AsyncObject, BaseFunction, BaseReferenceObject, BaseValueObject, BooleanValue, BooleanValueObject, CELL_INVERTED_INDEX_CACHE, CalculateController, CalculateFormulaService, CustomFunction, DEFAULT_INTERVAL_COUNT, DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME, DEFAULT_TOKEN_LET_FUNCTION_NAME, DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER, DEFAULT_TOKEN_TYPE_PARAMETER, DEFAULT_TOKEN_TYPE_ROOT, DefinedNamesService, DependencyManagerBaseService, DependencyManagerService, DescriptionService, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, ENGINE_FORMULA_RETURN_DEPENDENCY_TREE, ERROR_TYPE_SET, ErrorType, ErrorValueObject, FORMULA_REF_TO_ARRAY_CACHE, FUNCTION_LIST, FUNCTION_LIST_ARRAY, FUNCTION_LIST_COMPATIBILITY, FUNCTION_LIST_CUBE, FUNCTION_LIST_DATABASE, FUNCTION_LIST_DATE, FUNCTION_LIST_ENGINEERING, FUNCTION_LIST_FINANCIAL, FUNCTION_LIST_INFORMATION, FUNCTION_LIST_LOGICAL, FUNCTION_LIST_LOOKUP, FUNCTION_LIST_MATH, FUNCTION_LIST_STATISTICAL, FUNCTION_LIST_TEXT, FUNCTION_LIST_UNIVER, FUNCTION_LIST_WEB, FUNCTION_NAMES_ARRAY, FUNCTION_NAMES_COMPATIBILITY, FUNCTION_NAMES_CUBE, FUNCTION_NAMES_DATABASE, FUNCTION_NAMES_DATE, FUNCTION_NAMES_ENGINEERING, FUNCTION_NAMES_FINANCIAL, FUNCTION_NAMES_INFORMATION, FUNCTION_NAMES_LOGICAL, FUNCTION_NAMES_LOOKUP, FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT, FUNCTION_NAMES_UNIVER, FUNCTION_NAMES_WEB, FeatureCalculationManagerService, FormulaCalculationSessionController, FormulaCalculationSessionService, FormulaCalculationTriggerService, FormulaCurrentConfigService, FormulaDataModel, FormulaDependencyGenerator, FormulaDependencyTree, FormulaDependencyTreeModel, FormulaDependencyTreeType, FormulaDependencyTreeVirtual, FormulaExecuteStageType, FormulaExecutedStateType, FormulaResultApplicationType, FormulaResultStatus, FormulaRuntimeService, FormulaUnitReferenceResolver, FunctionNodeFactory, FunctionService, FunctionType, GlobalComputingStatusService, HyperlinkEngineFormulaService, IActiveDirtyManagerService, ICalculateFormulaService, IDefinedNamesService, IDependencyManagerService, IDescriptionService, IFeatureCalculationManagerService, IFormulaChangesetCalculationService, IFormulaCurrentConfigService, IFormulaDependencyGenerator, IFormulaExternalReferenceDataLoader, IFormulaRuntimeService, IFormulaUnitReferenceResolver, IFunctionService, IHyperlinkEngineFormulaService, IOtherFormulaManagerService, IRegisterFunctionService, ISheetRowFilteredService, ISuperTableService, Interpreter, LambdaNodeFactory, LambdaParameterNodeFactory, LambdaValueObjectObject, Lexer, LexerNode, LexerTreeBuilder, NEW_EXCEL_FUNCTIONS, NoopFormulaExternalReferenceDataLoader, NullValueObject, NumberValueObject, OPERATOR_TOKEN_SET, OperatorNodeFactory, OtherFormulaBizType, OtherFormulaManagerService, OtherFormulaMarkDirty, PrefixNodeFactory, RangeReferenceObject, ReferenceNodeFactory, RegisterFunctionMutation, RegisterFunctionService, RegisterOtherFormulaService, RemoveDefinedNameMutation, RemoveFeatureCalculationMutation, RemoveOtherFormulaMutation, RemoveSuperTableMutation, SUFFIX_TOKEN_SET, SetArrayFormulaDataMutation, SetCellFormulaDependencyCalculationMutation, SetCellFormulaDependencyCalculationResultMutation, SetDefinedNameMutation, SetDefinedNameMutationFactory, SetFeatureCalculationMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, SetFormulaDataMutation, SetFormulaDependencyCalculationMutation, SetFormulaDependencyCalculationResultMutation, SetFormulaStringBatchCalculationMutation, SetFormulaStringBatchCalculationResultMutation, SetImageFormulaDataMutation, SetOtherFormulaMutation, SetQueryFormulaDependencyAllMutation, SetQueryFormulaDependencyAllResultMutation, SetQueryFormulaDependencyMutation, SetQueryFormulaDependencyResultMutation, SetSuperTableMutation, SetSuperTableOptionMutation, SetTriggerFormulaCalculationStartMutation, SheetRowFilteredService, StringValueObject, SuffixNodeFactory, SuperTableActiveDirtyController, SuperTableService, UnionNodeFactory, UniverFormulaEnginePlugin, ValueNodeFactory, ValueObjectFactory, buildFormulaTextRuns, compareToken, convertUnitDataToRuntime, deserializeRangeForR1C1, deserializeRangeWithSheet, deserializeRangeWithSheetWithCache, extractFormulaError, findFormulaStructuredReferences, functionArray, functionCompatibility, functionCube, functionDatabase, functionDate, functionEngineering, functionFinancial, functionInformation, functionLogical, functionLookup, functionMath, functionMeta, functionStatistical, functionText, functionUniver, functionWeb, generateAstNode, generateExecuteAstNodeData, generateParam, generateRandomDependencyTreeId, generateStringWithSequence, getAbsoluteRefTypeWitString, getAbsoluteRefTypeWithSingleString, getFormulaHighlightDataStream, getFormulaReferenceIndex, getFormulaReplaceResult, getFormulaSequenceCharacterAtOffset, getFormulaSequenceNodeIndex, getFunctionName, getObjectValue, getRangeWithRefsString, handleNumfmtInCell, handleRefStringInfo, includeFormulaLexerToken, isFormulaLexerToken, isFormulaReferenceAddingContext, isFormulaReferenceAddingTextContext, isInDirtyRange, isReferenceString, isReferenceStringWithEffectiveColumn, isReferenceStrings, matchRefDrawToken, matchToken, mergeDirtyData, needsQuoting, normalizeFormulaUnitName, normalizeSheetName, operatorToken, prefixToken, quoteSheetName, refactorFormulaUnitQualifier, resolveFormulaReferenceEditingContext, searchFormulaFunctions, sequenceNodeType, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, splitTableStructuredRef, strip, stripErrorMargin, unquoteSheetName };