@odoo/o-spreadsheet 16.1.28 → 16.1.33

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.
@@ -309,15 +309,76 @@ for (let font of fontSizes) {
309
309
  // -----------------------------------------------------------------------------
310
310
  // Date Type
311
311
  // -----------------------------------------------------------------------------
312
+ /**
313
+ * A DateTime object that can be used to manipulate spreadsheet dates.
314
+ * Conceptually, a spreadsheet date is simply a number with a date format,
315
+ * and it is timezone-agnostic.
316
+ * This DateTime object consistently uses UTC time to represent a naive date and time.
317
+ */
318
+ class DateTime {
319
+ constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
320
+ this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
321
+ }
322
+ static fromTimestamp(timestamp) {
323
+ const date = new Date(timestamp);
324
+ return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
325
+ }
326
+ static now() {
327
+ const now = new Date();
328
+ return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
329
+ }
330
+ toString() {
331
+ return this.jsDate.toString();
332
+ }
333
+ getTime() {
334
+ return this.jsDate.getTime();
335
+ }
336
+ getFullYear() {
337
+ return this.jsDate.getUTCFullYear();
338
+ }
339
+ getMonth() {
340
+ return this.jsDate.getUTCMonth();
341
+ }
342
+ getDate() {
343
+ return this.jsDate.getUTCDate();
344
+ }
345
+ getDay() {
346
+ return this.jsDate.getUTCDay();
347
+ }
348
+ getHours() {
349
+ return this.jsDate.getUTCHours();
350
+ }
351
+ getMinutes() {
352
+ return this.jsDate.getUTCMinutes();
353
+ }
354
+ getSeconds() {
355
+ return this.jsDate.getUTCSeconds();
356
+ }
357
+ setFullYear(year) {
358
+ this.jsDate.setFullYear(year);
359
+ }
360
+ setDate(date) {
361
+ this.jsDate.setUTCDate(date);
362
+ }
363
+ setHours(hours) {
364
+ this.jsDate.setUTCHours(hours);
365
+ }
366
+ setMinutes(minutes) {
367
+ this.jsDate.setUTCMinutes(minutes);
368
+ }
369
+ setSeconds(seconds) {
370
+ this.jsDate.setUTCSeconds(seconds);
371
+ }
372
+ }
312
373
  // -----------------------------------------------------------------------------
313
374
  // Parsing
314
375
  // -----------------------------------------------------------------------------
315
- const INITIAL_1900_DAY = new Date(1899, 11, 30);
376
+ const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
316
377
  const MS_PER_DAY = 24 * 60 * 60 * 1000;
317
378
  const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
318
- const CURRENT_YEAR = new Date().getFullYear();
319
- const INITIAL_JS_DAY = new Date(0);
320
- const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
379
+ const CURRENT_YEAR = DateTime.now().getFullYear();
380
+ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
381
+ const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
321
382
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
322
383
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
323
384
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
@@ -366,7 +427,7 @@ function _parseDateTime(str) {
366
427
  return {
367
428
  value: date.value + time.value,
368
429
  format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
369
- jsDate: new Date(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
430
+ jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
370
431
  };
371
432
  }
372
433
  return date || time;
@@ -383,13 +444,13 @@ function parseDate(str, dateFormat) {
383
444
  const day = Number(parts[dayIndex]);
384
445
  const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
385
446
  const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
386
- const jsDate = new Date(year, month - 1, day);
447
+ const jsDate = new DateTime(year, month - 1, day);
387
448
  const sep = str.match(/\/|-|\s/)[0];
388
449
  if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
389
450
  // invalid date
390
451
  return null;
391
452
  }
392
- const delta = jsDate - INITIAL_1900_DAY;
453
+ const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
393
454
  let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
394
455
  if (parts[yearIndex]) {
395
456
  format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
@@ -449,7 +510,7 @@ function parseTime(str) {
449
510
  if (hours >= 24) {
450
511
  format = "hhhh:mm:ss";
451
512
  }
452
- const jsDate = new Date(1899, 11, 30, hours, minutes, seconds);
513
+ const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
453
514
  return {
454
515
  value: hours / 24 + minutes / 1440 + seconds / 86400,
455
516
  format: format,
@@ -463,7 +524,7 @@ function parseTime(str) {
463
524
  // -----------------------------------------------------------------------------
464
525
  function numberToJsDate(value) {
465
526
  const truncValue = Math.trunc(value);
466
- let date = new Date(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
527
+ let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
467
528
  let time = value - truncValue;
468
529
  time = time < 0 ? 1 + time : time;
469
530
  const hours = Math.round(time * 24);
@@ -480,7 +541,7 @@ function jsDateToRoundNumber(date) {
480
541
  }
481
542
  /** Return the number of days in the current month of the given date */
482
543
  function getDaysInMonth(date) {
483
- return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
544
+ return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
484
545
  }
485
546
  function isLastDayOfMonth(date) {
486
547
  return getDaysInMonth(date) === date.getDate();
@@ -498,7 +559,7 @@ function addMonthsToDate(date, months, keepEndOfMonth) {
498
559
  const yStart = date.getFullYear();
499
560
  const mStart = date.getMonth();
500
561
  const dStart = date.getDate();
501
- const jsDate = new Date(yStart, mStart + months);
562
+ const jsDate = new DateTime(yStart, mStart + months, 1);
502
563
  if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
503
564
  jsDate.setDate(getDaysInMonth(jsDate));
504
565
  }
@@ -852,7 +913,7 @@ function isBoolean(str) {
852
913
  function isDateTime(str) {
853
914
  return parseDateTime(str) !== null;
854
915
  }
855
- const MARKDOWN_LINK_REGEX = /^\[([^\[]+)\]\((.+)\)$/;
916
+ const MARKDOWN_LINK_REGEX = /^\[(.+)\]\((.+)\)$/;
856
917
  //link must start with http or https
857
918
  //https://stackoverflow.com/a/3809435/4760614
858
919
  const WEB_LINK_REGEX = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;
@@ -1347,8 +1408,10 @@ function isSameColor(color1, color2) {
1347
1408
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
1348
1409
  // Same as above, but matches the exact string (nothing before or after)
1349
1410
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
1350
- /** Reference of a column header (eg. A, AB) */
1351
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
1411
+ /** Reference of a column header (eg. A, AB, $A) */
1412
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
1413
+ /** Reference of a row header (eg. 1, $1) */
1414
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
1352
1415
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
1353
1416
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
1354
1417
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -1378,6 +1441,9 @@ function isRowReference(xc) {
1378
1441
  function isColHeader(str) {
1379
1442
  return colHeader.test(str);
1380
1443
  }
1444
+ function isRowHeader(str) {
1445
+ return rowHeader.test(str);
1446
+ }
1381
1447
  /**
1382
1448
  * Return true if the given xc is the reference of a single cell,
1383
1449
  * without any specified sheet (e.g. A1)
@@ -1876,7 +1942,7 @@ function formatJSTime(jsDate, format) {
1876
1942
  .map((p) => {
1877
1943
  switch (p) {
1878
1944
  case "hhhh":
1879
- const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
1945
+ const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
1880
1946
  return helapsedHours.toString();
1881
1947
  case "hh":
1882
1948
  return hours.toString().padStart(2, "0");
@@ -1939,27 +2005,30 @@ function detectFormat(content) {
1939
2005
  }
1940
2006
  function createLargeNumberFormat(format, magnitude, postFix) {
1941
2007
  const internalFormat = parseFormat(format || "#,##0");
1942
- const largeNumberFormat = internalFormat
1943
- .map((formatPart) => {
1944
- if (formatPart.type === "NUMBER") {
1945
- return [
1946
- {
1947
- ...formatPart,
1948
- format: {
1949
- ...formatPart.format,
1950
- magnitude,
1951
- decimalPart: undefined,
1952
- },
1953
- },
1954
- {
1955
- type: "STRING",
1956
- format: postFix,
1957
- },
1958
- ];
2008
+ const largeNumberFormat = [];
2009
+ for (let i = 0; i < internalFormat.length; i++) {
2010
+ const formatPart = internalFormat[i];
2011
+ if (formatPart.type !== "NUMBER") {
2012
+ largeNumberFormat.push(formatPart);
2013
+ continue;
1959
2014
  }
1960
- return formatPart;
1961
- })
1962
- .flat();
2015
+ largeNumberFormat.push({
2016
+ ...formatPart,
2017
+ format: {
2018
+ ...formatPart.format,
2019
+ magnitude,
2020
+ decimalPart: undefined,
2021
+ },
2022
+ });
2023
+ largeNumberFormat.push({
2024
+ type: "STRING",
2025
+ format: postFix,
2026
+ });
2027
+ const nextFormatPart = internalFormat[i + 1];
2028
+ if ((nextFormatPart === null || nextFormatPart === void 0 ? void 0 : nextFormatPart.type) === "STRING" && ["k", "m", "b"].includes(nextFormatPart.format)) {
2029
+ i++;
2030
+ }
2031
+ }
1963
2032
  return convertInternalFormatToFormat(largeNumberFormat);
1964
2033
  }
1965
2034
  function changeDecimalPlaces(format, step) {
@@ -2167,18 +2236,10 @@ class RangeImpl {
2167
2236
  if (isFullCol) {
2168
2237
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2169
2238
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2170
- if (zone.left === zone.right) {
2171
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2172
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2173
- }
2174
2239
  }
2175
2240
  if (isFullRow) {
2176
2241
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2177
2242
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2178
- if (zone.top === zone.bottom) {
2179
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2180
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2181
- }
2182
2243
  }
2183
2244
  return parts;
2184
2245
  }
@@ -3612,64 +3673,65 @@ exports.CommandResult = void 0;
3612
3673
  CommandResult[CommandResult["InvalidFigureId"] = 28] = "InvalidFigureId";
3613
3674
  CommandResult[CommandResult["InputAlreadyFocused"] = 29] = "InputAlreadyFocused";
3614
3675
  CommandResult[CommandResult["MaximumRangesReached"] = 30] = "MaximumRangesReached";
3615
- CommandResult[CommandResult["InvalidChartDefinition"] = 31] = "InvalidChartDefinition";
3616
- CommandResult[CommandResult["InvalidDataSet"] = 32] = "InvalidDataSet";
3617
- CommandResult[CommandResult["InvalidLabelRange"] = 33] = "InvalidLabelRange";
3618
- CommandResult[CommandResult["InvalidScorecardKeyValue"] = 34] = "InvalidScorecardKeyValue";
3619
- CommandResult[CommandResult["InvalidScorecardBaseline"] = 35] = "InvalidScorecardBaseline";
3620
- CommandResult[CommandResult["InvalidGaugeDataRange"] = 36] = "InvalidGaugeDataRange";
3621
- CommandResult[CommandResult["EmptyGaugeRangeMin"] = 37] = "EmptyGaugeRangeMin";
3622
- CommandResult[CommandResult["GaugeRangeMinNaN"] = 38] = "GaugeRangeMinNaN";
3623
- CommandResult[CommandResult["EmptyGaugeRangeMax"] = 39] = "EmptyGaugeRangeMax";
3624
- CommandResult[CommandResult["GaugeRangeMaxNaN"] = 40] = "GaugeRangeMaxNaN";
3625
- CommandResult[CommandResult["GaugeRangeMinBiggerThanRangeMax"] = 41] = "GaugeRangeMinBiggerThanRangeMax";
3626
- CommandResult[CommandResult["GaugeLowerInflectionPointNaN"] = 42] = "GaugeLowerInflectionPointNaN";
3627
- CommandResult[CommandResult["GaugeUpperInflectionPointNaN"] = 43] = "GaugeUpperInflectionPointNaN";
3628
- CommandResult[CommandResult["GaugeLowerBiggerThanUpper"] = 44] = "GaugeLowerBiggerThanUpper";
3629
- CommandResult[CommandResult["InvalidAutofillSelection"] = 45] = "InvalidAutofillSelection";
3630
- CommandResult[CommandResult["WrongComposerSelection"] = 46] = "WrongComposerSelection";
3631
- CommandResult[CommandResult["MinBiggerThanMax"] = 47] = "MinBiggerThanMax";
3632
- CommandResult[CommandResult["LowerBiggerThanUpper"] = 48] = "LowerBiggerThanUpper";
3633
- CommandResult[CommandResult["MidBiggerThanMax"] = 49] = "MidBiggerThanMax";
3634
- CommandResult[CommandResult["MinBiggerThanMid"] = 50] = "MinBiggerThanMid";
3635
- CommandResult[CommandResult["FirstArgMissing"] = 51] = "FirstArgMissing";
3636
- CommandResult[CommandResult["SecondArgMissing"] = 52] = "SecondArgMissing";
3637
- CommandResult[CommandResult["MinNaN"] = 53] = "MinNaN";
3638
- CommandResult[CommandResult["MidNaN"] = 54] = "MidNaN";
3639
- CommandResult[CommandResult["MaxNaN"] = 55] = "MaxNaN";
3640
- CommandResult[CommandResult["ValueUpperInflectionNaN"] = 56] = "ValueUpperInflectionNaN";
3641
- CommandResult[CommandResult["ValueLowerInflectionNaN"] = 57] = "ValueLowerInflectionNaN";
3642
- CommandResult[CommandResult["MinInvalidFormula"] = 58] = "MinInvalidFormula";
3643
- CommandResult[CommandResult["MidInvalidFormula"] = 59] = "MidInvalidFormula";
3644
- CommandResult[CommandResult["MaxInvalidFormula"] = 60] = "MaxInvalidFormula";
3645
- CommandResult[CommandResult["ValueUpperInvalidFormula"] = 61] = "ValueUpperInvalidFormula";
3646
- CommandResult[CommandResult["ValueLowerInvalidFormula"] = 62] = "ValueLowerInvalidFormula";
3647
- CommandResult[CommandResult["InvalidSortZone"] = 63] = "InvalidSortZone";
3648
- CommandResult[CommandResult["WaitingSessionConfirmation"] = 64] = "WaitingSessionConfirmation";
3649
- CommandResult[CommandResult["MergeOverlap"] = 65] = "MergeOverlap";
3650
- CommandResult[CommandResult["TooManyHiddenElements"] = 66] = "TooManyHiddenElements";
3651
- CommandResult[CommandResult["Readonly"] = 67] = "Readonly";
3652
- CommandResult[CommandResult["InvalidViewportSize"] = 68] = "InvalidViewportSize";
3653
- CommandResult[CommandResult["InvalidScrollingDirection"] = 69] = "InvalidScrollingDirection";
3654
- CommandResult[CommandResult["FigureDoesNotExist"] = 70] = "FigureDoesNotExist";
3655
- CommandResult[CommandResult["InvalidConditionalFormatId"] = 71] = "InvalidConditionalFormatId";
3656
- CommandResult[CommandResult["InvalidCellPopover"] = 72] = "InvalidCellPopover";
3657
- CommandResult[CommandResult["EmptyTarget"] = 73] = "EmptyTarget";
3658
- CommandResult[CommandResult["InvalidFreezeQuantity"] = 74] = "InvalidFreezeQuantity";
3659
- CommandResult[CommandResult["FrozenPaneOverlap"] = 75] = "FrozenPaneOverlap";
3660
- CommandResult[CommandResult["ValuesNotChanged"] = 76] = "ValuesNotChanged";
3661
- CommandResult[CommandResult["InvalidFilterZone"] = 77] = "InvalidFilterZone";
3662
- CommandResult[CommandResult["FilterOverlap"] = 78] = "FilterOverlap";
3663
- CommandResult[CommandResult["FilterNotFound"] = 79] = "FilterNotFound";
3664
- CommandResult[CommandResult["MergeInFilter"] = 80] = "MergeInFilter";
3665
- CommandResult[CommandResult["NonContinuousTargets"] = 81] = "NonContinuousTargets";
3666
- CommandResult[CommandResult["DuplicatedFigureId"] = 82] = "DuplicatedFigureId";
3667
- CommandResult[CommandResult["InvalidSelectionStep"] = 83] = "InvalidSelectionStep";
3668
- CommandResult[CommandResult["DuplicatedChartId"] = 84] = "DuplicatedChartId";
3669
- CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
3670
- CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
3671
- CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
3672
- CommandResult[CommandResult["NoChanges"] = 88] = "NoChanges";
3676
+ CommandResult[CommandResult["InvalidInputId"] = 31] = "InvalidInputId";
3677
+ CommandResult[CommandResult["InvalidChartDefinition"] = 32] = "InvalidChartDefinition";
3678
+ CommandResult[CommandResult["InvalidDataSet"] = 33] = "InvalidDataSet";
3679
+ CommandResult[CommandResult["InvalidLabelRange"] = 34] = "InvalidLabelRange";
3680
+ CommandResult[CommandResult["InvalidScorecardKeyValue"] = 35] = "InvalidScorecardKeyValue";
3681
+ CommandResult[CommandResult["InvalidScorecardBaseline"] = 36] = "InvalidScorecardBaseline";
3682
+ CommandResult[CommandResult["InvalidGaugeDataRange"] = 37] = "InvalidGaugeDataRange";
3683
+ CommandResult[CommandResult["EmptyGaugeRangeMin"] = 38] = "EmptyGaugeRangeMin";
3684
+ CommandResult[CommandResult["GaugeRangeMinNaN"] = 39] = "GaugeRangeMinNaN";
3685
+ CommandResult[CommandResult["EmptyGaugeRangeMax"] = 40] = "EmptyGaugeRangeMax";
3686
+ CommandResult[CommandResult["GaugeRangeMaxNaN"] = 41] = "GaugeRangeMaxNaN";
3687
+ CommandResult[CommandResult["GaugeRangeMinBiggerThanRangeMax"] = 42] = "GaugeRangeMinBiggerThanRangeMax";
3688
+ CommandResult[CommandResult["GaugeLowerInflectionPointNaN"] = 43] = "GaugeLowerInflectionPointNaN";
3689
+ CommandResult[CommandResult["GaugeUpperInflectionPointNaN"] = 44] = "GaugeUpperInflectionPointNaN";
3690
+ CommandResult[CommandResult["GaugeLowerBiggerThanUpper"] = 45] = "GaugeLowerBiggerThanUpper";
3691
+ CommandResult[CommandResult["InvalidAutofillSelection"] = 46] = "InvalidAutofillSelection";
3692
+ CommandResult[CommandResult["WrongComposerSelection"] = 47] = "WrongComposerSelection";
3693
+ CommandResult[CommandResult["MinBiggerThanMax"] = 48] = "MinBiggerThanMax";
3694
+ CommandResult[CommandResult["LowerBiggerThanUpper"] = 49] = "LowerBiggerThanUpper";
3695
+ CommandResult[CommandResult["MidBiggerThanMax"] = 50] = "MidBiggerThanMax";
3696
+ CommandResult[CommandResult["MinBiggerThanMid"] = 51] = "MinBiggerThanMid";
3697
+ CommandResult[CommandResult["FirstArgMissing"] = 52] = "FirstArgMissing";
3698
+ CommandResult[CommandResult["SecondArgMissing"] = 53] = "SecondArgMissing";
3699
+ CommandResult[CommandResult["MinNaN"] = 54] = "MinNaN";
3700
+ CommandResult[CommandResult["MidNaN"] = 55] = "MidNaN";
3701
+ CommandResult[CommandResult["MaxNaN"] = 56] = "MaxNaN";
3702
+ CommandResult[CommandResult["ValueUpperInflectionNaN"] = 57] = "ValueUpperInflectionNaN";
3703
+ CommandResult[CommandResult["ValueLowerInflectionNaN"] = 58] = "ValueLowerInflectionNaN";
3704
+ CommandResult[CommandResult["MinInvalidFormula"] = 59] = "MinInvalidFormula";
3705
+ CommandResult[CommandResult["MidInvalidFormula"] = 60] = "MidInvalidFormula";
3706
+ CommandResult[CommandResult["MaxInvalidFormula"] = 61] = "MaxInvalidFormula";
3707
+ CommandResult[CommandResult["ValueUpperInvalidFormula"] = 62] = "ValueUpperInvalidFormula";
3708
+ CommandResult[CommandResult["ValueLowerInvalidFormula"] = 63] = "ValueLowerInvalidFormula";
3709
+ CommandResult[CommandResult["InvalidSortZone"] = 64] = "InvalidSortZone";
3710
+ CommandResult[CommandResult["WaitingSessionConfirmation"] = 65] = "WaitingSessionConfirmation";
3711
+ CommandResult[CommandResult["MergeOverlap"] = 66] = "MergeOverlap";
3712
+ CommandResult[CommandResult["TooManyHiddenElements"] = 67] = "TooManyHiddenElements";
3713
+ CommandResult[CommandResult["Readonly"] = 68] = "Readonly";
3714
+ CommandResult[CommandResult["InvalidViewportSize"] = 69] = "InvalidViewportSize";
3715
+ CommandResult[CommandResult["InvalidScrollingDirection"] = 70] = "InvalidScrollingDirection";
3716
+ CommandResult[CommandResult["FigureDoesNotExist"] = 71] = "FigureDoesNotExist";
3717
+ CommandResult[CommandResult["InvalidConditionalFormatId"] = 72] = "InvalidConditionalFormatId";
3718
+ CommandResult[CommandResult["InvalidCellPopover"] = 73] = "InvalidCellPopover";
3719
+ CommandResult[CommandResult["EmptyTarget"] = 74] = "EmptyTarget";
3720
+ CommandResult[CommandResult["InvalidFreezeQuantity"] = 75] = "InvalidFreezeQuantity";
3721
+ CommandResult[CommandResult["FrozenPaneOverlap"] = 76] = "FrozenPaneOverlap";
3722
+ CommandResult[CommandResult["ValuesNotChanged"] = 77] = "ValuesNotChanged";
3723
+ CommandResult[CommandResult["InvalidFilterZone"] = 78] = "InvalidFilterZone";
3724
+ CommandResult[CommandResult["FilterOverlap"] = 79] = "FilterOverlap";
3725
+ CommandResult[CommandResult["FilterNotFound"] = 80] = "FilterNotFound";
3726
+ CommandResult[CommandResult["MergeInFilter"] = 81] = "MergeInFilter";
3727
+ CommandResult[CommandResult["NonContinuousTargets"] = 82] = "NonContinuousTargets";
3728
+ CommandResult[CommandResult["DuplicatedFigureId"] = 83] = "DuplicatedFigureId";
3729
+ CommandResult[CommandResult["InvalidSelectionStep"] = 84] = "InvalidSelectionStep";
3730
+ CommandResult[CommandResult["DuplicatedChartId"] = 85] = "DuplicatedChartId";
3731
+ CommandResult[CommandResult["ChartDoesNotExist"] = 86] = "ChartDoesNotExist";
3732
+ CommandResult[CommandResult["InvalidHeaderIndex"] = 87] = "InvalidHeaderIndex";
3733
+ CommandResult[CommandResult["InvalidQuantity"] = 88] = "InvalidQuantity";
3734
+ CommandResult[CommandResult["NoChanges"] = 89] = "NoChanges";
3673
3735
  })(exports.CommandResult || (exports.CommandResult = {}));
3674
3736
 
3675
3737
  function isMatrix(x) {
@@ -3943,11 +4005,11 @@ function checkDataset(definition) {
3943
4005
  if (definition.dataSets) {
3944
4006
  const invalidRanges = definition.dataSets.find((range) => !rangeReference.test(range)) !== undefined;
3945
4007
  if (invalidRanges) {
3946
- return 32 /* CommandResult.InvalidDataSet */;
4008
+ return 33 /* CommandResult.InvalidDataSet */;
3947
4009
  }
3948
4010
  const zones = definition.dataSets.map(toUnboundedZone);
3949
4011
  if (zones.some((zone) => zone.top !== zone.bottom && isFullRow(zone))) {
3950
- return 32 /* CommandResult.InvalidDataSet */;
4012
+ return 33 /* CommandResult.InvalidDataSet */;
3951
4013
  }
3952
4014
  }
3953
4015
  return 0 /* CommandResult.Success */;
@@ -3956,7 +4018,7 @@ function checkLabelRange(definition) {
3956
4018
  if (definition.labelRange) {
3957
4019
  const invalidLabels = !rangeReference.test(definition.labelRange || "");
3958
4020
  if (invalidLabels) {
3959
- return 33 /* CommandResult.InvalidLabelRange */;
4021
+ return 34 /* CommandResult.InvalidLabelRange */;
3960
4022
  }
3961
4023
  }
3962
4024
  return 0 /* CommandResult.Success */;
@@ -4029,22 +4091,22 @@ function getChartPositionAtCenterOfViewport(getters, chartSize) {
4029
4091
  const CfTerms = {
4030
4092
  Errors: {
4031
4093
  [25 /* CommandResult.InvalidRange */]: _lt("The range is invalid"),
4032
- [51 /* CommandResult.FirstArgMissing */]: _lt("The argument is missing. Please provide a value"),
4033
- [52 /* CommandResult.SecondArgMissing */]: _lt("The second argument is missing. Please provide a value"),
4034
- [53 /* CommandResult.MinNaN */]: _lt("The minpoint must be a number"),
4035
- [54 /* CommandResult.MidNaN */]: _lt("The midpoint must be a number"),
4036
- [55 /* CommandResult.MaxNaN */]: _lt("The maxpoint must be a number"),
4037
- [56 /* CommandResult.ValueUpperInflectionNaN */]: _lt("The first value must be a number"),
4038
- [57 /* CommandResult.ValueLowerInflectionNaN */]: _lt("The second value must be a number"),
4039
- [47 /* CommandResult.MinBiggerThanMax */]: _lt("Minimum must be smaller then Maximum"),
4040
- [50 /* CommandResult.MinBiggerThanMid */]: _lt("Minimum must be smaller then Midpoint"),
4041
- [49 /* CommandResult.MidBiggerThanMax */]: _lt("Midpoint must be smaller then Maximum"),
4042
- [48 /* CommandResult.LowerBiggerThanUpper */]: _lt("Lower inflection point must be smaller than upper inflection point"),
4043
- [58 /* CommandResult.MinInvalidFormula */]: _lt("Invalid Minpoint formula"),
4044
- [60 /* CommandResult.MaxInvalidFormula */]: _lt("Invalid Maxpoint formula"),
4045
- [59 /* CommandResult.MidInvalidFormula */]: _lt("Invalid Midpoint formula"),
4046
- [61 /* CommandResult.ValueUpperInvalidFormula */]: _lt("Invalid upper inflection point formula"),
4047
- [62 /* CommandResult.ValueLowerInvalidFormula */]: _lt("Invalid lower inflection point formula"),
4094
+ [52 /* CommandResult.FirstArgMissing */]: _lt("The argument is missing. Please provide a value"),
4095
+ [53 /* CommandResult.SecondArgMissing */]: _lt("The second argument is missing. Please provide a value"),
4096
+ [54 /* CommandResult.MinNaN */]: _lt("The minpoint must be a number"),
4097
+ [55 /* CommandResult.MidNaN */]: _lt("The midpoint must be a number"),
4098
+ [56 /* CommandResult.MaxNaN */]: _lt("The maxpoint must be a number"),
4099
+ [57 /* CommandResult.ValueUpperInflectionNaN */]: _lt("The first value must be a number"),
4100
+ [58 /* CommandResult.ValueLowerInflectionNaN */]: _lt("The second value must be a number"),
4101
+ [48 /* CommandResult.MinBiggerThanMax */]: _lt("Minimum must be smaller then Maximum"),
4102
+ [51 /* CommandResult.MinBiggerThanMid */]: _lt("Minimum must be smaller then Midpoint"),
4103
+ [50 /* CommandResult.MidBiggerThanMax */]: _lt("Midpoint must be smaller then Maximum"),
4104
+ [49 /* CommandResult.LowerBiggerThanUpper */]: _lt("Lower inflection point must be smaller than upper inflection point"),
4105
+ [59 /* CommandResult.MinInvalidFormula */]: _lt("Invalid Minpoint formula"),
4106
+ [61 /* CommandResult.MaxInvalidFormula */]: _lt("Invalid Maxpoint formula"),
4107
+ [60 /* CommandResult.MidInvalidFormula */]: _lt("Invalid Midpoint formula"),
4108
+ [62 /* CommandResult.ValueUpperInvalidFormula */]: _lt("Invalid upper inflection point formula"),
4109
+ [63 /* CommandResult.ValueLowerInvalidFormula */]: _lt("Invalid lower inflection point formula"),
4048
4110
  [24 /* CommandResult.EmptyRange */]: _lt("A range needs to be defined"),
4049
4111
  Unexpected: _lt("The rule is invalid for an unknown reason"),
4050
4112
  },
@@ -4072,20 +4134,20 @@ const ChartTerms = {
4072
4134
  Errors: {
4073
4135
  Unexpected: _lt("The chart definition is invalid for an unknown reason"),
4074
4136
  // BASIC CHART ERRORS (LINE | BAR | PIE)
4075
- [32 /* CommandResult.InvalidDataSet */]: _lt("The dataset is invalid"),
4076
- [33 /* CommandResult.InvalidLabelRange */]: _lt("Labels are invalid"),
4137
+ [33 /* CommandResult.InvalidDataSet */]: _lt("The dataset is invalid"),
4138
+ [34 /* CommandResult.InvalidLabelRange */]: _lt("Labels are invalid"),
4077
4139
  // SCORECARD CHART ERRORS
4078
- [34 /* CommandResult.InvalidScorecardKeyValue */]: _lt("The key value is invalid"),
4079
- [35 /* CommandResult.InvalidScorecardBaseline */]: _lt("The baseline value is invalid"),
4140
+ [35 /* CommandResult.InvalidScorecardKeyValue */]: _lt("The key value is invalid"),
4141
+ [36 /* CommandResult.InvalidScorecardBaseline */]: _lt("The baseline value is invalid"),
4080
4142
  // GAUGE CHART ERRORS
4081
- [36 /* CommandResult.InvalidGaugeDataRange */]: _lt("The data range is invalid"),
4082
- [37 /* CommandResult.EmptyGaugeRangeMin */]: _lt("A minimum range limit value is needed"),
4083
- [38 /* CommandResult.GaugeRangeMinNaN */]: _lt("The minimum range limit value must be a number"),
4084
- [39 /* CommandResult.EmptyGaugeRangeMax */]: _lt("A maximum range limit value is needed"),
4085
- [40 /* CommandResult.GaugeRangeMaxNaN */]: _lt("The maximum range limit value must be a number"),
4086
- [41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */]: _lt("Minimum range limit must be smaller than maximum range limit"),
4087
- [42 /* CommandResult.GaugeLowerInflectionPointNaN */]: _lt("The lower inflection point value must be a number"),
4088
- [43 /* CommandResult.GaugeUpperInflectionPointNaN */]: _lt("The upper inflection point value must be a number"),
4143
+ [37 /* CommandResult.InvalidGaugeDataRange */]: _lt("The data range is invalid"),
4144
+ [38 /* CommandResult.EmptyGaugeRangeMin */]: _lt("A minimum range limit value is needed"),
4145
+ [39 /* CommandResult.GaugeRangeMinNaN */]: _lt("The minimum range limit value must be a number"),
4146
+ [40 /* CommandResult.EmptyGaugeRangeMax */]: _lt("A maximum range limit value is needed"),
4147
+ [41 /* CommandResult.GaugeRangeMaxNaN */]: _lt("The maximum range limit value must be a number"),
4148
+ [42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */]: _lt("Minimum range limit must be smaller than maximum range limit"),
4149
+ [43 /* CommandResult.GaugeLowerInflectionPointNaN */]: _lt("The lower inflection point value must be a number"),
4150
+ [44 /* CommandResult.GaugeUpperInflectionPointNaN */]: _lt("The upper inflection point value must be a number"),
4089
4151
  },
4090
4152
  };
4091
4153
  const NumberFormatTerms = {
@@ -4457,7 +4519,7 @@ function createBarChartRuntime(chart, getters) {
4457
4519
 
4458
4520
  function isDataRangeValid(definition) {
4459
4521
  return definition.dataRange && !rangeReference.test(definition.dataRange)
4460
- ? 36 /* CommandResult.InvalidGaugeDataRange */
4522
+ ? 37 /* CommandResult.InvalidGaugeDataRange */
4461
4523
  : 0 /* CommandResult.Success */;
4462
4524
  }
4463
4525
  function checkRangeLimits(check, batchValidations) {
@@ -4489,7 +4551,7 @@ function checkInflectionPointsValue(check, batchValidations) {
4489
4551
  function checkRangeMinBiggerThanRangeMax(definition) {
4490
4552
  if (definition.sectionRule) {
4491
4553
  if (Number(definition.sectionRule.rangeMin) >= Number(definition.sectionRule.rangeMax)) {
4492
- return 41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */;
4554
+ return 42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */;
4493
4555
  }
4494
4556
  }
4495
4557
  return 0 /* CommandResult.Success */;
@@ -4498,9 +4560,9 @@ function checkEmpty(value, valueName) {
4498
4560
  if (value === "") {
4499
4561
  switch (valueName) {
4500
4562
  case "rangeMin":
4501
- return 37 /* CommandResult.EmptyGaugeRangeMin */;
4563
+ return 38 /* CommandResult.EmptyGaugeRangeMin */;
4502
4564
  case "rangeMax":
4503
- return 39 /* CommandResult.EmptyGaugeRangeMax */;
4565
+ return 40 /* CommandResult.EmptyGaugeRangeMax */;
4504
4566
  }
4505
4567
  }
4506
4568
  return 0 /* CommandResult.Success */;
@@ -4509,13 +4571,13 @@ function checkNaN(value, valueName) {
4509
4571
  if (isNaN(value)) {
4510
4572
  switch (valueName) {
4511
4573
  case "rangeMin":
4512
- return 38 /* CommandResult.GaugeRangeMinNaN */;
4574
+ return 39 /* CommandResult.GaugeRangeMinNaN */;
4513
4575
  case "rangeMax":
4514
- return 40 /* CommandResult.GaugeRangeMaxNaN */;
4576
+ return 41 /* CommandResult.GaugeRangeMaxNaN */;
4515
4577
  case "lowerInflectionPointValue":
4516
- return 42 /* CommandResult.GaugeLowerInflectionPointNaN */;
4578
+ return 43 /* CommandResult.GaugeLowerInflectionPointNaN */;
4517
4579
  case "upperInflectionPointValue":
4518
- return 43 /* CommandResult.GaugeUpperInflectionPointNaN */;
4580
+ return 44 /* CommandResult.GaugeUpperInflectionPointNaN */;
4519
4581
  }
4520
4582
  }
4521
4583
  return 0 /* CommandResult.Success */;
@@ -5266,12 +5328,12 @@ function createPieChartRuntime(chart, getters) {
5266
5328
 
5267
5329
  function checkKeyValue(definition) {
5268
5330
  return definition.keyValue && !rangeReference.test(definition.keyValue)
5269
- ? 34 /* CommandResult.InvalidScorecardKeyValue */
5331
+ ? 35 /* CommandResult.InvalidScorecardKeyValue */
5270
5332
  : 0 /* CommandResult.Success */;
5271
5333
  }
5272
5334
  function checkBaseline(definition) {
5273
5335
  return definition.baseline && !rangeReference.test(definition.baseline)
5274
- ? 35 /* CommandResult.InvalidScorecardBaseline */
5336
+ ? 36 /* CommandResult.InvalidScorecardBaseline */
5275
5337
  : 0 /* CommandResult.Success */;
5276
5338
  }
5277
5339
  class ScorecardChart extends AbstractChart {
@@ -5705,6 +5767,7 @@ function getMenuDescription(node) {
5705
5767
  return node.description ? node.description : "";
5706
5768
  }
5707
5769
 
5770
+ const macRegex = /Mac/i;
5708
5771
  /**
5709
5772
  * Return true if the event was triggered from
5710
5773
  * a child element.
@@ -5722,6 +5785,17 @@ function gridOverlayPosition() {
5722
5785
  }
5723
5786
  function getOpenedMenus() {
5724
5787
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5788
+ }
5789
+ function isMacOS() {
5790
+ return Boolean(macRegex.test(navigator.userAgent));
5791
+ }
5792
+ /**
5793
+ * @param {KeyboardEvent | MouseEvent} ev
5794
+ * @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
5795
+ * On Mac, this is the "meta" or "command" key.
5796
+ */
5797
+ function isCtrlKey(ev) {
5798
+ return isMacOS() ? ev.metaKey : ev.ctrlKey;
5725
5799
  }
5726
5800
 
5727
5801
  /**
@@ -6301,7 +6375,7 @@ function handlePasteResult(env, result) {
6301
6375
  else if (result.reasons.includes(22 /* CommandResult.WrongFigurePasteOption */)) {
6302
6376
  env.raiseError(PasteInteractiveContent.wrongFigurePasteOption);
6303
6377
  }
6304
- else if (result.reasons.includes(75 /* CommandResult.FrozenPaneOverlap */)) {
6378
+ else if (result.reasons.includes(76 /* CommandResult.FrozenPaneOverlap */)) {
6305
6379
  env.raiseError(PasteInteractiveContent.frozenPaneOverlap);
6306
6380
  }
6307
6381
  }
@@ -6588,7 +6662,7 @@ function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
6588
6662
  });
6589
6663
  }
6590
6664
  }
6591
- if (result.isCancelledBecause(63 /* CommandResult.InvalidSortZone */)) {
6665
+ if (result.isCancelledBecause(64 /* CommandResult.InvalidSortZone */)) {
6592
6666
  const { col, row } = anchor;
6593
6667
  env.model.selection.selectZone({ cell: { col, row }, zone });
6594
6668
  env.raiseError(_lt("Cannot sort. To sort, select only cells or only merges that have the same size."));
@@ -6602,13 +6676,13 @@ const AddFilterInteractiveContent = {
6602
6676
  };
6603
6677
  function interactiveAddFilter(env, sheetId, target) {
6604
6678
  const result = env.model.dispatch("CREATE_FILTER_TABLE", { target, sheetId });
6605
- if (result.isCancelledBecause(78 /* CommandResult.FilterOverlap */)) {
6679
+ if (result.isCancelledBecause(79 /* CommandResult.FilterOverlap */)) {
6606
6680
  env.raiseError(AddFilterInteractiveContent.filterOverlap);
6607
6681
  }
6608
- else if (result.isCancelledBecause(80 /* CommandResult.MergeInFilter */)) {
6682
+ else if (result.isCancelledBecause(81 /* CommandResult.MergeInFilter */)) {
6609
6683
  env.raiseError(AddFilterInteractiveContent.mergeInFilter);
6610
6684
  }
6611
- else if (result.isCancelledBecause(81 /* CommandResult.NonContinuousTargets */)) {
6685
+ else if (result.isCancelledBecause(82 /* CommandResult.NonContinuousTargets */)) {
6612
6686
  env.raiseError(AddFilterInteractiveContent.nonContinuousTargets);
6613
6687
  }
6614
6688
  }
@@ -10882,7 +10956,7 @@ const DATE = {
10882
10956
  if (_year < 1900) {
10883
10957
  _year += 1900;
10884
10958
  }
10885
- const jsDate = new Date(_year, _month - 1, _day);
10959
+ const jsDate = new DateTime(_year, _month - 1, _day);
10886
10960
  const result = jsDateToRoundNumber(jsDate);
10887
10961
  assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
10888
10962
  return result;
@@ -10994,7 +11068,7 @@ const EOMONTH = {
10994
11068
  const _months = Math.trunc(toNumber(months));
10995
11069
  const yStart = _startDate.getFullYear();
10996
11070
  const mStart = _startDate.getMonth();
10997
- const jsDate = new Date(yStart, mStart + _months + 1, 0);
11071
+ const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
10998
11072
  return jsDateToRoundNumber(jsDate);
10999
11073
  },
11000
11074
  isExported: true,
@@ -11033,17 +11107,17 @@ const ISOWEEKNUM = {
11033
11107
  // The first week of the year is the week that contains the first
11034
11108
  // Thursday of the year.
11035
11109
  let firstThursday = 1;
11036
- while (new Date(y, 0, firstThursday).getDay() !== 4) {
11110
+ while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
11037
11111
  firstThursday += 1;
11038
11112
  }
11039
- const firstDayOfFirstWeek = new Date(y, 0, firstThursday - 3);
11113
+ const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
11040
11114
  // The last week of the year is the week that contains the last Thursday of
11041
11115
  // the year.
11042
11116
  let lastThursday = 31;
11043
- while (new Date(y, 11, lastThursday).getDay() !== 4) {
11117
+ while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
11044
11118
  lastThursday -= 1;
11045
11119
  }
11046
- const lastDayOfLastWeek = new Date(y, 11, lastThursday + 3);
11120
+ const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
11047
11121
  // B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
11048
11122
  // If our date < firstDayOfFirstWeek then it's in the weeks of the year before
11049
11123
  let offsetYear;
@@ -11069,17 +11143,17 @@ const ISOWEEKNUM = {
11069
11143
  case 1:
11070
11144
  // firstDay is the 1st day of the 1st week of the year after
11071
11145
  // firstDay = lastDayOfLastWeek + 1 Day
11072
- firstDay = new Date(y, 11, lastThursday + 3 + 1);
11146
+ firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
11073
11147
  break;
11074
11148
  case -1:
11075
11149
  // firstDay is the 1st day of the 1st week of the previous year.
11076
11150
  // The first week of the previous year is the week that contains the
11077
11151
  // first Thursday of the previous year.
11078
11152
  let firstThursdayPreviousYear = 1;
11079
- while (new Date(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
11153
+ while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
11080
11154
  firstThursdayPreviousYear += 1;
11081
11155
  }
11082
- firstDay = new Date(y - 1, 0, firstThursdayPreviousYear - 3);
11156
+ firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
11083
11157
  break;
11084
11158
  }
11085
11159
  const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
@@ -11218,8 +11292,8 @@ const NETWORKDAYS_INTL = {
11218
11292
  });
11219
11293
  }
11220
11294
  const invertDate = _startDate.getTime() > _endDate.getTime();
11221
- const stopDate = new Date((invertDate ? _startDate : _endDate).getTime());
11222
- let stepDate = new Date((invertDate ? _endDate : _startDate).getTime());
11295
+ const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
11296
+ let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
11223
11297
  const timeStopDate = stopDate.getTime();
11224
11298
  let timeStepDate = stepDate.getTime();
11225
11299
  let netWorkingDay = 0;
@@ -11243,8 +11317,7 @@ const NOW = {
11243
11317
  returns: ["DATE"],
11244
11318
  computeFormat: () => "m/d/yyyy hh:mm:ss",
11245
11319
  compute: function () {
11246
- let today = new Date();
11247
- today.setMilliseconds(0);
11320
+ let today = DateTime.now();
11248
11321
  const delta = today.getTime() - INITIAL_1900_DAY.getTime();
11249
11322
  const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
11250
11323
  return Math.floor(delta / MS_PER_DAY) + time;
@@ -11318,8 +11391,8 @@ const TODAY = {
11318
11391
  returns: ["DATE"],
11319
11392
  computeFormat: () => "m/d/yyyy",
11320
11393
  compute: function () {
11321
- const today = new Date();
11322
- const jsDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
11394
+ const today = DateTime.now();
11395
+ const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
11323
11396
  return jsDateToRoundNumber(jsDate);
11324
11397
  },
11325
11398
  isExported: true,
@@ -11374,10 +11447,10 @@ const WEEKNUM = {
11374
11447
  }
11375
11448
  const y = _date.getFullYear();
11376
11449
  let dayStart = 1;
11377
- let startDayOfFirstWeek = new Date(y, 0, dayStart);
11450
+ let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
11378
11451
  while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
11379
11452
  dayStart += 1;
11380
- startDayOfFirstWeek = new Date(y, 0, dayStart);
11453
+ startDayOfFirstWeek = new DateTime(y, 0, dayStart);
11381
11454
  }
11382
11455
  const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
11383
11456
  if (dif < 0) {
@@ -11431,7 +11504,7 @@ const WORKDAY_INTL = {
11431
11504
  timesHoliday.add(holiday.getTime());
11432
11505
  });
11433
11506
  }
11434
- let stepDate = new Date(_startDate.getTime());
11507
+ let stepDate = DateTime.fromTimestamp(_startDate.getTime());
11435
11508
  let timeStepDate = stepDate.getTime();
11436
11509
  const unitDay = Math.sign(_numDays);
11437
11510
  let stepDay = Math.abs(_numDays);
@@ -11497,7 +11570,7 @@ const MONTH_START = {
11497
11570
  const _startDate = toJsDate(date);
11498
11571
  const yStart = _startDate.getFullYear();
11499
11572
  const mStart = _startDate.getMonth();
11500
- const jsDate = new Date(yStart, mStart, 1);
11573
+ const jsDate = new DateTime(yStart, mStart, 1);
11501
11574
  return jsDateToRoundNumber(jsDate);
11502
11575
  },
11503
11576
  };
@@ -11541,7 +11614,7 @@ const QUARTER_START = {
11541
11614
  compute: function (date) {
11542
11615
  const quarter = QUARTER.compute(date);
11543
11616
  const year = YEAR.compute(date);
11544
- const jsDate = new Date(year, (quarter - 1) * 3, 1);
11617
+ const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
11545
11618
  return jsDateToRoundNumber(jsDate);
11546
11619
  },
11547
11620
  };
@@ -11558,7 +11631,7 @@ const QUARTER_END = {
11558
11631
  compute: function (date) {
11559
11632
  const quarter = QUARTER.compute(date);
11560
11633
  const year = YEAR.compute(date);
11561
- const jsDate = new Date(year, quarter * 3, 0);
11634
+ const jsDate = new DateTime(year, quarter * 3, 0);
11562
11635
  return jsDateToRoundNumber(jsDate);
11563
11636
  },
11564
11637
  };
@@ -11574,7 +11647,7 @@ const YEAR_START = {
11574
11647
  computeFormat: () => "m/d/yyyy",
11575
11648
  compute: function (date) {
11576
11649
  const year = YEAR.compute(date);
11577
- const jsDate = new Date(year, 0, 1);
11650
+ const jsDate = new DateTime(year, 0, 1);
11578
11651
  return jsDateToRoundNumber(jsDate);
11579
11652
  },
11580
11653
  };
@@ -11590,7 +11663,7 @@ const YEAR_END = {
11590
11663
  computeFormat: () => "m/d/yyyy",
11591
11664
  compute: function (date) {
11592
11665
  const year = YEAR.compute(date);
11593
- const jsDate = new Date(year + 1, 0, 0);
11666
+ const jsDate = new DateTime(year + 1, 0, 0);
11594
11667
  return jsDateToRoundNumber(jsDate);
11595
11668
  },
11596
11669
  };
@@ -11724,7 +11797,7 @@ function assertDeprecationFactorStrictlyPositive(factor) {
11724
11797
  function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
11725
11798
  const startDate = toJsDate(settlement);
11726
11799
  const endDate = toJsDate(maturity);
11727
- const startDatePlusOneYear = new Date(startDate);
11800
+ const startDatePlusOneYear = toJsDate(settlement);
11728
11801
  startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
11729
11802
  assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
11730
11803
  }
@@ -15650,7 +15723,7 @@ const machine = {
15650
15723
  SPACE: goTo(State.RightRef),
15651
15724
  NUMBER: goTo(State.Found),
15652
15725
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
15653
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
15726
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
15654
15727
  },
15655
15728
  [State.RightColumnRef]: {
15656
15729
  SPACE: goTo(State.RightColumnRef),
@@ -15661,6 +15734,7 @@ const machine = {
15661
15734
  SPACE: goTo(State.RightRowRef),
15662
15735
  NUMBER: goTo(State.Found),
15663
15736
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
15737
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
15664
15738
  },
15665
15739
  [State.Found]: {},
15666
15740
  };
@@ -16170,6 +16244,10 @@ function setXcToReferenceType(xc, referenceType) {
16170
16244
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
16171
16245
  case "colrow":
16172
16246
  indexOfNumber = xc.search(/[0-9]/);
16247
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
16248
+ // no row number (eg. A) or no column (eg. 1)
16249
+ return "$" + xc;
16250
+ }
16173
16251
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
16174
16252
  return "$" + xc;
16175
16253
  case "none":
@@ -16555,7 +16633,7 @@ class EditionPlugin extends UIPlugin {
16555
16633
  validateSelection(length, start, end) {
16556
16634
  return start >= 0 && start <= length && end >= 0 && end <= length
16557
16635
  ? 0 /* CommandResult.Success */
16558
- : 46 /* CommandResult.WrongComposerSelection */;
16636
+ : 47 /* CommandResult.WrongComposerSelection */;
16559
16637
  }
16560
16638
  onColumnsRemoved(cmd) {
16561
16639
  if (cmd.elements.includes(this.col) && this.mode !== "inactive") {
@@ -16869,9 +16947,10 @@ class EditionPlugin extends UIPlugin {
16869
16947
  */
16870
16948
  getReferencedRanges() {
16871
16949
  const editionSheetId = this.getters.getEditionSheet();
16872
- return this.currentTokens
16950
+ const referenceRanges = this.currentTokens
16873
16951
  .filter((token) => token.type === "REFERENCE")
16874
16952
  .map((token) => this.getters.getRangeFromSheetXC(editionSheetId, token.value));
16953
+ return referenceRanges.filter((range) => !range.invalidSheetName && !range.invalidXc);
16875
16954
  }
16876
16955
  /**
16877
16956
  * Function used to determine when composer selection can start.
@@ -16943,10 +17022,10 @@ const arrowMap = {
16943
17022
  function updateSelectionWithArrowKeys(ev, selection) {
16944
17023
  const direction = arrowMap[ev.key];
16945
17024
  if (ev.shiftKey) {
16946
- selection.resizeAnchorZone(direction, ev.ctrlKey ? "end" : 1);
17025
+ selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
16947
17026
  }
16948
17027
  else {
16949
- selection.moveAnchorCell(direction, ev.ctrlKey ? "end" : 1);
17028
+ selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
16950
17029
  }
16951
17030
  }
16952
17031
 
@@ -19309,7 +19388,7 @@ function interactiveFreezeColumnsRows(env, dimension, base) {
19309
19388
  const sheetId = env.model.getters.getActiveSheetId();
19310
19389
  const cmd = dimension === "COL" ? "FREEZE_COLUMNS" : "FREEZE_ROWS";
19311
19390
  const result = env.model.dispatch(cmd, { sheetId, quantity: base });
19312
- if (result.isCancelledBecause(65 /* CommandResult.MergeOverlap */)) {
19391
+ if (result.isCancelledBecause(66 /* CommandResult.MergeOverlap */)) {
19313
19392
  env.raiseError(MergeErrorMessage);
19314
19393
  }
19315
19394
  }
@@ -20024,11 +20103,11 @@ class LineBarPieConfigPanel extends owl.Component {
20024
20103
  }
20025
20104
  get isDatasetInvalid() {
20026
20105
  var _a;
20027
- return !!((_a = this.state.datasetDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(32 /* CommandResult.InvalidDataSet */));
20106
+ return !!((_a = this.state.datasetDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(33 /* CommandResult.InvalidDataSet */));
20028
20107
  }
20029
20108
  get isLabelInvalid() {
20030
20109
  var _a;
20031
- return !!((_a = this.state.labelsDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(33 /* CommandResult.InvalidLabelRange */));
20110
+ return !!((_a = this.state.labelsDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(34 /* CommandResult.InvalidLabelRange */));
20032
20111
  }
20033
20112
  onUpdateDataSetsHaveTitle(ev) {
20034
20113
  this.props.updateChart(this.props.figureId, {
@@ -20401,7 +20480,7 @@ class GaugeChartConfigPanel extends owl.Component {
20401
20480
  }
20402
20481
  get isDataRangeInvalid() {
20403
20482
  var _a;
20404
- return !!((_a = this.state.dataRangeDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(36 /* CommandResult.InvalidGaugeDataRange */));
20483
+ return !!((_a = this.state.dataRangeDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(37 /* CommandResult.InvalidGaugeDataRange */));
20405
20484
  }
20406
20485
  onDataRangeChanged(ranges) {
20407
20486
  this.dataRange = ranges[0];
@@ -20493,28 +20572,28 @@ class GaugeChartDesignPanel extends owl.Component {
20493
20572
  }
20494
20573
  isRangeMinInvalid() {
20495
20574
  var _a, _b, _c;
20496
- return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(37 /* CommandResult.EmptyGaugeRangeMin */)) ||
20497
- ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(38 /* CommandResult.GaugeRangeMinNaN */)) ||
20498
- ((_c = this.state.sectionRuleDispatchResult) === null || _c === void 0 ? void 0 : _c.isCancelledBecause(41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */)));
20575
+ return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(38 /* CommandResult.EmptyGaugeRangeMin */)) ||
20576
+ ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(39 /* CommandResult.GaugeRangeMinNaN */)) ||
20577
+ ((_c = this.state.sectionRuleDispatchResult) === null || _c === void 0 ? void 0 : _c.isCancelledBecause(42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */)));
20499
20578
  }
20500
20579
  isRangeMaxInvalid() {
20501
20580
  var _a, _b, _c;
20502
- return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(39 /* CommandResult.EmptyGaugeRangeMax */)) ||
20503
- ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(40 /* CommandResult.GaugeRangeMaxNaN */)) ||
20504
- ((_c = this.state.sectionRuleDispatchResult) === null || _c === void 0 ? void 0 : _c.isCancelledBecause(41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */)));
20581
+ return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(40 /* CommandResult.EmptyGaugeRangeMax */)) ||
20582
+ ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(41 /* CommandResult.GaugeRangeMaxNaN */)) ||
20583
+ ((_c = this.state.sectionRuleDispatchResult) === null || _c === void 0 ? void 0 : _c.isCancelledBecause(42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */)));
20505
20584
  }
20506
20585
  // ---------------------------------------------------------------------------
20507
20586
  // COLOR_SECTION_TEMPLATE
20508
20587
  // ---------------------------------------------------------------------------
20509
20588
  get isLowerInflectionPointInvalid() {
20510
20589
  var _a, _b;
20511
- return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(42 /* CommandResult.GaugeLowerInflectionPointNaN */)) ||
20512
- ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(44 /* CommandResult.GaugeLowerBiggerThanUpper */)));
20590
+ return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(43 /* CommandResult.GaugeLowerInflectionPointNaN */)) ||
20591
+ ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(45 /* CommandResult.GaugeLowerBiggerThanUpper */)));
20513
20592
  }
20514
20593
  get isUpperInflectionPointInvalid() {
20515
20594
  var _a, _b;
20516
- return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(43 /* CommandResult.GaugeUpperInflectionPointNaN */)) ||
20517
- ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(44 /* CommandResult.GaugeLowerBiggerThanUpper */)));
20595
+ return !!(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(44 /* CommandResult.GaugeUpperInflectionPointNaN */)) ||
20596
+ ((_b = this.state.sectionRuleDispatchResult) === null || _b === void 0 ? void 0 : _b.isCancelledBecause(45 /* CommandResult.GaugeLowerBiggerThanUpper */)));
20518
20597
  }
20519
20598
  updateInflectionPointValue(attr, ev) {
20520
20599
  const sectionRule = deepCopy(this.props.definition.sectionRule);
@@ -20627,11 +20706,11 @@ class ScorecardChartConfigPanel extends owl.Component {
20627
20706
  }
20628
20707
  get isKeyValueInvalid() {
20629
20708
  var _a;
20630
- return !!((_a = this.state.keyValueDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(34 /* CommandResult.InvalidScorecardKeyValue */));
20709
+ return !!((_a = this.state.keyValueDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(35 /* CommandResult.InvalidScorecardKeyValue */));
20631
20710
  }
20632
20711
  get isBaselineInvalid() {
20633
20712
  var _a;
20634
- return !!((_a = this.state.keyValueDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(35 /* CommandResult.InvalidScorecardBaseline */));
20713
+ return !!((_a = this.state.keyValueDispatchResult) === null || _a === void 0 ? void 0 : _a.isCancelledBecause(36 /* CommandResult.InvalidScorecardBaseline */));
20635
20714
  }
20636
20715
  onKeyValueRangeChanged(ranges) {
20637
20716
  this.keyValue = ranges[0];
@@ -21487,11 +21566,11 @@ class ConditionalFormattingPanel extends owl.Component {
21487
21566
  ****************************************************************************/
21488
21567
  get isValue1Invalid() {
21489
21568
  var _a;
21490
- return !!((_a = this.state.errors) === null || _a === void 0 ? void 0 : _a.includes(51 /* CommandResult.FirstArgMissing */));
21569
+ return !!((_a = this.state.errors) === null || _a === void 0 ? void 0 : _a.includes(52 /* CommandResult.FirstArgMissing */));
21491
21570
  }
21492
21571
  get isValue2Invalid() {
21493
21572
  var _a;
21494
- return !!((_a = this.state.errors) === null || _a === void 0 ? void 0 : _a.includes(52 /* CommandResult.SecondArgMissing */));
21573
+ return !!((_a = this.state.errors) === null || _a === void 0 ? void 0 : _a.includes(53 /* CommandResult.SecondArgMissing */));
21495
21574
  }
21496
21575
  toggleStyle(tool) {
21497
21576
  const style = this.state.rules.cellIs.style;
@@ -21508,17 +21587,17 @@ class ConditionalFormattingPanel extends owl.Component {
21508
21587
  isValueInvalid(threshold) {
21509
21588
  switch (threshold) {
21510
21589
  case "minimum":
21511
- return (this.state.errors.includes(58 /* CommandResult.MinInvalidFormula */) ||
21512
- this.state.errors.includes(50 /* CommandResult.MinBiggerThanMid */) ||
21513
- this.state.errors.includes(47 /* CommandResult.MinBiggerThanMax */) ||
21514
- this.state.errors.includes(53 /* CommandResult.MinNaN */));
21590
+ return (this.state.errors.includes(59 /* CommandResult.MinInvalidFormula */) ||
21591
+ this.state.errors.includes(51 /* CommandResult.MinBiggerThanMid */) ||
21592
+ this.state.errors.includes(48 /* CommandResult.MinBiggerThanMax */) ||
21593
+ this.state.errors.includes(54 /* CommandResult.MinNaN */));
21515
21594
  case "midpoint":
21516
- return (this.state.errors.includes(59 /* CommandResult.MidInvalidFormula */) ||
21517
- this.state.errors.includes(54 /* CommandResult.MidNaN */) ||
21518
- this.state.errors.includes(49 /* CommandResult.MidBiggerThanMax */));
21595
+ return (this.state.errors.includes(60 /* CommandResult.MidInvalidFormula */) ||
21596
+ this.state.errors.includes(55 /* CommandResult.MidNaN */) ||
21597
+ this.state.errors.includes(50 /* CommandResult.MidBiggerThanMax */));
21519
21598
  case "maximum":
21520
- return (this.state.errors.includes(60 /* CommandResult.MaxInvalidFormula */) ||
21521
- this.state.errors.includes(55 /* CommandResult.MaxNaN */));
21599
+ return (this.state.errors.includes(61 /* CommandResult.MaxInvalidFormula */) ||
21600
+ this.state.errors.includes(56 /* CommandResult.MaxNaN */));
21522
21601
  default:
21523
21602
  return false;
21524
21603
  }
@@ -21567,13 +21646,13 @@ class ConditionalFormattingPanel extends owl.Component {
21567
21646
  isInflectionPointInvalid(inflectionPoint) {
21568
21647
  switch (inflectionPoint) {
21569
21648
  case "lowerInflectionPoint":
21570
- return (this.state.errors.includes(57 /* CommandResult.ValueLowerInflectionNaN */) ||
21571
- this.state.errors.includes(62 /* CommandResult.ValueLowerInvalidFormula */) ||
21572
- this.state.errors.includes(48 /* CommandResult.LowerBiggerThanUpper */));
21649
+ return (this.state.errors.includes(58 /* CommandResult.ValueLowerInflectionNaN */) ||
21650
+ this.state.errors.includes(63 /* CommandResult.ValueLowerInvalidFormula */) ||
21651
+ this.state.errors.includes(49 /* CommandResult.LowerBiggerThanUpper */));
21573
21652
  case "upperInflectionPoint":
21574
- return (this.state.errors.includes(56 /* CommandResult.ValueUpperInflectionNaN */) ||
21575
- this.state.errors.includes(61 /* CommandResult.ValueUpperInvalidFormula */) ||
21576
- this.state.errors.includes(48 /* CommandResult.LowerBiggerThanUpper */));
21653
+ return (this.state.errors.includes(57 /* CommandResult.ValueUpperInflectionNaN */) ||
21654
+ this.state.errors.includes(62 /* CommandResult.ValueUpperInvalidFormula */) ||
21655
+ this.state.errors.includes(49 /* CommandResult.LowerBiggerThanUpper */));
21577
21656
  default:
21578
21657
  return true;
21579
21658
  }
@@ -22603,7 +22682,10 @@ class GridOverlay extends owl.Component {
22603
22682
  return;
22604
22683
  }
22605
22684
  const [col, row] = this.getCartesianCoordinates(ev);
22606
- this.props.onCellClicked(col, row, { shiftKey: ev.shiftKey, ctrlKey: ev.ctrlKey });
22685
+ this.props.onCellClicked(col, row, {
22686
+ expandZone: ev.shiftKey,
22687
+ addZone: isCtrlKey(ev),
22688
+ });
22607
22689
  }
22608
22690
  onDoubleClick(ev) {
22609
22691
  const [col, row] = this.getCartesianCoordinates(ev);
@@ -22691,6 +22773,7 @@ class AbstractResizer extends owl.Component {
22691
22773
  draggerShadowThickness: 0,
22692
22774
  delta: 0,
22693
22775
  base: 0,
22776
+ position: "before",
22694
22777
  });
22695
22778
  }
22696
22779
  _computeHandleDisplay(ev) {
@@ -22816,11 +22899,13 @@ class AbstractResizer extends owl.Component {
22816
22899
  this.state.draggerLinePosition = dimensions.start;
22817
22900
  this.state.draggerShadowPosition = dimensions.start;
22818
22901
  this.state.base = elementIndex;
22902
+ this.state.position = "before";
22819
22903
  }
22820
22904
  else if (this._getSelectedZoneEnd() < elementIndex) {
22821
22905
  this.state.draggerLinePosition = dimensions.end;
22822
22906
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
22823
- this.state.base = elementIndex + 1;
22907
+ this.state.base = elementIndex;
22908
+ this.state.position = "after";
22824
22909
  }
22825
22910
  else {
22826
22911
  this.state.draggerLinePosition = startDimensions.start;
@@ -22844,7 +22929,7 @@ class AbstractResizer extends owl.Component {
22844
22929
  this._increaseSelection(index);
22845
22930
  }
22846
22931
  else {
22847
- this._selectElement(index, ev.ctrlKey);
22932
+ this._selectElement(index, isCtrlKey(ev));
22848
22933
  }
22849
22934
  this.lastSelectedElementIndex = index;
22850
22935
  const mouseMoveSelect = (col, row) => {
@@ -22857,7 +22942,7 @@ class AbstractResizer extends owl.Component {
22857
22942
  const mouseUpSelect = () => {
22858
22943
  this.state.isSelecting = false;
22859
22944
  this.lastSelectedElementIndex = null;
22860
- this.env.model.dispatch(ev.ctrlKey ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
22945
+ this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
22861
22946
  this._computeGrabDisplay(ev);
22862
22947
  };
22863
22948
  dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
@@ -23001,13 +23086,14 @@ class ColResizer extends AbstractResizer {
23001
23086
  dimension: "COL",
23002
23087
  base: this.state.base,
23003
23088
  elements,
23089
+ position: this.state.position,
23004
23090
  });
23005
23091
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
23006
23092
  this.env.raiseError(MergeErrorMessage);
23007
23093
  }
23008
23094
  }
23009
- _selectElement(index, ctrlKey) {
23010
- this.env.model.selection.selectColumn(index, ctrlKey ? "newAnchor" : "overrideSelection");
23095
+ _selectElement(index, addDistinctHeader) {
23096
+ this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
23011
23097
  }
23012
23098
  _increaseSelection(index) {
23013
23099
  this.env.model.selection.selectColumn(index, "updateAnchor");
@@ -23173,13 +23259,14 @@ class RowResizer extends AbstractResizer {
23173
23259
  dimension: "ROW",
23174
23260
  base: this.state.base,
23175
23261
  elements,
23262
+ position: this.state.position,
23176
23263
  });
23177
23264
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
23178
23265
  this.env.raiseError(MergeErrorMessage);
23179
23266
  }
23180
23267
  }
23181
- _selectElement(index, ctrlKey) {
23182
- this.env.model.selection.selectRow(index, ctrlKey ? "newAnchor" : "overrideSelection");
23268
+ _selectElement(index, addDistinctHeader) {
23269
+ this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
23183
23270
  }
23184
23271
  _increaseSelection(index) {
23185
23272
  this.env.model.selection.selectRow(index, "updateAnchor");
@@ -23281,8 +23368,8 @@ function useWheelHandler(handler) {
23281
23368
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
23282
23369
  }
23283
23370
  const onMouseWheel = (ev) => {
23284
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
23285
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
23371
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
23372
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
23286
23373
  handler(deltaX, deltaY);
23287
23374
  };
23288
23375
  return onMouseWheel;
@@ -23926,8 +24013,8 @@ class Grid extends owl.Component {
23926
24013
  // ---------------------------------------------------------------------------
23927
24014
  // Zone selection with mouse
23928
24015
  // ---------------------------------------------------------------------------
23929
- onCellClicked(col, row, { ctrlKey, shiftKey }) {
23930
- if (ctrlKey) {
24016
+ onCellClicked(col, row, { addZone, expandZone }) {
24017
+ if (addZone) {
23931
24018
  this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
23932
24019
  }
23933
24020
  if (this.env.model.getters.hasOpenedPopover()) {
@@ -23936,10 +24023,10 @@ class Grid extends owl.Component {
23936
24023
  if (this.env.model.getters.getEditionMode() === "editing") {
23937
24024
  this.env.model.dispatch("STOP_EDITION");
23938
24025
  }
23939
- if (shiftKey) {
24026
+ if (expandZone) {
23940
24027
  this.env.model.selection.setAnchorCorner(col, row);
23941
24028
  }
23942
- else if (ctrlKey) {
24029
+ else if (addZone) {
23943
24030
  this.env.model.selection.addCellToSelection(col, row);
23944
24031
  }
23945
24032
  else {
@@ -24001,9 +24088,7 @@ class Grid extends owl.Component {
24001
24088
  return;
24002
24089
  }
24003
24090
  let keyDownString = "";
24004
- if (ev.ctrlKey)
24005
- keyDownString += "CTRL+";
24006
- if (ev.metaKey)
24091
+ if (isCtrlKey(ev))
24007
24092
  keyDownString += "CTRL+";
24008
24093
  if (ev.altKey)
24009
24094
  keyDownString += "ALT+";
@@ -28363,7 +28448,7 @@ class BordersPlugin extends CorePlugin {
28363
28448
  const currentBorder = this.getCellBorder(cmd);
28364
28449
  const areAllNewBordersUndefined = !((_a = cmd.border) === null || _a === void 0 ? void 0 : _a.bottom) && !((_b = cmd.border) === null || _b === void 0 ? void 0 : _b.left) && !((_c = cmd.border) === null || _c === void 0 ? void 0 : _c.right) && !((_d = cmd.border) === null || _d === void 0 ? void 0 : _d.top);
28365
28450
  if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
28366
- return 88 /* CommandResult.NoChanges */;
28451
+ return 89 /* CommandResult.NoChanges */;
28367
28452
  }
28368
28453
  return 0 /* CommandResult.Success */;
28369
28454
  }
@@ -28885,9 +28970,9 @@ class CellPlugin extends CorePlugin {
28885
28970
  checkUselessClearCell(cmd) {
28886
28971
  const cell = this.getters.getCell(cmd);
28887
28972
  if (!cell)
28888
- return 88 /* CommandResult.NoChanges */;
28973
+ return 89 /* CommandResult.NoChanges */;
28889
28974
  if (!cell.content && !cell.style && !cell.format) {
28890
- return 88 /* CommandResult.NoChanges */;
28975
+ return 89 /* CommandResult.NoChanges */;
28891
28976
  }
28892
28977
  return 0 /* CommandResult.Success */;
28893
28978
  }
@@ -29096,13 +29181,13 @@ class ChartPlugin extends CorePlugin {
29096
29181
  }
29097
29182
  checkChartDuplicate(cmd) {
29098
29183
  return this.getters.getFigureSheetId(cmd.id)
29099
- ? 84 /* CommandResult.DuplicatedChartId */
29184
+ ? 85 /* CommandResult.DuplicatedChartId */
29100
29185
  : 0 /* CommandResult.Success */;
29101
29186
  }
29102
29187
  checkChartExists(cmd) {
29103
29188
  return this.getters.getFigureSheetId(cmd.id)
29104
29189
  ? 0 /* CommandResult.Success */
29105
- : 85 /* CommandResult.ChartDoesNotExist */;
29190
+ : 86 /* CommandResult.ChartDoesNotExist */;
29106
29191
  }
29107
29192
  }
29108
29193
  ChartPlugin.getters = [
@@ -29304,10 +29389,10 @@ class ConditionalFormatPlugin extends CorePlugin {
29304
29389
  return 27 /* CommandResult.InvalidSheetId */;
29305
29390
  const ruleIndex = this.cfRules[sheetId].findIndex((cf) => cf.id === cfId);
29306
29391
  if (ruleIndex === -1)
29307
- return 71 /* CommandResult.InvalidConditionalFormatId */;
29392
+ return 72 /* CommandResult.InvalidConditionalFormatId */;
29308
29393
  const cfIndex2 = direction === "up" ? ruleIndex - 1 : ruleIndex + 1;
29309
29394
  if (cfIndex2 < 0 || cfIndex2 >= this.cfRules[sheetId].length) {
29310
- return 71 /* CommandResult.InvalidConditionalFormatId */;
29395
+ return 72 /* CommandResult.InvalidConditionalFormatId */;
29311
29396
  }
29312
29397
  return 0 /* CommandResult.Success */;
29313
29398
  }
@@ -29348,10 +29433,10 @@ class ConditionalFormatPlugin extends CorePlugin {
29348
29433
  const errors = [];
29349
29434
  const isEmpty = (value) => value === undefined || value === "";
29350
29435
  if (expectedNumber >= 1 && isEmpty(rule.values[0])) {
29351
- errors.push(51 /* CommandResult.FirstArgMissing */);
29436
+ errors.push(52 /* CommandResult.FirstArgMissing */);
29352
29437
  }
29353
29438
  if (expectedNumber >= 2 && isEmpty(rule.values[1])) {
29354
- errors.push(52 /* CommandResult.SecondArgMissing */);
29439
+ errors.push(53 /* CommandResult.SecondArgMissing */);
29355
29440
  }
29356
29441
  return errors.length ? errors : 0 /* CommandResult.Success */;
29357
29442
  }
@@ -29363,15 +29448,15 @@ class ConditionalFormatPlugin extends CorePlugin {
29363
29448
  (threshold.value === "" || isNaN(threshold.value))) {
29364
29449
  switch (thresholdName) {
29365
29450
  case "min":
29366
- return 53 /* CommandResult.MinNaN */;
29451
+ return 54 /* CommandResult.MinNaN */;
29367
29452
  case "max":
29368
- return 55 /* CommandResult.MaxNaN */;
29453
+ return 56 /* CommandResult.MaxNaN */;
29369
29454
  case "mid":
29370
- return 54 /* CommandResult.MidNaN */;
29455
+ return 55 /* CommandResult.MidNaN */;
29371
29456
  case "upperInflectionPoint":
29372
- return 56 /* CommandResult.ValueUpperInflectionNaN */;
29457
+ return 57 /* CommandResult.ValueUpperInflectionNaN */;
29373
29458
  case "lowerInflectionPoint":
29374
- return 57 /* CommandResult.ValueLowerInflectionNaN */;
29459
+ return 58 /* CommandResult.ValueLowerInflectionNaN */;
29375
29460
  }
29376
29461
  }
29377
29462
  return 0 /* CommandResult.Success */;
@@ -29385,15 +29470,15 @@ class ConditionalFormatPlugin extends CorePlugin {
29385
29470
  catch (error) {
29386
29471
  switch (thresholdName) {
29387
29472
  case "min":
29388
- return 58 /* CommandResult.MinInvalidFormula */;
29473
+ return 59 /* CommandResult.MinInvalidFormula */;
29389
29474
  case "max":
29390
- return 60 /* CommandResult.MaxInvalidFormula */;
29475
+ return 61 /* CommandResult.MaxInvalidFormula */;
29391
29476
  case "mid":
29392
- return 59 /* CommandResult.MidInvalidFormula */;
29477
+ return 60 /* CommandResult.MidInvalidFormula */;
29393
29478
  case "upperInflectionPoint":
29394
- return 61 /* CommandResult.ValueUpperInvalidFormula */;
29479
+ return 62 /* CommandResult.ValueUpperInvalidFormula */;
29395
29480
  case "lowerInflectionPoint":
29396
- return 62 /* CommandResult.ValueLowerInvalidFormula */;
29481
+ return 63 /* CommandResult.ValueLowerInvalidFormula */;
29397
29482
  }
29398
29483
  }
29399
29484
  return 0 /* CommandResult.Success */;
@@ -29410,7 +29495,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29410
29495
  if (["number", "percentage", "percentile"].includes(rule.lowerInflectionPoint.type) &&
29411
29496
  rule.lowerInflectionPoint.type === rule.upperInflectionPoint.type &&
29412
29497
  Number(minValue) > Number(maxValue)) {
29413
- return 48 /* CommandResult.LowerBiggerThanUpper */;
29498
+ return 49 /* CommandResult.LowerBiggerThanUpper */;
29414
29499
  }
29415
29500
  return 0 /* CommandResult.Success */;
29416
29501
  }
@@ -29420,7 +29505,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29420
29505
  if (["number", "percentage", "percentile"].includes(rule.minimum.type) &&
29421
29506
  rule.minimum.type === rule.maximum.type &&
29422
29507
  stringToNumber(minValue) >= stringToNumber(maxValue)) {
29423
- return 47 /* CommandResult.MinBiggerThanMax */;
29508
+ return 48 /* CommandResult.MinBiggerThanMax */;
29424
29509
  }
29425
29510
  return 0 /* CommandResult.Success */;
29426
29511
  }
@@ -29432,7 +29517,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29432
29517
  ["number", "percentage", "percentile"].includes(rule.midpoint.type) &&
29433
29518
  rule.midpoint.type === rule.maximum.type &&
29434
29519
  stringToNumber(midValue) >= stringToNumber(maxValue)) {
29435
- return 49 /* CommandResult.MidBiggerThanMax */;
29520
+ return 50 /* CommandResult.MidBiggerThanMax */;
29436
29521
  }
29437
29522
  return 0 /* CommandResult.Success */;
29438
29523
  }
@@ -29444,7 +29529,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29444
29529
  ["number", "percentage", "percentile"].includes(rule.midpoint.type) &&
29445
29530
  rule.minimum.type === rule.midpoint.type &&
29446
29531
  stringToNumber(minValue) >= stringToNumber(midValue)) {
29447
- return 50 /* CommandResult.MinBiggerThanMid */;
29532
+ return 51 /* CommandResult.MinBiggerThanMid */;
29448
29533
  }
29449
29534
  return 0 /* CommandResult.Success */;
29450
29535
  }
@@ -29545,13 +29630,13 @@ class FigurePlugin extends CorePlugin {
29545
29630
  checkFigureExists(sheetId, figureId) {
29546
29631
  var _a;
29547
29632
  if (((_a = this.figures[sheetId]) === null || _a === void 0 ? void 0 : _a[figureId]) === undefined) {
29548
- return 70 /* CommandResult.FigureDoesNotExist */;
29633
+ return 71 /* CommandResult.FigureDoesNotExist */;
29549
29634
  }
29550
29635
  return 0 /* CommandResult.Success */;
29551
29636
  }
29552
29637
  checkFigureDuplicate(figureId) {
29553
29638
  if (Object.values(this.figures).find((sheet) => sheet === null || sheet === void 0 ? void 0 : sheet[figureId])) {
29554
- return 82 /* CommandResult.DuplicatedFigureId */;
29639
+ return 83 /* CommandResult.DuplicatedFigureId */;
29555
29640
  }
29556
29641
  return 0 /* CommandResult.Success */;
29557
29642
  }
@@ -29653,12 +29738,12 @@ class FiltersPlugin extends CorePlugin {
29653
29738
  switch (cmd.type) {
29654
29739
  case "CREATE_FILTER_TABLE":
29655
29740
  if (!areZonesContinuous(...cmd.target)) {
29656
- return 81 /* CommandResult.NonContinuousTargets */;
29741
+ return 82 /* CommandResult.NonContinuousTargets */;
29657
29742
  }
29658
29743
  const zone = union(...cmd.target);
29659
29744
  const checkFilterOverlap = () => {
29660
29745
  if (this.getFilterTables(cmd.sheetId).some((filter) => overlap(filter.zone, zone))) {
29661
- return 78 /* CommandResult.FilterOverlap */;
29746
+ return 79 /* CommandResult.FilterOverlap */;
29662
29747
  }
29663
29748
  return 0 /* CommandResult.Success */;
29664
29749
  };
@@ -29666,7 +29751,7 @@ class FiltersPlugin extends CorePlugin {
29666
29751
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, zone);
29667
29752
  for (let merge of mergesInTarget) {
29668
29753
  if (overlap(zone, merge)) {
29669
- return 80 /* CommandResult.MergeInFilter */;
29754
+ return 81 /* CommandResult.MergeInFilter */;
29670
29755
  }
29671
29756
  }
29672
29757
  return 0 /* CommandResult.Success */;
@@ -29676,7 +29761,7 @@ class FiltersPlugin extends CorePlugin {
29676
29761
  for (let merge of cmd.target) {
29677
29762
  for (let filterTable of this.getFilterTables(cmd.sheetId)) {
29678
29763
  if (overlap(filterTable.zone, merge)) {
29679
- return 80 /* CommandResult.MergeInFilter */;
29764
+ return 81 /* CommandResult.MergeInFilter */;
29680
29765
  }
29681
29766
  }
29682
29767
  }
@@ -30176,10 +30261,10 @@ class HeaderVisibilityPlugin extends CorePlugin {
30176
30261
  : this.getters.getNumberRows(cmd.sheetId);
30177
30262
  const hiddenElements = new Set((hiddenGroup || []).flat().concat(cmd.elements));
30178
30263
  if (hiddenElements.size >= elements) {
30179
- return 66 /* CommandResult.TooManyHiddenElements */;
30264
+ return 67 /* CommandResult.TooManyHiddenElements */;
30180
30265
  }
30181
30266
  else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
30182
- return 86 /* CommandResult.InvalidHeaderIndex */;
30267
+ return 87 /* CommandResult.InvalidHeaderIndex */;
30183
30268
  }
30184
30269
  else {
30185
30270
  return 0 /* CommandResult.Success */;
@@ -30705,7 +30790,7 @@ class MergePlugin extends CorePlugin {
30705
30790
  for (const zone of target) {
30706
30791
  for (const zone2 of target) {
30707
30792
  if (zone !== zone2 && overlap(zone, zone2)) {
30708
- return 65 /* CommandResult.MergeOverlap */;
30793
+ return 66 /* CommandResult.MergeOverlap */;
30709
30794
  }
30710
30795
  }
30711
30796
  }
@@ -30719,7 +30804,7 @@ class MergePlugin extends CorePlugin {
30719
30804
  for (const zone of target) {
30720
30805
  if ((zone.left < xSplit && zone.right >= xSplit) ||
30721
30806
  (zone.top < ySplit && zone.bottom >= ySplit)) {
30722
- return 75 /* CommandResult.FrozenPaneOverlap */;
30807
+ return 76 /* CommandResult.FrozenPaneOverlap */;
30723
30808
  }
30724
30809
  }
30725
30810
  return 0 /* CommandResult.Success */;
@@ -31251,9 +31336,10 @@ class RangeAdapter {
31251
31336
  * Get a Xc string that represent a part of a range
31252
31337
  */
31253
31338
  getRangePartString(range, part) {
31254
- const colFixed = range.parts && range.parts[part].colFixed ? "$" : "";
31339
+ var _a, _b;
31340
+ const colFixed = range.parts && ((_a = range.parts[part]) === null || _a === void 0 ? void 0 : _a.colFixed) ? "$" : "";
31255
31341
  const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
31256
- const rowFixed = range.parts && range.parts[part].rowFixed ? "$" : "";
31342
+ const rowFixed = range.parts && ((_b = range.parts[part]) === null || _b === void 0 ? void 0 : _b.rowFixed) ? "$" : "";
31257
31343
  const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
31258
31344
  let str = "";
31259
31345
  if (range.isFullCol) {
@@ -31351,11 +31437,11 @@ class SheetPlugin extends CorePlugin {
31351
31437
  const elements = cmd.dimension === "COL"
31352
31438
  ? this.getNumberCols(cmd.sheetId)
31353
31439
  : this.getNumberRows(cmd.sheetId);
31354
- if (cmd.base < 0 || cmd.base > elements) {
31355
- return 86 /* CommandResult.InvalidHeaderIndex */;
31440
+ if (cmd.base < 0 || cmd.base >= elements) {
31441
+ return 87 /* CommandResult.InvalidHeaderIndex */;
31356
31442
  }
31357
31443
  else if (cmd.quantity <= 0) {
31358
- return 87 /* CommandResult.InvalidQuantity */;
31444
+ return 88 /* CommandResult.InvalidQuantity */;
31359
31445
  }
31360
31446
  return 0 /* CommandResult.Success */;
31361
31447
  case "REMOVE_COLUMNS_ROWS": {
@@ -31363,7 +31449,7 @@ class SheetPlugin extends CorePlugin {
31363
31449
  ? this.getNumberCols(cmd.sheetId)
31364
31450
  : this.getNumberRows(cmd.sheetId);
31365
31451
  if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
31366
- return 86 /* CommandResult.InvalidHeaderIndex */;
31452
+ return 87 /* CommandResult.InvalidHeaderIndex */;
31367
31453
  }
31368
31454
  else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
31369
31455
  return 8 /* CommandResult.NotEnoughElements */;
@@ -31807,18 +31893,18 @@ class SheetPlugin extends CorePlugin {
31807
31893
  checkRowFreezeQuantity(cmd) {
31808
31894
  return cmd.quantity >= 1 && cmd.quantity < this.getNumberRows(cmd.sheetId)
31809
31895
  ? 0 /* CommandResult.Success */
31810
- : 74 /* CommandResult.InvalidFreezeQuantity */;
31896
+ : 75 /* CommandResult.InvalidFreezeQuantity */;
31811
31897
  }
31812
31898
  checkColFreezeQuantity(cmd) {
31813
31899
  return cmd.quantity >= 1 && cmd.quantity < this.getNumberCols(cmd.sheetId)
31814
31900
  ? 0 /* CommandResult.Success */
31815
- : 74 /* CommandResult.InvalidFreezeQuantity */;
31901
+ : 75 /* CommandResult.InvalidFreezeQuantity */;
31816
31902
  }
31817
31903
  checkRowFreezeOverlapMerge(cmd) {
31818
31904
  const merges = this.getters.getMerges(cmd.sheetId);
31819
31905
  for (let merge of merges) {
31820
31906
  if (merge.top < cmd.quantity && cmd.quantity <= merge.bottom) {
31821
- return 65 /* CommandResult.MergeOverlap */;
31907
+ return 66 /* CommandResult.MergeOverlap */;
31822
31908
  }
31823
31909
  }
31824
31910
  return 0 /* CommandResult.Success */;
@@ -31827,7 +31913,7 @@ class SheetPlugin extends CorePlugin {
31827
31913
  const merges = this.getters.getMerges(cmd.sheetId);
31828
31914
  for (let merge of merges) {
31829
31915
  if (merge.left < cmd.quantity && cmd.quantity <= merge.right) {
31830
- return 65 /* CommandResult.MergeOverlap */;
31916
+ return 66 /* CommandResult.MergeOverlap */;
31831
31917
  }
31832
31918
  }
31833
31919
  return 0 /* CommandResult.Success */;
@@ -32374,13 +32460,18 @@ class EvaluationPlugin extends UIPlugin {
32374
32460
  // Getters
32375
32461
  // ---------------------------------------------------------------------------
32376
32462
  evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
32377
- const compiledFormula = compile(formulaString);
32378
- const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
32379
- const ranges = [];
32380
- for (let xc of compiledFormula.dependencies) {
32381
- ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
32463
+ try {
32464
+ const compiledFormula = compile(formulaString);
32465
+ const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
32466
+ const ranges = [];
32467
+ for (let xc of compiledFormula.dependencies) {
32468
+ ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
32469
+ }
32470
+ return compiledFormula.execute(ranges, ...params).value;
32471
+ }
32472
+ catch (error) {
32473
+ return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
32382
32474
  }
32383
- return compiledFormula.execute(ranges, ...params).value;
32384
32475
  }
32385
32476
  /**
32386
32477
  * Return the value of each cell in the range as they are displayed in the grid.
@@ -32559,10 +32650,8 @@ class EvaluationPlugin extends UIPlugin {
32559
32650
  * that are actually present in the grid.
32560
32651
  */
32561
32652
  function range(range) {
32653
+ assertRangeValid(range);
32562
32654
  const sheetId = range.sheetId;
32563
- if (!isZoneValid(range.zone)) {
32564
- throw new InvalidReferenceError();
32565
- }
32566
32655
  // Performance issue: Avoid fetching data on positions that are out of the spreadsheet
32567
32656
  // e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
32568
32657
  const sheetZone = getters.getSheetZone(sheetId);
@@ -32597,23 +32686,26 @@ class EvaluationPlugin extends UIPlugin {
32597
32686
  * The `compute` of the formula's function must process it completely
32598
32687
  */
32599
32688
  function refFn(range, isMeta, functionName, paramNumber) {
32689
+ assertRangeValid(range);
32600
32690
  if (isMeta) {
32601
32691
  // Use zoneToXc of zone instead of getRangeString to avoid sending unbounded ranges
32602
32692
  return { value: zoneToXc(range.zone) };
32603
32693
  }
32604
- if (!isZoneValid(range.zone)) {
32605
- throw new InvalidReferenceError();
32606
- }
32607
32694
  // if the formula definition could have accepted a range, we would pass through the _range function and not here
32608
32695
  if (range.zone.bottom !== range.zone.top || range.zone.left !== range.zone.right) {
32609
32696
  throw new Error(paramNumber
32610
32697
  ? _lt("Function %s expects the parameter %s to be a single value or a single cell reference, not a range.", functionName.toString(), paramNumber.toString())
32611
32698
  : _lt("Function %s expects its parameters to be single values or single cell references, not ranges.", functionName.toString()));
32612
32699
  }
32700
+ return readCell(range);
32701
+ }
32702
+ function assertRangeValid(range) {
32703
+ if (!isZoneValid(range.zone)) {
32704
+ throw new InvalidReferenceError();
32705
+ }
32613
32706
  if (range.invalidSheetName) {
32614
32707
  throw new Error(_lt("Invalid sheet name: %s", range.invalidSheetName));
32615
32708
  }
32616
- return readCell(range);
32617
32709
  }
32618
32710
  return [refFn, range, evalContext];
32619
32711
  }
@@ -32872,39 +32964,34 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
32872
32964
  this.computedIcons[sheetId] = {};
32873
32965
  const computedStyle = this.computedStyles[sheetId];
32874
32966
  for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
32875
- try {
32876
- switch (cf.rule.type) {
32877
- case "ColorScaleRule":
32878
- for (let range of cf.ranges) {
32879
- this.applyColorScale(range, cf.rule);
32880
- }
32881
- break;
32882
- case "IconSetRule":
32883
- for (let range of cf.ranges) {
32884
- this.applyIcon(range, cf.rule);
32885
- }
32886
- break;
32887
- default:
32888
- for (let ref of cf.ranges) {
32889
- const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
32890
- for (let row = zone.top; row <= zone.bottom; row++) {
32891
- for (let col = zone.left; col <= zone.right; col++) {
32892
- const pr = this.rulePredicate[cf.rule.type];
32893
- let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
32894
- if (pr && pr(cell, cf.rule)) {
32895
- if (!computedStyle[col])
32896
- computedStyle[col] = [];
32897
- // we must combine all the properties of all the CF rules applied to the given cell
32898
- computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
32899
- }
32967
+ switch (cf.rule.type) {
32968
+ case "ColorScaleRule":
32969
+ for (let range of cf.ranges) {
32970
+ this.applyColorScale(range, cf.rule);
32971
+ }
32972
+ break;
32973
+ case "IconSetRule":
32974
+ for (let range of cf.ranges) {
32975
+ this.applyIcon(range, cf.rule);
32976
+ }
32977
+ break;
32978
+ default:
32979
+ for (let ref of cf.ranges) {
32980
+ const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
32981
+ for (let row = zone.top; row <= zone.bottom; row++) {
32982
+ for (let col = zone.left; col <= zone.right; col++) {
32983
+ const pr = this.rulePredicate[cf.rule.type];
32984
+ let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
32985
+ if (pr && pr(cell, cf.rule)) {
32986
+ if (!computedStyle[col])
32987
+ computedStyle[col] = [];
32988
+ // we must combine all the properties of all the CF rules applied to the given cell
32989
+ computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
32900
32990
  }
32901
32991
  }
32902
32992
  }
32903
- break;
32904
- }
32905
- }
32906
- catch (_) {
32907
- // we don't care about the errors within the evaluation of a rule
32993
+ }
32994
+ break;
32908
32995
  }
32909
32996
  }
32910
32997
  }
@@ -32929,7 +33016,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
32929
33016
  return percentile(rangeValues, Number(threshold.value) / 100, true);
32930
33017
  case "formula":
32931
33018
  const value = threshold.value && this.getters.evaluateFormula(threshold.value);
32932
- return !(value instanceof Promise) ? value : null;
33019
+ return typeof value === "number" ? value : null;
32933
33020
  default:
32934
33021
  return null;
32935
33022
  }
@@ -33117,7 +33204,7 @@ class FilterEvaluationPlugin extends UIPlugin {
33117
33204
  switch (cmd.type) {
33118
33205
  case "UPDATE_FILTER":
33119
33206
  if (!this.getters.getFilterId(cmd)) {
33120
- return 79 /* CommandResult.FilterNotFound */;
33207
+ return 80 /* CommandResult.FilterNotFound */;
33121
33208
  }
33122
33209
  break;
33123
33210
  }
@@ -34063,7 +34150,7 @@ class SheetViewPlugin extends UIPlugin {
34063
34150
  }
34064
34151
  checkPositiveDimension(cmd) {
34065
34152
  if (cmd.width < 0 || cmd.height < 0) {
34066
- return 68 /* CommandResult.InvalidViewportSize */;
34153
+ return 69 /* CommandResult.InvalidViewportSize */;
34067
34154
  }
34068
34155
  return 0 /* CommandResult.Success */;
34069
34156
  }
@@ -34073,7 +34160,7 @@ class SheetViewPlugin extends UIPlugin {
34073
34160
  cmd.gridOffsetY === this.gridOffsetY &&
34074
34161
  cmd.width === width &&
34075
34162
  cmd.height === height) {
34076
- return 76 /* CommandResult.ValuesNotChanged */;
34163
+ return 77 /* CommandResult.ValuesNotChanged */;
34077
34164
  }
34078
34165
  return 0 /* CommandResult.Success */;
34079
34166
  }
@@ -34081,7 +34168,7 @@ class SheetViewPlugin extends UIPlugin {
34081
34168
  const pane = this.getMainInternalViewport(this.getters.getActiveSheetId());
34082
34169
  if ((!pane.canScrollHorizontally && offsetX > 0) ||
34083
34170
  (!pane.canScrollVertically && offsetY > 0)) {
34084
- return 69 /* CommandResult.InvalidScrollingDirection */;
34171
+ return 70 /* CommandResult.InvalidScrollingDirection */;
34085
34172
  }
34086
34173
  return 0 /* CommandResult.Success */;
34087
34174
  }
@@ -34337,7 +34424,7 @@ class AutofillPlugin extends UIPlugin {
34337
34424
  if (this.lastCellSelected.col !== undefined && this.lastCellSelected.row !== undefined) {
34338
34425
  return 0 /* CommandResult.Success */;
34339
34426
  }
34340
- return 45 /* CommandResult.InvalidAutofillSelection */;
34427
+ return 46 /* CommandResult.InvalidAutofillSelection */;
34341
34428
  case "AUTOFILL_AUTO":
34342
34429
  const zone = this.getters.getSelectedZone();
34343
34430
  return zone.top === zone.bottom
@@ -34491,24 +34578,27 @@ class AutofillPlugin extends UIPlugin {
34491
34578
  * autofiller
34492
34579
  */
34493
34580
  autofillAuto() {
34581
+ var _a, _b;
34494
34582
  const zone = this.getters.getSelectedZone();
34495
34583
  const sheetId = this.getters.getActiveSheetId();
34496
34584
  let col = zone.left;
34497
34585
  let row = zone.bottom;
34498
34586
  if (col > 0) {
34499
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34500
- while (left.type !== CellValueType.empty) {
34587
+ let leftPosition = { sheetId, col: col - 1, row };
34588
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
34589
+ ((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
34501
34590
  row += 1;
34502
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34591
+ leftPosition = { sheetId, col: col - 1, row };
34503
34592
  }
34504
34593
  }
34505
34594
  if (row === zone.bottom) {
34506
34595
  col = zone.right;
34507
34596
  if (col <= this.getters.getNumberCols(sheetId)) {
34508
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34509
- while (right.type !== CellValueType.empty) {
34597
+ let rightPosition = { sheetId, col: col + 1, row };
34598
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
34599
+ ((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
34510
34600
  row += 1;
34511
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34601
+ rightPosition = { sheetId, col: col + 1, row };
34512
34602
  }
34513
34603
  }
34514
34604
  }
@@ -34936,7 +35026,7 @@ class CellPopoverPlugin extends UIPlugin {
34936
35026
  cellPopoverRegistry.get(cmd.popoverType);
34937
35027
  }
34938
35028
  catch (error) {
34939
- return 72 /* CommandResult.InvalidCellPopover */;
35029
+ return 73 /* CommandResult.InvalidCellPopover */;
34940
35030
  }
34941
35031
  return 0 /* CommandResult.Success */;
34942
35032
  default:
@@ -36139,21 +36229,6 @@ class SelectionInputPlugin extends UIPlugin {
36139
36229
  // ---------------------------------------------------------------------------
36140
36230
  // Command Handling
36141
36231
  // ---------------------------------------------------------------------------
36142
- allowDispatch(cmd) {
36143
- switch (cmd.type) {
36144
- case "ADD_EMPTY_RANGE":
36145
- if (this.inputHasSingleRange && this.ranges.length === 1) {
36146
- return 30 /* CommandResult.MaximumRangesReached */;
36147
- }
36148
- break;
36149
- case "CHANGE_RANGE":
36150
- if (this.inputHasSingleRange && cmd.value.split(",").length > 1) {
36151
- return 30 /* CommandResult.MaximumRangesReached */;
36152
- }
36153
- break;
36154
- }
36155
- return 0 /* CommandResult.Success */;
36156
- }
36157
36232
  handleEvent(event) {
36158
36233
  const xc = zoneToXc(event.anchor.zone);
36159
36234
  const inputSheetId = this.activeSheet;
@@ -36365,6 +36440,15 @@ class SelectionInputsManagerPlugin extends UIPlugin {
36365
36440
  // ---------------------------------------------------------------------------
36366
36441
  allowDispatch(cmd) {
36367
36442
  var _a, _b;
36443
+ switch (cmd.type) {
36444
+ case "FOCUS_RANGE":
36445
+ case "CHANGE_RANGE":
36446
+ case "ADD_EMPTY_RANGE":
36447
+ case "REMOVE_RANGE":
36448
+ if (!this.inputs[cmd.id]) {
36449
+ return 31 /* CommandResult.InvalidInputId */;
36450
+ }
36451
+ }
36368
36452
  switch (cmd.type) {
36369
36453
  case "FOCUS_RANGE":
36370
36454
  const index = (_a = this.currentInput) === null || _a === void 0 ? void 0 : _a.getIndex(cmd.rangeId);
@@ -36372,9 +36456,19 @@ class SelectionInputsManagerPlugin extends UIPlugin {
36372
36456
  return 29 /* CommandResult.InputAlreadyFocused */;
36373
36457
  }
36374
36458
  break;
36375
- }
36376
- if (this.currentInput) {
36377
- return this.currentInput.allowDispatch(cmd);
36459
+ case "ADD_EMPTY_RANGE":
36460
+ const input = this.inputs[cmd.id];
36461
+ if (input.inputHasSingleRange && input.ranges.length === 1) {
36462
+ return 30 /* CommandResult.MaximumRangesReached */;
36463
+ }
36464
+ break;
36465
+ case "CHANGE_RANGE": {
36466
+ const input = this.inputs[cmd.id];
36467
+ if (input.inputHasSingleRange && cmd.value.split(",").length > 1) {
36468
+ return 30 /* CommandResult.MaximumRangesReached */;
36469
+ }
36470
+ break;
36471
+ }
36378
36472
  }
36379
36473
  return 0 /* CommandResult.Success */;
36380
36474
  }
@@ -37357,7 +37451,7 @@ class SortPlugin extends UIPlugin {
37357
37451
  /*Test the presence of single cells*/
37358
37452
  const singleCells = positions(zone).some(({ col, row }) => !this.getters.isInMerge({ sheetId, col, row }));
37359
37453
  if (singleCells) {
37360
- return 63 /* CommandResult.InvalidSortZone */;
37454
+ return 64 /* CommandResult.InvalidSortZone */;
37361
37455
  }
37362
37456
  return 0 /* CommandResult.Success */;
37363
37457
  }
@@ -37376,7 +37470,7 @@ class SortPlugin extends UIPlugin {
37376
37470
  ];
37377
37471
  return widthCurrent === widthFirst && heightCurrent === heightFirst;
37378
37472
  })) {
37379
- return 63 /* CommandResult.InvalidSortZone */;
37473
+ return 64 /* CommandResult.InvalidSortZone */;
37380
37474
  }
37381
37475
  return 0 /* CommandResult.Success */;
37382
37476
  }
@@ -38004,7 +38098,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
38004
38098
  for (const zone of this.getPasteZones(target)) {
38005
38099
  if ((zone.left < xSplit && zone.right >= xSplit) ||
38006
38100
  (zone.top < ySplit && zone.bottom >= ySplit)) {
38007
- return 75 /* CommandResult.FrozenPaneOverlap */;
38101
+ return 76 /* CommandResult.FrozenPaneOverlap */;
38008
38102
  }
38009
38103
  }
38010
38104
  return 0 /* CommandResult.Success */;
@@ -38392,7 +38486,7 @@ class ClipboardFigureState {
38392
38486
  }
38393
38487
  isPasteAllowed(target, option) {
38394
38488
  if (target.length === 0) {
38395
- return 73 /* CommandResult.EmptyTarget */;
38489
+ return 74 /* CommandResult.EmptyTarget */;
38396
38490
  }
38397
38491
  if ((option === null || option === void 0 ? void 0 : option.pasteOption) !== undefined) {
38398
38492
  return 22 /* CommandResult.WrongFigurePasteOption */;
@@ -39240,7 +39334,7 @@ class GridSelectionPlugin extends UIPlugin {
39240
39334
  sheetId: cmd.sheetId,
39241
39335
  base: cmd.base,
39242
39336
  quantity: thickness,
39243
- position: "before",
39337
+ position: cmd.position,
39244
39338
  });
39245
39339
  const isCol = cmd.dimension === "COL";
39246
39340
  const start = cmd.elements[0];
@@ -39257,12 +39351,13 @@ class GridSelectionPlugin extends UIPlugin {
39257
39351
  },
39258
39352
  ];
39259
39353
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
39354
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
39260
39355
  const pasteTarget = [
39261
39356
  {
39262
- left: isCol ? cmd.base : 0,
39263
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39264
- top: !isCol ? cmd.base : 0,
39265
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39357
+ left: isCol ? base : 0,
39358
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39359
+ top: !isCol ? base : 0,
39360
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39266
39361
  },
39267
39362
  ];
39268
39363
  state.paste(pasteTarget, { selectTarget: true });
@@ -39299,6 +39394,11 @@ class GridSelectionPlugin extends UIPlugin {
39299
39394
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
39300
39395
  return 2 /* CommandResult.WillRemoveExistingMerge */;
39301
39396
  }
39397
+ const headers = [cmd.base, ...cmd.elements];
39398
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
39399
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
39400
+ return 87 /* CommandResult.InvalidHeaderIndex */;
39401
+ }
39302
39402
  return 0 /* CommandResult.Success */;
39303
39403
  }
39304
39404
  //-------------------------------------------
@@ -40105,7 +40205,7 @@ const AddMergeInteractiveContent = {
40105
40205
  };
40106
40206
  function interactiveAddMerge(env, sheetId, target) {
40107
40207
  const result = env.model.dispatch("ADD_MERGE", { sheetId, target });
40108
- if (result.isCancelledBecause(80 /* CommandResult.MergeInFilter */)) {
40208
+ if (result.isCancelledBecause(81 /* CommandResult.MergeInFilter */)) {
40109
40209
  env.raiseError(AddMergeInteractiveContent.MergeInFilter);
40110
40210
  }
40111
40211
  else if (result.isCancelledBecause(3 /* CommandResult.MergeIsDestructive */)) {
@@ -40852,7 +40952,7 @@ class Spreadsheet extends owl.Component {
40852
40952
  }
40853
40953
  onKeydown(ev) {
40854
40954
  let keyDownString = "";
40855
- if (ev.ctrlKey || ev.metaKey) {
40955
+ if (isCtrlKey(ev)) {
40856
40956
  keyDownString += "CTRL+";
40857
40957
  }
40858
40958
  keyDownString += ev.key.toUpperCase();
@@ -41980,7 +42080,7 @@ class SelectionStreamProcessor {
41980
42080
  */
41981
42081
  moveAnchorCell(direction, step = 1) {
41982
42082
  if (step !== "end" && step <= 0) {
41983
- return new DispatchResult(83 /* CommandResult.InvalidSelectionStep */);
42083
+ return new DispatchResult(84 /* CommandResult.InvalidSelectionStep */);
41984
42084
  }
41985
42085
  const { col, row } = this.getNextAvailablePosition(direction, step);
41986
42086
  return this.selectCell(col, row);
@@ -42026,7 +42126,7 @@ class SelectionStreamProcessor {
42026
42126
  */
42027
42127
  resizeAnchorZone(direction, step = 1) {
42028
42128
  if (step !== "end" && step <= 0) {
42029
- return new DispatchResult(83 /* CommandResult.InvalidSelectionStep */);
42129
+ return new DispatchResult(84 /* CommandResult.InvalidSelectionStep */);
42030
42130
  }
42031
42131
  const sheetId = this.getters.getActiveSheetId();
42032
42132
  const anchor = this.anchor;
@@ -43986,10 +44086,10 @@ class Model extends EventBus {
43986
44086
  const command = { ...payload, type };
43987
44087
  let status = this.status;
43988
44088
  if (this.getters.isReadonly() && !canExecuteInReadonly(command)) {
43989
- return new DispatchResult(67 /* CommandResult.Readonly */);
44089
+ return new DispatchResult(68 /* CommandResult.Readonly */);
43990
44090
  }
43991
44091
  if (!this.session.canApplyOptimisticUpdate()) {
43992
- return new DispatchResult(64 /* CommandResult.WaitingSessionConfirmation */);
44092
+ return new DispatchResult(65 /* CommandResult.WaitingSessionConfirmation */);
43993
44093
  }
43994
44094
  switch (status) {
43995
44095
  case 0 /* Status.Ready */:
@@ -44477,6 +44577,6 @@ exports.setTranslationMethod = setTranslationMethod;
44477
44577
  exports.tokenize = tokenize;
44478
44578
 
44479
44579
 
44480
- __info__.version = '16.1.28';
44481
- __info__.date = '2023-11-24T13:11:01.992Z';
44482
- __info__.hash = '257f369';
44580
+ __info__.version = '16.1.33';
44581
+ __info__.date = '2024-01-29T13:49:43.259Z';
44582
+ __info__.hash = 'd3b27dd';