@odoo/o-spreadsheet 18.3.17 → 18.3.19
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 +156 -111
- package/dist/o-spreadsheet.d.ts +67 -62
- package/dist/o-spreadsheet.esm.js +156 -111
- package/dist/o-spreadsheet.iife.js +156 -111
- package/dist/o-spreadsheet.iife.min.js +381 -381
- package/dist/o_spreadsheet.xml +17 -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.3.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.3.19
|
|
6
|
+
* @date 2025-09-05T07:38:30.661Z
|
|
7
|
+
* @hash 77fd307
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3499,6 +3499,7 @@ const invalidateBordersCommands = new Set([
|
|
|
3499
3499
|
"AUTOFILL_CELL",
|
|
3500
3500
|
"SET_BORDER",
|
|
3501
3501
|
"SET_ZONE_BORDERS",
|
|
3502
|
+
"SET_BORDERS_ON_TARGET",
|
|
3502
3503
|
]);
|
|
3503
3504
|
const readonlyAllowedCommands = new Set([
|
|
3504
3505
|
"START",
|
|
@@ -6444,40 +6445,44 @@ function orderRange(range) {
|
|
|
6444
6445
|
};
|
|
6445
6446
|
}
|
|
6446
6447
|
function getRangeAdapter(cmd) {
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
applyChange: getApplyRangeChangeAddColRow(cmd),
|
|
6457
|
-
sheetId: cmd.sheetId,
|
|
6458
|
-
sheetName: cmd.sheetName,
|
|
6459
|
-
};
|
|
6460
|
-
case "DELETE_SHEET":
|
|
6461
|
-
return {
|
|
6462
|
-
applyChange: getApplyRangeChangeDeleteSheet(cmd),
|
|
6463
|
-
sheetId: cmd.sheetId,
|
|
6464
|
-
sheetName: cmd.sheetName,
|
|
6465
|
-
};
|
|
6466
|
-
case "RENAME_SHEET":
|
|
6467
|
-
return {
|
|
6468
|
-
applyChange: getApplyRangeChangeRenameSheet(cmd),
|
|
6469
|
-
sheetId: cmd.sheetId,
|
|
6470
|
-
sheetName: cmd.oldName,
|
|
6471
|
-
};
|
|
6472
|
-
case "MOVE_RANGES":
|
|
6473
|
-
return {
|
|
6474
|
-
applyChange: getApplyRangeChangeMoveRange(cmd),
|
|
6475
|
-
sheetId: cmd.sheetId,
|
|
6476
|
-
sheetName: cmd.sheetName,
|
|
6477
|
-
};
|
|
6448
|
+
return rangeAdapterRegistry.get(cmd.type)?.(cmd);
|
|
6449
|
+
}
|
|
6450
|
+
class RangeAdapterRegistry extends Registry {
|
|
6451
|
+
add(cmdType, fn) {
|
|
6452
|
+
super.add(cmdType, fn);
|
|
6453
|
+
return this;
|
|
6454
|
+
}
|
|
6455
|
+
get(cmdType) {
|
|
6456
|
+
return this.content[cmdType];
|
|
6478
6457
|
}
|
|
6479
|
-
return undefined;
|
|
6480
6458
|
}
|
|
6459
|
+
const rangeAdapterRegistry = new RangeAdapterRegistry();
|
|
6460
|
+
rangeAdapterRegistry
|
|
6461
|
+
.add("REMOVE_COLUMNS_ROWS", (cmd) => ({
|
|
6462
|
+
applyChange: getApplyRangeChangeRemoveColRow(cmd),
|
|
6463
|
+
sheetId: cmd.sheetId,
|
|
6464
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6465
|
+
}))
|
|
6466
|
+
.add("ADD_COLUMNS_ROWS", (cmd) => ({
|
|
6467
|
+
applyChange: getApplyRangeChangeAddColRow(cmd),
|
|
6468
|
+
sheetId: cmd.sheetId,
|
|
6469
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6470
|
+
}))
|
|
6471
|
+
.add("DELETE_SHEET", (cmd) => ({
|
|
6472
|
+
applyChange: getApplyRangeChangeDeleteSheet(cmd),
|
|
6473
|
+
sheetId: cmd.sheetId,
|
|
6474
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6475
|
+
}))
|
|
6476
|
+
.add("RENAME_SHEET", (cmd) => ({
|
|
6477
|
+
applyChange: getApplyRangeChangeRenameSheet(cmd),
|
|
6478
|
+
sheetId: cmd.sheetId,
|
|
6479
|
+
sheetName: { old: cmd.oldName, current: cmd.newName },
|
|
6480
|
+
}))
|
|
6481
|
+
.add("MOVE_RANGES", (cmd) => ({
|
|
6482
|
+
applyChange: getApplyRangeChangeMoveRange(cmd),
|
|
6483
|
+
sheetId: cmd.sheetId,
|
|
6484
|
+
sheetName: { old: cmd.sheetName, current: cmd.sheetName },
|
|
6485
|
+
}));
|
|
6481
6486
|
function getApplyRangeChangeRemoveColRow(cmd) {
|
|
6482
6487
|
let start = cmd.dimension === "COL" ? "left" : "top";
|
|
6483
6488
|
let end = cmd.dimension === "COL" ? "right" : "bottom";
|
|
@@ -7105,14 +7110,11 @@ function getPasteZones(target, content) {
|
|
|
7105
7110
|
const width = content[0].length, height = content.length;
|
|
7106
7111
|
return target.map((t) => splitZoneForPaste(t, width, height)).flat();
|
|
7107
7112
|
}
|
|
7108
|
-
function parseOSClipboardContent(content
|
|
7113
|
+
function parseOSClipboardContent(content) {
|
|
7109
7114
|
let spreadsheetContent = undefined;
|
|
7110
7115
|
if (content[ClipboardMIMEType.Html]) {
|
|
7111
7116
|
const htmlDocument = new DOMParser().parseFromString(content[ClipboardMIMEType.Html], "text/html");
|
|
7112
|
-
|
|
7113
|
-
.querySelector("div")
|
|
7114
|
-
?.getAttribute("data-osheet-clipboard");
|
|
7115
|
-
spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
|
|
7117
|
+
spreadsheetContent = getOSheetDataFromHTML(htmlDocument);
|
|
7116
7118
|
}
|
|
7117
7119
|
const textContent = content[ClipboardMIMEType.PlainText] || "";
|
|
7118
7120
|
let imageBlob = undefined;
|
|
@@ -7131,6 +7133,17 @@ function parseOSClipboardContent(content, clipboardId) {
|
|
|
7131
7133
|
};
|
|
7132
7134
|
return osClipboardContent;
|
|
7133
7135
|
}
|
|
7136
|
+
function getOSheetDataFromHTML(htmlDocument) {
|
|
7137
|
+
const attributes = [...htmlDocument.documentElement.attributes];
|
|
7138
|
+
// Check if it's a Microsoft Office clipboard data (it will have some namespaces defined in the root element)
|
|
7139
|
+
if (attributes.some((attr) => attr.value.includes("microsoft"))) {
|
|
7140
|
+
return undefined;
|
|
7141
|
+
}
|
|
7142
|
+
const oSheetClipboardData = htmlDocument
|
|
7143
|
+
.querySelector("div")
|
|
7144
|
+
?.getAttribute("data-osheet-clipboard");
|
|
7145
|
+
return oSheetClipboardData && JSON.parse(oSheetClipboardData);
|
|
7146
|
+
}
|
|
7134
7147
|
/**
|
|
7135
7148
|
* Applies each clipboard handler to paste its corresponding data into the target.
|
|
7136
7149
|
*/
|
|
@@ -7820,8 +7833,11 @@ function invertMatrix(M) {
|
|
|
7820
7833
|
// (a) Swap 2 rows. This multiply the determinant by -1.
|
|
7821
7834
|
// (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
|
|
7822
7835
|
// (c) Add to a row a multiple of another row. This does not change the determinant.
|
|
7836
|
+
if (M.length < 1 || M[0].length < 1) {
|
|
7837
|
+
throw new Error("invertMatrix: an empty matrix cannot be inverted.");
|
|
7838
|
+
}
|
|
7823
7839
|
if (M.length !== M[0].length) {
|
|
7824
|
-
throw new
|
|
7840
|
+
throw new Error("invertMatrix: only square matrices are invertible");
|
|
7825
7841
|
}
|
|
7826
7842
|
let determinant = 1;
|
|
7827
7843
|
const dim = M.length;
|
|
@@ -7890,8 +7906,11 @@ function swapMatrixRows(matrix, row1, row2) {
|
|
|
7890
7906
|
* Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
|
|
7891
7907
|
*/
|
|
7892
7908
|
function multiplyMatrices(matrix1, matrix2) {
|
|
7909
|
+
if (matrix1.length < 1 || matrix2.length < 1) {
|
|
7910
|
+
throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
|
|
7911
|
+
}
|
|
7893
7912
|
if (matrix1.length !== matrix2[0].length) {
|
|
7894
|
-
throw new
|
|
7913
|
+
throw new Error("multiplyMatrices: incompatible matrices size.");
|
|
7895
7914
|
}
|
|
7896
7915
|
const rowsM1 = matrix1[0].length;
|
|
7897
7916
|
const colsM2 = matrix2.length;
|
|
@@ -7917,7 +7936,7 @@ function toScalar(arg) {
|
|
|
7917
7936
|
return arg;
|
|
7918
7937
|
}
|
|
7919
7938
|
if (!isSingleElementMatrix(arg)) {
|
|
7920
|
-
throw new
|
|
7939
|
+
throw new Error("The value should be a scalar or a 1x1 matrix");
|
|
7921
7940
|
}
|
|
7922
7941
|
return arg[0][0];
|
|
7923
7942
|
}
|
|
@@ -8154,6 +8173,16 @@ function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZ
|
|
|
8154
8173
|
}
|
|
8155
8174
|
return values;
|
|
8156
8175
|
}
|
|
8176
|
+
function assertNonEmptyMatrix(matrix, argName) {
|
|
8177
|
+
assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
|
|
8178
|
+
argName,
|
|
8179
|
+
}));
|
|
8180
|
+
}
|
|
8181
|
+
function assertNonEmpty(...data) {
|
|
8182
|
+
if (data.length === 0 || data.some((arg) => arg.length === 0)) {
|
|
8183
|
+
throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
|
|
8184
|
+
}
|
|
8185
|
+
}
|
|
8157
8186
|
|
|
8158
8187
|
const PREVIOUS_VALUE = "(previous)";
|
|
8159
8188
|
const NEXT_VALUE = "(next)";
|
|
@@ -10977,6 +11006,7 @@ const MMULT = {
|
|
|
10977
11006
|
compute: function (matrix1, matrix2) {
|
|
10978
11007
|
const _matrix1 = toNumberMatrix(matrix1, "matrix1");
|
|
10979
11008
|
const _matrix2 = toNumberMatrix(matrix2, "matrix2");
|
|
11009
|
+
assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
|
|
10980
11010
|
assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
|
|
10981
11011
|
number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
|
|
10982
11012
|
return multiplyMatrices(_matrix1, _matrix2);
|
|
@@ -12772,6 +12802,7 @@ const FORECAST = {
|
|
|
12772
12802
|
],
|
|
12773
12803
|
compute: function (x, dataY, dataX) {
|
|
12774
12804
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
12805
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
12775
12806
|
return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
|
|
12776
12807
|
},
|
|
12777
12808
|
isExported: true,
|
|
@@ -12788,6 +12819,7 @@ const GROWTH = {
|
|
|
12788
12819
|
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.")),
|
|
12789
12820
|
],
|
|
12790
12821
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
12822
|
+
assertNonEmptyMatrix(knownDataY, "known_data_y");
|
|
12791
12823
|
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)));
|
|
12792
12824
|
},
|
|
12793
12825
|
};
|
|
@@ -12802,6 +12834,7 @@ const INTERCEPT = {
|
|
|
12802
12834
|
],
|
|
12803
12835
|
compute: function (dataY, dataX) {
|
|
12804
12836
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
12837
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
12805
12838
|
const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
12806
12839
|
return intercept;
|
|
12807
12840
|
},
|
|
@@ -12851,6 +12884,7 @@ const LINEST = {
|
|
|
12851
12884
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
12852
12885
|
],
|
|
12853
12886
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
12887
|
+
assertNonEmptyMatrix(dataY, "data_y");
|
|
12854
12888
|
return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
|
|
12855
12889
|
},
|
|
12856
12890
|
isExported: true,
|
|
@@ -12867,6 +12901,7 @@ const LOGEST = {
|
|
|
12867
12901
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
12868
12902
|
],
|
|
12869
12903
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
12904
|
+
assertNonEmptyMatrix(dataY, "data_y");
|
|
12870
12905
|
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
|
|
12871
12906
|
for (let i = 0; i < coeffs.length; i++) {
|
|
12872
12907
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
@@ -12888,9 +12923,7 @@ const MATTHEWS = {
|
|
|
12888
12923
|
const flatX = dataX.flat();
|
|
12889
12924
|
const flatY = dataY.flat();
|
|
12890
12925
|
assertSameNumberOfElements(flatX, flatY);
|
|
12891
|
-
|
|
12892
|
-
return new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
|
|
12893
|
-
}
|
|
12926
|
+
assertNonEmpty(flatX, flatY);
|
|
12894
12927
|
const n = flatX.length;
|
|
12895
12928
|
let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
|
|
12896
12929
|
for (let i = 0; i < n; ++i) {
|
|
@@ -13054,12 +13087,7 @@ const MINIFS = {
|
|
|
13054
13087
|
// -----------------------------------------------------------------------------
|
|
13055
13088
|
function pearson(dataY, dataX) {
|
|
13056
13089
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13057
|
-
|
|
13058
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
|
|
13059
|
-
}
|
|
13060
|
-
if (flatDataX.length < 2) {
|
|
13061
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] needs at least two values for both parameters."));
|
|
13062
|
-
}
|
|
13090
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13063
13091
|
const n = flatDataX.length;
|
|
13064
13092
|
let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
|
|
13065
13093
|
for (let i = 0; i < n; i++) {
|
|
@@ -13148,6 +13176,7 @@ const POLYFIT_COEFFS = {
|
|
|
13148
13176
|
],
|
|
13149
13177
|
compute: function (dataY, dataX, order, intercept = { value: true }) {
|
|
13150
13178
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13179
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13151
13180
|
return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
|
|
13152
13181
|
},
|
|
13153
13182
|
isExported: false,
|
|
@@ -13167,6 +13196,7 @@ const POLYFIT_FORECAST = {
|
|
|
13167
13196
|
compute: function (x, dataY, dataX, order, intercept = { value: true }) {
|
|
13168
13197
|
const _order = toNumber(order, this.locale);
|
|
13169
13198
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13199
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13170
13200
|
const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
|
|
13171
13201
|
return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
|
|
13172
13202
|
},
|
|
@@ -13283,6 +13313,7 @@ const SLOPE = {
|
|
|
13283
13313
|
],
|
|
13284
13314
|
compute: function (dataY, dataX) {
|
|
13285
13315
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13316
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13286
13317
|
const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13287
13318
|
return slope;
|
|
13288
13319
|
},
|
|
@@ -13331,6 +13362,7 @@ const SPEARMAN = {
|
|
|
13331
13362
|
],
|
|
13332
13363
|
compute: function (dataX, dataY) {
|
|
13333
13364
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13365
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13334
13366
|
const n = flatDataX.length;
|
|
13335
13367
|
const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
|
|
13336
13368
|
order.sort((a, b) => a[0] - b[0]);
|
|
@@ -13441,6 +13473,7 @@ const STEYX = {
|
|
|
13441
13473
|
],
|
|
13442
13474
|
compute: function (dataY, dataX) {
|
|
13443
13475
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13476
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13444
13477
|
const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
|
|
13445
13478
|
return data[1][2];
|
|
13446
13479
|
},
|
|
@@ -13458,6 +13491,7 @@ const TREND = {
|
|
|
13458
13491
|
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.")),
|
|
13459
13492
|
],
|
|
13460
13493
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13494
|
+
assertNonEmptyMatrix(knownDataY, "known_data_y");
|
|
13461
13495
|
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));
|
|
13462
13496
|
},
|
|
13463
13497
|
};
|
|
@@ -20594,7 +20628,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
|
|
|
20594
20628
|
function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
20595
20629
|
const sheetName = splitReference(sheetXC).sheetName;
|
|
20596
20630
|
if (sheetName
|
|
20597
|
-
? !isSheetNameEqual(sheetName, applyChange.sheetName)
|
|
20631
|
+
? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
|
|
20598
20632
|
: defaultSheetId !== applyChange.sheetId) {
|
|
20599
20633
|
return sheetXC;
|
|
20600
20634
|
}
|
|
@@ -20611,7 +20645,7 @@ function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
|
20611
20645
|
}
|
|
20612
20646
|
function getSheetNameGetter(applyChange) {
|
|
20613
20647
|
return (sheetId) => {
|
|
20614
|
-
return sheetId === applyChange.sheetId ? applyChange.sheetName : "";
|
|
20648
|
+
return sheetId === applyChange.sheetId ? applyChange.sheetName.current : "";
|
|
20615
20649
|
};
|
|
20616
20650
|
}
|
|
20617
20651
|
function defaultGetSheetSize(sheetId) {
|
|
@@ -27202,10 +27236,6 @@ class ComboChart extends AbstractChart {
|
|
|
27202
27236
|
};
|
|
27203
27237
|
}
|
|
27204
27238
|
getDefinitionForExcel() {
|
|
27205
|
-
// Excel does not support aggregating labels
|
|
27206
|
-
if (this.aggregated) {
|
|
27207
|
-
return undefined;
|
|
27208
|
-
}
|
|
27209
27239
|
const dataSets = this.dataSets
|
|
27210
27240
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27211
27241
|
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
@@ -27578,9 +27608,13 @@ class GaugeChart extends AbstractChart {
|
|
|
27578
27608
|
: undefined,
|
|
27579
27609
|
};
|
|
27580
27610
|
}
|
|
27581
|
-
updateRanges(applyChange) {
|
|
27611
|
+
updateRanges(applyChange, sheetId, adaptSheetName) {
|
|
27582
27612
|
const dataRange = adaptChartRange(this.dataRange, applyChange);
|
|
27583
|
-
const adaptFormula = (formula) =>
|
|
27613
|
+
const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
|
|
27614
|
+
applyChange,
|
|
27615
|
+
sheetId,
|
|
27616
|
+
sheetName: adaptSheetName,
|
|
27617
|
+
});
|
|
27584
27618
|
const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
|
|
27585
27619
|
const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
|
|
27586
27620
|
return new GaugeChart(definition, this.sheetId, this.getters);
|
|
@@ -28503,10 +28537,6 @@ class ScatterChart extends AbstractChart {
|
|
|
28503
28537
|
return new ScatterChart(definition, this.sheetId, this.getters);
|
|
28504
28538
|
}
|
|
28505
28539
|
getDefinitionForExcel() {
|
|
28506
|
-
// Excel does not support aggregating labels
|
|
28507
|
-
if (this.aggregated) {
|
|
28508
|
-
return undefined;
|
|
28509
|
-
}
|
|
28510
28540
|
const dataSets = this.dataSets
|
|
28511
28541
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
28512
28542
|
.filter((ds) => ds.range !== "");
|
|
@@ -30211,7 +30241,8 @@ const inverseCommandRegistry = new Registry()
|
|
|
30211
30241
|
.add("HIDE_COLUMNS_ROWS", inverseHideColumnsRows)
|
|
30212
30242
|
.add("UNHIDE_COLUMNS_ROWS", inverseUnhideColumnsRows)
|
|
30213
30243
|
.add("CREATE_TABLE_STYLE", inverseCreateTableStyle)
|
|
30214
|
-
.add("ADD_PIVOT", inverseAddPivot)
|
|
30244
|
+
.add("ADD_PIVOT", inverseAddPivot)
|
|
30245
|
+
.add("RENAME_SHEET", inverseRenameSheet);
|
|
30215
30246
|
for (const cmd of coreTypes.values()) {
|
|
30216
30247
|
if (!inverseCommandRegistry.contains(cmd)) {
|
|
30217
30248
|
inverseCommandRegistry.add(cmd, identity);
|
|
@@ -30309,6 +30340,16 @@ function inverseUnhideColumnsRows(cmd) {
|
|
|
30309
30340
|
function inverseCreateTableStyle(cmd) {
|
|
30310
30341
|
return [{ type: "REMOVE_TABLE_STYLE", tableStyleId: cmd.tableStyleId }];
|
|
30311
30342
|
}
|
|
30343
|
+
function inverseRenameSheet(cmd) {
|
|
30344
|
+
return [
|
|
30345
|
+
{
|
|
30346
|
+
type: "RENAME_SHEET",
|
|
30347
|
+
sheetId: cmd.sheetId,
|
|
30348
|
+
oldName: cmd.newName,
|
|
30349
|
+
newName: cmd.oldName,
|
|
30350
|
+
},
|
|
30351
|
+
];
|
|
30352
|
+
}
|
|
30312
30353
|
|
|
30313
30354
|
/**
|
|
30314
30355
|
* The class Registry is extended in order to add the function addChild
|
|
@@ -31558,9 +31599,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
31558
31599
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
31559
31600
|
continue;
|
|
31560
31601
|
operator = convertCFCellIsOperator(rule.operator);
|
|
31561
|
-
values.push(rule.formula[0]);
|
|
31602
|
+
values.push(prefixFormula(rule.formula[0]));
|
|
31562
31603
|
if (rule.formula.length === 2) {
|
|
31563
|
-
values.push(rule.formula[1]);
|
|
31604
|
+
values.push(prefixFormula(rule.formula[1]));
|
|
31564
31605
|
}
|
|
31565
31606
|
break;
|
|
31566
31607
|
}
|
|
@@ -31718,6 +31759,11 @@ function convertIcons(xlsxIconSet, index) {
|
|
|
31718
31759
|
? ICON_SETS[iconSet].neutral
|
|
31719
31760
|
: ICON_SETS[iconSet].good;
|
|
31720
31761
|
}
|
|
31762
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
31763
|
+
function prefixFormula(formula) {
|
|
31764
|
+
const tokens = tokenize(formula);
|
|
31765
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
31766
|
+
}
|
|
31721
31767
|
// ---------------------------------------------------------------------------
|
|
31722
31768
|
// Warnings
|
|
31723
31769
|
// ---------------------------------------------------------------------------
|
|
@@ -31980,7 +32026,7 @@ function getColPosition(colIndex, sheetData) {
|
|
|
31980
32026
|
function getRowPosition(rowIndex, sheetData) {
|
|
31981
32027
|
let position = 0;
|
|
31982
32028
|
for (let i = 0; i < rowIndex; i++) {
|
|
31983
|
-
const rowAtIndex = sheetData.rows
|
|
32029
|
+
const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
|
|
31984
32030
|
if (rowAtIndex?.height) {
|
|
31985
32031
|
position += rowAtIndex.height;
|
|
31986
32032
|
}
|
|
@@ -32120,8 +32166,8 @@ function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
|
|
|
32120
32166
|
}
|
|
32121
32167
|
function convertAnchor(XLSXanchor) {
|
|
32122
32168
|
const offset = {
|
|
32123
|
-
x: convertEMUToDotValue(XLSXanchor.colOffset),
|
|
32124
|
-
y: convertEMUToDotValue(XLSXanchor.rowOffset),
|
|
32169
|
+
x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
|
|
32170
|
+
y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
|
|
32125
32171
|
};
|
|
32126
32172
|
return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
|
|
32127
32173
|
}
|
|
@@ -32504,8 +32550,12 @@ function getSheetDims(sheet) {
|
|
|
32504
32550
|
dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
|
|
32505
32551
|
dims[1] = Math.max(dims[1], row.index);
|
|
32506
32552
|
}
|
|
32507
|
-
|
|
32508
|
-
|
|
32553
|
+
for (const fig of sheet.figures) {
|
|
32554
|
+
dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
|
|
32555
|
+
dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
|
|
32556
|
+
}
|
|
32557
|
+
dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
|
|
32558
|
+
dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
|
|
32509
32559
|
return dims;
|
|
32510
32560
|
}
|
|
32511
32561
|
/**
|
|
@@ -34510,7 +34560,7 @@ function getRelationFile(file, xmls) {
|
|
|
34510
34560
|
return relsFile;
|
|
34511
34561
|
}
|
|
34512
34562
|
|
|
34513
|
-
const EXCEL_IMPORT_VERSION = "18.3";
|
|
34563
|
+
const EXCEL_IMPORT_VERSION = "18.3.1";
|
|
34514
34564
|
class XlsxReader {
|
|
34515
34565
|
warningManager;
|
|
34516
34566
|
xmls;
|
|
@@ -38514,7 +38564,7 @@ const splitToColumns = {
|
|
|
38514
38564
|
const reinsertDynamicPivotMenu = {
|
|
38515
38565
|
id: "reinsert_dynamic_pivot",
|
|
38516
38566
|
name: _t("Re-insert dynamic pivot"),
|
|
38517
|
-
sequence:
|
|
38567
|
+
sequence: 60,
|
|
38518
38568
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
38519
38569
|
children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
|
|
38520
38570
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -38522,7 +38572,7 @@ const reinsertDynamicPivotMenu = {
|
|
|
38522
38572
|
const reinsertStaticPivotMenu = {
|
|
38523
38573
|
id: "reinsert_static_pivot",
|
|
38524
38574
|
name: _t("Re-insert static pivot"),
|
|
38525
|
-
sequence:
|
|
38575
|
+
sequence: 70,
|
|
38526
38576
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
38527
38577
|
children: [REINSERT_STATIC_PIVOT_CHILDREN],
|
|
38528
38578
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -40191,8 +40241,9 @@ topbarMenuRegistry
|
|
|
40191
40241
|
sequence: 40,
|
|
40192
40242
|
separator: true,
|
|
40193
40243
|
})
|
|
40194
|
-
.addChild("
|
|
40244
|
+
.addChild("pivot_data_sources", ["data"], (env) => {
|
|
40195
40245
|
const sequence = 50;
|
|
40246
|
+
const numberOfPivots = env.model.getters.getPivotIds().length;
|
|
40196
40247
|
return env.model.getters.getPivotIds().map((pivotId, index) => {
|
|
40197
40248
|
const highlightProvider = {
|
|
40198
40249
|
get highlights() {
|
|
@@ -40202,7 +40253,7 @@ topbarMenuRegistry
|
|
|
40202
40253
|
return {
|
|
40203
40254
|
id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
40204
40255
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
40205
|
-
sequence: sequence + index,
|
|
40256
|
+
sequence: sequence + index / numberOfPivots,
|
|
40206
40257
|
isReadonlyAllowed: true,
|
|
40207
40258
|
execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
|
|
40208
40259
|
onStartHover: (env) => env.getStore(HighlightStore).register(highlightProvider),
|
|
@@ -43760,6 +43811,9 @@ class Composer extends owl.Component {
|
|
|
43760
43811
|
this.contentHelper.removeSelection();
|
|
43761
43812
|
}
|
|
43762
43813
|
onMouseup() {
|
|
43814
|
+
if (this.env.model.getters.isReadonly()) {
|
|
43815
|
+
return;
|
|
43816
|
+
}
|
|
43763
43817
|
const selection = this.contentHelper.getCurrentSelection();
|
|
43764
43818
|
if (selection.start !== selection.end) {
|
|
43765
43819
|
this.props.composerStore.hoverToken(undefined);
|
|
@@ -57197,7 +57251,8 @@ class CorePlugin extends BasePlugin {
|
|
|
57197
57251
|
* the type of change that occurred.
|
|
57198
57252
|
*
|
|
57199
57253
|
* @param applyChange a function that, when called, will adapt the range according to the change on the grid
|
|
57200
|
-
* @param sheetId an
|
|
57254
|
+
* @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
|
|
57255
|
+
* @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
|
|
57201
57256
|
*/
|
|
57202
57257
|
adaptRanges(applyChange, sheetId, sheetName) { }
|
|
57203
57258
|
/**
|
|
@@ -57800,9 +57855,7 @@ class CellPlugin extends CorePlugin {
|
|
|
57800
57855
|
for (const cell of Object.values(this.cells[sheet] || {})) {
|
|
57801
57856
|
if (cell.isFormula) {
|
|
57802
57857
|
for (const range of cell.compiledFormula.dependencies) {
|
|
57803
|
-
if (
|
|
57804
|
-
range.sheetId === sheetId ||
|
|
57805
|
-
(sheetName && range.invalidSheetName === sheetName)) {
|
|
57858
|
+
if (range.sheetId === sheetId || range.invalidSheetName === sheetName.old) {
|
|
57806
57859
|
const change = applyChange(range);
|
|
57807
57860
|
if (change.changeType !== "NONE") {
|
|
57808
57861
|
this.history.update("cells", sheet, cell.id, "compiledFormula", "dependencies", cell.compiledFormula.dependencies.indexOf(range), change.range);
|
|
@@ -58418,9 +58471,9 @@ class ChartPlugin extends CorePlugin {
|
|
|
58418
58471
|
charts = {};
|
|
58419
58472
|
createChart = chartFactory(this.getters);
|
|
58420
58473
|
validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
|
|
58421
|
-
adaptRanges(applyChange) {
|
|
58474
|
+
adaptRanges(applyChange, sheetId, adaptSheetName) {
|
|
58422
58475
|
for (const [chartId, chart] of Object.entries(this.charts)) {
|
|
58423
|
-
this.history.update("charts", chartId, chart?.updateRanges(applyChange));
|
|
58476
|
+
this.history.update("charts", chartId, chart?.updateRanges(applyChange, sheetId, adaptSheetName));
|
|
58424
58477
|
}
|
|
58425
58478
|
}
|
|
58426
58479
|
// ---------------------------------------------------------------------------
|
|
@@ -58683,7 +58736,7 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
58683
58736
|
}
|
|
58684
58737
|
}
|
|
58685
58738
|
}
|
|
58686
|
-
adaptRanges(applyChange, sheetId
|
|
58739
|
+
adaptRanges(applyChange, sheetId) {
|
|
58687
58740
|
const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
|
|
58688
58741
|
for (const sheetId of sheetIds) {
|
|
58689
58742
|
this.adaptCFRanges(sheetId, applyChange);
|
|
@@ -59079,11 +59132,8 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
59079
59132
|
"getValidationRuleForCell",
|
|
59080
59133
|
];
|
|
59081
59134
|
rules = {};
|
|
59082
|
-
adaptRanges(applyChange, sheetId
|
|
59083
|
-
|
|
59084
|
-
for (const sheetId of sheetIds) {
|
|
59085
|
-
this.adaptDVRanges(sheetId, applyChange);
|
|
59086
|
-
}
|
|
59135
|
+
adaptRanges(applyChange, sheetId) {
|
|
59136
|
+
this.adaptDVRanges(sheetId, applyChange);
|
|
59087
59137
|
this.adaptDVFormulas(applyChange);
|
|
59088
59138
|
}
|
|
59089
59139
|
adaptDVFormulas(applyChange) {
|
|
@@ -59373,9 +59423,6 @@ class FigurePlugin extends CorePlugin {
|
|
|
59373
59423
|
// Command Handling
|
|
59374
59424
|
// ---------------------------------------------------------------------------
|
|
59375
59425
|
adaptRanges(applyChange, sheetId) {
|
|
59376
|
-
if (!sheetId) {
|
|
59377
|
-
return;
|
|
59378
|
-
}
|
|
59379
59426
|
for (const figure of this.getFigures(sheetId)) {
|
|
59380
59427
|
const change = applyChange(this.getters.getRangeFromZone(sheetId, {
|
|
59381
59428
|
left: figure.col,
|
|
@@ -60183,11 +60230,8 @@ class MergePlugin extends CorePlugin {
|
|
|
60183
60230
|
break;
|
|
60184
60231
|
}
|
|
60185
60232
|
}
|
|
60186
|
-
adaptRanges(applyChange, sheetId
|
|
60187
|
-
|
|
60188
|
-
for (const sheetId of sheetIds) {
|
|
60189
|
-
this.applyRangeChangeOnSheet(sheetId, applyChange);
|
|
60190
|
-
}
|
|
60233
|
+
adaptRanges(applyChange, sheetId) {
|
|
60234
|
+
this.applyRangeChangeOnSheet(sheetId, applyChange);
|
|
60191
60235
|
}
|
|
60192
60236
|
// ---------------------------------------------------------------------------
|
|
60193
60237
|
// Getters
|
|
@@ -61695,12 +61739,9 @@ class TablePlugin extends CorePlugin {
|
|
|
61695
61739
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
61696
61740
|
tables = {};
|
|
61697
61741
|
nextTableId = 1;
|
|
61698
|
-
adaptRanges(applyChange, sheetId
|
|
61699
|
-
const
|
|
61700
|
-
|
|
61701
|
-
for (const table of this.getCoreTables(sheetId)) {
|
|
61702
|
-
this.applyRangeChangeOnTable(sheetId, table, applyChange);
|
|
61703
|
-
}
|
|
61742
|
+
adaptRanges(applyChange, sheetId) {
|
|
61743
|
+
for (const table of this.getCoreTables(sheetId)) {
|
|
61744
|
+
this.applyRangeChangeOnTable(sheetId, table, applyChange);
|
|
61704
61745
|
}
|
|
61705
61746
|
}
|
|
61706
61747
|
allowDispatch(cmd) {
|
|
@@ -62663,7 +62704,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62663
62704
|
}
|
|
62664
62705
|
}
|
|
62665
62706
|
}
|
|
62666
|
-
adaptRanges(applyChange
|
|
62707
|
+
adaptRanges(applyChange) {
|
|
62667
62708
|
for (const sheetId in this.compiledMeasureFormulas) {
|
|
62668
62709
|
for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
|
|
62669
62710
|
const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
|
|
@@ -66824,7 +66865,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
66824
66865
|
if (!result) {
|
|
66825
66866
|
return EMPTY_PIVOT_CELL;
|
|
66826
66867
|
}
|
|
66827
|
-
|
|
66868
|
+
let { functionName, args } = result;
|
|
66828
66869
|
const formulaId = args[0];
|
|
66829
66870
|
if (!formulaId) {
|
|
66830
66871
|
return EMPTY_PIVOT_CELL;
|
|
@@ -66854,6 +66895,9 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
66854
66895
|
return pivotCells[pivotCol][pivotRow];
|
|
66855
66896
|
}
|
|
66856
66897
|
try {
|
|
66898
|
+
const offsetRow = position.row - mainPosition.row;
|
|
66899
|
+
const offsetCol = position.col - mainPosition.col;
|
|
66900
|
+
args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
|
|
66857
66901
|
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
66858
66902
|
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
66859
66903
|
return {
|
|
@@ -68052,7 +68096,8 @@ function transformAll(toTransform, executed) {
|
|
|
68052
68096
|
// If the executed command is not in the registry, we skip it
|
|
68053
68097
|
// because we know there won't be any transformation impacting the
|
|
68054
68098
|
// commands to transform.
|
|
68055
|
-
if (possibleTransformations.has(executedCommand.type)
|
|
68099
|
+
if (possibleTransformations.has(executedCommand.type) ||
|
|
68100
|
+
rangeAdapterRegistry.contains(executedCommand.type)) {
|
|
68056
68101
|
transformedCommands = transformedCommands.reduce((acc, cmd) => {
|
|
68057
68102
|
const transformed = transform(cmd, executedCommand);
|
|
68058
68103
|
if (transformed) {
|
|
@@ -79213,7 +79258,7 @@ function figureCoordinates(headers, anchor, offset) {
|
|
|
79213
79258
|
for (const [headerIndex, header] of headers.slice(anchor).entries()) {
|
|
79214
79259
|
if (currentPosition <= offset && offset < currentPosition + header.size) {
|
|
79215
79260
|
return {
|
|
79216
|
-
index: headerIndex,
|
|
79261
|
+
index: anchor + headerIndex,
|
|
79217
79262
|
offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
|
|
79218
79263
|
};
|
|
79219
79264
|
}
|
|
@@ -80209,7 +80254,7 @@ class Model extends EventBus {
|
|
|
80209
80254
|
handlers = [];
|
|
80210
80255
|
uiHandlers = [];
|
|
80211
80256
|
coreHandlers = [];
|
|
80212
|
-
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport =
|
|
80257
|
+
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
|
|
80213
80258
|
const start = performance.now();
|
|
80214
80259
|
console.debug("##### Model creation #####");
|
|
80215
80260
|
super();
|
|
@@ -80952,6 +80997,6 @@ exports.tokenColors = tokenColors;
|
|
|
80952
80997
|
exports.tokenize = tokenize;
|
|
80953
80998
|
|
|
80954
80999
|
|
|
80955
|
-
__info__.version = "18.3.
|
|
80956
|
-
__info__.date = "2025-
|
|
80957
|
-
__info__.hash = "
|
|
81000
|
+
__info__.version = "18.3.19";
|
|
81001
|
+
__info__.date = "2025-09-05T07:38:30.661Z";
|
|
81002
|
+
__info__.hash = "77fd307";
|