@odoo/o-spreadsheet 17.4.0-alpha.12 → 17.4.0-alpha.13

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.
@@ -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 17.4.0-alpha.12
6
- * @date 2024-07-08T05:43:07.933Z
7
- * @hash 7cfe14a
5
+ * @version 17.4.0-alpha.13
6
+ * @date 2024-07-11T06:36:58.556Z
7
+ * @hash e0f506b
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -591,7 +591,7 @@
591
591
  /**
592
592
  * Compares two objects.
593
593
  */
594
- function deepEquals(o1, o2, ignoreFunctions) {
594
+ function deepEquals(o1, o2) {
595
595
  if (o1 === o2)
596
596
  return true;
597
597
  if ((o1 && !o2) || (o2 && !o1))
@@ -607,17 +607,13 @@
607
607
  }
608
608
  }
609
609
  for (const key in o1) {
610
- const typeOfO1Key = typeof o1[key];
611
- if (typeOfO1Key !== typeof o2[key])
610
+ if (typeof o1[key] !== typeof o2[key])
612
611
  return false;
613
- if (typeOfO1Key === "object") {
614
- if (!deepEquals(o1[key], o2[key], ignoreFunctions))
612
+ if (typeof o1[key] === "object") {
613
+ if (!deepEquals(o1[key], o2[key]))
615
614
  return false;
616
615
  }
617
616
  else {
618
- if (ignoreFunctions && typeOfO1Key === "function") {
619
- continue;
620
- }
621
617
  if (o1[key] !== o2[key])
622
618
  return false;
623
619
  }
@@ -2640,11 +2636,11 @@
2640
2636
  }
2641
2637
  return returned;
2642
2638
  }
2643
- function matrixMap(matrix, fn) {
2639
+ function matrixMap(matrix, callback) {
2644
2640
  if (matrix.length === 0) {
2645
2641
  return [];
2646
2642
  }
2647
- return generateMatrix(matrix.length, matrix[0].length, (col, row) => fn(matrix[col][row]));
2643
+ return generateMatrix(matrix.length, matrix[0].length, (col, row) => callback(matrix[col][row]));
2648
2644
  }
2649
2645
  function matrixForEach(matrix, fn) {
2650
2646
  const numberOfCols = matrix.length;
@@ -2744,6 +2740,9 @@
2744
2740
  * If the character is a special regular expression character, it is escaped with "\\".
2745
2741
  */
2746
2742
  const wildcardToRegExp = memoize(function wildcardToRegExp(operand) {
2743
+ if (operand === "*") {
2744
+ return /.+/;
2745
+ }
2747
2746
  let exp = "";
2748
2747
  let predecessor = "";
2749
2748
  for (let char of operand) {
@@ -2767,9 +2766,9 @@
2767
2766
  }
2768
2767
  return new RegExp("^" + exp + "$", "i");
2769
2768
  });
2770
- function evaluatePredicate(value, criterion) {
2769
+ function evaluatePredicate(value = "", criterion) {
2771
2770
  const { operator, operand } = criterion;
2772
- if (value === undefined || operand === undefined || value === null || operand === null) {
2771
+ if (operand === undefined || value === null || operand === null) {
2773
2772
  return false;
2774
2773
  }
2775
2774
  if (typeof operand === "number" && operator === "=") {
@@ -8072,8 +8071,8 @@
8072
8071
 
8073
8072
  function evaluateLiteral(literalCell, localeFormat) {
8074
8073
  const value = localeFormat.format === PLAIN_TEXT_FORMAT ? literalCell.content : literalCell.parsedValue;
8075
- const fPayload = { value, format: localeFormat.format };
8076
- return createEvaluatedCell(fPayload, localeFormat.locale);
8074
+ const functionResult = { value, format: localeFormat.format };
8075
+ return createEvaluatedCell(functionResult, localeFormat.locale);
8077
8076
  }
8078
8077
  function parseLiteral(content, locale) {
8079
8078
  if (content.startsWith("=")) {
@@ -8094,13 +8093,13 @@
8094
8093
  }
8095
8094
  return content;
8096
8095
  }
8097
- function createEvaluatedCell(fPayload, locale = DEFAULT_LOCALE, cell) {
8098
- const link = detectLink(fPayload.value);
8096
+ function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
8097
+ const link = detectLink(functionResult.value);
8099
8098
  if (!link) {
8100
- return _createEvaluatedCell(fPayload, locale, cell);
8099
+ return _createEvaluatedCell(functionResult, locale, cell);
8101
8100
  }
8102
8101
  const value = parseLiteral(link.label, locale);
8103
- const format = fPayload.format ||
8102
+ const format = functionResult.format ||
8104
8103
  (typeof value === "number"
8105
8104
  ? detectDateFormat(link.label, locale) || detectNumberFormat(link.label)
8106
8105
  : undefined);
@@ -8113,8 +8112,8 @@
8113
8112
  link,
8114
8113
  };
8115
8114
  }
8116
- function _createEvaluatedCell(fPayload, locale, cell) {
8117
- let { value, format, message } = fPayload;
8115
+ function _createEvaluatedCell(functionResult, locale, cell) {
8116
+ let { value, format, message } = functionResult;
8118
8117
  format = cell?.format || format;
8119
8118
  const formattedValue = formatValue(value, { format, locale });
8120
8119
  if (isEvaluationError(value)) {
@@ -10301,7 +10300,6 @@ stores.inject(MyMetaStore, storeInstance);
10301
10300
  return bars.find((bar, i) => i > startIndex && bar.height !== 0);
10302
10301
  }
10303
10302
 
10304
- // @ts-ignore
10305
10303
  window.Chart?.register(waterfallLinesPlugin);
10306
10304
  class ChartJsComponent extends owl.Component {
10307
10305
  static template = "o-spreadsheet-ChartJsComponent";
@@ -10334,7 +10332,7 @@ stores.inject(MyMetaStore, storeInstance);
10334
10332
  owl.onWillUnmount(() => this.chart?.destroy());
10335
10333
  owl.useEffect(() => {
10336
10334
  const runtime = this.chartRuntime;
10337
- if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
10335
+ if (runtime !== this.currentRuntime) {
10338
10336
  if (runtime.chartJsConfig.type !== this.currentRuntime.chartJsConfig.type) {
10339
10337
  this.chart?.destroy();
10340
10338
  this.createChart(deepCopy(runtime.chartJsConfig));
@@ -10349,7 +10347,6 @@ stores.inject(MyMetaStore, storeInstance);
10349
10347
  createChart(chartData) {
10350
10348
  const canvas = this.canvas.el;
10351
10349
  const ctx = canvas.getContext("2d");
10352
- // @ts-ignore
10353
10350
  this.chart = new window.Chart(ctx, chartData);
10354
10351
  }
10355
10352
  updateChartJs(chartRuntime) {
@@ -19101,7 +19098,7 @@ stores.inject(MyMetaStore, storeInstance);
19101
19098
  arg("include_column_titles (boolean, default=TRUE)", _t("Whether to include the column titles or not.")),
19102
19099
  arg("column_count (number, optional)", _t("number of columns")),
19103
19100
  ],
19104
- compute: function (pivotFormulaId, rowCount = { value: Number.MAX_VALUE }, includeTotal = { value: true }, includeColumnHeaders = { value: true }, columnCount = { value: Number.MAX_VALUE }) {
19101
+ compute: function (pivotFormulaId, rowCount = { value: 10000 }, includeTotal = { value: true }, includeColumnHeaders = { value: true }, columnCount = { value: Number.MAX_VALUE }) {
19105
19102
  const _pivotFormulaId = toString(pivotFormulaId);
19106
19103
  const _rowCount = toNumber(rowCount, this.locale);
19107
19104
  if (_rowCount < 0) {
@@ -19525,6 +19522,320 @@ stores.inject(MyMetaStore, storeInstance);
19525
19522
  UPLUS: UPLUS
19526
19523
  });
19527
19524
 
19525
+ const transformFromFactor = (factor) => ({
19526
+ transform: (x) => x * factor,
19527
+ inverseTransform: (x) => x / factor,
19528
+ });
19529
+ const standard = { transform: (x) => x, inverseTransform: (x) => x };
19530
+ const ANG2M = 1e-10;
19531
+ const IN2M = 0.0254;
19532
+ const PICAPT2M = IN2M / 72;
19533
+ const FT2M = 0.3048;
19534
+ const YD2M = 0.9144;
19535
+ const MI2M = 1609.34;
19536
+ const NMI2M = 1852;
19537
+ const LY2M = 9.46073047258e15;
19538
+ const UNITS = {
19539
+ // WEIGHT UNITs : Standard = gramme
19540
+ g: { ...standard, category: "weight" },
19541
+ u: { ...transformFromFactor(1.66053e-24), category: "weight" },
19542
+ grain: { ...transformFromFactor(0.0647989), category: "weight" },
19543
+ ozm: { ...transformFromFactor(28.3495), category: "weight" },
19544
+ lbm: { ...transformFromFactor(453.592), category: "weight" },
19545
+ stone: { ...transformFromFactor(6350.29), category: "weight" },
19546
+ sg: { ...transformFromFactor(14593.90294), category: "weight" },
19547
+ cwt: { ...transformFromFactor(45359.237), category: "weight" },
19548
+ uk_cwt: { ...transformFromFactor(50802.3), category: "weight" },
19549
+ ton: { ...transformFromFactor(907184.74), category: "weight" },
19550
+ uk_ton: { ...transformFromFactor(1016046.9), category: "weight" },
19551
+ // DISTANCE UNITS : Standard = meter
19552
+ m: { ...standard, category: "distance" },
19553
+ km: { ...transformFromFactor(1000), category: "distance" },
19554
+ ang: { ...transformFromFactor(ANG2M), category: "distance" },
19555
+ Picapt: { ...transformFromFactor(PICAPT2M), category: "distance" },
19556
+ pica: { ...transformFromFactor(IN2M / 6), category: "distance" },
19557
+ in: { ...transformFromFactor(IN2M), category: "distance" },
19558
+ ft: { ...transformFromFactor(FT2M), category: "distance" },
19559
+ yd: { ...transformFromFactor(YD2M), category: "distance" },
19560
+ ell: { ...transformFromFactor(1.143), category: "distance" },
19561
+ mi: { ...transformFromFactor(MI2M), category: "distance" },
19562
+ survey_mi: { ...transformFromFactor(1609.34), category: "distance" },
19563
+ Nmi: { ...transformFromFactor(NMI2M), category: "distance" },
19564
+ ly: { ...transformFromFactor(LY2M), category: "distance" },
19565
+ parsec: { ...transformFromFactor(3.0856775814914e16), category: "distance" },
19566
+ // TIME UNITS : Standard = second
19567
+ sec: { ...standard, category: "time" },
19568
+ min: { ...transformFromFactor(60), category: "time" },
19569
+ hr: { ...transformFromFactor(3600), category: "time" },
19570
+ day: { ...transformFromFactor(86400), category: "time" },
19571
+ yr: { ...transformFromFactor(31556952), category: "time" },
19572
+ // PRESSURE UNITS : Standard = Pascal
19573
+ Pa: { ...standard, category: "pressure" },
19574
+ bar: { ...transformFromFactor(100000), category: "pressure" },
19575
+ mmHg: { ...transformFromFactor(133.322), category: "pressure" },
19576
+ Torr: { ...transformFromFactor(133.322), category: "pressure" },
19577
+ psi: { ...transformFromFactor(6894.76), category: "pressure" },
19578
+ atm: { ...transformFromFactor(101325), category: "pressure" },
19579
+ // FORCE UNITS : Standard = Newton
19580
+ N: { ...standard, category: "force" },
19581
+ dyn: { ...transformFromFactor(1e-5), category: "force" },
19582
+ pond: { ...transformFromFactor(0.00980665), category: "force" },
19583
+ lbf: { ...transformFromFactor(4.44822), category: "force" },
19584
+ // ENERGY UNITS : Standard = Joule
19585
+ J: { ...standard, category: "energy" },
19586
+ eV: { ...transformFromFactor(1.60218e-19), category: "energy" },
19587
+ e: { ...transformFromFactor(1e-7), category: "energy" },
19588
+ flb: { ...transformFromFactor(1.3558179483), category: "energy" },
19589
+ c: { ...transformFromFactor(4.184), category: "energy" },
19590
+ cal: { ...transformFromFactor(4.1868), category: "energy" },
19591
+ BTU: { ...transformFromFactor(1055.06), category: "energy" },
19592
+ Wh: { ...transformFromFactor(3600), category: "energy" },
19593
+ HPh: { ...transformFromFactor(2684520), category: "energy" },
19594
+ // POWER UNITS : Standard = Watt
19595
+ W: { ...standard, category: "power" },
19596
+ PS: { ...transformFromFactor(735.499), category: "power" },
19597
+ HP: { ...transformFromFactor(745.7), category: "power" },
19598
+ // MAGNETISM UNITS : Standard = Tesla
19599
+ T: { ...standard, category: "magnetism" },
19600
+ ga: { ...transformFromFactor(1e-4), category: "magnetism" },
19601
+ // TEMPERATURE UNITS : Standard = Kelvin
19602
+ K: { ...standard, category: "temperature" },
19603
+ C: {
19604
+ transform: (T) => T + 273.15,
19605
+ inverseTransform: (T) => T - 273.15,
19606
+ category: "temperature",
19607
+ },
19608
+ F: {
19609
+ transform: (T) => ((T - 32) * 5) / 9 + 273.15,
19610
+ inverseTransform: (T) => ((T - 273.15) * 9) / 5 + 32,
19611
+ category: "temperature",
19612
+ },
19613
+ Rank: { ...transformFromFactor(5 / 9), category: "temperature" },
19614
+ Reau: {
19615
+ transform: (T) => T * 1.25 + 273.15,
19616
+ inverseTransform: (T) => (T - 273.15) / 1.25,
19617
+ category: "temperature",
19618
+ },
19619
+ // VOLUME UNITS : Standard = cubic meter
19620
+ "m^3": { ...standard, category: "volume", order: 3 },
19621
+ "ang^3": { ...transformFromFactor(Math.pow(ANG2M, 3)), category: "volume", order: 3 },
19622
+ "Picapt^3": { ...transformFromFactor(Math.pow(PICAPT2M, 3)), category: "volume", order: 3 },
19623
+ tsp: { ...transformFromFactor(4.92892e-6), category: "volume" },
19624
+ tspm: { ...transformFromFactor(5e-6), category: "volume" },
19625
+ tbs: { ...transformFromFactor(1.4786764825785619e-5), category: "volume" },
19626
+ "in^3": { ...transformFromFactor(Math.pow(IN2M, 3)), category: "volume", order: 3 },
19627
+ oz: { ...transformFromFactor(2.95735295625e-5), category: "volume" },
19628
+ cup: { ...transformFromFactor(0.000237), category: "volume" },
19629
+ pt: { ...transformFromFactor(0.0004731765), category: "volume" },
19630
+ uk_pt: { ...transformFromFactor(0.000568261), category: "volume" },
19631
+ qt: { ...transformFromFactor(0.0009463529), category: "volume" },
19632
+ l: { ...transformFromFactor(1e-3), category: "volume" },
19633
+ uk_qt: { ...transformFromFactor(0.0011365225), category: "volume" },
19634
+ gal: { ...transformFromFactor(0.0037854118), category: "volume" },
19635
+ uk_gal: { ...transformFromFactor(0.00454609), category: "volume" },
19636
+ "ft^3": { ...transformFromFactor(Math.pow(FT2M, 3)), category: "volume", order: 3 },
19637
+ bushel: { ...transformFromFactor(0.0352390704), category: "volume" },
19638
+ barrel: { ...transformFromFactor(0.158987295), category: "volume" },
19639
+ "yd^3": { ...transformFromFactor(Math.pow(YD2M, 3)), category: "volume", order: 3 },
19640
+ MTON: { ...transformFromFactor(1.13267386368), category: "volume" },
19641
+ GRT: { ...transformFromFactor(2.83168), category: "volume" },
19642
+ "mi^3": { ...transformFromFactor(Math.pow(MI2M, 3)), category: "volume", order: 3 },
19643
+ "Nmi^3": { ...transformFromFactor(Math.pow(NMI2M, 3)), category: "volume", order: 3 },
19644
+ "ly^3": { ...transformFromFactor(Math.pow(LY2M, 3)), category: "volume", order: 3 },
19645
+ // AREA UNITS : Standard = square meter
19646
+ "m^2": { ...standard, category: "area", order: 2 },
19647
+ "ang^2": { ...transformFromFactor(Math.pow(ANG2M, 2)), category: "area", order: 2 },
19648
+ "Picapt^2": { ...transformFromFactor(Math.pow(PICAPT2M, 2)), category: "area", order: 2 },
19649
+ "in^2": { ...transformFromFactor(Math.pow(IN2M, 2)), category: "area", order: 2 },
19650
+ "ft^2": { ...transformFromFactor(Math.pow(FT2M, 2)), category: "area", order: 2 },
19651
+ "yd^2": { ...transformFromFactor(Math.pow(YD2M, 2)), category: "area", order: 2 },
19652
+ ar: { ...transformFromFactor(100), category: "area" },
19653
+ Morgen: { ...transformFromFactor(2500), category: "area" },
19654
+ uk_acre: { ...transformFromFactor(4046.8564224), category: "area" },
19655
+ us_acre: { ...transformFromFactor(4046.8726098743), category: "area" },
19656
+ ha: { ...transformFromFactor(1e4), category: "area" },
19657
+ "mi^2": { ...transformFromFactor(Math.pow(MI2M, 2)), category: "area", order: 2 },
19658
+ "Nmi^2": { ...transformFromFactor(Math.pow(NMI2M, 2)), category: "area", order: 2 },
19659
+ "ly^2": { ...transformFromFactor(Math.pow(LY2M, 2)), category: "area", order: 2 },
19660
+ // INFORMATION UNITS : Standard = bit
19661
+ bit: { ...standard, category: "information" },
19662
+ byte: { ...transformFromFactor(8), category: "information" },
19663
+ // SPEED UNITS : Standard = m/s
19664
+ "m/s": { ...standard, category: "speed" },
19665
+ "m/hr": { ...transformFromFactor(1 / 3600), category: "speed" },
19666
+ "km/hr": { ...transformFromFactor(1 / 3.6), category: "speed" },
19667
+ mph: { ...transformFromFactor(0.44704), category: "speed" },
19668
+ kn: { ...transformFromFactor(0.5144444444), category: "speed" },
19669
+ admkn: { ...transformFromFactor(0.5147733333), category: "speed" },
19670
+ };
19671
+ const UNITS_ALIASES = {
19672
+ shweight: "cwt",
19673
+ lcwt: "uk_cwt",
19674
+ hweight: "uk_cwt",
19675
+ LTON: "uk_ton",
19676
+ brton: "uk_ton",
19677
+ pc: "parsec",
19678
+ Pica: "Picapt",
19679
+ d: "day",
19680
+ mn: "min",
19681
+ s: "sec",
19682
+ p: "Pa",
19683
+ at: "atm",
19684
+ dy: "dyn",
19685
+ ev: "eV",
19686
+ hh: "HPh",
19687
+ wh: "Wh",
19688
+ btu: "BTU",
19689
+ h: "HP",
19690
+ cel: "C",
19691
+ fah: "F",
19692
+ kel: "K",
19693
+ us_pt: "pt",
19694
+ L: "l",
19695
+ lt: "l",
19696
+ ang3: "ang^3",
19697
+ ft3: "ft^3",
19698
+ in3: "in^3",
19699
+ ly3: "ly^3",
19700
+ m3: "m^3",
19701
+ mi3: "mi^3",
19702
+ yd3: "yd^3",
19703
+ Nmi3: "Nmi^3",
19704
+ Picapt3: "Picapt^3",
19705
+ "Pica^3": "Picapt^3",
19706
+ Pica3: "Picapt^3",
19707
+ regton: "GRT",
19708
+ ang2: "ang^2",
19709
+ ft2: "ft^2",
19710
+ in2: "in^2",
19711
+ ly2: "ly^2",
19712
+ m2: "m^2",
19713
+ mi2: "mi^2",
19714
+ Nmi2: "Nmi^2",
19715
+ Picapt2: "Picapt^2",
19716
+ "Pica^2": "Picapt^2",
19717
+ Pica2: "Picapt^2",
19718
+ yd2: "yd^2",
19719
+ "m/h": "m/hr",
19720
+ "m/sec": "m/s",
19721
+ };
19722
+ const UNIT_PREFIXES = {
19723
+ "": 1,
19724
+ Y: 1e24,
19725
+ Z: 1e21,
19726
+ E: 1e18,
19727
+ P: 1e15,
19728
+ T: 1e12,
19729
+ G: 1e9,
19730
+ M: 1e6,
19731
+ k: 1e3,
19732
+ h: 1e2,
19733
+ da: 1e1,
19734
+ e: 1e1,
19735
+ d: 1e-1,
19736
+ c: 1e-2,
19737
+ m: 1e-3,
19738
+ u: 1e-6,
19739
+ n: 1e-9,
19740
+ p: 1e-12,
19741
+ f: 1e-15,
19742
+ a: 1e-18,
19743
+ z: 1e-21,
19744
+ y: 1e-21,
19745
+ Yi: Math.pow(2, 80),
19746
+ Zi: Math.pow(2, 70),
19747
+ Ei: Math.pow(2, 60),
19748
+ Pi: Math.pow(2, 50),
19749
+ Ti: Math.pow(2, 40),
19750
+ Gi: Math.pow(2, 30),
19751
+ Mi: Math.pow(2, 20),
19752
+ ki: Math.pow(2, 10),
19753
+ };
19754
+ const TRANSLATED_CATEGORIES = {
19755
+ weight: _t("Weight"),
19756
+ distance: _t("Distance"),
19757
+ time: _t("Time"),
19758
+ pressure: _t("Pressure"),
19759
+ force: _t("Force"),
19760
+ energy: _t("Energy"),
19761
+ power: _t("Power"),
19762
+ magnetism: _t("Magnetism"),
19763
+ temperature: _t("Temperature"),
19764
+ volume: _t("Volume"),
19765
+ area: _t("Area"),
19766
+ information: _t("Information"),
19767
+ speed: _t("Speed"),
19768
+ };
19769
+ function getTranslatedCategory(key) {
19770
+ return TRANSLATED_CATEGORIES[key] ?? "";
19771
+ }
19772
+ function getTransformation(key) {
19773
+ for (const [prefix, value] of Object.entries(UNIT_PREFIXES)) {
19774
+ if (prefix && !key.startsWith(prefix))
19775
+ continue;
19776
+ const _key = key.slice(prefix.length);
19777
+ let conversion = UNITS[_key];
19778
+ if (!conversion && UNITS_ALIASES[_key]) {
19779
+ conversion = UNITS[UNITS_ALIASES[_key]];
19780
+ }
19781
+ if (conversion) {
19782
+ return {
19783
+ ...conversion,
19784
+ factor: conversion.order ? Math.pow(value, conversion.order) : value,
19785
+ };
19786
+ }
19787
+ }
19788
+ return;
19789
+ }
19790
+
19791
+ // -----------------------------------------------------------------------------
19792
+ // CONVERT
19793
+ // -----------------------------------------------------------------------------
19794
+ const CONVERT = {
19795
+ description: _t("Converts a numeric value to a different unit of measure."),
19796
+ args: [
19797
+ arg("value (number)", _t("the numeric value in start_unit to convert to end_unit")),
19798
+ arg("start_unit (string)", _t("The starting unit, the unit currently assigned to value")),
19799
+ arg("end_unit (string)", _t("The unit of measure into which to convert value")),
19800
+ ],
19801
+ compute: function (value, startUnit, endUnit) {
19802
+ const _value = toNumber(value, this.locale);
19803
+ const _startUnit = toString(startUnit);
19804
+ const _endUnit = toString(endUnit);
19805
+ const startConversion = getTransformation(_startUnit);
19806
+ const endConversion = getTransformation(_endUnit);
19807
+ if (!startConversion) {
19808
+ return {
19809
+ value: CellErrorType.GenericError,
19810
+ message: _t("Invalid units of measure ('%s')", _startUnit),
19811
+ };
19812
+ }
19813
+ if (!endConversion) {
19814
+ return {
19815
+ value: CellErrorType.GenericError,
19816
+ message: _t("Invalid units of measure ('%s')", _endUnit),
19817
+ };
19818
+ }
19819
+ if (startConversion.category !== endConversion.category) {
19820
+ return {
19821
+ value: CellErrorType.GenericError,
19822
+ message: _t("Incompatible units of measure ('%s' vs '%s')", getTranslatedCategory(startConversion.category), getTranslatedCategory(endConversion.category)),
19823
+ };
19824
+ }
19825
+ return {
19826
+ value: endConversion.inverseTransform(startConversion.factor * startConversion.transform(_value)) /
19827
+ endConversion.factor,
19828
+ format: value?.format,
19829
+ };
19830
+ },
19831
+ isExported: true,
19832
+ };
19833
+
19834
+ var parser = /*#__PURE__*/Object.freeze({
19835
+ __proto__: null,
19836
+ CONVERT: CONVERT
19837
+ });
19838
+
19528
19839
  const DEFAULT_STARTING_AT = 1;
19529
19840
  /** Regex matching all the words in a string */
19530
19841
  const wordRegex = /[A-Za-zÀ-ÖØ-öø-ÿ]+/g;
@@ -19942,6 +20253,7 @@ stores.inject(MyMetaStore, storeInstance);
19942
20253
  { name: _t("Text"), functions: text },
19943
20254
  { name: _t("Engineering"), functions: engineering },
19944
20255
  { name: _t("Web"), functions: web },
20256
+ { name: _t("Parser"), functions: parser },
19945
20257
  ];
19946
20258
  const functionNameRegex = /^[A-Z0-9\_\.]+$/;
19947
20259
  class FunctionRegistry extends Registry {
@@ -19953,41 +20265,127 @@ stores.inject(MyMetaStore, storeInstance);
19953
20265
  }
19954
20266
  const descr = addMetaInfoFromArg(addDescr);
19955
20267
  validateArguments(descr.args);
19956
- this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr), name), name);
20268
+ this.mapping[name] = createComputeFunction(descr, name);
19957
20269
  super.add(name, descr);
19958
20270
  return this;
19959
20271
  }
19960
20272
  }
19961
- function addInputHandling(descr) {
19962
- function computeWithInputHandling(...args) {
20273
+ const functionRegistry = new FunctionRegistry();
20274
+ for (let category of categories) {
20275
+ const fns = category.functions;
20276
+ for (let name in fns) {
20277
+ const addDescr = fns[name];
20278
+ addDescr.category = addDescr.category || category.name;
20279
+ name = name.replace(/_/g, ".");
20280
+ functionRegistry.add(name, { isExported: false, ...addDescr });
20281
+ }
20282
+ }
20283
+ const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
20284
+ function createComputeFunction(descr, functionName) {
20285
+ function runtimeCompute(...args) {
20286
+ try {
20287
+ return vectorizedCompute.apply(this, args);
20288
+ }
20289
+ catch (e) {
20290
+ return handleError(e, functionName);
20291
+ }
20292
+ }
20293
+ function vectorizedCompute(...args) {
20294
+ let countVectorizableCol = 1;
20295
+ let countVectorizableRow = 1;
20296
+ let vectorizableColLimit = Infinity;
20297
+ let vectorizableRowLimit = Infinity;
20298
+ let vectorArgsType = undefined;
20299
+ //#region Compute vectorisation limits
19963
20300
  for (let i = 0; i < args.length; i++) {
19964
20301
  const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
19965
20302
  const arg = args[i];
19966
20303
  if (isMatrix(arg) && !argDefinition.acceptMatrix) {
19967
- if (arg.length !== 1 || arg[0].length !== 1) {
19968
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be a single value or a single cell reference, not a range.", argDefinition.name));
20304
+ // if argDefinition does not accept a matrix but arg is still a matrix
20305
+ // --> triggers the arguments vectorization
20306
+ const nColumns = arg.length;
20307
+ const nRows = arg[0].length;
20308
+ if (nColumns !== 1 || nRows !== 1) {
20309
+ vectorArgsType ??= new Array(args.length);
20310
+ if (nColumns !== 1 && nRows !== 1) {
20311
+ vectorArgsType[i] = "matrix";
20312
+ countVectorizableCol = Math.max(countVectorizableCol, nColumns);
20313
+ countVectorizableRow = Math.max(countVectorizableRow, nRows);
20314
+ vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
20315
+ vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
20316
+ }
20317
+ else if (nColumns !== 1) {
20318
+ vectorArgsType[i] = "horizontal";
20319
+ countVectorizableCol = Math.max(countVectorizableCol, nColumns);
20320
+ vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
20321
+ }
20322
+ else if (nRows !== 1) {
20323
+ vectorArgsType[i] = "vertical";
20324
+ countVectorizableRow = Math.max(countVectorizableRow, nRows);
20325
+ vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
20326
+ }
20327
+ }
20328
+ else {
20329
+ args[i] = arg[0][0];
19969
20330
  }
19970
- args[i] = arg[0][0];
19971
20331
  }
19972
20332
  if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
19973
20333
  throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
19974
20334
  }
19975
20335
  }
19976
- return descr.compute.apply(this, args);
20336
+ //#endregion
20337
+ if (countVectorizableCol === 1 && countVectorizableRow === 1) {
20338
+ // either this function is not vectorized or it ends up with a 1x1 dimension
20339
+ return computeFunctionToObject.apply(this, args);
20340
+ }
20341
+ const getArgOffset = (i, j) => args.map((arg, index) => {
20342
+ switch (vectorArgsType?.[index]) {
20343
+ case "matrix":
20344
+ return arg[i][j];
20345
+ case "horizontal":
20346
+ return arg[i][0];
20347
+ case "vertical":
20348
+ return arg[0][j];
20349
+ case undefined:
20350
+ return arg;
20351
+ }
20352
+ });
20353
+ return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
20354
+ if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
20355
+ return notAvailableError;
20356
+ }
20357
+ const singleCellComputeResult = computeFunctionToObject.apply(this, getArgOffset(col, row));
20358
+ // In the case where the user tries to vectorize arguments of an array formula, we will get an
20359
+ // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
20360
+ // we won't be able to return the values.
20361
+ // In this case, we keep the first element of each spreading part, just as Excel does, and
20362
+ // create an array with these parts.
20363
+ // For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
20364
+ // range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
20365
+ // for the value in A2). In this case, we will simply take the first value of each matrix and
20366
+ // return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
20367
+ return isMatrix(singleCellComputeResult)
20368
+ ? singleCellComputeResult[0][0]
20369
+ : singleCellComputeResult;
20370
+ });
19977
20371
  }
19978
- return computeWithInputHandling;
19979
- }
19980
- function addErrorHandling(compute, functionName) {
19981
- return function (...args) {
19982
- try {
19983
- return compute.apply(this, args);
20372
+ function computeFunctionToObject(...args) {
20373
+ const result = descr.compute.apply(this, args);
20374
+ if (!isMatrix(result)) {
20375
+ if (typeof result === "object" && result !== null && "value" in result) {
20376
+ replaceFunctionNamePlaceholder(result, functionName);
20377
+ return result;
20378
+ }
20379
+ return { value: result };
19984
20380
  }
19985
- catch (e) {
19986
- return handleError(e, functionName);
20381
+ if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
20382
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, functionName));
20383
+ return result;
19987
20384
  }
19988
- };
20385
+ return matrixMap(result, (row) => ({ value: row }));
20386
+ }
20387
+ return runtimeCompute;
19989
20388
  }
19990
- const implementationErrorMessage = _t("An unexpected error occurred. Submit a support ticket at odoo.com/help.");
19991
20389
  function handleError(e, functionName) {
19992
20390
  // the error could be an user error (instance of EvaluationError)
19993
20391
  // or a javascript error (instance of Error)
@@ -20006,42 +20404,16 @@ stores.inject(MyMetaStore, storeInstance);
20006
20404
  return (obj?.value !== undefined &&
20007
20405
  typeof obj.value === "string");
20008
20406
  }
20009
- function hasStringMessage(obj) {
20010
- return (obj?.message !== undefined &&
20011
- typeof obj.message === "string");
20012
- }
20013
- function addResultHandling(compute, functionName) {
20014
- return function computeWithResultHandling(...args) {
20015
- const result = compute.apply(this, args);
20016
- if (!isMatrix(result)) {
20017
- if (typeof result === "object" && result !== null && "value" in result) {
20018
- replaceFunctionNamePlaceholder(result, functionName);
20019
- return result;
20020
- }
20021
- return { value: result };
20022
- }
20023
- if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
20024
- matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, functionName));
20025
- return result;
20026
- }
20027
- return matrixMap(result, (row) => ({ value: row }));
20028
- };
20029
- }
20030
- function replaceFunctionNamePlaceholder(fPayload, functionName) {
20407
+ function replaceFunctionNamePlaceholder(functionResult, functionName) {
20031
20408
  // for performance reasons: change in place and only if needed
20032
- if (fPayload.message?.includes("[[FUNCTION_NAME]]")) {
20033
- fPayload.message = fPayload.message.replace("[[FUNCTION_NAME]]", functionName);
20409
+ if (functionResult.message?.includes("[[FUNCTION_NAME]]")) {
20410
+ functionResult.message = functionResult.message.replace("[[FUNCTION_NAME]]", functionName);
20034
20411
  }
20035
20412
  }
20036
- const functionRegistry = new FunctionRegistry();
20037
- for (let category of categories) {
20038
- const fns = category.functions;
20039
- for (let name in fns) {
20040
- const addDescr = fns[name];
20041
- addDescr.category = addDescr.category || category.name;
20042
- name = name.replace(/_/g, ".");
20043
- functionRegistry.add(name, { isExported: false, ...addDescr });
20044
- }
20413
+ const implementationErrorMessage = _t("An unexpected error occurred. Submit a support ticket at odoo.com/help.");
20414
+ function hasStringMessage(obj) {
20415
+ return (obj?.message !== undefined &&
20416
+ typeof obj.message === "string");
20045
20417
  }
20046
20418
 
20047
20419
  autoCompleteProviders.add("functions", {
@@ -21490,6 +21862,7 @@ stores.inject(MyMetaStore, storeInstance);
21490
21862
 
21491
21863
  const functions$1 = functionRegistry.content;
21492
21864
  const OPERATOR_MAP = {
21865
+ // export for test
21493
21866
  "=": "EQ",
21494
21867
  "+": "ADD",
21495
21868
  "-": "MINUS",
@@ -21504,6 +21877,7 @@ stores.inject(MyMetaStore, storeInstance);
21504
21877
  "&": "CONCATENATE",
21505
21878
  };
21506
21879
  const UNARY_OPERATOR_MAP = {
21880
+ // export for test
21507
21881
  "-": "UMINUS",
21508
21882
  "+": "UPLUS",
21509
21883
  "%": "UNARY.PERCENT",
@@ -22792,8 +23166,7 @@ stores.inject(MyMetaStore, storeInstance);
22792
23166
  /**
22793
23167
  * Get a default chart js configuration
22794
23168
  */
22795
- function getDefaultChartJsRuntime(chart, labels, fontColor, args) {
22796
- const { format, locale, truncateLabels, horizontalChart } = args;
23169
+ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels = true, horizontalChart, }) {
22797
23170
  const chartTitle = chart.title.text ? chart.title : { ...chart.title, content: "" };
22798
23171
  const options = {
22799
23172
  // https://www.chartjs.org/docs/latest/general/responsive.html
@@ -22969,7 +23342,6 @@ stores.inject(MyMetaStore, storeInstance);
22969
23342
  if ("chartJsConfig" in runtime) {
22970
23343
  const config = deepCopy(runtime.chartJsConfig);
22971
23344
  config.plugins = [backgroundColorChartJSPlugin];
22972
- // @ts-ignore
22973
23345
  const chart = new window.Chart(canvas, config);
22974
23346
  const imgContent = chart.toBase64Image();
22975
23347
  chart.destroy();
@@ -23890,13 +24262,11 @@ stores.inject(MyMetaStore, storeInstance);
23890
24262
  }
23891
24263
  let missingTimeAdapterAlreadyWarned = false;
23892
24264
  function isLuxonTimeAdapterInstalled() {
23893
- // @ts-ignore
23894
24265
  if (!window.Chart) {
23895
24266
  return false;
23896
24267
  }
23897
24268
  // @ts-ignore
23898
24269
  const adapter = new window.Chart._adapters._date({});
23899
- // @ts-ignore
23900
24270
  const isInstalled = adapter._id === "luxon";
23901
24271
  if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
23902
24272
  missingTimeAdapterAlreadyWarned = true;
@@ -23913,9 +24283,7 @@ stores.inject(MyMetaStore, storeInstance);
23913
24283
  generateLabels(chart) {
23914
24284
  // color the legend labels with the dataset color, without any transparency
23915
24285
  const { data } = chart;
23916
- /** @ts-ignore */
23917
- const labels = window.Chart.defaults.plugins.legend.labels
23918
- .generateLabels(chart);
24286
+ const labels = window.Chart.defaults.plugins.legend.labels.generateLabels(chart);
23919
24287
  for (const [index, label] of labels.entries()) {
23920
24288
  label.fillStyle = data.datasets[index].borderColor;
23921
24289
  }
@@ -33157,21 +33525,25 @@ stores.inject(MyMetaStore, storeInstance);
33157
33525
 
33158
33526
  function useHighlightsOnHover(ref, highlightProvider) {
33159
33527
  const hoverState = useHoveredElement(ref);
33160
- const stores = useStoreProvider();
33161
33528
  useHighlights({
33162
33529
  get highlights() {
33163
33530
  return hoverState.hovered ? highlightProvider.highlights : [];
33164
33531
  },
33165
33532
  });
33166
- owl.useEffect(() => {
33167
- stores.trigger("store-updated");
33168
- }, () => [hoverState.hovered]);
33169
33533
  }
33170
33534
  function useHighlights(highlightProvider) {
33535
+ const stores = useStoreProvider();
33171
33536
  const store = useLocalStore(HighlightStore);
33172
33537
  owl.onMounted(() => {
33173
33538
  store.register(highlightProvider);
33174
33539
  });
33540
+ let currentHighlights = highlightProvider.highlights;
33541
+ owl.useEffect((highlights) => {
33542
+ if (!deepEquals(highlights, currentHighlights)) {
33543
+ currentHighlights = highlights;
33544
+ stores.trigger("store-updated");
33545
+ }
33546
+ }, () => [highlightProvider.highlights]);
33175
33547
  }
33176
33548
 
33177
33549
  css /* scss */ `
@@ -45765,7 +46137,7 @@ stores.inject(MyMetaStore, storeInstance);
45765
46137
  return relsFile;
45766
46138
  }
45767
46139
 
45768
- const EXCEL_IMPORT_VERSION = 16;
46140
+ const EXCEL_IMPORT_VERSION = 17;
45769
46141
  class XlsxReader {
45770
46142
  warningManager;
45771
46143
  xmls;
@@ -45897,7 +46269,7 @@ stores.inject(MyMetaStore, storeInstance);
45897
46269
  * a breaking change is made in the way the state is handled, and an upgrade
45898
46270
  * function should be defined
45899
46271
  */
45900
- const CURRENT_VERSION = 16;
46272
+ const CURRENT_VERSION = 17;
45901
46273
  const INITIAL_SHEET_ID = "Sheet1";
45902
46274
  /**
45903
46275
  * This function tries to load anything that could look like a valid
@@ -49234,10 +49606,12 @@ stores.inject(MyMetaStore, storeInstance);
49234
49606
  if (!sheetMap)
49235
49607
  return [];
49236
49608
  const mergeIds = new Set();
49237
- for (const { col, row } of positions(zone)) {
49238
- const mergeId = sheetMap[col]?.[row];
49239
- if (mergeId) {
49240
- mergeIds.add(mergeId);
49609
+ for (let col = zone.left; col <= zone.right; col++) {
49610
+ for (let row = zone.top; row <= zone.bottom; row++) {
49611
+ const mergeId = sheetMap[col]?.[row];
49612
+ if (mergeId) {
49613
+ mergeIds.add(mergeId);
49614
+ }
49241
49615
  }
49242
49616
  }
49243
49617
  return Array.from(mergeIds)
@@ -53105,7 +53479,13 @@ stores.inject(MyMetaStore, storeInstance);
53105
53479
  const queue = Array.from(ranges).reverse();
53106
53480
  while (queue.length > 0) {
53107
53481
  const range = queue.pop();
53108
- visited.addMany(positions(range.zone).map((position) => ({ sheetId: range.sheetId, ...position })));
53482
+ const zone = range.zone;
53483
+ const sheetId = range.sheetId;
53484
+ for (let col = zone.left; col <= zone.right; col++) {
53485
+ for (let row = zone.top; row <= zone.bottom; row++) {
53486
+ visited.add({ sheetId, col, row });
53487
+ }
53488
+ }
53109
53489
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
53110
53490
  const nextInQueue = {};
53111
53491
  for (const position of impactedPositions) {
@@ -53121,7 +53501,16 @@ stores.inject(MyMetaStore, storeInstance);
53121
53501
  queue.push(...zones.map((zone) => ({ sheetId, zone })));
53122
53502
  }
53123
53503
  }
53124
- visited.deleteMany(ranges.flatMap((r) => positions(r.zone).map((position) => ({ sheetId: r.sheetId, ...position }))));
53504
+ // remove initial ranges
53505
+ for (const range of ranges) {
53506
+ const zone = range.zone;
53507
+ const sheetId = range.sheetId;
53508
+ for (let col = zone.left; col <= zone.right; col++) {
53509
+ for (let row = zone.top; row <= zone.bottom; row++) {
53510
+ visited.delete({ sheetId, col, row });
53511
+ }
53512
+ }
53513
+ }
53125
53514
  return visited;
53126
53515
  }
53127
53516
  }
@@ -53252,7 +53641,7 @@ stores.inject(MyMetaStore, storeInstance);
53252
53641
  return this.sheets[position.sheetId].getValue(position) === 1;
53253
53642
  }
53254
53643
  clear() {
53255
- const insertions = this.insertions;
53644
+ const insertions = [...this];
53256
53645
  this.insertions = [];
53257
53646
  for (const sheetId in this.sheets) {
53258
53647
  this.sheets[sheetId].clear();
@@ -53596,6 +53985,7 @@ stores.inject(MyMetaStore, storeInstance);
53596
53985
  }
53597
53986
  finally {
53598
53987
  this.cellsBeingComputed.delete(cellId);
53988
+ this.nextPositionsToUpdate.delete(position);
53599
53989
  }
53600
53990
  }
53601
53991
  computeAndSave(position) {
@@ -53622,8 +54012,33 @@ stores.inject(MyMetaStore, storeInstance);
53622
54012
  forEachSpreadPositionInMatrix(nbColumns, nbRows,
53623
54013
  // thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
53624
54014
  this.spreadValues(formulaPosition, formulaReturn));
54015
+ this.invalidatePositionsDependingOnSpread(formulaPosition, nbColumns, nbRows);
53625
54016
  return createEvaluatedCell(nullValueToZeroValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
53626
54017
  }
54018
+ invalidatePositionsDependingOnSpread(arrayFormulaPosition, nbColumns, nbRows) {
54019
+ // the result matrix is split in 2 zones to exclude the array formula position
54020
+ const top = arrayFormulaPosition.row;
54021
+ const left = arrayFormulaPosition.col;
54022
+ const bottom = top + nbRows - 1;
54023
+ const leftColumnZone = {
54024
+ top: top + 1,
54025
+ bottom,
54026
+ left,
54027
+ right: left,
54028
+ };
54029
+ const rightPartZone = {
54030
+ top,
54031
+ bottom,
54032
+ left: left + 1,
54033
+ right: left + nbColumns - 1,
54034
+ };
54035
+ const sheetId = arrayFormulaPosition.sheetId;
54036
+ const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
54037
+ { sheetId, zone: rightPartZone },
54038
+ { sheetId, zone: leftColumnZone },
54039
+ ]);
54040
+ this.nextPositionsToUpdate.addMany(invalidatedPositions);
54041
+ }
53627
54042
  assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
53628
54043
  const numberOfCols = this.getters.getNumberCols(sheetId);
53629
54044
  const numberOfRows = this.getters.getNumberRows(sheetId);
@@ -53654,14 +54069,15 @@ stores.inject(MyMetaStore, storeInstance);
53654
54069
  }
53655
54070
  updateSpreadRelation({ sheetId, col, row, }) {
53656
54071
  const arrayFormulaPosition = { sheetId, col, row };
53657
- return (i, j) => {
54072
+ const updateSpreadRelation = (i, j) => {
53658
54073
  const position = { sheetId, col: i + col, row: j + row };
53659
54074
  this.spreadingRelations.addRelation({ resultPosition: position, arrayFormulaPosition });
53660
54075
  };
54076
+ return updateSpreadRelation;
53661
54077
  }
53662
54078
  checkCollision(formulaPosition) {
53663
54079
  const { sheetId, col, row } = formulaPosition;
53664
- return (i, j) => {
54080
+ const checkCollision = (i, j) => {
53665
54081
  const position = { sheetId: sheetId, col: i + col, row: j + row };
53666
54082
  const rawCell = this.getters.getCell(position);
53667
54083
  if (rawCell?.content ||
@@ -53671,17 +54087,16 @@ stores.inject(MyMetaStore, storeInstance);
53671
54087
  }
53672
54088
  this.blockedArrayFormulas.delete(formulaPosition);
53673
54089
  };
54090
+ return checkCollision;
53674
54091
  }
53675
54092
  spreadValues({ sheetId, col, row }, matrixResult) {
53676
- return (i, j) => {
54093
+ const spreadValues = (i, j) => {
53677
54094
  const position = { sheetId, col: i + col, row: j + row };
53678
54095
  const cell = this.getters.getCell(position);
53679
54096
  const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
53680
54097
  this.evaluatedCells.set(position, evaluatedCell);
53681
- // check if formula dependencies present in the spread zone
53682
- // if so, they need to be recomputed
53683
- this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([position]));
53684
54098
  };
54099
+ return spreadValues;
53685
54100
  }
53686
54101
  invalidateSpreading(position) {
53687
54102
  if (!this.spreadingRelations.isArrayFormula(position)) {
@@ -53736,12 +54151,12 @@ stores.inject(MyMetaStore, storeInstance);
53736
54151
  * rather than appearing empty. This indicates that the
53737
54152
  * cell is the result of a non-empty content.
53738
54153
  */
53739
- function nullValueToZeroValue(fPayload) {
53740
- if (fPayload.value === null || fPayload.value === undefined) {
53741
- // 'fPayload.value === undefined' is supposed to never happen, it's a safety net for javascript use
53742
- return { ...fPayload, value: 0 };
54154
+ function nullValueToZeroValue(functionResult) {
54155
+ if (functionResult.value === null || functionResult.value === undefined) {
54156
+ // 'functionResult.value === undefined' is supposed to never happen, it's a safety net for javascript use
54157
+ return { ...functionResult, value: 0 };
53743
54158
  }
53744
- return fPayload;
54159
+ return functionResult;
53745
54160
  }
53746
54161
  function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
53747
54162
  compilationParams.evalContext.__originCellXC = lazy(() => {
@@ -67832,9 +68247,9 @@ stores.inject(MyMetaStore, storeInstance);
67832
68247
  exports.tokenize = tokenize;
67833
68248
 
67834
68249
 
67835
- __info__.version = "17.4.0-alpha.12";
67836
- __info__.date = "2024-07-08T05:43:07.933Z";
67837
- __info__.hash = "7cfe14a";
68250
+ __info__.version = "17.4.0-alpha.13";
68251
+ __info__.date = "2024-07-11T06:36:58.556Z";
68252
+ __info__.hash = "e0f506b";
67838
68253
 
67839
68254
 
67840
68255
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);