@odoo/o-spreadsheet 18.4.8 → 18.4.9
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 +174 -103
- package/dist/o-spreadsheet.d.ts +75 -70
- package/dist/o-spreadsheet.esm.js +174 -103
- package/dist/o-spreadsheet.iife.js +174 -103
- package/dist/o-spreadsheet.iife.min.js +388 -388
- package/dist/o_spreadsheet.xml +16 -9
- package/package.json +1 -1
|
@@ -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.9
|
|
6
|
+
* @date 2025-09-05T07:38:32.126Z
|
|
7
|
+
* @hash a261873
|
|
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";
|
|
@@ -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
|
}
|
|
@@ -11238,6 +11253,9 @@ const MMULT = {
|
|
|
11238
11253
|
compute: function (matrix1, matrix2) {
|
|
11239
11254
|
const _matrix1 = toNumberMatrix(matrix1, "matrix1");
|
|
11240
11255
|
const _matrix2 = toNumberMatrix(matrix2, "matrix2");
|
|
11256
|
+
if (_matrix1.length === 0 || _matrix2.length === 0) {
|
|
11257
|
+
return new EvaluationError(_t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
|
|
11258
|
+
}
|
|
11241
11259
|
if (_matrix1.length !== _matrix2[0].length) {
|
|
11242
11260
|
return new EvaluationError(_t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
|
|
11243
11261
|
number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
|
|
@@ -12850,7 +12868,7 @@ function centile(data, percent, isInclusive, locale) {
|
|
|
12850
12868
|
count++;
|
|
12851
12869
|
}
|
|
12852
12870
|
});
|
|
12853
|
-
assert(count !== 0,
|
|
12871
|
+
assert(count !== 0, noValidInputErrorMessage);
|
|
12854
12872
|
if (!isInclusive) {
|
|
12855
12873
|
// 2nd argument must be between 1/(n+1) and n/(n+1) with n the number of data
|
|
12856
12874
|
assert(1 / (count + 1) <= _percent && _percent <= count / (count + 1), _t("Function [[FUNCTION_NAME]] parameter 2 value is out of range."));
|
|
@@ -13125,6 +13143,9 @@ const FORECAST = {
|
|
|
13125
13143
|
],
|
|
13126
13144
|
compute: function (x, dataY, dataX) {
|
|
13127
13145
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13146
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13147
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13148
|
+
}
|
|
13128
13149
|
return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
|
|
13129
13150
|
},
|
|
13130
13151
|
isExported: true,
|
|
@@ -13141,6 +13162,9 @@ const GROWTH = {
|
|
|
13141
13162
|
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
13163
|
],
|
|
13143
13164
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13165
|
+
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13166
|
+
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13167
|
+
}
|
|
13144
13168
|
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
13169
|
},
|
|
13146
13170
|
};
|
|
@@ -13155,6 +13179,9 @@ const INTERCEPT = {
|
|
|
13155
13179
|
],
|
|
13156
13180
|
compute: function (dataY, dataX) {
|
|
13157
13181
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13182
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13183
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13184
|
+
}
|
|
13158
13185
|
const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13159
13186
|
return intercept;
|
|
13160
13187
|
},
|
|
@@ -13187,7 +13214,7 @@ const LARGE = {
|
|
|
13187
13214
|
});
|
|
13188
13215
|
const result = largests.shift();
|
|
13189
13216
|
if (result === undefined) {
|
|
13190
|
-
return new EvaluationError(
|
|
13217
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
13191
13218
|
}
|
|
13192
13219
|
if (count < _n) {
|
|
13193
13220
|
return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
|
|
@@ -13208,6 +13235,9 @@ const LINEST = {
|
|
|
13208
13235
|
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
13236
|
],
|
|
13210
13237
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13238
|
+
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13239
|
+
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13240
|
+
}
|
|
13211
13241
|
return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
|
|
13212
13242
|
},
|
|
13213
13243
|
isExported: true,
|
|
@@ -13224,6 +13254,9 @@ const LOGEST = {
|
|
|
13224
13254
|
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
13255
|
],
|
|
13226
13256
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13257
|
+
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13258
|
+
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13259
|
+
}
|
|
13227
13260
|
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
|
|
13228
13261
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13229
13262
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
@@ -13245,8 +13278,8 @@ const MATTHEWS = {
|
|
|
13245
13278
|
const flatX = dataX.flat();
|
|
13246
13279
|
const flatY = dataY.flat();
|
|
13247
13280
|
assertSameNumberOfElements(flatX, flatY);
|
|
13248
|
-
if (flatX.length === 0) {
|
|
13249
|
-
return new
|
|
13281
|
+
if (flatX.length === 0 || flatY.length === 0) {
|
|
13282
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13250
13283
|
}
|
|
13251
13284
|
const n = flatX.length;
|
|
13252
13285
|
let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
|
|
@@ -13411,11 +13444,8 @@ const MINIFS = {
|
|
|
13411
13444
|
// -----------------------------------------------------------------------------
|
|
13412
13445
|
function pearson(dataY, dataX) {
|
|
13413
13446
|
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."));
|
|
13447
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13448
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13419
13449
|
}
|
|
13420
13450
|
const n = flatDataX.length;
|
|
13421
13451
|
let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
|
|
@@ -13505,6 +13535,9 @@ const POLYFIT_COEFFS = {
|
|
|
13505
13535
|
],
|
|
13506
13536
|
compute: function (dataY, dataX, order, intercept = { value: true }) {
|
|
13507
13537
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13538
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13539
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13540
|
+
}
|
|
13508
13541
|
return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
|
|
13509
13542
|
},
|
|
13510
13543
|
isExported: false,
|
|
@@ -13524,6 +13557,9 @@ const POLYFIT_FORECAST = {
|
|
|
13524
13557
|
compute: function (x, dataY, dataX, order, intercept = { value: true }) {
|
|
13525
13558
|
const _order = toNumber(order, this.locale);
|
|
13526
13559
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13560
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13561
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13562
|
+
}
|
|
13527
13563
|
const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
|
|
13528
13564
|
return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
|
|
13529
13565
|
},
|
|
@@ -13625,7 +13661,11 @@ const RSQ = {
|
|
|
13625
13661
|
arg("data_x (range<number>)", _t("The range representing the array or matrix of independent data.")),
|
|
13626
13662
|
],
|
|
13627
13663
|
compute: function (dataY, dataX) {
|
|
13628
|
-
|
|
13664
|
+
const value = pearson(dataY, dataX);
|
|
13665
|
+
if (value instanceof Error) {
|
|
13666
|
+
throw value;
|
|
13667
|
+
}
|
|
13668
|
+
return Math.pow(value, 2.0);
|
|
13629
13669
|
},
|
|
13630
13670
|
isExported: true,
|
|
13631
13671
|
};
|
|
@@ -13640,6 +13680,9 @@ const SLOPE = {
|
|
|
13640
13680
|
],
|
|
13641
13681
|
compute: function (dataY, dataX) {
|
|
13642
13682
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13683
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13684
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13685
|
+
}
|
|
13643
13686
|
const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13644
13687
|
return slope;
|
|
13645
13688
|
},
|
|
@@ -13672,7 +13715,7 @@ const SMALL = {
|
|
|
13672
13715
|
});
|
|
13673
13716
|
const result = largests.pop();
|
|
13674
13717
|
if (result === undefined) {
|
|
13675
|
-
return new EvaluationError(
|
|
13718
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
13676
13719
|
}
|
|
13677
13720
|
if (count < _n) {
|
|
13678
13721
|
return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
|
|
@@ -13692,6 +13735,9 @@ const SPEARMAN = {
|
|
|
13692
13735
|
],
|
|
13693
13736
|
compute: function (dataX, dataY) {
|
|
13694
13737
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13738
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13739
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13740
|
+
}
|
|
13695
13741
|
const n = flatDataX.length;
|
|
13696
13742
|
const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
|
|
13697
13743
|
order.sort((a, b) => a[0] - b[0]);
|
|
@@ -13802,6 +13848,9 @@ const STEYX = {
|
|
|
13802
13848
|
],
|
|
13803
13849
|
compute: function (dataY, dataX) {
|
|
13804
13850
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13851
|
+
if (flatDataX.length === 0 || flatDataY.length === 0) {
|
|
13852
|
+
return new NotAvailableError(noValidInputErrorMessage);
|
|
13853
|
+
}
|
|
13805
13854
|
const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
|
|
13806
13855
|
return data[1][2];
|
|
13807
13856
|
},
|
|
@@ -13819,6 +13868,9 @@ const TREND = {
|
|
|
13819
13868
|
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
13869
|
],
|
|
13821
13870
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13871
|
+
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13872
|
+
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13873
|
+
}
|
|
13822
13874
|
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
13875
|
},
|
|
13824
13876
|
};
|
|
@@ -18734,7 +18786,7 @@ const AND = {
|
|
|
18734
18786
|
compute: function (...logicalExpressions) {
|
|
18735
18787
|
const { result, foundBoolean } = boolAnd(logicalExpressions);
|
|
18736
18788
|
if (!foundBoolean) {
|
|
18737
|
-
return new EvaluationError(
|
|
18789
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
18738
18790
|
}
|
|
18739
18791
|
return result;
|
|
18740
18792
|
},
|
|
@@ -18860,7 +18912,7 @@ const OR = {
|
|
|
18860
18912
|
compute: function (...logicalExpressions) {
|
|
18861
18913
|
const { result, foundBoolean } = boolOr(logicalExpressions);
|
|
18862
18914
|
if (!foundBoolean) {
|
|
18863
|
-
return new EvaluationError(
|
|
18915
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
18864
18916
|
}
|
|
18865
18917
|
return result;
|
|
18866
18918
|
},
|
|
@@ -18923,7 +18975,7 @@ const XOR = {
|
|
|
18923
18975
|
return true; // no stop condition
|
|
18924
18976
|
});
|
|
18925
18977
|
if (!foundBoolean) {
|
|
18926
|
-
return new EvaluationError(
|
|
18978
|
+
return new EvaluationError(noValidInputErrorMessage);
|
|
18927
18979
|
}
|
|
18928
18980
|
return acc;
|
|
18929
18981
|
},
|
|
@@ -21387,7 +21439,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
|
|
|
21387
21439
|
function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
21388
21440
|
const sheetName = splitReference(sheetXC).sheetName;
|
|
21389
21441
|
if (sheetName
|
|
21390
|
-
? !isSheetNameEqual(sheetName, applyChange.sheetName)
|
|
21442
|
+
? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
|
|
21391
21443
|
: defaultSheetId !== applyChange.sheetId) {
|
|
21392
21444
|
return sheetXC;
|
|
21393
21445
|
}
|
|
@@ -21404,7 +21456,7 @@ function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
|
21404
21456
|
}
|
|
21405
21457
|
function getSheetNameGetter(applyChange) {
|
|
21406
21458
|
return (sheetId) => {
|
|
21407
|
-
return sheetId === applyChange.sheetId ? applyChange.sheetName : "";
|
|
21459
|
+
return sheetId === applyChange.sheetId ? applyChange.sheetName.current : "";
|
|
21408
21460
|
};
|
|
21409
21461
|
}
|
|
21410
21462
|
function defaultGetSheetSize(sheetId) {
|
|
@@ -27395,9 +27447,13 @@ class GaugeChart extends AbstractChart {
|
|
|
27395
27447
|
: undefined,
|
|
27396
27448
|
};
|
|
27397
27449
|
}
|
|
27398
|
-
updateRanges(applyChange) {
|
|
27450
|
+
updateRanges(applyChange, sheetId, adaptSheetName) {
|
|
27399
27451
|
const dataRange = adaptChartRange(this.dataRange, applyChange);
|
|
27400
|
-
const adaptFormula = (formula) =>
|
|
27452
|
+
const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
|
|
27453
|
+
applyChange,
|
|
27454
|
+
sheetId,
|
|
27455
|
+
sheetName: adaptSheetName,
|
|
27456
|
+
});
|
|
27401
27457
|
const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
|
|
27402
27458
|
const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
|
|
27403
27459
|
return new GaugeChart(definition, this.sheetId, this.getters);
|
|
@@ -33720,6 +33776,9 @@ class Composer extends owl.Component {
|
|
|
33720
33776
|
this.contentHelper.removeSelection();
|
|
33721
33777
|
}
|
|
33722
33778
|
onMouseup() {
|
|
33779
|
+
if (this.env.model.getters.isReadonly()) {
|
|
33780
|
+
return;
|
|
33781
|
+
}
|
|
33723
33782
|
const selection = this.contentHelper.getCurrentSelection();
|
|
33724
33783
|
if (selection.start !== selection.end) {
|
|
33725
33784
|
this.props.composerStore.hoverToken(undefined);
|
|
@@ -38183,9 +38242,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38183
38242
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
38184
38243
|
continue;
|
|
38185
38244
|
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
|
|
38186
|
-
values.push(rule.formula[0]);
|
|
38245
|
+
values.push(prefixFormula(rule.formula[0]));
|
|
38187
38246
|
if (rule.formula.length === 2) {
|
|
38188
|
-
values.push(rule.formula[1]);
|
|
38247
|
+
values.push(prefixFormula(rule.formula[1]));
|
|
38189
38248
|
}
|
|
38190
38249
|
break;
|
|
38191
38250
|
}
|
|
@@ -38343,6 +38402,11 @@ function convertIcons(xlsxIconSet, index) {
|
|
|
38343
38402
|
? ICON_SETS[iconSet].neutral
|
|
38344
38403
|
: ICON_SETS[iconSet].good;
|
|
38345
38404
|
}
|
|
38405
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
38406
|
+
function prefixFormula(formula) {
|
|
38407
|
+
const tokens = tokenize(formula);
|
|
38408
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
38409
|
+
}
|
|
38346
38410
|
// ---------------------------------------------------------------------------
|
|
38347
38411
|
// Warnings
|
|
38348
38412
|
// ---------------------------------------------------------------------------
|
|
@@ -38625,7 +38689,7 @@ function getColPosition(colIndex, sheetData) {
|
|
|
38625
38689
|
function getRowPosition(rowIndex, sheetData) {
|
|
38626
38690
|
let position = 0;
|
|
38627
38691
|
for (let i = 0; i < rowIndex; i++) {
|
|
38628
|
-
const rowAtIndex = sheetData.rows
|
|
38692
|
+
const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
|
|
38629
38693
|
if (rowAtIndex?.height) {
|
|
38630
38694
|
position += rowAtIndex.height;
|
|
38631
38695
|
}
|
|
@@ -38780,8 +38844,8 @@ function convertExcelTrendline(trend) {
|
|
|
38780
38844
|
}
|
|
38781
38845
|
function convertAnchor(XLSXanchor) {
|
|
38782
38846
|
const offset = {
|
|
38783
|
-
x: convertEMUToDotValue(XLSXanchor.colOffset),
|
|
38784
|
-
y: convertEMUToDotValue(XLSXanchor.rowOffset),
|
|
38847
|
+
x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
|
|
38848
|
+
y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
|
|
38785
38849
|
};
|
|
38786
38850
|
return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
|
|
38787
38851
|
}
|
|
@@ -39164,8 +39228,12 @@ function getSheetDims(sheet) {
|
|
|
39164
39228
|
dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
|
|
39165
39229
|
dims[1] = Math.max(dims[1], row.index);
|
|
39166
39230
|
}
|
|
39167
|
-
|
|
39168
|
-
|
|
39231
|
+
for (const fig of sheet.figures) {
|
|
39232
|
+
dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
|
|
39233
|
+
dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
|
|
39234
|
+
}
|
|
39235
|
+
dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
|
|
39236
|
+
dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
|
|
39169
39237
|
return dims;
|
|
39170
39238
|
}
|
|
39171
39239
|
/**
|
|
@@ -40868,7 +40936,7 @@ function getRelationFile(file, xmls) {
|
|
|
40868
40936
|
return relsFile;
|
|
40869
40937
|
}
|
|
40870
40938
|
|
|
40871
|
-
const EXCEL_IMPORT_VERSION = "18.4.
|
|
40939
|
+
const EXCEL_IMPORT_VERSION = "18.4.2";
|
|
40872
40940
|
class XlsxReader {
|
|
40873
40941
|
warningManager;
|
|
40874
40942
|
xmls;
|
|
@@ -44413,7 +44481,7 @@ const splitToColumns = {
|
|
|
44413
44481
|
const reinsertDynamicPivotMenu = {
|
|
44414
44482
|
id: "reinsert_dynamic_pivot",
|
|
44415
44483
|
name: _t("Re-insert dynamic pivot"),
|
|
44416
|
-
sequence:
|
|
44484
|
+
sequence: 60,
|
|
44417
44485
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
44418
44486
|
children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
|
|
44419
44487
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -44421,7 +44489,7 @@ const reinsertDynamicPivotMenu = {
|
|
|
44421
44489
|
const reinsertStaticPivotMenu = {
|
|
44422
44490
|
id: "reinsert_static_pivot",
|
|
44423
44491
|
name: _t("Re-insert static pivot"),
|
|
44424
|
-
sequence:
|
|
44492
|
+
sequence: 70,
|
|
44425
44493
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
44426
44494
|
children: [REINSERT_STATIC_PIVOT_CHILDREN],
|
|
44427
44495
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -58692,7 +58760,8 @@ class CorePlugin extends BasePlugin {
|
|
|
58692
58760
|
* the type of change that occurred.
|
|
58693
58761
|
*
|
|
58694
58762
|
* @param applyChange a function that, when called, will adapt the range according to the change on the grid
|
|
58695
|
-
* @param sheetId an
|
|
58763
|
+
* @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
|
|
58764
|
+
* @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
|
|
58696
58765
|
*/
|
|
58697
58766
|
adaptRanges(applyChange, sheetId, sheetName) { }
|
|
58698
58767
|
/**
|
|
@@ -59295,9 +59364,7 @@ class CellPlugin extends CorePlugin {
|
|
|
59295
59364
|
for (const cell of Object.values(this.cells[sheet] || {})) {
|
|
59296
59365
|
if (cell.isFormula) {
|
|
59297
59366
|
for (const range of cell.compiledFormula.dependencies) {
|
|
59298
|
-
if (
|
|
59299
|
-
range.sheetId === sheetId ||
|
|
59300
|
-
(sheetName && range.invalidSheetName === sheetName)) {
|
|
59367
|
+
if (range.sheetId === sheetId || range.invalidSheetName === sheetName.old) {
|
|
59301
59368
|
const change = applyChange(range);
|
|
59302
59369
|
if (change.changeType !== "NONE") {
|
|
59303
59370
|
this.history.update("cells", sheet, cell.id, "compiledFormula", "dependencies", cell.compiledFormula.dependencies.indexOf(range), change.range);
|
|
@@ -59913,9 +59980,9 @@ class ChartPlugin extends CorePlugin {
|
|
|
59913
59980
|
charts = {};
|
|
59914
59981
|
createChart = chartFactory(this.getters);
|
|
59915
59982
|
validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
|
|
59916
|
-
adaptRanges(applyChange) {
|
|
59983
|
+
adaptRanges(applyChange, sheetId, adaptSheetName) {
|
|
59917
59984
|
for (const [chartId, chart] of Object.entries(this.charts)) {
|
|
59918
|
-
this.history.update("charts", chartId, chart?.updateRanges(applyChange));
|
|
59985
|
+
this.history.update("charts", chartId, chart?.updateRanges(applyChange, sheetId, adaptSheetName));
|
|
59919
59986
|
}
|
|
59920
59987
|
}
|
|
59921
59988
|
// ---------------------------------------------------------------------------
|
|
@@ -60178,7 +60245,7 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
60178
60245
|
}
|
|
60179
60246
|
}
|
|
60180
60247
|
}
|
|
60181
|
-
adaptRanges(applyChange, sheetId
|
|
60248
|
+
adaptRanges(applyChange, sheetId) {
|
|
60182
60249
|
const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
|
|
60183
60250
|
for (const sheetId of sheetIds) {
|
|
60184
60251
|
this.adaptCFRanges(sheetId, applyChange);
|
|
@@ -60560,11 +60627,8 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
60560
60627
|
"getValidationRuleForCell",
|
|
60561
60628
|
];
|
|
60562
60629
|
rules = {};
|
|
60563
|
-
adaptRanges(applyChange, sheetId
|
|
60564
|
-
|
|
60565
|
-
for (const sheetId of sheetIds) {
|
|
60566
|
-
this.adaptDVRanges(sheetId, applyChange);
|
|
60567
|
-
}
|
|
60630
|
+
adaptRanges(applyChange, sheetId) {
|
|
60631
|
+
this.adaptDVRanges(sheetId, applyChange);
|
|
60568
60632
|
this.adaptDVFormulas(applyChange);
|
|
60569
60633
|
}
|
|
60570
60634
|
adaptDVFormulas(applyChange) {
|
|
@@ -60854,9 +60918,6 @@ class FigurePlugin extends CorePlugin {
|
|
|
60854
60918
|
// Command Handling
|
|
60855
60919
|
// ---------------------------------------------------------------------------
|
|
60856
60920
|
adaptRanges(applyChange, sheetId) {
|
|
60857
|
-
if (!sheetId) {
|
|
60858
|
-
return;
|
|
60859
|
-
}
|
|
60860
60921
|
for (const figure of this.getFigures(sheetId)) {
|
|
60861
60922
|
const change = applyChange(this.getters.getRangeFromZone(sheetId, {
|
|
60862
60923
|
left: figure.col,
|
|
@@ -61665,11 +61726,8 @@ class MergePlugin extends CorePlugin {
|
|
|
61665
61726
|
break;
|
|
61666
61727
|
}
|
|
61667
61728
|
}
|
|
61668
|
-
adaptRanges(applyChange, sheetId
|
|
61669
|
-
|
|
61670
|
-
for (const sheetId of sheetIds) {
|
|
61671
|
-
this.applyRangeChangeOnSheet(sheetId, applyChange);
|
|
61672
|
-
}
|
|
61729
|
+
adaptRanges(applyChange, sheetId) {
|
|
61730
|
+
this.applyRangeChangeOnSheet(sheetId, applyChange);
|
|
61673
61731
|
}
|
|
61674
61732
|
// ---------------------------------------------------------------------------
|
|
61675
61733
|
// Getters
|
|
@@ -63174,12 +63232,9 @@ class TablePlugin extends CorePlugin {
|
|
|
63174
63232
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
63175
63233
|
tables = {};
|
|
63176
63234
|
nextTableId = 1;
|
|
63177
|
-
adaptRanges(applyChange, sheetId
|
|
63178
|
-
const
|
|
63179
|
-
|
|
63180
|
-
for (const table of this.getCoreTables(sheetId)) {
|
|
63181
|
-
this.applyRangeChangeOnTable(sheetId, table, applyChange);
|
|
63182
|
-
}
|
|
63235
|
+
adaptRanges(applyChange, sheetId) {
|
|
63236
|
+
for (const table of this.getCoreTables(sheetId)) {
|
|
63237
|
+
this.applyRangeChangeOnTable(sheetId, table, applyChange);
|
|
63183
63238
|
}
|
|
63184
63239
|
}
|
|
63185
63240
|
allowDispatch(cmd) {
|
|
@@ -64142,7 +64197,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64142
64197
|
}
|
|
64143
64198
|
}
|
|
64144
64199
|
}
|
|
64145
|
-
adaptRanges(applyChange
|
|
64200
|
+
adaptRanges(applyChange) {
|
|
64146
64201
|
for (const sheetId in this.compiledMeasureFormulas) {
|
|
64147
64202
|
for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
|
|
64148
64203
|
const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
|
|
@@ -68543,7 +68598,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68543
68598
|
if (!result) {
|
|
68544
68599
|
return EMPTY_PIVOT_CELL;
|
|
68545
68600
|
}
|
|
68546
|
-
|
|
68601
|
+
let { functionName, args } = result;
|
|
68547
68602
|
const formulaId = args[0];
|
|
68548
68603
|
if (!formulaId) {
|
|
68549
68604
|
return EMPTY_PIVOT_CELL;
|
|
@@ -68578,6 +68633,9 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68578
68633
|
return pivotCells[pivotCol][pivotRow];
|
|
68579
68634
|
}
|
|
68580
68635
|
try {
|
|
68636
|
+
const offsetRow = position.row - mainPosition.row;
|
|
68637
|
+
const offsetCol = position.col - mainPosition.col;
|
|
68638
|
+
args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
|
|
68581
68639
|
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
68582
68640
|
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
68583
68641
|
return {
|
|
@@ -70186,7 +70244,8 @@ function transformAll(toTransform, executed) {
|
|
|
70186
70244
|
// If the executed command is not in the registry, we skip it
|
|
70187
70245
|
// because we know there won't be any transformation impacting the
|
|
70188
70246
|
// commands to transform.
|
|
70189
|
-
if (possibleTransformations.has(executedCommand.type)
|
|
70247
|
+
if (possibleTransformations.has(executedCommand.type) ||
|
|
70248
|
+
rangeAdapterRegistry.contains(executedCommand.type)) {
|
|
70190
70249
|
transformedCommands = transformedCommands.reduce((acc, cmd) => {
|
|
70191
70250
|
const transformed = transform(cmd, executedCommand);
|
|
70192
70251
|
if (transformed) {
|
|
@@ -76178,7 +76237,8 @@ const inverseCommandRegistry = new Registry()
|
|
|
76178
76237
|
.add("HIDE_COLUMNS_ROWS", inverseHideColumnsRows)
|
|
76179
76238
|
.add("UNHIDE_COLUMNS_ROWS", inverseUnhideColumnsRows)
|
|
76180
76239
|
.add("CREATE_TABLE_STYLE", inverseCreateTableStyle)
|
|
76181
|
-
.add("ADD_PIVOT", inverseAddPivot)
|
|
76240
|
+
.add("ADD_PIVOT", inverseAddPivot)
|
|
76241
|
+
.add("RENAME_SHEET", inverseRenameSheet);
|
|
76182
76242
|
for (const cmd of coreTypes.values()) {
|
|
76183
76243
|
if (!inverseCommandRegistry.contains(cmd)) {
|
|
76184
76244
|
inverseCommandRegistry.add(cmd, identity);
|
|
@@ -76276,6 +76336,16 @@ function inverseUnhideColumnsRows(cmd) {
|
|
|
76276
76336
|
function inverseCreateTableStyle(cmd) {
|
|
76277
76337
|
return [{ type: "REMOVE_TABLE_STYLE", tableStyleId: cmd.tableStyleId }];
|
|
76278
76338
|
}
|
|
76339
|
+
function inverseRenameSheet(cmd) {
|
|
76340
|
+
return [
|
|
76341
|
+
{
|
|
76342
|
+
type: "RENAME_SHEET",
|
|
76343
|
+
sheetId: cmd.sheetId,
|
|
76344
|
+
oldName: cmd.newName,
|
|
76345
|
+
newName: cmd.oldName,
|
|
76346
|
+
},
|
|
76347
|
+
];
|
|
76348
|
+
}
|
|
76279
76349
|
|
|
76280
76350
|
const numberFormatMenuRegistry = new Registry();
|
|
76281
76351
|
numberFormatMenuRegistry
|
|
@@ -76874,8 +76944,9 @@ topbarMenuRegistry
|
|
|
76874
76944
|
sequence: 40,
|
|
76875
76945
|
separator: true,
|
|
76876
76946
|
})
|
|
76877
|
-
.addChild("
|
|
76947
|
+
.addChild("pivot_data_sources", ["data"], (env) => {
|
|
76878
76948
|
const sequence = 50;
|
|
76949
|
+
const numberOfPivots = env.model.getters.getPivotIds().length;
|
|
76879
76950
|
return env.model.getters.getPivotIds().map((pivotId, index) => {
|
|
76880
76951
|
const highlightProvider = {
|
|
76881
76952
|
get highlights() {
|
|
@@ -76885,7 +76956,7 @@ topbarMenuRegistry
|
|
|
76885
76956
|
return {
|
|
76886
76957
|
id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
76887
76958
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
76888
|
-
sequence: sequence + index,
|
|
76959
|
+
sequence: sequence + index / numberOfPivots,
|
|
76889
76960
|
isReadonlyAllowed: true,
|
|
76890
76961
|
execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
|
|
76891
76962
|
isEnabled: (env) => !env.isSmall,
|
|
@@ -83005,7 +83076,7 @@ function figureCoordinates(headers, anchor, offset) {
|
|
|
83005
83076
|
for (const [headerIndex, header] of headers.slice(anchor).entries()) {
|
|
83006
83077
|
if (currentPosition <= offset && offset < currentPosition + header.size) {
|
|
83007
83078
|
return {
|
|
83008
|
-
index: headerIndex,
|
|
83079
|
+
index: anchor + headerIndex,
|
|
83009
83080
|
offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
|
|
83010
83081
|
};
|
|
83011
83082
|
}
|
|
@@ -84001,7 +84072,7 @@ class Model extends EventBus {
|
|
|
84001
84072
|
handlers = [];
|
|
84002
84073
|
uiHandlers = [];
|
|
84003
84074
|
coreHandlers = [];
|
|
84004
|
-
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport =
|
|
84075
|
+
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
|
|
84005
84076
|
const start = performance.now();
|
|
84006
84077
|
console.debug("##### Model creation #####");
|
|
84007
84078
|
super();
|
|
@@ -84751,6 +84822,6 @@ exports.tokenColors = tokenColors;
|
|
|
84751
84822
|
exports.tokenize = tokenize;
|
|
84752
84823
|
|
|
84753
84824
|
|
|
84754
|
-
__info__.version = "18.4.
|
|
84755
|
-
__info__.date = "2025-
|
|
84756
|
-
__info__.hash = "
|
|
84825
|
+
__info__.version = "18.4.9";
|
|
84826
|
+
__info__.date = "2025-09-05T07:38:32.126Z";
|
|
84827
|
+
__info__.hash = "a261873";
|