@odoo/o-spreadsheet 18.4.8 → 18.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +225 -136
- package/dist/o-spreadsheet.d.ts +78 -72
- package/dist/o-spreadsheet.esm.js +225 -136
- package/dist/o-spreadsheet.iife.js +225 -136
- package/dist/o-spreadsheet.iife.min.js +388 -388
- package/dist/o_spreadsheet.xml +17 -13
- package/package.json +2 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.4.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.4.10
|
|
6
|
+
* @date 2025-09-11T08:45:39.178Z
|
|
7
|
+
* @hash 15a11a4
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2645,6 +2645,7 @@ const invalidateBordersCommands = new Set([
|
|
|
2645
2645
|
"AUTOFILL_CELL",
|
|
2646
2646
|
"SET_BORDER",
|
|
2647
2647
|
"SET_ZONE_BORDERS",
|
|
2648
|
+
"SET_BORDERS_ON_TARGET",
|
|
2648
2649
|
]);
|
|
2649
2650
|
const readonlyAllowedCommands = new Set([
|
|
2650
2651
|
"START",
|
|
@@ -3991,6 +3992,10 @@ function isDataNonEmpty(data) {
|
|
|
3991
3992
|
}
|
|
3992
3993
|
return true;
|
|
3993
3994
|
}
|
|
3995
|
+
const noValidInputErrorMessage = _t("[[FUNCTION_NAME]] has no valid input data.");
|
|
3996
|
+
function emptyDataErrorMessage(argName) {
|
|
3997
|
+
return _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", { argName });
|
|
3998
|
+
}
|
|
3994
3999
|
|
|
3995
4000
|
function tokenizeFormat(str) {
|
|
3996
4001
|
const chars = new TokenizingChars(str);
|
|
@@ -6592,40 +6597,44 @@ function orderRange(range) {
|
|
|
6592
6597
|
};
|
|
6593
6598
|
}
|
|
6594
6599
|
function getRangeAdapter(cmd) {
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
applyChange: getApplyRangeChangeAddColRow(cmd),
|
|
6605
|
-
sheetId: cmd.sheetId,
|
|
6606
|
-
sheetName: cmd.sheetName,
|
|
6607
|
-
};
|
|
6608
|
-
case "DELETE_SHEET":
|
|
6609
|
-
return {
|
|
6610
|
-
applyChange: getApplyRangeChangeDeleteSheet(cmd),
|
|
6611
|
-
sheetId: cmd.sheetId,
|
|
6612
|
-
sheetName: cmd.sheetName,
|
|
6613
|
-
};
|
|
6614
|
-
case "RENAME_SHEET":
|
|
6615
|
-
return {
|
|
6616
|
-
applyChange: getApplyRangeChangeRenameSheet(cmd),
|
|
6617
|
-
sheetId: cmd.sheetId,
|
|
6618
|
-
sheetName: cmd.oldName,
|
|
6619
|
-
};
|
|
6620
|
-
case "MOVE_RANGES":
|
|
6621
|
-
return {
|
|
6622
|
-
applyChange: getApplyRangeChangeMoveRange(cmd),
|
|
6623
|
-
sheetId: cmd.sheetId,
|
|
6624
|
-
sheetName: cmd.sheetName,
|
|
6625
|
-
};
|
|
6600
|
+
return rangeAdapterRegistry.get(cmd.type)?.(cmd);
|
|
6601
|
+
}
|
|
6602
|
+
class RangeAdapterRegistry extends Registry {
|
|
6603
|
+
add(cmdType, fn) {
|
|
6604
|
+
super.add(cmdType, fn);
|
|
6605
|
+
return this;
|
|
6606
|
+
}
|
|
6607
|
+
get(cmdType) {
|
|
6608
|
+
return this.content[cmdType];
|
|
6626
6609
|
}
|
|
6627
|
-
return undefined;
|
|
6628
6610
|
}
|
|
6611
|
+
const rangeAdapterRegistry = new RangeAdapterRegistry();
|
|
6612
|
+
rangeAdapterRegistry
|
|
6613
|
+
.add("REMOVE_COLUMNS_ROWS", (cmd) => ({
|
|
6614
|
+
applyChange: getApplyRangeChangeRemoveColRow(cmd),
|
|
6615
|
+
sheetId: cmd.sheetId,
|
|
6616
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6617
|
+
}))
|
|
6618
|
+
.add("ADD_COLUMNS_ROWS", (cmd) => ({
|
|
6619
|
+
applyChange: getApplyRangeChangeAddColRow(cmd),
|
|
6620
|
+
sheetId: cmd.sheetId,
|
|
6621
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6622
|
+
}))
|
|
6623
|
+
.add("DELETE_SHEET", (cmd) => ({
|
|
6624
|
+
applyChange: getApplyRangeChangeDeleteSheet(cmd),
|
|
6625
|
+
sheetId: cmd.sheetId,
|
|
6626
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6627
|
+
}))
|
|
6628
|
+
.add("RENAME_SHEET", (cmd) => ({
|
|
6629
|
+
applyChange: getApplyRangeChangeRenameSheet(cmd),
|
|
6630
|
+
sheetId: cmd.sheetId,
|
|
6631
|
+
sheetName: { old: cmd.oldName, current: cmd.newName },
|
|
6632
|
+
}))
|
|
6633
|
+
.add("MOVE_RANGES", (cmd) => ({
|
|
6634
|
+
applyChange: getApplyRangeChangeMoveRange(cmd),
|
|
6635
|
+
sheetId: cmd.sheetId,
|
|
6636
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6637
|
+
}));
|
|
6629
6638
|
function getApplyRangeChangeRemoveColRow(cmd) {
|
|
6630
6639
|
const start = cmd.dimension === "COL" ? "left" : "top";
|
|
6631
6640
|
const end = cmd.dimension === "COL" ? "right" : "bottom";
|
|
@@ -7347,7 +7356,7 @@ class ClipboardHandler {
|
|
|
7347
7356
|
this.getters = getters;
|
|
7348
7357
|
this.dispatch = dispatch;
|
|
7349
7358
|
}
|
|
7350
|
-
copy(data, isCutOperation) {
|
|
7359
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
7351
7360
|
return;
|
|
7352
7361
|
}
|
|
7353
7362
|
paste(target, clippedContent, options) { }
|
|
@@ -7366,7 +7375,7 @@ class ClipboardHandler {
|
|
|
7366
7375
|
}
|
|
7367
7376
|
|
|
7368
7377
|
class AbstractCellClipboardHandler extends ClipboardHandler {
|
|
7369
|
-
copy(data) {
|
|
7378
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
7370
7379
|
return;
|
|
7371
7380
|
}
|
|
7372
7381
|
pasteFromCopy(sheetId, target, content, options) {
|
|
@@ -8002,8 +8011,11 @@ function invertMatrix(M) {
|
|
|
8002
8011
|
// (a) Swap 2 rows. This multiply the determinant by -1.
|
|
8003
8012
|
// (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
|
|
8004
8013
|
// (c) Add to a row a multiple of another row. This does not change the determinant.
|
|
8014
|
+
if (M.length < 1 || M[0].length < 1) {
|
|
8015
|
+
throw new Error("invertMatrix: an empty matrix cannot be inverted.");
|
|
8016
|
+
}
|
|
8005
8017
|
if (M.length !== M[0].length) {
|
|
8006
|
-
throw new
|
|
8018
|
+
throw new Error("invertMatrix: only square matrices are invertible");
|
|
8007
8019
|
}
|
|
8008
8020
|
let determinant = 1;
|
|
8009
8021
|
const dim = M.length;
|
|
@@ -8072,8 +8084,11 @@ function swapMatrixRows(matrix, row1, row2) {
|
|
|
8072
8084
|
* Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
|
|
8073
8085
|
*/
|
|
8074
8086
|
function multiplyMatrices(matrix1, matrix2) {
|
|
8087
|
+
if (matrix1.length < 1 || matrix2.length < 1) {
|
|
8088
|
+
throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
|
|
8089
|
+
}
|
|
8075
8090
|
if (matrix1.length !== matrix2[0].length) {
|
|
8076
|
-
throw new
|
|
8091
|
+
throw new Error("multiplyMatrices: incompatible matrices size.");
|
|
8077
8092
|
}
|
|
8078
8093
|
const rowsM1 = matrix1[0].length;
|
|
8079
8094
|
const colsM2 = matrix2.length;
|
|
@@ -8099,7 +8114,7 @@ function toScalar(arg) {
|
|
|
8099
8114
|
return arg;
|
|
8100
8115
|
}
|
|
8101
8116
|
if (!isSingleElementMatrix(arg)) {
|
|
8102
|
-
throw new
|
|
8117
|
+
throw new Error("The value should be a scalar or a 1x1 matrix");
|
|
8103
8118
|
}
|
|
8104
8119
|
return arg[0][0];
|
|
8105
8120
|
}
|
|
@@ -8890,7 +8905,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8890
8905
|
}
|
|
8891
8906
|
return "Success" /* CommandResult.Success */;
|
|
8892
8907
|
}
|
|
8893
|
-
copy(data) {
|
|
8908
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
8894
8909
|
const sheetId = data.sheetId;
|
|
8895
8910
|
const { clippedZones, rowsIndexes, columnsIndexes } = data;
|
|
8896
8911
|
const clippedCells = [];
|
|
@@ -8903,7 +8918,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8903
8918
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
8904
8919
|
const pivotId = this.getters.getPivotIdFromPosition(position);
|
|
8905
8920
|
const spreader = this.getters.getArrayFormulaSpreadingOn(position);
|
|
8906
|
-
if (pivotId && spreader) {
|
|
8921
|
+
if (mode !== "shiftCells" && pivotId && spreader) {
|
|
8907
8922
|
const pivotZone = this.getters.getSpreadZone(spreader);
|
|
8908
8923
|
if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
|
|
8909
8924
|
pivotZone &&
|
|
@@ -8921,7 +8936,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8921
8936
|
};
|
|
8922
8937
|
}
|
|
8923
8938
|
}
|
|
8924
|
-
else {
|
|
8939
|
+
else if (mode !== "shiftCells") {
|
|
8925
8940
|
if (spreader && !deepEquals(spreader, position)) {
|
|
8926
8941
|
const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
|
|
8927
8942
|
const content = isSpreaderCopied
|
|
@@ -9619,7 +9634,7 @@ class SheetClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9619
9634
|
}
|
|
9620
9635
|
|
|
9621
9636
|
class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
9622
|
-
copy(data, isCutOperation) {
|
|
9637
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
9623
9638
|
const sheetId = data.sheetId;
|
|
9624
9639
|
const { rowsIndexes, columnsIndexes, zones } = data;
|
|
9625
9640
|
const copiedTablesIds = new Set();
|
|
@@ -9657,11 +9672,13 @@ class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9657
9672
|
type: coreTable.type,
|
|
9658
9673
|
};
|
|
9659
9674
|
}
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9675
|
+
if (mode !== "shiftCells") {
|
|
9676
|
+
tableCellsInRow.push({
|
|
9677
|
+
table: copiedTable,
|
|
9678
|
+
style: this.getTableStyleToCopy(position),
|
|
9679
|
+
isWholeTableCopied: copiedTablesIds.has(table.id),
|
|
9680
|
+
});
|
|
9681
|
+
}
|
|
9665
9682
|
}
|
|
9666
9683
|
}
|
|
9667
9684
|
return {
|
|
@@ -11238,6 +11255,9 @@ const MMULT = {
|
|
|
11238
11255
|
compute: function (matrix1, matrix2) {
|
|
11239
11256
|
const _matrix1 = toNumberMatrix(matrix1, "matrix1");
|
|
11240
11257
|
const _matrix2 = toNumberMatrix(matrix2, "matrix2");
|
|
11258
|
+
if (_matrix1.length === 0 || _matrix2.length === 0) {
|
|
11259
|
+
return new EvaluationError(_t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
|
|
11260
|
+
}
|
|
11241
11261
|
if (_matrix1.length !== _matrix2[0].length) {
|
|
11242
11262
|
return new EvaluationError(_t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
|
|
11243
11263
|
number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
|
|
@@ -12850,7 +12870,7 @@ function centile(data, percent, isInclusive, locale) {
|
|
|
12850
12870
|
count++;
|
|
12851
12871
|
}
|
|
12852
12872
|
});
|
|
12853
|
-
assert(count !== 0,
|
|
12873
|
+
assert(count !== 0, noValidInputErrorMessage);
|
|
12854
12874
|
if (!isInclusive) {
|
|
12855
12875
|
// 2nd argument must be between 1/(n+1) and n/(n+1) with n the number of data
|
|
12856
12876
|
assert(1 / (count + 1) <= _percent && _percent <= count / (count + 1), _t("Function [[FUNCTION_NAME]] parameter 2 value is out of range."));
|
|
@@ -13125,6 +13145,9 @@ const FORECAST = {
|
|
|
13125
13145
|
],
|
|
13126
13146
|
compute: function (x, dataY, dataX) {
|
|
13127
13147
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13148
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13149
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13150
|
+
}
|
|
13128
13151
|
return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
|
|
13129
13152
|
},
|
|
13130
13153
|
isExported: true,
|
|
@@ -13141,6 +13164,9 @@ const GROWTH = {
|
|
|
13141
13164
|
arg("b (boolean, default=TRUE)", _t("Given a general exponential form of y = b*m^x for a curve fit, calculates b if TRUE or forces b to be 1 and only calculates the m values if FALSE.")),
|
|
13142
13165
|
],
|
|
13143
13166
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13167
|
+
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13168
|
+
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13169
|
+
}
|
|
13144
13170
|
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "the first argument (known_data_y)")), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
|
|
13145
13171
|
},
|
|
13146
13172
|
};
|
|
@@ -13155,6 +13181,9 @@ const INTERCEPT = {
|
|
|
13155
13181
|
],
|
|
13156
13182
|
compute: function (dataY, dataX) {
|
|
13157
13183
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13184
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13185
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13186
|
+
}
|
|
13158
13187
|
const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13159
13188
|
return intercept;
|
|
13160
13189
|
},
|
|
@@ -13187,7 +13216,7 @@ const LARGE = {
|
|
|
13187
13216
|
});
|
|
13188
13217
|
const result = largests.shift();
|
|
13189
13218
|
if (result === undefined) {
|
|
13190
|
-
return new EvaluationError(
|
|
13219
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
13191
13220
|
}
|
|
13192
13221
|
if (count < _n) {
|
|
13193
13222
|
return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
|
|
@@ -13208,6 +13237,9 @@ const LINEST = {
|
|
|
13208
13237
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
13209
13238
|
],
|
|
13210
13239
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13240
|
+
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13241
|
+
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13242
|
+
}
|
|
13211
13243
|
return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
|
|
13212
13244
|
},
|
|
13213
13245
|
isExported: true,
|
|
@@ -13224,6 +13256,9 @@ const LOGEST = {
|
|
|
13224
13256
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
13225
13257
|
],
|
|
13226
13258
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13259
|
+
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13260
|
+
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13261
|
+
}
|
|
13227
13262
|
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
|
|
13228
13263
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13229
13264
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
@@ -13245,8 +13280,8 @@ const MATTHEWS = {
|
|
|
13245
13280
|
const flatX = dataX.flat();
|
|
13246
13281
|
const flatY = dataY.flat();
|
|
13247
13282
|
assertSameNumberOfElements(flatX, flatY);
|
|
13248
|
-
if (flatX.length === 0) {
|
|
13249
|
-
return new
|
|
13283
|
+
if (flatX.length === 0 || flatY.length === 0) {
|
|
13284
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13250
13285
|
}
|
|
13251
13286
|
const n = flatX.length;
|
|
13252
13287
|
let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
|
|
@@ -13411,11 +13446,8 @@ const MINIFS = {
|
|
|
13411
13446
|
// -----------------------------------------------------------------------------
|
|
13412
13447
|
function pearson(dataY, dataX) {
|
|
13413
13448
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13414
|
-
if (flatDataX.length === 0) {
|
|
13415
|
-
|
|
13416
|
-
}
|
|
13417
|
-
if (flatDataX.length < 2) {
|
|
13418
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] needs at least two values for both parameters."));
|
|
13449
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13450
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13419
13451
|
}
|
|
13420
13452
|
const n = flatDataX.length;
|
|
13421
13453
|
let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
|
|
@@ -13505,6 +13537,9 @@ const POLYFIT_COEFFS = {
|
|
|
13505
13537
|
],
|
|
13506
13538
|
compute: function (dataY, dataX, order, intercept = { value: true }) {
|
|
13507
13539
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13540
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13541
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13542
|
+
}
|
|
13508
13543
|
return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
|
|
13509
13544
|
},
|
|
13510
13545
|
isExported: false,
|
|
@@ -13524,6 +13559,9 @@ const POLYFIT_FORECAST = {
|
|
|
13524
13559
|
compute: function (x, dataY, dataX, order, intercept = { value: true }) {
|
|
13525
13560
|
const _order = toNumber(order, this.locale);
|
|
13526
13561
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13562
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13563
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13564
|
+
}
|
|
13527
13565
|
const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
|
|
13528
13566
|
return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
|
|
13529
13567
|
},
|
|
@@ -13625,7 +13663,11 @@ const RSQ = {
|
|
|
13625
13663
|
arg("data_x (range<number>)", _t("The range representing the array or matrix of independent data.")),
|
|
13626
13664
|
],
|
|
13627
13665
|
compute: function (dataY, dataX) {
|
|
13628
|
-
|
|
13666
|
+
const value = pearson(dataY, dataX);
|
|
13667
|
+
if (value instanceof Error) {
|
|
13668
|
+
throw value;
|
|
13669
|
+
}
|
|
13670
|
+
return Math.pow(value, 2.0);
|
|
13629
13671
|
},
|
|
13630
13672
|
isExported: true,
|
|
13631
13673
|
};
|
|
@@ -13640,6 +13682,9 @@ const SLOPE = {
|
|
|
13640
13682
|
],
|
|
13641
13683
|
compute: function (dataY, dataX) {
|
|
13642
13684
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13685
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13686
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13687
|
+
}
|
|
13643
13688
|
const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13644
13689
|
return slope;
|
|
13645
13690
|
},
|
|
@@ -13672,7 +13717,7 @@ const SMALL = {
|
|
|
13672
13717
|
});
|
|
13673
13718
|
const result = largests.pop();
|
|
13674
13719
|
if (result === undefined) {
|
|
13675
|
-
return new EvaluationError(
|
|
13720
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
13676
13721
|
}
|
|
13677
13722
|
if (count < _n) {
|
|
13678
13723
|
return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
|
|
@@ -13692,6 +13737,9 @@ const SPEARMAN = {
|
|
|
13692
13737
|
],
|
|
13693
13738
|
compute: function (dataX, dataY) {
|
|
13694
13739
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13740
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13741
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13742
|
+
}
|
|
13695
13743
|
const n = flatDataX.length;
|
|
13696
13744
|
const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
|
|
13697
13745
|
order.sort((a, b) => a[0] - b[0]);
|
|
@@ -13802,6 +13850,9 @@ const STEYX = {
|
|
|
13802
13850
|
],
|
|
13803
13851
|
compute: function (dataY, dataX) {
|
|
13804
13852
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13853
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13854
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13855
|
+
}
|
|
13805
13856
|
const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
|
|
13806
13857
|
return data[1][2];
|
|
13807
13858
|
},
|
|
@@ -13819,6 +13870,9 @@ const TREND = {
|
|
|
13819
13870
|
arg("b (boolean, optional, default=TRUE)", _t("Given a general linear form of y = m*x+b for a curve fit, calculates b if TRUE or forces b to be 0 and only calculates the m values if FALSE, i.e. forces the curve fit to pass through the origin.")),
|
|
13820
13871
|
],
|
|
13821
13872
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13873
|
+
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13874
|
+
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13875
|
+
}
|
|
13822
13876
|
return predictLinearValues(toNumberMatrix(knownDataY, "the first argument (known_data_y)"), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
|
|
13823
13877
|
},
|
|
13824
13878
|
};
|
|
@@ -18734,7 +18788,7 @@ const AND = {
|
|
|
18734
18788
|
compute: function (...logicalExpressions) {
|
|
18735
18789
|
const { result, foundBoolean } = boolAnd(logicalExpressions);
|
|
18736
18790
|
if (!foundBoolean) {
|
|
18737
|
-
return new EvaluationError(
|
|
18791
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
18738
18792
|
}
|
|
18739
18793
|
return result;
|
|
18740
18794
|
},
|
|
@@ -18860,7 +18914,7 @@ const OR = {
|
|
|
18860
18914
|
compute: function (...logicalExpressions) {
|
|
18861
18915
|
const { result, foundBoolean } = boolOr(logicalExpressions);
|
|
18862
18916
|
if (!foundBoolean) {
|
|
18863
|
-
return new EvaluationError(
|
|
18917
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
18864
18918
|
}
|
|
18865
18919
|
return result;
|
|
18866
18920
|
},
|
|
@@ -18923,7 +18977,7 @@ const XOR = {
|
|
|
18923
18977
|
return true; // no stop condition
|
|
18924
18978
|
});
|
|
18925
18979
|
if (!foundBoolean) {
|
|
18926
|
-
return new EvaluationError(
|
|
18980
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
18927
18981
|
}
|
|
18928
18982
|
return acc;
|
|
18929
18983
|
},
|
|
@@ -21387,7 +21441,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
|
|
|
21387
21441
|
function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
21388
21442
|
const sheetName = splitReference(sheetXC).sheetName;
|
|
21389
21443
|
if (sheetName
|
|
21390
|
-
? !isSheetNameEqual(sheetName, applyChange.sheetName)
|
|
21444
|
+
? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
|
|
21391
21445
|
: defaultSheetId !== applyChange.sheetId) {
|
|
21392
21446
|
return sheetXC;
|
|
21393
21447
|
}
|
|
@@ -21404,7 +21458,7 @@ function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
|
21404
21458
|
}
|
|
21405
21459
|
function getSheetNameGetter(applyChange) {
|
|
21406
21460
|
return (sheetId) => {
|
|
21407
|
-
return sheetId === applyChange.sheetId ? applyChange.sheetName : "";
|
|
21461
|
+
return sheetId === applyChange.sheetId ? applyChange.sheetName.current : "";
|
|
21408
21462
|
};
|
|
21409
21463
|
}
|
|
21410
21464
|
function defaultGetSheetSize(sheetId) {
|
|
@@ -27395,9 +27449,13 @@ class GaugeChart extends AbstractChart {
|
|
|
27395
27449
|
: undefined,
|
|
27396
27450
|
};
|
|
27397
27451
|
}
|
|
27398
|
-
updateRanges(applyChange) {
|
|
27452
|
+
updateRanges(applyChange, sheetId, adaptSheetName) {
|
|
27399
27453
|
const dataRange = adaptChartRange(this.dataRange, applyChange);
|
|
27400
|
-
const adaptFormula = (formula) =>
|
|
27454
|
+
const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
|
|
27455
|
+
applyChange,
|
|
27456
|
+
sheetId,
|
|
27457
|
+
sheetName: adaptSheetName,
|
|
27458
|
+
});
|
|
27401
27459
|
const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
|
|
27402
27460
|
const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
|
|
27403
27461
|
return new GaugeChart(definition, this.sheetId, this.getters);
|
|
@@ -33720,6 +33778,9 @@ class Composer extends owl.Component {
|
|
|
33720
33778
|
this.contentHelper.removeSelection();
|
|
33721
33779
|
}
|
|
33722
33780
|
onMouseup() {
|
|
33781
|
+
if (this.env.model.getters.isReadonly()) {
|
|
33782
|
+
return;
|
|
33783
|
+
}
|
|
33723
33784
|
const selection = this.contentHelper.getCurrentSelection();
|
|
33724
33785
|
if (selection.start !== selection.end) {
|
|
33725
33786
|
this.props.composerStore.hoverToken(undefined);
|
|
@@ -37455,7 +37516,7 @@ const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
|
|
|
37455
37516
|
];
|
|
37456
37517
|
const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
|
|
37457
37518
|
const SUPPORTED_FONTS = ["Arial"];
|
|
37458
|
-
const SUPPORTED_FILL_PATTERNS = ["solid"];
|
|
37519
|
+
const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
|
|
37459
37520
|
const SUPPORTED_CF_TYPES = [
|
|
37460
37521
|
"expression",
|
|
37461
37522
|
"cellIs",
|
|
@@ -37655,7 +37716,7 @@ const SUBTOTAL_FUNCTION_CONVERSION_MAP = {
|
|
|
37655
37716
|
};
|
|
37656
37717
|
/** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
|
|
37657
37718
|
const XLSX_FORMATS_CONVERSION_MAP = {
|
|
37658
|
-
0: "",
|
|
37719
|
+
0: "General",
|
|
37659
37720
|
1: "0",
|
|
37660
37721
|
2: "0.00",
|
|
37661
37722
|
3: "#,#00",
|
|
@@ -37981,11 +38042,11 @@ const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/
|
|
|
37981
38042
|
* Excel format are defined in openXML §18.8.31
|
|
37982
38043
|
*/
|
|
37983
38044
|
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
37984
|
-
if (numFmtId === 0) {
|
|
37985
|
-
return undefined;
|
|
37986
|
-
}
|
|
37987
38045
|
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
37988
38046
|
const format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
|
|
38047
|
+
if (format === "General") {
|
|
38048
|
+
return undefined;
|
|
38049
|
+
}
|
|
37989
38050
|
if (format) {
|
|
37990
38051
|
try {
|
|
37991
38052
|
let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
@@ -38183,9 +38244,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38183
38244
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
38184
38245
|
continue;
|
|
38185
38246
|
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
|
|
38186
|
-
values.push(rule.formula[0]);
|
|
38247
|
+
values.push(prefixFormula(rule.formula[0]));
|
|
38187
38248
|
if (rule.formula.length === 2) {
|
|
38188
|
-
values.push(rule.formula[1]);
|
|
38249
|
+
values.push(prefixFormula(rule.formula[1]));
|
|
38189
38250
|
}
|
|
38190
38251
|
break;
|
|
38191
38252
|
}
|
|
@@ -38343,6 +38404,11 @@ function convertIcons(xlsxIconSet, index) {
|
|
|
38343
38404
|
? ICON_SETS[iconSet].neutral
|
|
38344
38405
|
: ICON_SETS[iconSet].good;
|
|
38345
38406
|
}
|
|
38407
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
38408
|
+
function prefixFormula(formula) {
|
|
38409
|
+
const tokens = tokenize(formula);
|
|
38410
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
38411
|
+
}
|
|
38346
38412
|
// ---------------------------------------------------------------------------
|
|
38347
38413
|
// Warnings
|
|
38348
38414
|
// ---------------------------------------------------------------------------
|
|
@@ -38625,7 +38691,7 @@ function getColPosition(colIndex, sheetData) {
|
|
|
38625
38691
|
function getRowPosition(rowIndex, sheetData) {
|
|
38626
38692
|
let position = 0;
|
|
38627
38693
|
for (let i = 0; i < rowIndex; i++) {
|
|
38628
|
-
const rowAtIndex = sheetData.rows
|
|
38694
|
+
const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
|
|
38629
38695
|
if (rowAtIndex?.height) {
|
|
38630
38696
|
position += rowAtIndex.height;
|
|
38631
38697
|
}
|
|
@@ -38780,8 +38846,8 @@ function convertExcelTrendline(trend) {
|
|
|
38780
38846
|
}
|
|
38781
38847
|
function convertAnchor(XLSXanchor) {
|
|
38782
38848
|
const offset = {
|
|
38783
|
-
x: convertEMUToDotValue(XLSXanchor.colOffset),
|
|
38784
|
-
y: convertEMUToDotValue(XLSXanchor.rowOffset),
|
|
38849
|
+
x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
|
|
38850
|
+
y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
|
|
38785
38851
|
};
|
|
38786
38852
|
return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
|
|
38787
38853
|
}
|
|
@@ -39164,8 +39230,12 @@ function getSheetDims(sheet) {
|
|
|
39164
39230
|
dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
|
|
39165
39231
|
dims[1] = Math.max(dims[1], row.index);
|
|
39166
39232
|
}
|
|
39167
|
-
|
|
39168
|
-
|
|
39233
|
+
for (const fig of sheet.figures) {
|
|
39234
|
+
dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
|
|
39235
|
+
dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
|
|
39236
|
+
}
|
|
39237
|
+
dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
|
|
39238
|
+
dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
|
|
39169
39239
|
return dims;
|
|
39170
39240
|
}
|
|
39171
39241
|
/**
|
|
@@ -40554,10 +40624,11 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
40554
40624
|
});
|
|
40555
40625
|
}
|
|
40556
40626
|
extractRows(worksheet) {
|
|
40627
|
+
const spilledCells = new Set();
|
|
40557
40628
|
return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
|
|
40558
40629
|
return {
|
|
40559
40630
|
index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
|
|
40560
|
-
cells: this.extractCells(rowElement),
|
|
40631
|
+
cells: this.extractCells(rowElement, spilledCells),
|
|
40561
40632
|
height: this.extractAttr(rowElement, "ht")?.asNum(),
|
|
40562
40633
|
customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
|
|
40563
40634
|
hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
|
|
@@ -40567,14 +40638,26 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
40567
40638
|
};
|
|
40568
40639
|
});
|
|
40569
40640
|
}
|
|
40570
|
-
extractCells(row) {
|
|
40641
|
+
extractCells(row, spilledCells) {
|
|
40571
40642
|
return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
|
|
40643
|
+
const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
|
|
40644
|
+
const formula = this.extractCellFormula(cellElement);
|
|
40645
|
+
if (formula?.ref && formula.sharedIndex === undefined) {
|
|
40646
|
+
const zone = toZone(formula.ref);
|
|
40647
|
+
for (const { col, row } of positions(zone)) {
|
|
40648
|
+
const followerXc = toXC(col, row);
|
|
40649
|
+
if (followerXc !== xc) {
|
|
40650
|
+
spilledCells.add(followerXc);
|
|
40651
|
+
}
|
|
40652
|
+
}
|
|
40653
|
+
}
|
|
40654
|
+
const isSpilled = spilledCells.has(xc);
|
|
40572
40655
|
return {
|
|
40573
|
-
xc
|
|
40656
|
+
xc,
|
|
40574
40657
|
styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
|
|
40575
40658
|
type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
|
|
40576
|
-
value: this.extractChildTextContent(cellElement, "v"),
|
|
40577
|
-
formula:
|
|
40659
|
+
value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
|
|
40660
|
+
formula: isSpilled ? undefined : formula,
|
|
40578
40661
|
};
|
|
40579
40662
|
});
|
|
40580
40663
|
}
|
|
@@ -40582,11 +40665,14 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
40582
40665
|
const formulaElement = this.querySelector(cellElement, "f");
|
|
40583
40666
|
if (!formulaElement)
|
|
40584
40667
|
return undefined;
|
|
40585
|
-
|
|
40586
|
-
|
|
40587
|
-
|
|
40588
|
-
|
|
40589
|
-
|
|
40668
|
+
const content = this.extractTextContent(formulaElement);
|
|
40669
|
+
const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
|
|
40670
|
+
const ref = this.extractAttr(formulaElement, "ref")?.asString();
|
|
40671
|
+
// This is the case of spilled cells of array formulas where <f> is empty
|
|
40672
|
+
if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
|
|
40673
|
+
return undefined;
|
|
40674
|
+
}
|
|
40675
|
+
return { content, sharedIndex, ref };
|
|
40590
40676
|
}
|
|
40591
40677
|
extractHyperLinks(worksheet) {
|
|
40592
40678
|
return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
|
|
@@ -40868,7 +40954,7 @@ function getRelationFile(file, xmls) {
|
|
|
40868
40954
|
return relsFile;
|
|
40869
40955
|
}
|
|
40870
40956
|
|
|
40871
|
-
const EXCEL_IMPORT_VERSION = "18.4.
|
|
40957
|
+
const EXCEL_IMPORT_VERSION = "18.4.2";
|
|
40872
40958
|
class XlsxReader {
|
|
40873
40959
|
warningManager;
|
|
40874
40960
|
xmls;
|
|
@@ -44413,7 +44499,7 @@ const splitToColumns = {
|
|
|
44413
44499
|
const reinsertDynamicPivotMenu = {
|
|
44414
44500
|
id: "reinsert_dynamic_pivot",
|
|
44415
44501
|
name: _t("Re-insert dynamic pivot"),
|
|
44416
|
-
sequence:
|
|
44502
|
+
sequence: 60,
|
|
44417
44503
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
44418
44504
|
children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
|
|
44419
44505
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -44421,7 +44507,7 @@ const reinsertDynamicPivotMenu = {
|
|
|
44421
44507
|
const reinsertStaticPivotMenu = {
|
|
44422
44508
|
id: "reinsert_static_pivot",
|
|
44423
44509
|
name: _t("Re-insert static pivot"),
|
|
44424
|
-
sequence:
|
|
44510
|
+
sequence: 70,
|
|
44425
44511
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
44426
44512
|
children: [REINSERT_STATIC_PIVOT_CHILDREN],
|
|
44427
44513
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -58692,7 +58778,8 @@ class CorePlugin extends BasePlugin {
|
|
|
58692
58778
|
* the type of change that occurred.
|
|
58693
58779
|
*
|
|
58694
58780
|
* @param applyChange a function that, when called, will adapt the range according to the change on the grid
|
|
58695
|
-
* @param sheetId an
|
|
58781
|
+
* @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
|
|
58782
|
+
* @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
|
|
58696
58783
|
*/
|
|
58697
58784
|
adaptRanges(applyChange, sheetId, sheetName) { }
|
|
58698
58785
|
/**
|
|
@@ -59295,9 +59382,7 @@ class CellPlugin extends CorePlugin {
|
|
|
59295
59382
|
for (const cell of Object.values(this.cells[sheet] || {})) {
|
|
59296
59383
|
if (cell.isFormula) {
|
|
59297
59384
|
for (const range of cell.compiledFormula.dependencies) {
|
|
59298
|
-
if (
|
|
59299
|
-
range.sheetId === sheetId ||
|
|
59300
|
-
(sheetName && range.invalidSheetName === sheetName)) {
|
|
59385
|
+
if (range.sheetId === sheetId || range.invalidSheetName === sheetName.old) {
|
|
59301
59386
|
const change = applyChange(range);
|
|
59302
59387
|
if (change.changeType !== "NONE") {
|
|
59303
59388
|
this.history.update("cells", sheet, cell.id, "compiledFormula", "dependencies", cell.compiledFormula.dependencies.indexOf(range), change.range);
|
|
@@ -59913,9 +59998,9 @@ class ChartPlugin extends CorePlugin {
|
|
|
59913
59998
|
charts = {};
|
|
59914
59999
|
createChart = chartFactory(this.getters);
|
|
59915
60000
|
validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
|
|
59916
|
-
adaptRanges(applyChange) {
|
|
60001
|
+
adaptRanges(applyChange, sheetId, adaptSheetName) {
|
|
59917
60002
|
for (const [chartId, chart] of Object.entries(this.charts)) {
|
|
59918
|
-
this.history.update("charts", chartId, chart?.updateRanges(applyChange));
|
|
60003
|
+
this.history.update("charts", chartId, chart?.updateRanges(applyChange, sheetId, adaptSheetName));
|
|
59919
60004
|
}
|
|
59920
60005
|
}
|
|
59921
60006
|
// ---------------------------------------------------------------------------
|
|
@@ -60178,7 +60263,7 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
60178
60263
|
}
|
|
60179
60264
|
}
|
|
60180
60265
|
}
|
|
60181
|
-
adaptRanges(applyChange, sheetId
|
|
60266
|
+
adaptRanges(applyChange, sheetId) {
|
|
60182
60267
|
const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
|
|
60183
60268
|
for (const sheetId of sheetIds) {
|
|
60184
60269
|
this.adaptCFRanges(sheetId, applyChange);
|
|
@@ -60560,11 +60645,8 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
60560
60645
|
"getValidationRuleForCell",
|
|
60561
60646
|
];
|
|
60562
60647
|
rules = {};
|
|
60563
|
-
adaptRanges(applyChange, sheetId
|
|
60564
|
-
|
|
60565
|
-
for (const sheetId of sheetIds) {
|
|
60566
|
-
this.adaptDVRanges(sheetId, applyChange);
|
|
60567
|
-
}
|
|
60648
|
+
adaptRanges(applyChange, sheetId) {
|
|
60649
|
+
this.adaptDVRanges(sheetId, applyChange);
|
|
60568
60650
|
this.adaptDVFormulas(applyChange);
|
|
60569
60651
|
}
|
|
60570
60652
|
adaptDVFormulas(applyChange) {
|
|
@@ -60854,9 +60936,6 @@ class FigurePlugin extends CorePlugin {
|
|
|
60854
60936
|
// Command Handling
|
|
60855
60937
|
// ---------------------------------------------------------------------------
|
|
60856
60938
|
adaptRanges(applyChange, sheetId) {
|
|
60857
|
-
if (!sheetId) {
|
|
60858
|
-
return;
|
|
60859
|
-
}
|
|
60860
60939
|
for (const figure of this.getFigures(sheetId)) {
|
|
60861
60940
|
const change = applyChange(this.getters.getRangeFromZone(sheetId, {
|
|
60862
60941
|
left: figure.col,
|
|
@@ -61665,11 +61744,8 @@ class MergePlugin extends CorePlugin {
|
|
|
61665
61744
|
break;
|
|
61666
61745
|
}
|
|
61667
61746
|
}
|
|
61668
|
-
adaptRanges(applyChange, sheetId
|
|
61669
|
-
|
|
61670
|
-
for (const sheetId of sheetIds) {
|
|
61671
|
-
this.applyRangeChangeOnSheet(sheetId, applyChange);
|
|
61672
|
-
}
|
|
61747
|
+
adaptRanges(applyChange, sheetId) {
|
|
61748
|
+
this.applyRangeChangeOnSheet(sheetId, applyChange);
|
|
61673
61749
|
}
|
|
61674
61750
|
// ---------------------------------------------------------------------------
|
|
61675
61751
|
// Getters
|
|
@@ -63174,12 +63250,9 @@ class TablePlugin extends CorePlugin {
|
|
|
63174
63250
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
63175
63251
|
tables = {};
|
|
63176
63252
|
nextTableId = 1;
|
|
63177
|
-
adaptRanges(applyChange, sheetId
|
|
63178
|
-
const
|
|
63179
|
-
|
|
63180
|
-
for (const table of this.getCoreTables(sheetId)) {
|
|
63181
|
-
this.applyRangeChangeOnTable(sheetId, table, applyChange);
|
|
63182
|
-
}
|
|
63253
|
+
adaptRanges(applyChange, sheetId) {
|
|
63254
|
+
for (const table of this.getCoreTables(sheetId)) {
|
|
63255
|
+
this.applyRangeChangeOnTable(sheetId, table, applyChange);
|
|
63183
63256
|
}
|
|
63184
63257
|
}
|
|
63185
63258
|
allowDispatch(cmd) {
|
|
@@ -64142,7 +64215,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64142
64215
|
}
|
|
64143
64216
|
}
|
|
64144
64217
|
}
|
|
64145
|
-
adaptRanges(applyChange
|
|
64218
|
+
adaptRanges(applyChange) {
|
|
64146
64219
|
for (const sheetId in this.compiledMeasureFormulas) {
|
|
64147
64220
|
for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
|
|
64148
64221
|
const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
|
|
@@ -68543,7 +68616,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68543
68616
|
if (!result) {
|
|
68544
68617
|
return EMPTY_PIVOT_CELL;
|
|
68545
68618
|
}
|
|
68546
|
-
|
|
68619
|
+
let { functionName, args } = result;
|
|
68547
68620
|
const formulaId = args[0];
|
|
68548
68621
|
if (!formulaId) {
|
|
68549
68622
|
return EMPTY_PIVOT_CELL;
|
|
@@ -68578,6 +68651,9 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68578
68651
|
return pivotCells[pivotCol][pivotRow];
|
|
68579
68652
|
}
|
|
68580
68653
|
try {
|
|
68654
|
+
const offsetRow = position.row - mainPosition.row;
|
|
68655
|
+
const offsetCol = position.col - mainPosition.col;
|
|
68656
|
+
args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
|
|
68581
68657
|
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
68582
68658
|
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
68583
68659
|
return {
|
|
@@ -70186,7 +70262,8 @@ function transformAll(toTransform, executed) {
|
|
|
70186
70262
|
// If the executed command is not in the registry, we skip it
|
|
70187
70263
|
// because we know there won't be any transformation impacting the
|
|
70188
70264
|
// commands to transform.
|
|
70189
|
-
if (possibleTransformations.has(executedCommand.type)
|
|
70265
|
+
if (possibleTransformations.has(executedCommand.type) ||
|
|
70266
|
+
rangeAdapterRegistry.contains(executedCommand.type)) {
|
|
70190
70267
|
transformedCommands = transformedCommands.reduce((acc, cmd) => {
|
|
70191
70268
|
const transformed = transform(cmd, executedCommand);
|
|
70192
70269
|
if (transformed) {
|
|
@@ -70933,7 +71010,7 @@ class DataCleanupPlugin extends UIPlugin {
|
|
|
70933
71010
|
bottom: rowIndex,
|
|
70934
71011
|
}));
|
|
70935
71012
|
const handler = new CellClipboardHandler(this.getters, this.dispatch);
|
|
70936
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep));
|
|
71013
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep), false);
|
|
70937
71014
|
if (!data) {
|
|
70938
71015
|
return;
|
|
70939
71016
|
}
|
|
@@ -73018,12 +73095,12 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
73018
73095
|
}
|
|
73019
73096
|
case "INSERT_CELL": {
|
|
73020
73097
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
73021
|
-
const copiedData = this.copy(cut);
|
|
73098
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73022
73099
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
73023
73100
|
}
|
|
73024
73101
|
case "DELETE_CELL": {
|
|
73025
73102
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
73026
|
-
const copiedData = this.copy(cut);
|
|
73103
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73027
73104
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
73028
73105
|
}
|
|
73029
73106
|
}
|
|
@@ -73134,13 +73211,13 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
73134
73211
|
});
|
|
73135
73212
|
break;
|
|
73136
73213
|
}
|
|
73137
|
-
const copiedData = this.copy(cut);
|
|
73214
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73138
73215
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
73139
73216
|
break;
|
|
73140
73217
|
}
|
|
73141
73218
|
case "INSERT_CELL": {
|
|
73142
73219
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
73143
|
-
const copiedData = this.copy(cut);
|
|
73220
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73144
73221
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
73145
73222
|
break;
|
|
73146
73223
|
}
|
|
@@ -73255,11 +73332,11 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
73255
73332
|
}
|
|
73256
73333
|
return false;
|
|
73257
73334
|
}
|
|
73258
|
-
copy(zones) {
|
|
73335
|
+
copy(zones, mode = "copyPaste") {
|
|
73259
73336
|
const copiedData = {};
|
|
73260
73337
|
const clipboardData = this.getClipboardData(zones);
|
|
73261
73338
|
for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
|
|
73262
|
-
const data = handler.copy(clipboardData, this._isCutOperation);
|
|
73339
|
+
const data = handler.copy(clipboardData, this._isCutOperation, mode);
|
|
73263
73340
|
copiedData[handlerName] = data;
|
|
73264
73341
|
const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
|
|
73265
73342
|
for (const key of minimalKeys) {
|
|
@@ -74273,7 +74350,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74273
74350
|
];
|
|
74274
74351
|
for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
|
|
74275
74352
|
const handler = new Handler(this.getters, this.dispatch);
|
|
74276
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, target));
|
|
74353
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, target), false, "shiftCells");
|
|
74277
74354
|
if (!data) {
|
|
74278
74355
|
continue;
|
|
74279
74356
|
}
|
|
@@ -76178,7 +76255,8 @@ const inverseCommandRegistry = new Registry()
|
|
|
76178
76255
|
.add("HIDE_COLUMNS_ROWS", inverseHideColumnsRows)
|
|
76179
76256
|
.add("UNHIDE_COLUMNS_ROWS", inverseUnhideColumnsRows)
|
|
76180
76257
|
.add("CREATE_TABLE_STYLE", inverseCreateTableStyle)
|
|
76181
|
-
.add("ADD_PIVOT", inverseAddPivot)
|
|
76258
|
+
.add("ADD_PIVOT", inverseAddPivot)
|
|
76259
|
+
.add("RENAME_SHEET", inverseRenameSheet);
|
|
76182
76260
|
for (const cmd of coreTypes.values()) {
|
|
76183
76261
|
if (!inverseCommandRegistry.contains(cmd)) {
|
|
76184
76262
|
inverseCommandRegistry.add(cmd, identity);
|
|
@@ -76276,6 +76354,16 @@ function inverseUnhideColumnsRows(cmd) {
|
|
|
76276
76354
|
function inverseCreateTableStyle(cmd) {
|
|
76277
76355
|
return [{ type: "REMOVE_TABLE_STYLE", tableStyleId: cmd.tableStyleId }];
|
|
76278
76356
|
}
|
|
76357
|
+
function inverseRenameSheet(cmd) {
|
|
76358
|
+
return [
|
|
76359
|
+
{
|
|
76360
|
+
type: "RENAME_SHEET",
|
|
76361
|
+
sheetId: cmd.sheetId,
|
|
76362
|
+
oldName: cmd.newName,
|
|
76363
|
+
newName: cmd.oldName,
|
|
76364
|
+
},
|
|
76365
|
+
];
|
|
76366
|
+
}
|
|
76279
76367
|
|
|
76280
76368
|
const numberFormatMenuRegistry = new Registry();
|
|
76281
76369
|
numberFormatMenuRegistry
|
|
@@ -76874,8 +76962,9 @@ topbarMenuRegistry
|
|
|
76874
76962
|
sequence: 40,
|
|
76875
76963
|
separator: true,
|
|
76876
76964
|
})
|
|
76877
|
-
.addChild("
|
|
76965
|
+
.addChild("pivot_data_sources", ["data"], (env) => {
|
|
76878
76966
|
const sequence = 50;
|
|
76967
|
+
const numberOfPivots = env.model.getters.getPivotIds().length;
|
|
76879
76968
|
return env.model.getters.getPivotIds().map((pivotId, index) => {
|
|
76880
76969
|
const highlightProvider = {
|
|
76881
76970
|
get highlights() {
|
|
@@ -76885,7 +76974,7 @@ topbarMenuRegistry
|
|
|
76885
76974
|
return {
|
|
76886
76975
|
id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
76887
76976
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
76888
|
-
sequence: sequence + index,
|
|
76977
|
+
sequence: sequence + index / numberOfPivots,
|
|
76889
76978
|
isReadonlyAllowed: true,
|
|
76890
76979
|
execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
|
|
76891
76980
|
isEnabled: (env) => !env.isSmall,
|
|
@@ -83005,7 +83094,7 @@ function figureCoordinates(headers, anchor, offset) {
|
|
|
83005
83094
|
for (const [headerIndex, header] of headers.slice(anchor).entries()) {
|
|
83006
83095
|
if (currentPosition <= offset && offset < currentPosition + header.size) {
|
|
83007
83096
|
return {
|
|
83008
|
-
index: headerIndex,
|
|
83097
|
+
index: anchor + headerIndex,
|
|
83009
83098
|
offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
|
|
83010
83099
|
};
|
|
83011
83100
|
}
|
|
@@ -84751,6 +84840,6 @@ exports.tokenColors = tokenColors;
|
|
|
84751
84840
|
exports.tokenize = tokenize;
|
|
84752
84841
|
|
|
84753
84842
|
|
|
84754
|
-
__info__.version = "18.4.
|
|
84755
|
-
__info__.date = "2025-
|
|
84756
|
-
__info__.hash = "
|
|
84843
|
+
__info__.version = "18.4.10";
|
|
84844
|
+
__info__.date = "2025-09-11T08:45:39.178Z";
|
|
84845
|
+
__info__.hash = "15a11a4";
|