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