@odoo/o-spreadsheet 18.2.27 → 18.2.29
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 +107 -58
- package/dist/o-spreadsheet.d.ts +14 -13
- package/dist/o-spreadsheet.esm.js +107 -58
- package/dist/o-spreadsheet.iife.js +107 -58
- package/dist/o-spreadsheet.iife.min.js +388 -388
- package/dist/o_spreadsheet.xml +4 -7
- 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.2.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.29
|
|
6
|
+
* @date 2025-09-11T08:44:31.801Z
|
|
7
|
+
* @hash 665bc43
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -3476,6 +3476,7 @@ const invalidateBordersCommands = new Set([
|
|
|
3476
3476
|
"AUTOFILL_CELL",
|
|
3477
3477
|
"SET_BORDER",
|
|
3478
3478
|
"SET_ZONE_BORDERS",
|
|
3479
|
+
"SET_BORDERS_ON_TARGET",
|
|
3479
3480
|
]);
|
|
3480
3481
|
const readonlyAllowedCommands = new Set([
|
|
3481
3482
|
"START",
|
|
@@ -6902,7 +6903,7 @@ class ClipboardHandler {
|
|
|
6902
6903
|
this.getters = getters;
|
|
6903
6904
|
this.dispatch = dispatch;
|
|
6904
6905
|
}
|
|
6905
|
-
copy(data) {
|
|
6906
|
+
copy(data, mode = "copyPaste") {
|
|
6906
6907
|
return;
|
|
6907
6908
|
}
|
|
6908
6909
|
paste(target, clippedContent, options) { }
|
|
@@ -6921,7 +6922,7 @@ class ClipboardHandler {
|
|
|
6921
6922
|
}
|
|
6922
6923
|
|
|
6923
6924
|
class AbstractCellClipboardHandler extends ClipboardHandler {
|
|
6924
|
-
copy(data) {
|
|
6925
|
+
copy(data, mode = "copyPaste") {
|
|
6925
6926
|
return;
|
|
6926
6927
|
}
|
|
6927
6928
|
pasteFromCopy(sheetId, target, content, options) {
|
|
@@ -7526,8 +7527,11 @@ function invertMatrix(M) {
|
|
|
7526
7527
|
// (a) Swap 2 rows. This multiply the determinant by -1.
|
|
7527
7528
|
// (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
|
|
7528
7529
|
// (c) Add to a row a multiple of another row. This does not change the determinant.
|
|
7530
|
+
if (M.length < 1 || M[0].length < 1) {
|
|
7531
|
+
throw new Error("invertMatrix: an empty matrix cannot be inverted.");
|
|
7532
|
+
}
|
|
7529
7533
|
if (M.length !== M[0].length) {
|
|
7530
|
-
throw new
|
|
7534
|
+
throw new Error("invertMatrix: only square matrices are invertible");
|
|
7531
7535
|
}
|
|
7532
7536
|
let determinant = 1;
|
|
7533
7537
|
const dim = M.length;
|
|
@@ -7596,8 +7600,11 @@ function swapMatrixRows(matrix, row1, row2) {
|
|
|
7596
7600
|
* Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
|
|
7597
7601
|
*/
|
|
7598
7602
|
function multiplyMatrices(matrix1, matrix2) {
|
|
7603
|
+
if (matrix1.length < 1 || matrix2.length < 1) {
|
|
7604
|
+
throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
|
|
7605
|
+
}
|
|
7599
7606
|
if (matrix1.length !== matrix2[0].length) {
|
|
7600
|
-
throw new
|
|
7607
|
+
throw new Error("multiplyMatrices: incompatible matrices size.");
|
|
7601
7608
|
}
|
|
7602
7609
|
const rowsM1 = matrix1[0].length;
|
|
7603
7610
|
const colsM2 = matrix2.length;
|
|
@@ -7623,7 +7630,7 @@ function toScalar(arg) {
|
|
|
7623
7630
|
return arg;
|
|
7624
7631
|
}
|
|
7625
7632
|
if (!isSingleElementMatrix(arg)) {
|
|
7626
|
-
throw new
|
|
7633
|
+
throw new Error("The value should be a scalar or a 1x1 matrix");
|
|
7627
7634
|
}
|
|
7628
7635
|
return arg[0][0];
|
|
7629
7636
|
}
|
|
@@ -7860,6 +7867,16 @@ function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZ
|
|
|
7860
7867
|
}
|
|
7861
7868
|
return values;
|
|
7862
7869
|
}
|
|
7870
|
+
function assertNonEmptyMatrix(matrix, argName) {
|
|
7871
|
+
assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
|
|
7872
|
+
argName,
|
|
7873
|
+
}));
|
|
7874
|
+
}
|
|
7875
|
+
function assertNonEmpty(...data) {
|
|
7876
|
+
if (data.length === 0 || data.some((arg) => arg.length === 0)) {
|
|
7877
|
+
throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
|
|
7878
|
+
}
|
|
7879
|
+
}
|
|
7863
7880
|
|
|
7864
7881
|
const PREVIOUS_VALUE = "(previous)";
|
|
7865
7882
|
const NEXT_VALUE = "(next)";
|
|
@@ -8622,7 +8639,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8622
8639
|
}
|
|
8623
8640
|
return "Success" /* CommandResult.Success */;
|
|
8624
8641
|
}
|
|
8625
|
-
copy(data) {
|
|
8642
|
+
copy(data, mode = "copyPaste") {
|
|
8626
8643
|
const sheetId = data.sheetId;
|
|
8627
8644
|
const { clippedZones, rowsIndexes, columnsIndexes } = data;
|
|
8628
8645
|
const clippedCells = [];
|
|
@@ -8635,7 +8652,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8635
8652
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
8636
8653
|
const pivotId = this.getters.getPivotIdFromPosition(position);
|
|
8637
8654
|
const spreader = this.getters.getArrayFormulaSpreadingOn(position);
|
|
8638
|
-
if (pivotId && spreader) {
|
|
8655
|
+
if (mode !== "shiftCells" && pivotId && spreader) {
|
|
8639
8656
|
const pivotZone = this.getters.getSpreadZone(spreader);
|
|
8640
8657
|
if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
|
|
8641
8658
|
pivotZone &&
|
|
@@ -8653,7 +8670,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8653
8670
|
};
|
|
8654
8671
|
}
|
|
8655
8672
|
}
|
|
8656
|
-
else {
|
|
8673
|
+
else if (mode !== "shiftCells") {
|
|
8657
8674
|
if (spreader && !deepEquals(spreader, position)) {
|
|
8658
8675
|
const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
|
|
8659
8676
|
const content = isSpreaderCopied
|
|
@@ -9346,7 +9363,7 @@ class SheetClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9346
9363
|
}
|
|
9347
9364
|
|
|
9348
9365
|
class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
9349
|
-
copy(data) {
|
|
9366
|
+
copy(data, mode = "copyPaste") {
|
|
9350
9367
|
const sheetId = data.sheetId;
|
|
9351
9368
|
const { rowsIndexes, columnsIndexes, zones } = data;
|
|
9352
9369
|
const copiedTablesIds = new Set();
|
|
@@ -9376,11 +9393,13 @@ class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9376
9393
|
type: coreTable.type,
|
|
9377
9394
|
};
|
|
9378
9395
|
}
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9396
|
+
if (mode !== "shiftCells") {
|
|
9397
|
+
tableCellsInRow.push({
|
|
9398
|
+
table: copiedTable,
|
|
9399
|
+
style: this.getTableStyleToCopy(position),
|
|
9400
|
+
isWholeTableCopied: copiedTablesIds.has(table.id),
|
|
9401
|
+
});
|
|
9402
|
+
}
|
|
9384
9403
|
}
|
|
9385
9404
|
}
|
|
9386
9405
|
return {
|
|
@@ -11797,6 +11816,7 @@ const MMULT = {
|
|
|
11797
11816
|
compute: function (matrix1, matrix2) {
|
|
11798
11817
|
const _matrix1 = toNumberMatrix(matrix1, "matrix1");
|
|
11799
11818
|
const _matrix2 = toNumberMatrix(matrix2, "matrix2");
|
|
11819
|
+
assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
|
|
11800
11820
|
assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
|
|
11801
11821
|
number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
|
|
11802
11822
|
return multiplyMatrices(_matrix1, _matrix2);
|
|
@@ -13592,6 +13612,7 @@ const FORECAST = {
|
|
|
13592
13612
|
],
|
|
13593
13613
|
compute: function (x, dataY, dataX) {
|
|
13594
13614
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13615
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13595
13616
|
return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
|
|
13596
13617
|
},
|
|
13597
13618
|
isExported: true,
|
|
@@ -13608,6 +13629,7 @@ const GROWTH = {
|
|
|
13608
13629
|
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.")),
|
|
13609
13630
|
],
|
|
13610
13631
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13632
|
+
assertNonEmptyMatrix(knownDataY, "known_data_y");
|
|
13611
13633
|
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)));
|
|
13612
13634
|
},
|
|
13613
13635
|
};
|
|
@@ -13622,6 +13644,7 @@ const INTERCEPT = {
|
|
|
13622
13644
|
],
|
|
13623
13645
|
compute: function (dataY, dataX) {
|
|
13624
13646
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13647
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13625
13648
|
const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13626
13649
|
return intercept;
|
|
13627
13650
|
},
|
|
@@ -13671,6 +13694,7 @@ const LINEST = {
|
|
|
13671
13694
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
13672
13695
|
],
|
|
13673
13696
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13697
|
+
assertNonEmptyMatrix(dataY, "data_y");
|
|
13674
13698
|
return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
|
|
13675
13699
|
},
|
|
13676
13700
|
isExported: true,
|
|
@@ -13687,6 +13711,7 @@ const LOGEST = {
|
|
|
13687
13711
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
13688
13712
|
],
|
|
13689
13713
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13714
|
+
assertNonEmptyMatrix(dataY, "data_y");
|
|
13690
13715
|
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
|
|
13691
13716
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13692
13717
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
@@ -13708,9 +13733,7 @@ const MATTHEWS = {
|
|
|
13708
13733
|
const flatX = dataX.flat();
|
|
13709
13734
|
const flatY = dataY.flat();
|
|
13710
13735
|
assertSameNumberOfElements(flatX, flatY);
|
|
13711
|
-
|
|
13712
|
-
return new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
|
|
13713
|
-
}
|
|
13736
|
+
assertNonEmpty(flatX, flatY);
|
|
13714
13737
|
const n = flatX.length;
|
|
13715
13738
|
let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
|
|
13716
13739
|
for (let i = 0; i < n; ++i) {
|
|
@@ -13874,12 +13897,7 @@ const MINIFS = {
|
|
|
13874
13897
|
// -----------------------------------------------------------------------------
|
|
13875
13898
|
function pearson(dataY, dataX) {
|
|
13876
13899
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13877
|
-
|
|
13878
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
|
|
13879
|
-
}
|
|
13880
|
-
if (flatDataX.length < 2) {
|
|
13881
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] needs at least two values for both parameters."));
|
|
13882
|
-
}
|
|
13900
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13883
13901
|
const n = flatDataX.length;
|
|
13884
13902
|
let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
|
|
13885
13903
|
for (let i = 0; i < n; i++) {
|
|
@@ -13968,6 +13986,7 @@ const POLYFIT_COEFFS = {
|
|
|
13968
13986
|
],
|
|
13969
13987
|
compute: function (dataY, dataX, order, intercept = { value: true }) {
|
|
13970
13988
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13989
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13971
13990
|
return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
|
|
13972
13991
|
},
|
|
13973
13992
|
isExported: false,
|
|
@@ -13987,6 +14006,7 @@ const POLYFIT_FORECAST = {
|
|
|
13987
14006
|
compute: function (x, dataY, dataX, order, intercept = { value: true }) {
|
|
13988
14007
|
const _order = toNumber(order, this.locale);
|
|
13989
14008
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14009
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13990
14010
|
const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
|
|
13991
14011
|
return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
|
|
13992
14012
|
},
|
|
@@ -14103,6 +14123,7 @@ const SLOPE = {
|
|
|
14103
14123
|
],
|
|
14104
14124
|
compute: function (dataY, dataX) {
|
|
14105
14125
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14126
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
14106
14127
|
const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
14107
14128
|
return slope;
|
|
14108
14129
|
},
|
|
@@ -14151,6 +14172,7 @@ const SPEARMAN = {
|
|
|
14151
14172
|
],
|
|
14152
14173
|
compute: function (dataX, dataY) {
|
|
14153
14174
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14175
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
14154
14176
|
const n = flatDataX.length;
|
|
14155
14177
|
const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
|
|
14156
14178
|
order.sort((a, b) => a[0] - b[0]);
|
|
@@ -14261,6 +14283,7 @@ const STEYX = {
|
|
|
14261
14283
|
],
|
|
14262
14284
|
compute: function (dataY, dataX) {
|
|
14263
14285
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14286
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
14264
14287
|
const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
|
|
14265
14288
|
return data[1][2];
|
|
14266
14289
|
},
|
|
@@ -14278,6 +14301,7 @@ const TREND = {
|
|
|
14278
14301
|
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.")),
|
|
14279
14302
|
],
|
|
14280
14303
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
14304
|
+
assertNonEmptyMatrix(knownDataY, "known_data_y");
|
|
14281
14305
|
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));
|
|
14282
14306
|
},
|
|
14283
14307
|
};
|
|
@@ -23771,7 +23795,7 @@ const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
|
|
|
23771
23795
|
];
|
|
23772
23796
|
const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
|
|
23773
23797
|
const SUPPORTED_FONTS = ["Arial"];
|
|
23774
|
-
const SUPPORTED_FILL_PATTERNS = ["solid"];
|
|
23798
|
+
const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
|
|
23775
23799
|
const SUPPORTED_CF_TYPES = [
|
|
23776
23800
|
"expression",
|
|
23777
23801
|
"cellIs",
|
|
@@ -23956,7 +23980,7 @@ const SUBTOTAL_FUNCTION_CONVERSION_MAP = {
|
|
|
23956
23980
|
};
|
|
23957
23981
|
/** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
|
|
23958
23982
|
const XLSX_FORMATS_CONVERSION_MAP = {
|
|
23959
|
-
0: "",
|
|
23983
|
+
0: "General",
|
|
23960
23984
|
1: "0",
|
|
23961
23985
|
2: "0.00",
|
|
23962
23986
|
3: "#,#00",
|
|
@@ -24282,11 +24306,11 @@ const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/
|
|
|
24282
24306
|
* Excel format are defined in openXML §18.8.31
|
|
24283
24307
|
*/
|
|
24284
24308
|
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
24285
|
-
if (numFmtId === 0) {
|
|
24286
|
-
return undefined;
|
|
24287
|
-
}
|
|
24288
24309
|
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
24289
24310
|
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
|
|
24311
|
+
if (format === "General") {
|
|
24312
|
+
return undefined;
|
|
24313
|
+
}
|
|
24290
24314
|
if (format) {
|
|
24291
24315
|
try {
|
|
24292
24316
|
let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
@@ -24484,9 +24508,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
24484
24508
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
24485
24509
|
continue;
|
|
24486
24510
|
operator = convertCFCellIsOperator(rule.operator);
|
|
24487
|
-
values.push(rule.formula[0]);
|
|
24511
|
+
values.push(prefixFormula(rule.formula[0]));
|
|
24488
24512
|
if (rule.formula.length === 2) {
|
|
24489
|
-
values.push(rule.formula[1]);
|
|
24513
|
+
values.push(prefixFormula(rule.formula[1]));
|
|
24490
24514
|
}
|
|
24491
24515
|
break;
|
|
24492
24516
|
}
|
|
@@ -24644,6 +24668,11 @@ function convertIcons(xlsxIconSet, index) {
|
|
|
24644
24668
|
? ICON_SETS[iconSet].neutral
|
|
24645
24669
|
: ICON_SETS[iconSet].good;
|
|
24646
24670
|
}
|
|
24671
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
24672
|
+
function prefixFormula(formula) {
|
|
24673
|
+
const tokens = tokenize(formula);
|
|
24674
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
24675
|
+
}
|
|
24647
24676
|
// ---------------------------------------------------------------------------
|
|
24648
24677
|
// Warnings
|
|
24649
24678
|
// ---------------------------------------------------------------------------
|
|
@@ -27242,10 +27271,11 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
27242
27271
|
});
|
|
27243
27272
|
}
|
|
27244
27273
|
extractRows(worksheet) {
|
|
27274
|
+
const spilledCells = new Set();
|
|
27245
27275
|
return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
|
|
27246
27276
|
return {
|
|
27247
27277
|
index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
|
|
27248
|
-
cells: this.extractCells(rowElement),
|
|
27278
|
+
cells: this.extractCells(rowElement, spilledCells),
|
|
27249
27279
|
height: this.extractAttr(rowElement, "ht")?.asNum(),
|
|
27250
27280
|
customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
|
|
27251
27281
|
hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
|
|
@@ -27255,14 +27285,26 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
27255
27285
|
};
|
|
27256
27286
|
});
|
|
27257
27287
|
}
|
|
27258
|
-
extractCells(row) {
|
|
27288
|
+
extractCells(row, spilledCells) {
|
|
27259
27289
|
return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
|
|
27290
|
+
const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
|
|
27291
|
+
const formula = this.extractCellFormula(cellElement);
|
|
27292
|
+
if (formula?.ref && formula.sharedIndex === undefined) {
|
|
27293
|
+
const zone = toZone(formula.ref);
|
|
27294
|
+
for (const { col, row } of positions(zone)) {
|
|
27295
|
+
const followerXc = toXC(col, row);
|
|
27296
|
+
if (followerXc !== xc) {
|
|
27297
|
+
spilledCells.add(followerXc);
|
|
27298
|
+
}
|
|
27299
|
+
}
|
|
27300
|
+
}
|
|
27301
|
+
const isSpilled = spilledCells.has(xc);
|
|
27260
27302
|
return {
|
|
27261
|
-
xc
|
|
27303
|
+
xc,
|
|
27262
27304
|
styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
|
|
27263
27305
|
type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
|
|
27264
|
-
value: this.extractChildTextContent(cellElement, "v"),
|
|
27265
|
-
formula:
|
|
27306
|
+
value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
|
|
27307
|
+
formula: isSpilled ? undefined : formula,
|
|
27266
27308
|
};
|
|
27267
27309
|
});
|
|
27268
27310
|
}
|
|
@@ -27270,11 +27312,14 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
27270
27312
|
const formulaElement = this.querySelector(cellElement, "f");
|
|
27271
27313
|
if (!formulaElement)
|
|
27272
27314
|
return undefined;
|
|
27273
|
-
|
|
27274
|
-
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27315
|
+
const content = this.extractTextContent(formulaElement);
|
|
27316
|
+
const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
|
|
27317
|
+
const ref = this.extractAttr(formulaElement, "ref")?.asString();
|
|
27318
|
+
// This is the case of spilled cells of array formulas where <f> is empty
|
|
27319
|
+
if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
|
|
27320
|
+
return undefined;
|
|
27321
|
+
}
|
|
27322
|
+
return { content, sharedIndex, ref };
|
|
27278
27323
|
}
|
|
27279
27324
|
extractHyperLinks(worksheet) {
|
|
27280
27325
|
return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
|
|
@@ -36168,7 +36213,7 @@ const splitToColumns = {
|
|
|
36168
36213
|
const reinsertDynamicPivotMenu = {
|
|
36169
36214
|
id: "reinsert_dynamic_pivot",
|
|
36170
36215
|
name: _t("Re-insert dynamic pivot"),
|
|
36171
|
-
sequence:
|
|
36216
|
+
sequence: 60,
|
|
36172
36217
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
36173
36218
|
children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
|
|
36174
36219
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -36176,7 +36221,7 @@ const reinsertDynamicPivotMenu = {
|
|
|
36176
36221
|
const reinsertStaticPivotMenu = {
|
|
36177
36222
|
id: "reinsert_static_pivot",
|
|
36178
36223
|
name: _t("Re-insert static pivot"),
|
|
36179
|
-
sequence:
|
|
36224
|
+
sequence: 70,
|
|
36180
36225
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
36181
36226
|
children: [REINSERT_STATIC_PIVOT_CHILDREN],
|
|
36182
36227
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -37914,8 +37959,9 @@ topbarMenuRegistry
|
|
|
37914
37959
|
sequence: 40,
|
|
37915
37960
|
separator: true,
|
|
37916
37961
|
})
|
|
37917
|
-
.addChild("
|
|
37962
|
+
.addChild("pivot_data_sources", ["data"], (env) => {
|
|
37918
37963
|
const sequence = 50;
|
|
37964
|
+
const numberOfPivots = env.model.getters.getPivotIds().length;
|
|
37919
37965
|
return env.model.getters.getPivotIds().map((pivotId, index) => {
|
|
37920
37966
|
const highlightProvider = {
|
|
37921
37967
|
get highlights() {
|
|
@@ -37925,7 +37971,7 @@ topbarMenuRegistry
|
|
|
37925
37971
|
return {
|
|
37926
37972
|
id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
37927
37973
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
37928
|
-
sequence: sequence + index,
|
|
37974
|
+
sequence: sequence + index / numberOfPivots,
|
|
37929
37975
|
isReadonlyAllowed: true,
|
|
37930
37976
|
execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
|
|
37931
37977
|
onStartHover: (env) => env.getStore(HighlightStore).register(highlightProvider),
|
|
@@ -63897,7 +63943,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
63897
63943
|
if (!result) {
|
|
63898
63944
|
return EMPTY_PIVOT_CELL;
|
|
63899
63945
|
}
|
|
63900
|
-
|
|
63946
|
+
let { functionName, args } = result;
|
|
63901
63947
|
const formulaId = args[0];
|
|
63902
63948
|
if (!formulaId) {
|
|
63903
63949
|
return EMPTY_PIVOT_CELL;
|
|
@@ -63927,6 +63973,9 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
63927
63973
|
return pivotCells[pivotCol][pivotRow];
|
|
63928
63974
|
}
|
|
63929
63975
|
try {
|
|
63976
|
+
const offsetRow = position.row - mainPosition.row;
|
|
63977
|
+
const offsetCol = position.col - mainPosition.col;
|
|
63978
|
+
args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
|
|
63930
63979
|
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
63931
63980
|
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
63932
63981
|
return {
|
|
@@ -67775,12 +67824,12 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
67775
67824
|
}
|
|
67776
67825
|
case "INSERT_CELL": {
|
|
67777
67826
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
67778
|
-
const copiedData = this.copy(cut);
|
|
67827
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67779
67828
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
67780
67829
|
}
|
|
67781
67830
|
case "DELETE_CELL": {
|
|
67782
67831
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
67783
|
-
const copiedData = this.copy(cut);
|
|
67832
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67784
67833
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
67785
67834
|
}
|
|
67786
67835
|
}
|
|
@@ -67870,13 +67919,13 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
67870
67919
|
});
|
|
67871
67920
|
break;
|
|
67872
67921
|
}
|
|
67873
|
-
const copiedData = this.copy(cut);
|
|
67922
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67874
67923
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
67875
67924
|
break;
|
|
67876
67925
|
}
|
|
67877
67926
|
case "INSERT_CELL": {
|
|
67878
67927
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
67879
|
-
const copiedData = this.copy(cut);
|
|
67928
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67880
67929
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
67881
67930
|
break;
|
|
67882
67931
|
}
|
|
@@ -67991,11 +68040,11 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
67991
68040
|
}
|
|
67992
68041
|
return false;
|
|
67993
68042
|
}
|
|
67994
|
-
copy(zones) {
|
|
68043
|
+
copy(zones, mode = "copyPaste") {
|
|
67995
68044
|
let copiedData = {};
|
|
67996
68045
|
const clipboardData = this.getClipboardData(zones);
|
|
67997
68046
|
for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
|
|
67998
|
-
const data = handler.copy(clipboardData);
|
|
68047
|
+
const data = handler.copy(clipboardData, mode);
|
|
67999
68048
|
copiedData[handlerName] = data;
|
|
68000
68049
|
const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
|
|
68001
68050
|
for (const key of minimalKeys) {
|
|
@@ -68859,7 +68908,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
68859
68908
|
];
|
|
68860
68909
|
for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
|
|
68861
68910
|
const handler = new Handler(this.getters, this.dispatch);
|
|
68862
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, target));
|
|
68911
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, target), "shiftCells");
|
|
68863
68912
|
if (!data) {
|
|
68864
68913
|
continue;
|
|
68865
68914
|
}
|
|
@@ -77238,6 +77287,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
77238
77287
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
77239
77288
|
|
|
77240
77289
|
|
|
77241
|
-
__info__.version = "18.2.
|
|
77242
|
-
__info__.date = "2025-
|
|
77243
|
-
__info__.hash = "
|
|
77290
|
+
__info__.version = "18.2.29";
|
|
77291
|
+
__info__.date = "2025-09-11T08:44:31.801Z";
|
|
77292
|
+
__info__.hash = "665bc43";
|