@odoo/o-spreadsheet 17.2.14 → 17.2.16
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 +233 -191
- package/dist/o-spreadsheet.d.ts +6 -3
- package/dist/o-spreadsheet.esm.js +233 -191
- package/dist/o-spreadsheet.iife.js +233 -191
- package/dist/o-spreadsheet.iife.min.js +6 -6
- package/dist/o_spreadsheet.xml +4 -4
- package/package.json +1 -1
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.2.
|
|
7
|
-
* @date 2024-07-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.16
|
|
7
|
+
* @date 2024-07-11T06:38:53.101Z
|
|
8
|
+
* @hash 9f20685
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
(function (exports, owl) {
|
|
@@ -576,7 +576,7 @@
|
|
|
576
576
|
/**
|
|
577
577
|
* Compares two objects.
|
|
578
578
|
*/
|
|
579
|
-
function deepEquals(o1, o2
|
|
579
|
+
function deepEquals(o1, o2) {
|
|
580
580
|
if (o1 === o2)
|
|
581
581
|
return true;
|
|
582
582
|
if ((o1 && !o2) || (o2 && !o1))
|
|
@@ -592,17 +592,13 @@
|
|
|
592
592
|
}
|
|
593
593
|
}
|
|
594
594
|
for (const key in o1) {
|
|
595
|
-
|
|
596
|
-
if (typeOfO1Key !== typeof o2[key])
|
|
595
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
597
596
|
return false;
|
|
598
|
-
if (
|
|
599
|
-
if (!deepEquals(o1[key], o2[key]
|
|
597
|
+
if (typeof o1[key] === "object") {
|
|
598
|
+
if (!deepEquals(o1[key], o2[key]))
|
|
600
599
|
return false;
|
|
601
600
|
}
|
|
602
601
|
else {
|
|
603
|
-
if (ignoreFunctions && typeOfO1Key === "function") {
|
|
604
|
-
continue;
|
|
605
|
-
}
|
|
606
602
|
if (o1[key] !== o2[key])
|
|
607
603
|
return false;
|
|
608
604
|
}
|
|
@@ -1751,7 +1747,7 @@
|
|
|
1751
1747
|
});
|
|
1752
1748
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
1753
1749
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
1754
|
-
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
|
|
1750
|
+
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
|
|
1755
1751
|
const pIntegerAndDecimals = `(\\d+(${thousandsSeparator}\\d{3,})*(${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
|
|
1756
1752
|
const pOnlyDecimals = `(${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
|
|
1757
1753
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -1778,7 +1774,7 @@
|
|
|
1778
1774
|
return getNumberRegex(locale).test(value.trim());
|
|
1779
1775
|
}
|
|
1780
1776
|
const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
|
|
1781
|
-
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
|
|
1777
|
+
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
|
|
1782
1778
|
});
|
|
1783
1779
|
/**
|
|
1784
1780
|
* Convert a string into a number. It assumes that the string actually represents
|
|
@@ -2647,6 +2643,9 @@
|
|
|
2647
2643
|
* If the character is a special regular expression character, it is escaped with "\\".
|
|
2648
2644
|
*/
|
|
2649
2645
|
const wildcardToRegExp = memoize(function wildcardToRegExp(operand) {
|
|
2646
|
+
if (operand === "*") {
|
|
2647
|
+
return /.+/;
|
|
2648
|
+
}
|
|
2650
2649
|
let exp = "";
|
|
2651
2650
|
let predecessor = "";
|
|
2652
2651
|
for (let char of operand) {
|
|
@@ -2670,9 +2669,9 @@
|
|
|
2670
2669
|
}
|
|
2671
2670
|
return new RegExp("^" + exp + "$", "i");
|
|
2672
2671
|
});
|
|
2673
|
-
function evaluatePredicate(value, criterion) {
|
|
2672
|
+
function evaluatePredicate(value = "", criterion) {
|
|
2674
2673
|
const { operator, operand } = criterion;
|
|
2675
|
-
if (
|
|
2674
|
+
if (operand === undefined || value === null || operand === null) {
|
|
2676
2675
|
return false;
|
|
2677
2676
|
}
|
|
2678
2677
|
if (typeof operand === "number" && operator === "=") {
|
|
@@ -5358,19 +5357,22 @@
|
|
|
5358
5357
|
}
|
|
5359
5358
|
|
|
5360
5359
|
function isValidLocale(locale) {
|
|
5361
|
-
if (!
|
|
5362
|
-
typeof locale
|
|
5363
|
-
typeof locale.
|
|
5364
|
-
typeof locale.code === "string" &&
|
|
5365
|
-
typeof locale.thousandsSeparator === "string" &&
|
|
5366
|
-
typeof locale.decimalSeparator === "string" &&
|
|
5367
|
-
typeof locale.dateFormat === "string" &&
|
|
5368
|
-
typeof locale.timeFormat === "string" &&
|
|
5369
|
-
typeof locale.formulaArgSeparator === "string")) {
|
|
5360
|
+
if (!locale ||
|
|
5361
|
+
typeof locale !== "object" ||
|
|
5362
|
+
!(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
|
|
5370
5363
|
return false;
|
|
5371
5364
|
}
|
|
5372
|
-
|
|
5373
|
-
|
|
5365
|
+
for (const property of [
|
|
5366
|
+
"code",
|
|
5367
|
+
"name",
|
|
5368
|
+
"decimalSeparator",
|
|
5369
|
+
"dateFormat",
|
|
5370
|
+
"timeFormat",
|
|
5371
|
+
"formulaArgSeparator",
|
|
5372
|
+
]) {
|
|
5373
|
+
if (!locale[property] || typeof locale[property] !== "string") {
|
|
5374
|
+
return false;
|
|
5375
|
+
}
|
|
5374
5376
|
}
|
|
5375
5377
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
5376
5378
|
return false;
|
|
@@ -5468,7 +5470,10 @@
|
|
|
5468
5470
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
5469
5471
|
return content;
|
|
5470
5472
|
}
|
|
5471
|
-
|
|
5473
|
+
if (locale.thousandsSeparator) {
|
|
5474
|
+
content = content.replaceAll(locale.thousandsSeparator, "");
|
|
5475
|
+
}
|
|
5476
|
+
return content.replace(locale.decimalSeparator, ".");
|
|
5472
5477
|
}
|
|
5473
5478
|
/**
|
|
5474
5479
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -6452,6 +6457,146 @@
|
|
|
6452
6457
|
return undefined;
|
|
6453
6458
|
}
|
|
6454
6459
|
|
|
6460
|
+
var State;
|
|
6461
|
+
(function (State) {
|
|
6462
|
+
/**
|
|
6463
|
+
* Initial state.
|
|
6464
|
+
* Expecting any reference for the left part of a range
|
|
6465
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6466
|
+
*/
|
|
6467
|
+
State[State["LeftRef"] = 0] = "LeftRef";
|
|
6468
|
+
/**
|
|
6469
|
+
* Expecting any reference for the right part of a range
|
|
6470
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6471
|
+
*/
|
|
6472
|
+
State[State["RightRef"] = 1] = "RightRef";
|
|
6473
|
+
/**
|
|
6474
|
+
* Expecting the separator without any constraint on the right part
|
|
6475
|
+
*/
|
|
6476
|
+
State[State["Separator"] = 2] = "Separator";
|
|
6477
|
+
/**
|
|
6478
|
+
* Expecting the separator for a full column range
|
|
6479
|
+
*/
|
|
6480
|
+
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
6481
|
+
/**
|
|
6482
|
+
* Expecting the separator for a full row range
|
|
6483
|
+
*/
|
|
6484
|
+
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
6485
|
+
/**
|
|
6486
|
+
* Expecting the right part of a full column range
|
|
6487
|
+
* e.g. "1", "A1"
|
|
6488
|
+
*/
|
|
6489
|
+
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
6490
|
+
/**
|
|
6491
|
+
* Expecting the right part of a full row range
|
|
6492
|
+
* e.g. "A", "A1"
|
|
6493
|
+
*/
|
|
6494
|
+
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
6495
|
+
/**
|
|
6496
|
+
* Final state. A range has been matched
|
|
6497
|
+
*/
|
|
6498
|
+
State[State["Found"] = 7] = "Found";
|
|
6499
|
+
})(State || (State = {}));
|
|
6500
|
+
const goTo = (state, guard = () => true) => [
|
|
6501
|
+
{
|
|
6502
|
+
goTo: state,
|
|
6503
|
+
guard,
|
|
6504
|
+
},
|
|
6505
|
+
];
|
|
6506
|
+
const goToMulti = (state, guard = () => true) => ({
|
|
6507
|
+
goTo: state,
|
|
6508
|
+
guard,
|
|
6509
|
+
});
|
|
6510
|
+
const machine = {
|
|
6511
|
+
[State.LeftRef]: {
|
|
6512
|
+
REFERENCE: goTo(State.Separator),
|
|
6513
|
+
NUMBER: goTo(State.FullRowSeparator),
|
|
6514
|
+
SYMBOL: [
|
|
6515
|
+
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
6516
|
+
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
6517
|
+
],
|
|
6518
|
+
},
|
|
6519
|
+
[State.FullColumnSeparator]: {
|
|
6520
|
+
SPACE: goTo(State.FullColumnSeparator),
|
|
6521
|
+
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
6522
|
+
},
|
|
6523
|
+
[State.FullRowSeparator]: {
|
|
6524
|
+
SPACE: goTo(State.FullRowSeparator),
|
|
6525
|
+
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
6526
|
+
},
|
|
6527
|
+
[State.Separator]: {
|
|
6528
|
+
SPACE: goTo(State.Separator),
|
|
6529
|
+
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
6530
|
+
},
|
|
6531
|
+
[State.RightRef]: {
|
|
6532
|
+
SPACE: goTo(State.RightRef),
|
|
6533
|
+
NUMBER: goTo(State.Found),
|
|
6534
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6535
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
6536
|
+
},
|
|
6537
|
+
[State.RightColumnRef]: {
|
|
6538
|
+
SPACE: goTo(State.RightColumnRef),
|
|
6539
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
6540
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6541
|
+
},
|
|
6542
|
+
[State.RightRowRef]: {
|
|
6543
|
+
SPACE: goTo(State.RightRowRef),
|
|
6544
|
+
NUMBER: goTo(State.Found),
|
|
6545
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6546
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
6547
|
+
},
|
|
6548
|
+
[State.Found]: {},
|
|
6549
|
+
};
|
|
6550
|
+
/**
|
|
6551
|
+
* Check if the list of tokens starts with a sequence of tokens representing
|
|
6552
|
+
* a range.
|
|
6553
|
+
* If a range is found, the sequence is removed from the list and is returned
|
|
6554
|
+
* as a single token.
|
|
6555
|
+
*/
|
|
6556
|
+
function matchReference(tokens) {
|
|
6557
|
+
let head = 0;
|
|
6558
|
+
let transitions = machine[State.LeftRef];
|
|
6559
|
+
let matchedTokens = "";
|
|
6560
|
+
while (transitions !== undefined) {
|
|
6561
|
+
const token = tokens[head++];
|
|
6562
|
+
if (!token) {
|
|
6563
|
+
return null;
|
|
6564
|
+
}
|
|
6565
|
+
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
6566
|
+
const nextState = transition ? transition.goTo : undefined;
|
|
6567
|
+
switch (nextState) {
|
|
6568
|
+
case undefined:
|
|
6569
|
+
return null;
|
|
6570
|
+
case State.Found:
|
|
6571
|
+
matchedTokens += token.value;
|
|
6572
|
+
tokens.splice(0, head);
|
|
6573
|
+
return {
|
|
6574
|
+
type: "REFERENCE",
|
|
6575
|
+
value: matchedTokens,
|
|
6576
|
+
};
|
|
6577
|
+
default:
|
|
6578
|
+
transitions = machine[nextState];
|
|
6579
|
+
matchedTokens += token.value;
|
|
6580
|
+
break;
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
return null;
|
|
6584
|
+
}
|
|
6585
|
+
/**
|
|
6586
|
+
* Take the result of the tokenizer and transform it to be usable in the
|
|
6587
|
+
* manipulations of range
|
|
6588
|
+
*
|
|
6589
|
+
* @param formula
|
|
6590
|
+
*/
|
|
6591
|
+
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
6592
|
+
const tokens = tokenize(formula, locale);
|
|
6593
|
+
const result = [];
|
|
6594
|
+
while (tokens.length) {
|
|
6595
|
+
result.push(matchReference(tokens) || tokens.shift());
|
|
6596
|
+
}
|
|
6597
|
+
return result;
|
|
6598
|
+
}
|
|
6599
|
+
|
|
6455
6600
|
const functionRegex = /[a-zA-Z0-9\_]+(\.[a-zA-Z0-9\_]+)*/;
|
|
6456
6601
|
const UNARY_OPERATORS_PREFIX = ["-", "+"];
|
|
6457
6602
|
const UNARY_OPERATORS_POSTFIX = ["%"];
|
|
@@ -6600,7 +6745,7 @@
|
|
|
6600
6745
|
* Parse an expression (as a string) into an AST.
|
|
6601
6746
|
*/
|
|
6602
6747
|
function parse(str) {
|
|
6603
|
-
return parseTokens(
|
|
6748
|
+
return parseTokens(rangeTokenize(str));
|
|
6604
6749
|
}
|
|
6605
6750
|
function parseTokens(tokens) {
|
|
6606
6751
|
tokens = tokens.filter((x) => x.type !== "SPACE");
|
|
@@ -6736,146 +6881,6 @@
|
|
|
6736
6881
|
return needParenthesis ? `(${astToFormula(rightOperation)})` : astToFormula(rightOperation);
|
|
6737
6882
|
}
|
|
6738
6883
|
|
|
6739
|
-
var State;
|
|
6740
|
-
(function (State) {
|
|
6741
|
-
/**
|
|
6742
|
-
* Initial state.
|
|
6743
|
-
* Expecting any reference for the left part of a range
|
|
6744
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6745
|
-
*/
|
|
6746
|
-
State[State["LeftRef"] = 0] = "LeftRef";
|
|
6747
|
-
/**
|
|
6748
|
-
* Expecting any reference for the right part of a range
|
|
6749
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6750
|
-
*/
|
|
6751
|
-
State[State["RightRef"] = 1] = "RightRef";
|
|
6752
|
-
/**
|
|
6753
|
-
* Expecting the separator without any constraint on the right part
|
|
6754
|
-
*/
|
|
6755
|
-
State[State["Separator"] = 2] = "Separator";
|
|
6756
|
-
/**
|
|
6757
|
-
* Expecting the separator for a full column range
|
|
6758
|
-
*/
|
|
6759
|
-
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
6760
|
-
/**
|
|
6761
|
-
* Expecting the separator for a full row range
|
|
6762
|
-
*/
|
|
6763
|
-
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
6764
|
-
/**
|
|
6765
|
-
* Expecting the right part of a full column range
|
|
6766
|
-
* e.g. "1", "A1"
|
|
6767
|
-
*/
|
|
6768
|
-
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
6769
|
-
/**
|
|
6770
|
-
* Expecting the right part of a full row range
|
|
6771
|
-
* e.g. "A", "A1"
|
|
6772
|
-
*/
|
|
6773
|
-
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
6774
|
-
/**
|
|
6775
|
-
* Final state. A range has been matched
|
|
6776
|
-
*/
|
|
6777
|
-
State[State["Found"] = 7] = "Found";
|
|
6778
|
-
})(State || (State = {}));
|
|
6779
|
-
const goTo = (state, guard = () => true) => [
|
|
6780
|
-
{
|
|
6781
|
-
goTo: state,
|
|
6782
|
-
guard,
|
|
6783
|
-
},
|
|
6784
|
-
];
|
|
6785
|
-
const goToMulti = (state, guard = () => true) => ({
|
|
6786
|
-
goTo: state,
|
|
6787
|
-
guard,
|
|
6788
|
-
});
|
|
6789
|
-
const machine = {
|
|
6790
|
-
[State.LeftRef]: {
|
|
6791
|
-
REFERENCE: goTo(State.Separator),
|
|
6792
|
-
NUMBER: goTo(State.FullRowSeparator),
|
|
6793
|
-
SYMBOL: [
|
|
6794
|
-
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
6795
|
-
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
6796
|
-
],
|
|
6797
|
-
},
|
|
6798
|
-
[State.FullColumnSeparator]: {
|
|
6799
|
-
SPACE: goTo(State.FullColumnSeparator),
|
|
6800
|
-
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
6801
|
-
},
|
|
6802
|
-
[State.FullRowSeparator]: {
|
|
6803
|
-
SPACE: goTo(State.FullRowSeparator),
|
|
6804
|
-
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
6805
|
-
},
|
|
6806
|
-
[State.Separator]: {
|
|
6807
|
-
SPACE: goTo(State.Separator),
|
|
6808
|
-
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
6809
|
-
},
|
|
6810
|
-
[State.RightRef]: {
|
|
6811
|
-
SPACE: goTo(State.RightRef),
|
|
6812
|
-
NUMBER: goTo(State.Found),
|
|
6813
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6814
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
6815
|
-
},
|
|
6816
|
-
[State.RightColumnRef]: {
|
|
6817
|
-
SPACE: goTo(State.RightColumnRef),
|
|
6818
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
6819
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6820
|
-
},
|
|
6821
|
-
[State.RightRowRef]: {
|
|
6822
|
-
SPACE: goTo(State.RightRowRef),
|
|
6823
|
-
NUMBER: goTo(State.Found),
|
|
6824
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6825
|
-
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
6826
|
-
},
|
|
6827
|
-
[State.Found]: {},
|
|
6828
|
-
};
|
|
6829
|
-
/**
|
|
6830
|
-
* Check if the list of tokens starts with a sequence of tokens representing
|
|
6831
|
-
* a range.
|
|
6832
|
-
* If a range is found, the sequence is removed from the list and is returned
|
|
6833
|
-
* as a single token.
|
|
6834
|
-
*/
|
|
6835
|
-
function matchReference(tokens) {
|
|
6836
|
-
let head = 0;
|
|
6837
|
-
let transitions = machine[State.LeftRef];
|
|
6838
|
-
let matchedTokens = "";
|
|
6839
|
-
while (transitions !== undefined) {
|
|
6840
|
-
const token = tokens[head++];
|
|
6841
|
-
if (!token) {
|
|
6842
|
-
return null;
|
|
6843
|
-
}
|
|
6844
|
-
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
6845
|
-
const nextState = transition ? transition.goTo : undefined;
|
|
6846
|
-
switch (nextState) {
|
|
6847
|
-
case undefined:
|
|
6848
|
-
return null;
|
|
6849
|
-
case State.Found:
|
|
6850
|
-
matchedTokens += token.value;
|
|
6851
|
-
tokens.splice(0, head);
|
|
6852
|
-
return {
|
|
6853
|
-
type: "REFERENCE",
|
|
6854
|
-
value: matchedTokens,
|
|
6855
|
-
};
|
|
6856
|
-
default:
|
|
6857
|
-
transitions = machine[nextState];
|
|
6858
|
-
matchedTokens += token.value;
|
|
6859
|
-
break;
|
|
6860
|
-
}
|
|
6861
|
-
}
|
|
6862
|
-
return null;
|
|
6863
|
-
}
|
|
6864
|
-
/**
|
|
6865
|
-
* Take the result of the tokenizer and transform it to be usable in the
|
|
6866
|
-
* manipulations of range
|
|
6867
|
-
*
|
|
6868
|
-
* @param formula
|
|
6869
|
-
*/
|
|
6870
|
-
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
6871
|
-
const tokens = tokenize(formula, locale);
|
|
6872
|
-
const result = [];
|
|
6873
|
-
while (tokens.length) {
|
|
6874
|
-
result.push(matchReference(tokens) || tokens.shift());
|
|
6875
|
-
}
|
|
6876
|
-
return result;
|
|
6877
|
-
}
|
|
6878
|
-
|
|
6879
6884
|
/**
|
|
6880
6885
|
* Add the following information on tokens:
|
|
6881
6886
|
* - length
|
|
@@ -9199,7 +9204,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9199
9204
|
};
|
|
9200
9205
|
canvas = owl.useRef("graphContainer");
|
|
9201
9206
|
chart;
|
|
9202
|
-
currentRuntime;
|
|
9203
9207
|
get background() {
|
|
9204
9208
|
return this.chartRuntime.background;
|
|
9205
9209
|
}
|
|
@@ -9216,18 +9220,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9216
9220
|
setup() {
|
|
9217
9221
|
owl.onMounted(() => {
|
|
9218
9222
|
const runtime = this.chartRuntime;
|
|
9219
|
-
this.currentRuntime = runtime;
|
|
9220
9223
|
// Note: chartJS modify the runtime in place, so it's important to give it a copy
|
|
9221
9224
|
this.createChart(deepCopy(runtime.chartJsConfig));
|
|
9222
9225
|
});
|
|
9223
9226
|
owl.onWillUnmount(() => this.chart?.destroy());
|
|
9224
|
-
owl.useEffect(() =>
|
|
9225
|
-
const runtime = this.chartRuntime;
|
|
9226
|
-
if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
|
|
9227
|
-
this.currentRuntime = runtime;
|
|
9228
|
-
this.updateChartJs(deepCopy(runtime));
|
|
9229
|
-
}
|
|
9230
|
-
});
|
|
9227
|
+
owl.useEffect(() => this.updateChartJs(deepCopy(this.chartRuntime)), () => [this.chartRuntime]);
|
|
9231
9228
|
}
|
|
9232
9229
|
createChart(chartData) {
|
|
9233
9230
|
const canvas = this.canvas.el;
|
|
@@ -19629,7 +19626,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19629
19626
|
/**
|
|
19630
19627
|
* Get a default chart js configuration
|
|
19631
19628
|
*/
|
|
19632
|
-
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
|
|
19629
|
+
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels = true }) {
|
|
19633
19630
|
const options = {
|
|
19634
19631
|
// https://www.chartjs.org/docs/latest/general/responsive.html
|
|
19635
19632
|
responsive: true,
|
|
@@ -20547,10 +20544,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20547
20544
|
const cumulative = "cumulative" in chart ? chart.cumulative : false;
|
|
20548
20545
|
const colors = new ChartColors();
|
|
20549
20546
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
20550
|
-
if (["linear", "time"].includes(axisType)) {
|
|
20551
|
-
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
20552
|
-
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
20553
|
-
}
|
|
20554
20547
|
const color = colors.next();
|
|
20555
20548
|
let backgroundRGBA = colorToRGBA(color);
|
|
20556
20549
|
if (stacked) {
|
|
@@ -20566,6 +20559,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20566
20559
|
return value;
|
|
20567
20560
|
});
|
|
20568
20561
|
}
|
|
20562
|
+
if (["linear", "time"].includes(axisType)) {
|
|
20563
|
+
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
20564
|
+
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
20565
|
+
}
|
|
20569
20566
|
const backgroundColor = rgbaToHex(backgroundRGBA);
|
|
20570
20567
|
const dataset = {
|
|
20571
20568
|
label,
|
|
@@ -30423,7 +30420,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30423
30420
|
}
|
|
30424
30421
|
async loadLocales() {
|
|
30425
30422
|
this.loadedLocales = (await this.env.loadLocales())
|
|
30426
|
-
.filter(
|
|
30423
|
+
.filter((locale) => {
|
|
30424
|
+
const isValid = isValidLocale(locale);
|
|
30425
|
+
if (!isValid) {
|
|
30426
|
+
console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
|
|
30427
|
+
}
|
|
30428
|
+
return isValid;
|
|
30429
|
+
})
|
|
30427
30430
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
30428
30431
|
}
|
|
30429
30432
|
get numberFormatPreview() {
|
|
@@ -36231,6 +36234,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36231
36234
|
return;
|
|
36232
36235
|
}
|
|
36233
36236
|
if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
|
|
36237
|
+
ev.preventDefault();
|
|
36234
36238
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
36235
36239
|
const target = this.env.model.getters.getSelectedZones();
|
|
36236
36240
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
@@ -40807,6 +40811,21 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40807
40811
|
return [];
|
|
40808
40812
|
return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
|
|
40809
40813
|
}
|
|
40814
|
+
/**
|
|
40815
|
+
* Get all the rows which contains at least a border
|
|
40816
|
+
*/
|
|
40817
|
+
getRowsWithBorders(sheetId) {
|
|
40818
|
+
const sheetBorders = this.borders[sheetId]?.filter(isDefined$1);
|
|
40819
|
+
if (!sheetBorders)
|
|
40820
|
+
return [];
|
|
40821
|
+
const rowsWithBorders = new Set();
|
|
40822
|
+
for (const rowBorders of sheetBorders) {
|
|
40823
|
+
for (const rowBorder in rowBorders) {
|
|
40824
|
+
rowsWithBorders.add(parseInt(rowBorder, 10));
|
|
40825
|
+
}
|
|
40826
|
+
}
|
|
40827
|
+
return Array.from(rowsWithBorders);
|
|
40828
|
+
}
|
|
40810
40829
|
/**
|
|
40811
40830
|
* Get the range of all the rows in the sheet
|
|
40812
40831
|
*/
|
|
@@ -40856,7 +40875,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40856
40875
|
destructive: false,
|
|
40857
40876
|
});
|
|
40858
40877
|
}
|
|
40859
|
-
this.
|
|
40878
|
+
this.getRowsWithBorders(sheetId)
|
|
40860
40879
|
.filter((row) => row >= start)
|
|
40861
40880
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
40862
40881
|
.forEach((row) => {
|
|
@@ -47479,7 +47498,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47479
47498
|
return this.sheets[position.sheetId].getValue(position) === 1;
|
|
47480
47499
|
}
|
|
47481
47500
|
clear() {
|
|
47482
|
-
const insertions = this
|
|
47501
|
+
const insertions = [...this];
|
|
47483
47502
|
this.insertions = [];
|
|
47484
47503
|
for (const sheetId in this.sheets) {
|
|
47485
47504
|
this.sheets[sheetId].clear();
|
|
@@ -47797,6 +47816,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47797
47816
|
}
|
|
47798
47817
|
finally {
|
|
47799
47818
|
this.cellsBeingComputed.delete(cellId);
|
|
47819
|
+
this.nextPositionsToUpdate.delete(position);
|
|
47800
47820
|
}
|
|
47801
47821
|
}
|
|
47802
47822
|
computeAndSave(position) {
|
|
@@ -47821,8 +47841,33 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47821
47841
|
forEachSpreadPositionInMatrix(nbColumns, nbRows,
|
|
47822
47842
|
// thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
|
|
47823
47843
|
this.spreadValues(formulaPosition, formulaReturn));
|
|
47844
|
+
this.invalidatePositionsDependingOnSpread(formulaPosition, nbColumns, nbRows);
|
|
47824
47845
|
return createEvaluatedCell(nullValueToZeroValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
|
|
47825
47846
|
}
|
|
47847
|
+
invalidatePositionsDependingOnSpread(arrayFormulaPosition, nbColumns, nbRows) {
|
|
47848
|
+
// the result matrix is split in 2 zones to exclude the array formula position
|
|
47849
|
+
const top = arrayFormulaPosition.row;
|
|
47850
|
+
const left = arrayFormulaPosition.col;
|
|
47851
|
+
const bottom = top + nbRows - 1;
|
|
47852
|
+
const leftColumnZone = {
|
|
47853
|
+
top: top + 1,
|
|
47854
|
+
bottom,
|
|
47855
|
+
left,
|
|
47856
|
+
right: left,
|
|
47857
|
+
};
|
|
47858
|
+
const rightPartZone = {
|
|
47859
|
+
top,
|
|
47860
|
+
bottom,
|
|
47861
|
+
left: left + 1,
|
|
47862
|
+
right: left + nbColumns - 1,
|
|
47863
|
+
};
|
|
47864
|
+
const sheetId = arrayFormulaPosition.sheetId;
|
|
47865
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
|
|
47866
|
+
{ sheetId, zone: rightPartZone },
|
|
47867
|
+
{ sheetId, zone: leftColumnZone },
|
|
47868
|
+
]);
|
|
47869
|
+
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
47870
|
+
}
|
|
47826
47871
|
assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
|
|
47827
47872
|
const numberOfCols = this.getters.getNumberCols(sheetId);
|
|
47828
47873
|
const numberOfRows = this.getters.getNumberRows(sheetId);
|
|
@@ -47865,9 +47910,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47865
47910
|
const cell = this.getters.getCell(position);
|
|
47866
47911
|
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
47867
47912
|
this.evaluatedCells.set(position, evaluatedCell);
|
|
47868
|
-
// check if formula dependencies present in the spread zone
|
|
47869
|
-
// if so, they need to be recomputed
|
|
47870
|
-
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([position]));
|
|
47871
47913
|
};
|
|
47872
47914
|
}
|
|
47873
47915
|
invalidateSpreading(position) {
|
|
@@ -60840,9 +60882,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60840
60882
|
exports.tokenize = tokenize;
|
|
60841
60883
|
|
|
60842
60884
|
|
|
60843
|
-
__info__.version = "17.2.
|
|
60844
|
-
__info__.date = "2024-07-
|
|
60845
|
-
__info__.hash = "
|
|
60885
|
+
__info__.version = "17.2.16";
|
|
60886
|
+
__info__.date = "2024-07-11T06:38:53.101Z";
|
|
60887
|
+
__info__.hash = "9f20685";
|
|
60846
60888
|
|
|
60847
60889
|
|
|
60848
60890
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|