@odoo/o-spreadsheet 19.4.12 → 19.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 19.4.12
6
- * @date 2026-09-10T05:38:01.898Z
7
- * @hash cdb63b4
5
+ * @version 19.4.14
6
+ * @date 2026-10-01T07:47:35.933Z
7
+ * @hash 67c7fe5
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -451,6 +451,9 @@ _odoo_owl = __toESM(_odoo_owl, 1);
451
451
  const CHART_WATERFALL_POSITIVE_COLOR = "#4EA7F2";
452
452
  const CHART_WATERFALL_NEGATIVE_COLOR = "#EA6175";
453
453
  const CHART_WATERFALL_SUBTOTAL_COLOR = "#AAAAAA";
454
+ const MIN_BUBBLE_RADIUS = 10;
455
+ const DEFAULT_BUBBLE_RADIUS = 2;
456
+ const MAX_BUBBLE_RADIUS = 30;
454
457
  const GRAY_900 = "#111827";
455
458
  const GRAY_400 = "#ced4da";
456
459
  const GRAY_300 = "#D8DADD";
@@ -458,12 +461,19 @@ _odoo_owl = __toESM(_odoo_owl, 1);
458
461
  const TEXT_BODY = "#374151";
459
462
  const TEXT_BODY_MUTED = "#374151C2";
460
463
  const ACTION_COLOR = HIGHLIGHT_COLOR$1;
464
+ const CHART_PADDING = 20;
465
+ const CHART_PADDING_BOTTOM = 10;
466
+ const CHART_PADDING_TOP = 15;
461
467
  const CHART_TITLE_FONT_SIZE = 16;
468
+ const CHART_AXIS_TITLE_FONT_SIZE = 12;
469
+ const MASTER_CHART_HEIGHT = 60;
470
+ const CHART_COLORSCALE_WIDTH = 70;
462
471
  const DEFAULT_CHART_COLOR_SCALE = {
463
472
  minColor: "#FFF5EB",
464
473
  midColor: "#FD8D3C",
465
474
  maxColor: "#7F2704"
466
475
  };
476
+ const SCORECARD_CHART_TITLE_FONT_SIZE = 14;
467
477
  const PIVOT_TOKEN_COLOR = "#F28C28";
468
478
  const COLOR_PICKER_DEFAULTS = [
469
479
  "#000000",
@@ -547,8 +557,32 @@ _odoo_owl = __toESM(_odoo_owl, 1);
547
557
  "#20124D",
548
558
  "#4C1130"
549
559
  ];
560
+ const MIN_ROW_HEIGHT = 10;
561
+ const MIN_COL_WIDTH = 5;
562
+ const HEADER_HEIGHT = 26;
563
+ const HEADER_WIDTH = 48;
564
+ const DESKTOP_TOPBAR_TOOLBAR_HEIGHT = 34;
565
+ const DESKTOP_BOTTOMBAR_HEIGHT = 36;
566
+ const DEFAULT_CELL_WIDTH = 96;
550
567
  const DEFAULT_CELL_HEIGHT = 23;
551
- const FOOTER_HEIGHT = 2 * 23;
568
+ const SCROLLBAR_WIDTH = 15;
569
+ const AUTOFILL_EDGE_LENGTH = 8;
570
+ const ICON_EDGE_LENGTH = 18;
571
+ const MIN_CF_ICON_MARGIN = 4;
572
+ const MIN_CELL_TEXT_MARGIN = 4;
573
+ const PADDING_AUTORESIZE_VERTICAL = 3;
574
+ const PADDING_AUTORESIZE_HORIZONTAL = MIN_CELL_TEXT_MARGIN;
575
+ const GROUP_LAYER_WIDTH = 21;
576
+ const GRID_ICON_MARGIN = 2;
577
+ const GRID_ICON_EDGE_LENGTH = 17;
578
+ const FOOTER_HEIGHT = 2 * DEFAULT_CELL_HEIGHT;
579
+ const DATA_VALIDATION_CHIP_MARGIN = 5;
580
+ const MOBILE_WIDTH_BREAKPOINT = 768;
581
+ const MENU_WIDTH = 250;
582
+ const MENU_VERTICAL_PADDING = 6;
583
+ const DESKTOP_MENU_ITEM_HEIGHT = 26;
584
+ const MIN_ZOOM_LEVEL = .5;
585
+ const MAX_ZOOM_LEVEL = 2;
552
586
  const ZOOM_VALUES = [
553
587
  50,
554
588
  75,
@@ -578,20 +612,34 @@ _odoo_owl = __toESM(_odoo_owl, 1);
578
612
  };
579
613
  const DEFAULT_VERTICAL_ALIGN = DEFAULT_STYLE.verticalAlign;
580
614
  const DEFAULT_WRAPPING_MODE = DEFAULT_STYLE.wrapping;
615
+ const DEFAULT_FONT_WEIGHT = "400";
581
616
  const DEFAULT_FONT_SIZE = DEFAULT_STYLE.fontSize;
617
+ const HEADER_FONT_SIZE = 11;
582
618
  const DEFAULT_FONT = "'Roboto', arial, 'Liberation Sans'";
583
619
  const DEFAULT_BORDER_DESC = {
584
620
  style: "thin",
585
621
  color: "#000000"
586
622
  };
623
+ const MAX_HISTORY_STEPS = 99;
587
624
  const DEFAULT_REVISION_ID = "START_REVISION";
625
+ const DEFAULT_FIGURE_HEIGHT = 335;
626
+ const DEFAULT_FIGURE_WIDTH = 536;
627
+ const FIGURE_BORDER_WIDTH = 1;
628
+ const MIN_FIG_SIZE = 80;
629
+ const MAX_CHAR_LABEL = 20;
630
+ const FIGURE_ID_SPLITTER = "??";
588
631
  const DEFAULT_GAUGE_LOWER_COLOR = "#EA6175";
589
632
  const DEFAULT_GAUGE_MIDDLE_COLOR = "#FFD86D";
590
633
  const DEFAULT_GAUGE_UPPER_COLOR = "#43C5B1";
591
634
  const DEFAULT_SCORECARD_BASELINE_MODE = "difference";
592
635
  const DEFAULT_SCORECARD_BASELINE_COLOR_UP = "#43C5B1";
593
636
  const DEFAULT_SCORECARD_BASELINE_COLOR_DOWN = "#EA6175";
637
+ const DEFAULT_SCORECARD_KEY_VALUE_FONT_SIZE = 32;
638
+ const DEFAULT_SCORECARD_BASELINE_FONT_SIZE = 16;
594
639
  const LINE_FILL_TRANSPARENCY = .4;
640
+ const LINE_DATA_POINT_RADIUS = 3;
641
+ const DEFAULT_WINDOW_SIZE = 2;
642
+ const MESSAGE_VERSION = 1;
595
643
  const FORBIDDEN_SHEETNAME_CHARS = [
596
644
  "'",
597
645
  "*",
@@ -602,6 +650,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
602
650
  "]"
603
651
  ];
604
652
  const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
653
+ const FORMULA_REF_IDENTIFIER = "|";
605
654
  let DEFAULT_SHEETVIEW_SIZE = 0;
606
655
  /**
607
656
  * The viewport dimensions are usually set by one of the components
@@ -616,6 +665,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
616
665
  DEFAULT_SHEETVIEW_SIZE = size;
617
666
  }
618
667
  const MAXIMAL_FREEZABLE_RATIO = .85;
668
+ const NEWLINE = "\n";
619
669
  const FONT_SIZES = [
620
670
  6,
621
671
  7,
@@ -641,6 +691,8 @@ _odoo_owl = __toESM(_odoo_owl, 1);
641
691
  automaticAutofill: false
642
692
  };
643
693
  const PIVOT_INSERT_TABLE_STYLE_ID = "PivotTableStyleMedium12";
694
+ const PIVOT_INDENT = 15;
695
+ const PIVOT_COLLAPSE_ICON_SIZE = 12;
644
696
  const PIVOT_MAX_NUMBER_OF_CELLS = 5e5;
645
697
  const DEFAULT_CURRENCY = {
646
698
  symbol: "$",
@@ -650,7 +702,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
650
702
  name: "Dollar"
651
703
  };
652
704
  const DEFAULT_CAROUSEL_TITLE_STYLE = {
653
- fontSize: 16,
705
+ fontSize: CHART_TITLE_FONT_SIZE,
654
706
  color: TEXT_BODY
655
707
  };
656
708
  const DEFAULT_TOKEN_COLOR = "light-dark(#000000, #ffffff)";
@@ -667,6 +719,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
667
719
  ARG_SEPARATOR: functionColor,
668
720
  ORPHAN_RIGHT_PAREN: "#ff0000"
669
721
  };
722
+ const DRAG_THRESHOLD = 5;
670
723
 
671
724
  //#endregion
672
725
  //#region src/types/misc.ts
@@ -1073,7 +1126,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
1073
1126
  */
1074
1127
  function replaceNewLines(text) {
1075
1128
  if (!text) return "";
1076
- return text.replace(newLineRegexp, "\n");
1129
+ return text.replace(newLineRegexp, NEWLINE);
1077
1130
  }
1078
1131
  /**
1079
1132
  * Determine if the numbers are consecutive.
@@ -1341,7 +1394,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
1341
1394
  consumeSpaces(chars);
1342
1395
  const col = letterPart - 1;
1343
1396
  const row = num - 1;
1344
- if (!chars.isOver() || col > MAX_COL || row > 9999998) throw new Error(`Invalid cell description: ${xc}`);
1397
+ if (!chars.isOver() || col > MAX_COL || row > MAX_ROW) throw new Error(`Invalid cell description: ${xc}`);
1345
1398
  return {
1346
1399
  col,
1347
1400
  row
@@ -1752,7 +1805,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
1752
1805
  const orderedZone = reorderZone(toZoneWithoutBoundaryChanges(xc));
1753
1806
  const bottom = orderedZone.bottom;
1754
1807
  const right = orderedZone.right;
1755
- if (bottom !== void 0 && bottom > 9999998 || right !== void 0 && right > MAX_COL) throw new Error(`Range string out of bounds: ${xc}`);
1808
+ if (bottom !== void 0 && bottom > MAX_ROW || right !== void 0 && right > MAX_COL) throw new Error(`Range string out of bounds: ${xc}`);
1756
1809
  if (bottom === void 0 && right === void 0) throw new Error("Wrong zone xc. The zone cannot be at the same time a full column and a full row");
1757
1810
  return orderedZone;
1758
1811
  }
@@ -1913,7 +1966,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
1913
1966
  return {
1914
1967
  top: Math.max(z1.top, z2.top),
1915
1968
  left: Math.max(z1.left, z2.left),
1916
- bottom: Math.min(z1.bottom ?? 9999998, z2.bottom),
1969
+ bottom: Math.min(z1.bottom ?? MAX_ROW, z2.bottom),
1917
1970
  right: Math.min(z1.right ?? MAX_COL, z2.right)
1918
1971
  };
1919
1972
  }
@@ -4744,7 +4797,7 @@ set(value) {
4744
4797
  switch (token.type) {
4745
4798
  case "DIGIT":
4746
4799
  if (parsedPart === integerPart) parsedPart.push(token);
4747
- else if (numberOfDecimalsDigits < 20) {
4800
+ else if (numberOfDecimalsDigits < MAX_DECIMAL_PLACES) {
4748
4801
  parsedPart.push(token);
4749
4802
  numberOfDecimalsDigits++;
4750
4803
  }
@@ -5048,7 +5101,7 @@ set(value) {
5048
5101
  if (digitType === "0") digit = digit || "0";
5049
5102
  if (!digit) return;
5050
5103
  const digitIndex = integerDigits.length - 1 - indexInIntegerString;
5051
- const groups = getIndexesOfDigitsWithThousandSeparator(locale.digitGrouping || "[3,0]");
5104
+ const groups = getIndexesOfDigitsWithThousandSeparator(locale.digitGrouping || DEFAULT_LOCALE_DIGIT_GROUPING);
5052
5105
  if (thousandsSeparator && groups.has(digitIndex - 1)) formattedInteger = digit + thousandsSeparator + formattedInteger;
5053
5106
  else formattedInteger = digit + formattedInteger;
5054
5107
  }
@@ -5108,7 +5161,7 @@ set(value) {
5108
5161
  * exceed in the decimal part, in which case digits are rounded.
5109
5162
  *
5110
5163
  **/
5111
- function splitNumber(value, maxDecimals = 20) {
5164
+ function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
5112
5165
  const asString = value.toString();
5113
5166
  if (asString.includes("e")) return splitNumberIntl(value, maxDecimals);
5114
5167
  if (Number.isInteger(value)) return {
@@ -5177,7 +5230,7 @@ set(value) {
5177
5230
  * Supports numbers with a lot of digits that are transformed to scientific notation by
5178
5231
  * number.toString(), but is slow.
5179
5232
  */
5180
- function splitNumberIntl(value, maxDecimals = 20) {
5233
+ function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
5181
5234
  let formatter = numberRepresentation[maxDecimals];
5182
5235
  if (!formatter) {
5183
5236
  formatter = new Intl.NumberFormat("en-US", {
@@ -6145,11 +6198,11 @@ set(value) {
6145
6198
  return result;
6146
6199
  }
6147
6200
  function tokenizeDebugger(chars) {
6148
- if (chars.current === "?") {
6201
+ if (chars.current === DEBUGGER_CHAR) {
6149
6202
  chars.shift();
6150
6203
  return {
6151
6204
  type: "DEBUGGER",
6152
- value: "?"
6205
+ value: DEBUGGER_CHAR
6153
6206
  };
6154
6207
  }
6155
6208
  return null;
@@ -6308,13 +6361,13 @@ set(value) {
6308
6361
  }
6309
6362
  function tokenizeNewLine(chars) {
6310
6363
  let length = 0;
6311
- while (chars.current === "\n") {
6364
+ while (chars.current === NEWLINE) {
6312
6365
  length++;
6313
6366
  chars.shift();
6314
6367
  }
6315
6368
  if (length) return {
6316
6369
  type: "SPACE",
6317
- value: "\n".repeat(length)
6370
+ value: NEWLINE.repeat(length)
6318
6371
  };
6319
6372
  return null;
6320
6373
  }
@@ -8452,7 +8505,7 @@ set(value) {
8452
8505
  //#endregion
8453
8506
  //#region src/helpers/text_helper.ts
8454
8507
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
8455
- return numberOfLines * (textLineHeight + 4) - 4;
8508
+ return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
8456
8509
  }
8457
8510
  function getCanvas(width = 100, height = 100) {
8458
8511
  return new OffscreenCanvas(width, height).getContext("2d");
@@ -8461,7 +8514,7 @@ set(value) {
8461
8514
  * Get the default height of the cell given its style.
8462
8515
  */
8463
8516
  function getDefaultCellHeight(ctx, cell, locale, colSize) {
8464
- if (!cell || !cell.isFormula && !cell.content) return 23;
8517
+ if (!cell || !cell.isFormula && !cell.content) return DEFAULT_CELL_HEIGHT;
8465
8518
  let content = "";
8466
8519
  try {
8467
8520
  if (!cell.isFormula) {
@@ -8477,7 +8530,7 @@ set(value) {
8477
8530
  return getCellContentHeight(ctx, content, cell.style, colSize);
8478
8531
  }
8479
8532
  function getCellContentHeight(ctx, content, style, colSize) {
8480
- return computeMultilineTextSize(ctx, splitTextToWidth(ctx, content, style, style?.wrapping === "wrap" ? colSize - 2 * 4 : void 0), style).height + 2 * 3;
8533
+ return computeMultilineTextSize(ctx, splitTextToWidth(ctx, content, style, style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : void 0), style).height + 2 * PADDING_AUTORESIZE_VERTICAL;
8481
8534
  }
8482
8535
  function getDefaultContextFont(fontSize, bold = false, italic = false) {
8483
8536
  return `${italic ? "italic" : ""} ${bold ? "bold" : ""} ${fontSize}px ${DEFAULT_FONT}`;
@@ -8543,7 +8596,7 @@ set(value) {
8543
8596
  return Math.round(fontSize * 96 / 72);
8544
8597
  }
8545
8598
  function computeTextFont(style, fontUnit = "pt") {
8546
- return `${style.italic ? "italic " : ""}${style.bold ? "bold" : "400"} ${(fontUnit === "pt" ? computeTextFontSizeInPixels(style) : style.fontSize) ?? DEFAULT_FONT_SIZE}px ${DEFAULT_FONT}`;
8599
+ return `${style.italic ? "italic " : ""}${style.bold ? "bold" : DEFAULT_FONT_WEIGHT} ${(fontUnit === "pt" ? computeTextFontSizeInPixels(style) : style.fontSize) ?? DEFAULT_FONT_SIZE}px ${DEFAULT_FONT}`;
8547
8600
  }
8548
8601
  function computeTextFontSizeInPixels(style) {
8549
8602
  return fontSizeInPixels(style?.fontSize || DEFAULT_FONT_SIZE);
@@ -8567,7 +8620,7 @@ set(value) {
8567
8620
  if (!style) style = {};
8568
8621
  if (isMarkdownLink(text)) text = parseMarkdownLink(text).label;
8569
8622
  const brokenText = [];
8570
- const lines = text.includes("\n") ? text.split("\n") : [text];
8623
+ const lines = text.includes(NEWLINE) ? text.split(NEWLINE) : [text];
8571
8624
  for (const line of lines) {
8572
8625
  const words = line.includes(" ") ? line.split(" ") : [line];
8573
8626
  if (!width) {
@@ -8733,7 +8786,7 @@ set(value) {
8733
8786
  let { x, y } = rect;
8734
8787
  const cos = Math.cos(-style.rotation);
8735
8788
  const sin = Math.sin(-style.rotation);
8736
- const width = rect.textWidth - 2 * 4;
8789
+ const width = rect.textWidth - 2 * MIN_CELL_TEXT_MARGIN;
8737
8790
  const height = rect.textHeight;
8738
8791
  const center = style.align === "center";
8739
8792
  const rotateTowardCellCenter = style.align === "left" === sin < 0;
@@ -8783,7 +8836,7 @@ set(value) {
8783
8836
  ctx.miterLimit = 1;
8784
8837
  const gradientHeight = (chart.chartArea.bottom - chart.chartArea.top) / 2;
8785
8838
  const gradientWidth = 10;
8786
- const gradientX = options.position === "left" ? 20 : ctx.canvas.width - 70;
8839
+ const gradientX = options.position === "left" ? CHART_PADDING : ctx.canvas.width - CHART_COLORSCALE_WIDTH;
8787
8840
  const gradientY = chart.chartArea.top;
8788
8841
  const gradient = ctx.createLinearGradient(0, gradientY + gradientHeight, 0, gradientY);
8789
8842
  const step = 1 / (options.colorScale.length - 1);
@@ -8793,7 +8846,7 @@ set(value) {
8793
8846
  ctx.fillStyle = gradient;
8794
8847
  ctx.fillRect(gradientX, gradientY, gradientWidth, gradientHeight);
8795
8848
  ctx.fillStyle = options.fontColor ?? "black";
8796
- ctx.font = getDefaultContextFont(12);
8849
+ ctx.font = getDefaultContextFont(CHART_AXIS_TITLE_FONT_SIZE);
8797
8850
  ctx.textAlign = "left";
8798
8851
  let minValue = Math.round(options.minValue * 100) / 100;
8799
8852
  let maxValue = Math.round(options.maxValue * 100) / 100;
@@ -9063,6 +9116,12 @@ set(value) {
9063
9116
  const EXCEL_DEFAULT_COL_WIDTH = 8.43;
9064
9117
  /** unit : points */
9065
9118
  const EXCEL_DEFAULT_ROW_HEIGHT = 12.75;
9119
+ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS = 30;
9120
+ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
9121
+ /** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
9122
+ const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
9123
+ const FIRST_NUMFMT_ID = 164;
9124
+ const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
9066
9125
  const FORCE_DEFAULT_ARGS_FUNCTIONS = {
9067
9126
  FLOOR: [{
9068
9127
  type: "NUMBER",
@@ -10065,8 +10124,8 @@ set(value) {
10065
10124
  if (dataSetStyle.trend?.type) trend = {
10066
10125
  type: dataSetStyle.trend.type === "polynomial" && dataSetStyle.trend.order === 1 ? "linear" : SPREADSHEET_TO_EXCEL_TRENDLINE_TYPE_MAPPING[dataSetStyle.trend.type],
10067
10126
  color: dataSetStyle.trend.color,
10068
- order: dataSetStyle.trend.order ? Math.min(dataSetStyle.trend.order, 6) : void 0,
10069
- window: dataSetStyle.trend.window || 2
10127
+ order: dataSetStyle.trend.order ? Math.min(dataSetStyle.trend.order, MAX_XLSX_POLYNOMIAL_DEGREE) : void 0,
10128
+ window: dataSetStyle.trend.window || DEFAULT_WINDOW_SIZE
10070
10129
  };
10071
10130
  return {
10072
10131
  label,
@@ -10172,13 +10231,13 @@ set(value) {
10172
10231
  for (let i = 0; i <= maxLength; i++) pieColors.push(colors.next());
10173
10232
  return pieColors;
10174
10233
  }
10175
- function truncateLabel(label, maxLen = 20) {
10234
+ function truncateLabel(label, maxLen = MAX_CHAR_LABEL) {
10176
10235
  if (!label) return "";
10177
10236
  if (label.length > maxLen) return label.substring(0, maxLen) + "…";
10178
10237
  return label;
10179
10238
  }
10180
10239
  function isTrendLineAxis(axisID) {
10181
- return axisID === "x1" || axisID === "xMovingAverage";
10240
+ return axisID === TREND_LINE_XAXIS_ID || axisID === MOVING_AVERAGE_TREND_LINE_XAXIS_ID;
10182
10241
  }
10183
10242
  function getChartBackgroundColor({ background }, getters) {
10184
10243
  const defaultColor = getters.getSpreadsheetTheme().backgroundColor;
@@ -10536,7 +10595,7 @@ set(value) {
10536
10595
  scales = removeFalsyAttributes(scales);
10537
10596
  if (trendDatasets && trendDatasets.length && trendDatasets.some(isDefined)) {
10538
10597
  const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
10539
- scales["x1"] = {
10598
+ scales[TREND_LINE_XAXIS_ID] = {
10540
10599
  ...scales.x,
10541
10600
  labels: Array(maxLength).fill(""),
10542
10601
  offset: false,
@@ -10647,7 +10706,7 @@ set(value) {
10647
10706
  });
10648
10707
  }
10649
10708
  if (trendDatasets && trendDatasets.length && trendDatasets.some(isDefined)) {
10650
- scales["x1"] = {
10709
+ scales[TREND_LINE_XAXIS_ID] = {
10651
10710
  ...scales.x,
10652
10711
  display: false
10653
10712
  };
@@ -10657,9 +10716,9 @@ set(value) {
10657
10716
  };
10658
10717
  if (axisType === "category" || axisType === "time") {
10659
10718
  const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
10660
- scales["x1"]["type"] = "category";
10661
- scales["x1"]["labels"] = range(0, maxLength).map((x) => x.toString());
10662
- scales["x1"]["offset"] = false;
10719
+ scales[TREND_LINE_XAXIS_ID]["type"] = "category";
10720
+ scales[TREND_LINE_XAXIS_ID]["labels"] = range(0, maxLength).map((x) => x.toString());
10721
+ scales[TREND_LINE_XAXIS_ID]["offset"] = false;
10663
10722
  scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID]["type"] = "category";
10664
10723
  scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID]["offset"] = false;
10665
10724
  }
@@ -10832,7 +10891,7 @@ set(value) {
10832
10891
  font: {
10833
10892
  style: italic ? "italic" : "normal",
10834
10893
  weight: bold ? "bold" : "normal",
10835
- size: design.title.fontSize ?? 12
10894
+ size: design.title.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE
10836
10895
  },
10837
10896
  align: align === "left" ? "start" : align === "right" ? "end" : "center"
10838
10897
  };
@@ -10920,16 +10979,16 @@ set(value) {
10920
10979
  switch (definition.legendPosition) {
10921
10980
  case "top":
10922
10981
  case "right": return {
10923
- top: !!definition.title.text ? 15 + 30 : 15,
10924
- left: 20,
10925
- right: 20
10982
+ top: !!definition.title.text ? CHART_PADDING_TOP + 30 : CHART_PADDING_TOP,
10983
+ left: CHART_PADDING,
10984
+ right: CHART_PADDING
10926
10985
  };
10927
10986
  case "bottom":
10928
10987
  case "left":
10929
10988
  case "none": return {
10930
- left: 20,
10931
- right: 20,
10932
- bottom: 10
10989
+ left: CHART_PADDING,
10990
+ right: CHART_PADDING,
10991
+ bottom: CHART_PADDING_BOTTOM
10933
10992
  };
10934
10993
  }
10935
10994
  }
@@ -10998,7 +11057,7 @@ set(value) {
10998
11057
  order: -1,
10999
11058
  tension: 0,
11000
11059
  fill: false,
11001
- pointRadius: 3,
11060
+ pointRadius: LINE_DATA_POINT_RADIUS,
11002
11061
  borderWidth: 2,
11003
11062
  backgroundColor: color,
11004
11063
  borderColor: color,
@@ -11017,7 +11076,7 @@ set(value) {
11017
11076
  for (const dataSetValues of dataSetsValues) dataSets.push({
11018
11077
  label: dataSetValues.label,
11019
11078
  data: dataSetValues.data.map((v) => 1),
11020
- backgroundColor: dataSetValues.data.map((v) => isNumberResult(v) ? colorMap(v.value) : definition.missingValueColor || "#00000000"),
11079
+ backgroundColor: dataSetValues.data.map((v) => isNumberResult(v) ? colorMap(v.value) : definition.missingValueColor || COLOR_TRANSPARENT),
11021
11080
  borderColor: definition.background || background,
11022
11081
  borderSkipped: false,
11023
11082
  borderWidth: 1,
@@ -11032,9 +11091,9 @@ set(value) {
11032
11091
  }
11033
11092
  function getWaterfallDatasetAndLabels(definition, args) {
11034
11093
  const { dataSetsValues, labels } = args;
11035
- const negativeColor = definition.negativeValuesColor || "#EA6175";
11036
- const positiveColor = definition.positiveValuesColor || "#4EA7F2";
11037
- const subTotalColor = definition.subTotalValuesColor || "#AAAAAA";
11094
+ const negativeColor = definition.negativeValuesColor || CHART_WATERFALL_NEGATIVE_COLOR;
11095
+ const positiveColor = definition.positiveValuesColor || CHART_WATERFALL_POSITIVE_COLOR;
11096
+ const subTotalColor = definition.subTotalValuesColor || CHART_WATERFALL_SUBTOTAL_COLOR;
11038
11097
  const backgroundColor = [];
11039
11098
  const datasetValues = [];
11040
11099
  const dataset = {
@@ -11098,7 +11157,7 @@ set(value) {
11098
11157
  backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
11099
11158
  pointBackgroundColor: color,
11100
11159
  fill: areaChart ? getFillingMode(index, stackedChart) : false,
11101
- pointRadius: definition.hideDataMarkers ? 0 : 3,
11160
+ pointRadius: definition.hideDataMarkers ? 0 : LINE_DATA_POINT_RADIUS,
11102
11161
  yAxisID: dataSetStyle?.yAxisId || "y"
11103
11162
  };
11104
11163
  dataSets.push(dataset);
@@ -11153,12 +11212,12 @@ set(value) {
11153
11212
  const finiteSizes = sizeValues.filter((value) => Number.isFinite(value) && value > 0);
11154
11213
  const min = finiteSizes.length ? Math.min(...finiteSizes) : 0;
11155
11214
  const range = (finiteSizes.length ? Math.max(...finiteSizes) : 0) - min;
11156
- if (!finiteSizes.length) return sizeValues.map(() => 2);
11215
+ if (!finiteSizes.length) return sizeValues.map(() => DEFAULT_BUBBLE_RADIUS);
11157
11216
  return sizeValues.map((value) => {
11158
11217
  if (value === void 0 || !Number.isFinite(value) || value < 0) return 0;
11159
- if (value === 0) return 2;
11160
- if (range === 0) return 10;
11161
- return 10 + clip((value - min) / range, 0, 1) * (30 - 10);
11218
+ if (value === 0) return DEFAULT_BUBBLE_RADIUS;
11219
+ if (range === 0) return MIN_BUBBLE_RADIUS;
11220
+ return MIN_BUBBLE_RADIUS + clip((value - min) / range, 0, 1) * (MAX_BUBBLE_RADIUS - MIN_BUBBLE_RADIUS);
11162
11221
  });
11163
11222
  }
11164
11223
  function getPieChartDatasets(definition, args) {
@@ -11201,7 +11260,7 @@ set(value) {
11201
11260
  xAxisID: "x",
11202
11261
  type,
11203
11262
  order: type === "bar" ? dataSetsValues.length + index : index,
11204
- pointRadius: definition.hideDataMarkers ? 0 : 3
11263
+ pointRadius: definition.hideDataMarkers ? 0 : LINE_DATA_POINT_RADIUS
11205
11264
  };
11206
11265
  if (dataset.type === "bar") {
11207
11266
  dataset.barPercentage = .9;
@@ -11233,7 +11292,7 @@ set(value) {
11233
11292
  borderColor,
11234
11293
  backgroundColor: borderColor,
11235
11294
  pointBackgroundColor: borderColor,
11236
- pointRadius: definition.hideDataMarkers ? 0 : 3
11295
+ pointRadius: definition.hideDataMarkers ? 0 : LINE_DATA_POINT_RADIUS
11237
11296
  };
11238
11297
  if (fill) {
11239
11298
  dataset.backgroundColor = setColorAlpha(borderColor, LINE_FILL_TRANSPARENCY);
@@ -11319,12 +11378,12 @@ set(value) {
11319
11378
  data: data[i],
11320
11379
  borderColor: (ctx) => {
11321
11380
  const data = ctx.type === "data" ? ctx.raw : void 0;
11322
- if (!data || data.label === "nullValue") return COLOR_TRANSPARENT;
11381
+ if (!data || data.label === GHOST_SUNBURST_VALUE) return COLOR_TRANSPARENT;
11323
11382
  return definition.background || background;
11324
11383
  },
11325
11384
  backgroundColor: (ctx) => {
11326
11385
  const data = ctx.type === "data" ? ctx.raw : void 0;
11327
- if (!data || data.label === "nullValue") return COLOR_TRANSPARENT;
11386
+ if (!data || data.label === GHOST_SUNBURST_VALUE) return COLOR_TRANSPARENT;
11328
11387
  const rootGroup = data.groups[0];
11329
11388
  return groupColors.find((groupColor) => groupColor.label === rootGroup)?.color;
11330
11389
  },
@@ -11465,7 +11524,7 @@ set(value) {
11465
11524
  const borderColor = config.color || lightenColor(rgbaToHex(defaultBorderColor), .5);
11466
11525
  return {
11467
11526
  type: "line",
11468
- xAxisID: config.type === "trailingMovingAverage" ? MOVING_AVERAGE_TREND_LINE_XAXIS_ID : "x1",
11527
+ xAxisID: config.type === "trailingMovingAverage" ? MOVING_AVERAGE_TREND_LINE_XAXIS_ID : TREND_LINE_XAXIS_ID,
11469
11528
  yAxisID: dataset.yAxisID,
11470
11529
  label: dataset.label ? _t("Trend line for %s", dataset.label) : "",
11471
11530
  data,
@@ -11578,7 +11637,7 @@ set(value) {
11578
11637
  for (const metaSet of chart.getSortedVisibleDatasetMetas()) for (const arcElement of metaSet.data) {
11579
11638
  const context = arcElement["$context"];
11580
11639
  const { datasetIndex, index, dataset, raw } = context;
11581
- if (raw.label === "nullValue") continue;
11640
+ if (raw.label === GHOST_SUNBURST_VALUE) continue;
11582
11641
  const originalBackgroundColor = typeof dataset.backgroundColor === "function" ? dataset.backgroundColor(context) : dataset.backgroundColor;
11583
11642
  if (activeDataPoints.length && !activeDataPoints.some((el) => el.datasetIndex === datasetIndex && el.index === index)) arcElement.options.backgroundColor = lightenColor(originalBackgroundColor, .5);
11584
11643
  else arcElement.options.backgroundColor = originalBackgroundColor;
@@ -11606,7 +11665,7 @@ set(value) {
11606
11665
  const lineHeight = fontSize + Y_PADDING;
11607
11666
  for (const dataset of chart._metasets) for (let i = 0; i < dataset._dataset.data.length; i++) {
11608
11667
  const rawData = dataset._dataset.data[i];
11609
- if (rawData.label === "nullValue") continue;
11668
+ if (rawData.label === GHOST_SUNBURST_VALUE) continue;
11610
11669
  const valuesToDisplay = [options.showLabels ? rawData.label : void 0, options.showValues ? options.callback(rawData.value, "y") : void 0].filter(isDefined);
11611
11670
  const arc = dataset.data[i];
11612
11671
  let { startAngle, endAngle, innerRadius, outerRadius, circumference } = arc;
@@ -12135,7 +12194,7 @@ set(value) {
12135
12194
  canvas.width = dpr * structure.canvas.width * zoom;
12136
12195
  canvas.height = dpr * structure.canvas.height * zoom;
12137
12196
  ctx.scale(dpr * zoom, dpr * zoom);
12138
- const availableWidth = structure.canvas.width - 20;
12197
+ const availableWidth = structure.canvas.width - CHART_PADDING;
12139
12198
  ctx.fillStyle = structure.canvas.backgroundColor;
12140
12199
  ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
12141
12200
  if (structure.title) {
@@ -12243,16 +12302,16 @@ set(value) {
12243
12302
  x = (this.width - titleWidth) / 2;
12244
12303
  break;
12245
12304
  case "right":
12246
- x = this.width - titleWidth - 20;
12305
+ x = this.width - titleWidth - CHART_PADDING;
12247
12306
  break;
12248
- default: x = 20;
12307
+ default: x = CHART_PADDING;
12249
12308
  }
12250
12309
  structure.title = {
12251
12310
  text: this.title,
12252
12311
  style: style.title,
12253
12312
  position: {
12254
12313
  x,
12255
- y: 10 + titleHeight / 2
12314
+ y: CHART_PADDING_BOTTOM + titleHeight / 2
12256
12315
  }
12257
12316
  };
12258
12317
  }
@@ -12263,10 +12322,10 @@ set(value) {
12263
12322
  let baselineX;
12264
12323
  switch (this.runtime.baselineStyle?.align) {
12265
12324
  case "right":
12266
- baselineX = this.width - 20 - baselineDescrWidth - baselineWidth;
12325
+ baselineX = this.width - CHART_PADDING - baselineDescrWidth - baselineWidth;
12267
12326
  break;
12268
12327
  case "left":
12269
- baselineX = 20 + baselineArrowSize;
12328
+ baselineX = CHART_PADDING + baselineArrowSize;
12270
12329
  break;
12271
12330
  default: baselineX = (this.width - baselineWidth - baselineDescrWidth + baselineArrowSize) / 2;
12272
12331
  }
@@ -12276,7 +12335,7 @@ set(value) {
12276
12335
  style: style.baselineValue,
12277
12336
  position: {
12278
12337
  x: baselineX,
12279
- y: this.keyValue ? this.height * (1 - BOTTOM_PADDING_RATIO * (this.runtime.progressBar ? 1 : 2)) : this.height - (this.height - titleHeight - baselineHeight) / 2 - 10
12338
+ y: this.keyValue ? this.height * (1 - BOTTOM_PADDING_RATIO * (this.runtime.progressBar ? 1 : 2)) : this.height - (this.height - titleHeight - baselineHeight) / 2 - CHART_PADDING_BOTTOM
12280
12339
  }
12281
12340
  };
12282
12341
  if (style.baselineArrow && !this.runtime.progressBar) structure.baselineArrow = {
@@ -12304,12 +12363,12 @@ set(value) {
12304
12363
  progressBarHeight = this.height * .05;
12305
12364
  structure.progressBar = {
12306
12365
  position: {
12307
- x: 2 * 20,
12366
+ x: 2 * CHART_PADDING,
12308
12367
  y: this.height * (1 - 2 * BOTTOM_PADDING_RATIO) - baselineHeight - progressBarHeight
12309
12368
  },
12310
12369
  dimension: {
12311
12370
  height: progressBarHeight,
12312
- width: this.width - 4 * 20
12371
+ width: this.width - 4 * CHART_PADDING
12313
12372
  },
12314
12373
  value: this.runtime.progressBar.value,
12315
12374
  style: {
@@ -12323,10 +12382,10 @@ set(value) {
12323
12382
  let keyX;
12324
12383
  switch (this.runtime.keyValueStyle?.align) {
12325
12384
  case "right":
12326
- keyX = this.width - 20 - keyDescrWidth - keyWidth;
12385
+ keyX = this.width - CHART_PADDING - keyDescrWidth - keyWidth;
12327
12386
  break;
12328
12387
  case "left":
12329
- keyX = 20;
12388
+ keyX = CHART_PADDING;
12330
12389
  break;
12331
12390
  default: keyX = (this.width - keyWidth - keyDescrWidth) / 2;
12332
12391
  }
@@ -12334,8 +12393,8 @@ set(value) {
12334
12393
  text: this.keyValue,
12335
12394
  style: style.keyValue,
12336
12395
  position: {
12337
- x: Math.max(20, keyX),
12338
- y: this.height * (.5 - BOTTOM_PADDING_RATIO * 2) + 10 / 2 + (titleHeight + keyHeight / 2) / 2
12396
+ x: Math.max(CHART_PADDING, keyX),
12397
+ y: this.height * (.5 - BOTTOM_PADDING_RATIO * 2) + CHART_PADDING_BOTTOM / 2 + (titleHeight + keyHeight / 2) / 2
12339
12398
  }
12340
12399
  };
12341
12400
  if (structure.key && this.keyDescr) {
@@ -12392,14 +12451,14 @@ set(value) {
12392
12451
  };
12393
12452
  }
12394
12453
  getTextStyles() {
12395
- const keyValueFontSize = this.runtime.keyValueStyle?.fontSize ?? 32;
12454
+ const keyValueFontSize = this.runtime.keyValueStyle?.fontSize ?? DEFAULT_SCORECARD_KEY_VALUE_FONT_SIZE;
12396
12455
  const keyValueDescrFontSize = Math.floor(.9 * keyValueFontSize);
12397
- let baselineValueFontSize = this.runtime.baselineStyle?.fontSize ?? 16;
12456
+ let baselineValueFontSize = this.runtime.baselineStyle?.fontSize ?? DEFAULT_SCORECARD_BASELINE_FONT_SIZE;
12398
12457
  const baselineDescrFontSize = Math.floor(.9 * baselineValueFontSize);
12399
12458
  if (this.runtime.progressBar) baselineValueFontSize /= 1.5;
12400
12459
  return {
12401
12460
  title: {
12402
- font: getDefaultContextFont(this.runtime.title.fontSize ?? 14, this.runtime.title.bold, this.runtime.title.italic),
12461
+ font: getDefaultContextFont(this.runtime.title.fontSize ?? SCORECARD_CHART_TITLE_FONT_SIZE, this.runtime.title.bold, this.runtime.title.italic),
12403
12462
  color: this.runtime.title.color ?? this.secondaryFontColor
12404
12463
  },
12405
12464
  keyValue: {
@@ -12654,35 +12713,35 @@ set(value) {
12654
12713
  x: boundingRect.width / 2,
12655
12714
  y: gaugeRect.y + gaugeRect.height - gaugeRect.height / 12
12656
12715
  };
12657
- let gaugeValueFontSize = 80;
12716
+ let gaugeValueFontSize = GAUGE_DEFAULT_VALUE_FONT_SIZE;
12658
12717
  if (gaugeRect.height < 300) gaugeValueFontSize = gaugeValueFontSize * (gaugeRect.height / 300);
12659
12718
  const maxTextWidth = gaugeRect.width / 2;
12660
12719
  const gaugeLabel = runtime.gaugeValue?.label || "-";
12661
12720
  if (computeTextWidth(ctx, gaugeLabel, { fontSize: gaugeValueFontSize }, "px") > maxTextWidth) gaugeValueFontSize = getFontSizeMatchingWidth(maxTextWidth, gaugeValueFontSize, (fontSize) => computeTextWidth(ctx, gaugeLabel, { fontSize }, "px"));
12662
12721
  const minLabelPosition = {
12663
12722
  x: gaugeRect.x + gaugeArcWidth / 2,
12664
- y: gaugeRect.y + gaugeRect.height + 12
12723
+ y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE
12665
12724
  };
12666
12725
  const maxLabelPosition = {
12667
12726
  x: gaugeRect.x + gaugeRect.width - gaugeArcWidth / 2,
12668
- y: gaugeRect.y + gaugeRect.height + 12
12727
+ y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE
12669
12728
  };
12670
12729
  const textColor = chartMutedFontColor(runtime.background);
12671
12730
  const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
12672
12731
  let x = 0, titleWidth = 0, titleHeight = 0;
12673
12732
  if (runtime.title.text) ({width: titleWidth, height: titleHeight} = computeTextDimension(ctx, runtime.title.text, {
12674
- fontSize: 16,
12733
+ fontSize: CHART_TITLE_FONT_SIZE,
12675
12734
  ...runtime.title
12676
12735
  }, "px"));
12677
12736
  switch (runtime.title.align) {
12678
12737
  case "right":
12679
- x = boundingRect.width - titleWidth - 20;
12738
+ x = boundingRect.width - titleWidth - CHART_PADDING;
12680
12739
  break;
12681
12740
  case "center":
12682
12741
  x = (boundingRect.width - titleWidth) / 2;
12683
12742
  break;
12684
12743
  default:
12685
- x = 20;
12744
+ x = CHART_PADDING;
12686
12745
  break;
12687
12746
  }
12688
12747
  return {
@@ -12690,10 +12749,10 @@ set(value) {
12690
12749
  height: boundingRect.height,
12691
12750
  title: {
12692
12751
  label: runtime.title.text ?? "",
12693
- fontSize: runtime.title.fontSize ?? 16,
12752
+ fontSize: runtime.title.fontSize ?? CHART_TITLE_FONT_SIZE,
12694
12753
  textPosition: {
12695
12754
  x,
12696
- y: 15 + titleHeight / 2
12755
+ y: CHART_PADDING_TOP + titleHeight / 2
12697
12756
  },
12698
12757
  color: runtime.title.color ?? textColor,
12699
12758
  bold: runtime.title.bold,
@@ -12716,13 +12775,13 @@ set(value) {
12716
12775
  minLabel: {
12717
12776
  label: runtime.minValue.label,
12718
12777
  textPosition: minLabelPosition,
12719
- fontSize: 12,
12778
+ fontSize: GAUGE_LABELS_FONT_SIZE,
12720
12779
  color: textColor
12721
12780
  },
12722
12781
  maxLabel: {
12723
12782
  label: runtime.maxValue.label,
12724
12783
  textPosition: maxLabelPosition,
12725
- fontSize: 12,
12784
+ fontSize: GAUGE_LABELS_FONT_SIZE,
12726
12785
  color: textColor
12727
12786
  }
12728
12787
  };
@@ -12732,9 +12791,9 @@ set(value) {
12732
12791
  * space for the title and labels.
12733
12792
  */
12734
12793
  function getGaugeRect(boundingRect, title) {
12735
- const titleHeight = title ? 25 : 0;
12736
- const drawHeight = boundingRect.height - 20 - titleHeight - 10;
12737
- const drawWidth = boundingRect.width - 30 * 2;
12794
+ const titleHeight = title ? GAUGE_TITLE_SECTION_HEIGHT : 0;
12795
+ const drawHeight = boundingRect.height - GAUGE_PADDING_BOTTOM - titleHeight - GAUGE_PADDING_TOP;
12796
+ const drawWidth = boundingRect.width - GAUGE_PADDING_SIDE * 2;
12738
12797
  let gaugeWidth;
12739
12798
  let gaugeHeight;
12740
12799
  if (drawWidth > 2 * drawHeight) {
@@ -12745,8 +12804,8 @@ set(value) {
12745
12804
  gaugeHeight = drawWidth / 2;
12746
12805
  }
12747
12806
  return {
12748
- x: 30 + (drawWidth - gaugeWidth) / 2,
12749
- y: titleHeight + 10 + (drawHeight - gaugeHeight) / 2,
12807
+ x: GAUGE_PADDING_SIDE + (drawWidth - gaugeWidth) / 2,
12808
+ y: titleHeight + GAUGE_PADDING_TOP + (drawHeight - gaugeHeight) / 2,
12750
12809
  width: gaugeWidth,
12751
12810
  height: gaugeHeight
12752
12811
  };
@@ -12763,20 +12822,20 @@ set(value) {
12763
12822
  x: gaugeRect.x + gaugeRect.width / 2,
12764
12823
  y: gaugeRect.y + gaugeRect.height
12765
12824
  };
12766
- const textStyle = { fontSize: 12 };
12825
+ const textStyle = { fontSize: GAUGE_LABELS_FONT_SIZE };
12767
12826
  const inflectionValues = [];
12768
12827
  const inflectionValuesTextRects = [];
12769
12828
  for (const inflectionValue of runtime.inflectionValues) {
12770
12829
  const percentage = (inflectionValue.value - minValue.value) / (maxValue.value - minValue.value);
12771
12830
  const labelWidth = computeTextWidth(ctx, inflectionValue.label, textStyle, "px");
12772
12831
  const angle = Math.PI - Math.PI * percentage;
12773
- const textRect = getRectangleTangentToCircle(angle, gaugeRect.height + GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN, gaugeCircleCenter.x, gaugeCircleCenter.y, labelWidth + 2, 12);
12774
- const offset = inflectionValuesTextRects.some((rect) => doRectanglesIntersect(rect, textRect)) ? 12 : 0;
12832
+ const textRect = getRectangleTangentToCircle(angle, gaugeRect.height + GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN, gaugeCircleCenter.x, gaugeCircleCenter.y, labelWidth + 2, GAUGE_LABELS_FONT_SIZE);
12833
+ const offset = inflectionValuesTextRects.some((rect) => doRectanglesIntersect(rect, textRect)) ? GAUGE_LABELS_FONT_SIZE : 0;
12775
12834
  inflectionValuesTextRects.push(textRect);
12776
12835
  inflectionValues.push({
12777
12836
  rotation: angle,
12778
12837
  label: inflectionValue.label,
12779
- fontSize: 12,
12838
+ fontSize: GAUGE_LABELS_FONT_SIZE,
12780
12839
  color: textColor,
12781
12840
  offset
12782
12841
  });
@@ -13388,7 +13447,7 @@ set(value) {
13388
13447
 
13389
13448
  //#endregion
13390
13449
  //#region src/components/figures/chart/chartJs/zoomable_chart/zoomable_chart_store.ts
13391
- const TREND_LINE_AXES_IDS = ["x1", MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
13450
+ const TREND_LINE_AXES_IDS = [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
13392
13451
  const ZOOMABLE_AXIS_IDS = ["x", ...TREND_LINE_AXES_IDS];
13393
13452
  var ZoomableChartStore = class extends SpreadsheetStore {
13394
13453
  mutators = [
@@ -13504,7 +13563,7 @@ set(value) {
13504
13563
  this.removeEventListeners();
13505
13564
  }
13506
13565
  get containerStyle() {
13507
- return cssPropertiesToCss({ height: this.sliceable ? `calc(100% - ${60}px)` : "100%" });
13566
+ return cssPropertiesToCss({ height: this.sliceable ? `calc(100% - ${MASTER_CHART_HEIGHT}px)` : "100%" });
13508
13567
  }
13509
13568
  get masterChartContainerStyle() {
13510
13569
  const runtime = this.env.model.getters.getChartRuntime(this.props.chartId);
@@ -13655,7 +13714,7 @@ set(value) {
13655
13714
  updateTrendingLineAxes() {
13656
13715
  this.store.updateTrendLineConfiguration(this.chartId);
13657
13716
  const limits = this.store.currentAxesLimits[this.chartId];
13658
- for (const axisId of ["x1", MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
13717
+ for (const axisId of [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
13659
13718
  if (!this.chart?.config?.options?.scales?.[axisId] || !limits?.[axisId]) continue;
13660
13719
  this.chart.config.options.scales[axisId].min = limits[axisId].min;
13661
13720
  this.chart.config.options.scales[axisId].max = limits[axisId].max;
@@ -14838,7 +14897,7 @@ set(value) {
14838
14897
  onClickMenu: this.onClickMenu.bind(this),
14839
14898
  onMouseEnter: this.onMenuItemMouseEnter.bind(this),
14840
14899
  onMouseLeave: this.onMouseLeave.bind(this),
14841
- width: this.props.width || 250,
14900
+ width: this.props.width || MENU_WIDTH,
14842
14901
  onScroll: this.onScroll.bind(this),
14843
14902
  onKeyDown: this.onKeydown.bind(this),
14844
14903
  hoveredMenuId,
@@ -14857,11 +14916,11 @@ set(value) {
14857
14916
  anchorRect: {
14858
14917
  x: this.props.anchorRect.x,
14859
14918
  y: this.props.anchorRect.y,
14860
- width: isRoot ? this.props.anchorRect.width : this.props.width || 250,
14861
- height: isRoot ? this.props.anchorRect.height : 26
14919
+ width: isRoot ? this.props.anchorRect.width : this.props.width || MENU_WIDTH,
14920
+ height: isRoot ? this.props.anchorRect.height : DESKTOP_MENU_ITEM_HEIGHT
14862
14921
  },
14863
14922
  positioning: this.props.popoverPositioning,
14864
- verticalOffset: isRoot ? 0 : 6,
14923
+ verticalOffset: isRoot ? 0 : MENU_VERTICAL_PADDING,
14865
14924
  onPopoverHidden: () => this.closeSubMenu(),
14866
14925
  onPopoverMoved: () => this.closeSubMenu(),
14867
14926
  maxHeight: this.props.maxHeight
@@ -14918,8 +14977,8 @@ set(value) {
14918
14977
  this.subMenu.anchorRect = {
14919
14978
  x: getElBoundingRect(this.menuRef()).x,
14920
14979
  y: y - (this.subMenu.scrollOffset || 0),
14921
- width: this.props.width || 250,
14922
- height: 26
14980
+ width: this.props.width || MENU_WIDTH,
14981
+ height: DESKTOP_MENU_ITEM_HEIGHT
14923
14982
  };
14924
14983
  this.subMenu.menuItems = menu.children(this.env);
14925
14984
  this.subMenu.isOpen = true;
@@ -17023,7 +17082,7 @@ set(value) {
17023
17082
  alignment: {
17024
17083
  horizontal: style.align === "default" ? void 0 : style.align,
17025
17084
  vertical: style.verticalAlign ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign] : void 0,
17026
- wrapText: style.wrapping === "wrap" || content?.includes("\n") ? true : void 0,
17085
+ wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : void 0,
17027
17086
  textRotation: style.rotation ? rotationToXLSX(style.rotation) : void 0,
17028
17087
  shrinkToFit: style.wrapping === "clip" ? true : void 0
17029
17088
  }
@@ -17064,7 +17123,7 @@ set(value) {
17064
17123
  function convertFormat(format, numFmtStructure) {
17065
17124
  if (!format) return 0;
17066
17125
  let formatId = XLSX_FORMAT_MAP[format.format];
17067
- if (!formatId) formatId = pushElement(format, numFmtStructure) + 164;
17126
+ if (!formatId) formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
17068
17127
  return formatId;
17069
17128
  }
17070
17129
  /**
@@ -17325,7 +17384,7 @@ set(value) {
17325
17384
  width: 512,
17326
17385
  height: 512,
17327
17386
  paths: [{
17328
- fillColor: color.textColor || "#374151C2",
17387
+ fillColor: color.textColor || TEXT_BODY_MUTED,
17329
17388
  path: CARET_DOWN_PATH
17330
17389
  }]
17331
17390
  };
@@ -17336,7 +17395,7 @@ set(value) {
17336
17395
  width: 512,
17337
17396
  height: 512,
17338
17397
  paths: [{
17339
- fillColor: color.textColor || "#374151C2",
17398
+ fillColor: color.textColor || TEXT_BODY_MUTED,
17340
17399
  path: CARET_UP_PATH
17341
17400
  }]
17342
17401
  };
@@ -17347,7 +17406,7 @@ set(value) {
17347
17406
  width: 512,
17348
17407
  height: 512,
17349
17408
  paths: [{
17350
- fillColor: color.textColor || "#374151C2",
17409
+ fillColor: color.textColor || TEXT_BODY_MUTED,
17351
17410
  path: HOVERED_CARET_DOWN_PATH
17352
17411
  }, {
17353
17412
  fillColor: color.fillColor || "#fff",
@@ -18241,14 +18300,14 @@ set(value) {
18241
18300
  type: trend.type === "linear" ? "polynomial" : EXCEL_TO_SPREADSHEET_TRENDLINE_TYPE_MAPPING[trend.type],
18242
18301
  order: trend.type === "linear" ? 1 : trend.order,
18243
18302
  color: trend.color,
18244
- window: trend.window || 2,
18303
+ window: trend.window || DEFAULT_WINDOW_SIZE,
18245
18304
  display: true
18246
18305
  };
18247
18306
  }
18248
18307
  function convertAnchor(XLSXanchor) {
18249
18308
  const offset = {
18250
- x: convertEMUToDotValue(XLSXanchor.colOffset) - 1,
18251
- y: convertEMUToDotValue(XLSXanchor.rowOffset) - 1
18309
+ x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
18310
+ y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH
18252
18311
  };
18253
18312
  return {
18254
18313
  col: XLSXanchor.col,
@@ -18521,8 +18580,8 @@ set(value) {
18521
18580
  dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
18522
18581
  dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
18523
18582
  }
18524
- dims[0] = Math.max(dims[0] + 5, 30);
18525
- dims[1] = Math.max(dims[1] + 5, 100);
18583
+ dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
18584
+ dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
18526
18585
  return dims;
18527
18586
  }
18528
18587
  /**
@@ -19706,7 +19765,7 @@ set(value) {
19706
19765
  rgb = this.getThemeColor(themeIndex, theme.clrScheme);
19707
19766
  } else {
19708
19767
  rgb = this.extractAttr(colorElement, "rgb")?.asString();
19709
- rgb = rgb === "FF000000" ? void 0 : rgb;
19768
+ rgb = rgb === DEFAULT_SYSTEM_COLOR ? void 0 : rgb;
19710
19769
  }
19711
19770
  return {
19712
19771
  rgb: rgb || defaultColor,
@@ -20968,7 +21027,7 @@ set(value) {
20968
21027
  * Get the corresponding relationship file for a given xml file in a XLSX directory.
20969
21028
  */
20970
21029
  function getRelationFile(file, xmls) {
20971
- if (file === "[Content_Types].xml") return "_rels/.rels";
21030
+ if (file === CONTENT_TYPES_FILE) return "_rels/.rels";
20972
21031
  let relsFile = "";
20973
21032
  const pathParts = file.split("/");
20974
21033
  for (let i = 0; i < pathParts.length - 1; i++) relsFile += pathParts[i] + "/";
@@ -21413,7 +21472,7 @@ set(value) {
21413
21472
  });
21414
21473
  return newY.length === newX.length ? newY : transposeMatrix(newY);
21415
21474
  }
21416
- function getMovingAverageValues(dataset, labels, windowSize = 2) {
21475
+ function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZE) {
21417
21476
  const values = [];
21418
21477
  for (let i = 0; i < windowSize - 1; i++) values.push({
21419
21478
  x: labels[i],
@@ -22095,7 +22154,7 @@ set(value) {
22095
22154
  if (token.type === "REFERENCE" && cellReference.test(token.value)) {
22096
22155
  const value = token.value.trim();
22097
22156
  if (!dependencies.includes(value)) dependencies.push(value);
22098
- return `${"|"}${dependencies.indexOf(value)}${"|"}`;
22157
+ return `${FORMULA_REF_IDENTIFIER}${dependencies.indexOf(value)}${FORMULA_REF_IDENTIFIER}`;
22099
22158
  } else return token.value;
22100
22159
  })),
22101
22160
  dependencies
@@ -22291,7 +22350,7 @@ set(value) {
22291
22350
  if (cell.formula) {
22292
22351
  let { text, dependencies } = cell.formula;
22293
22352
  for (const [index, d] of Object.entries(dependencies)) {
22294
- const stringPosition = `\\${"|"}${index}\\${"|"}`;
22353
+ const stringPosition = `\\${FORMULA_REF_IDENTIFIER}${index}\\${FORMULA_REF_IDENTIFIER}`;
22295
22354
  text = text.replace(new RegExp(stringPosition, "g"), d);
22296
22355
  }
22297
22356
  cell.content = text;
@@ -23848,8 +23907,8 @@ set(value) {
23848
23907
  zones = getters.getSelectedZones();
23849
23908
  }
23850
23909
  const size = {
23851
- width: 536,
23852
- height: 335
23910
+ width: DEFAULT_FIGURE_WIDTH,
23911
+ height: DEFAULT_FIGURE_HEIGHT
23853
23912
  };
23854
23913
  const { col, row, offset } = centerFigurePosition(getters, size);
23855
23914
  if (env.model.dispatch("CREATE_CHART", {
@@ -23871,8 +23930,8 @@ set(value) {
23871
23930
  const figureId = UuidGenerator.smallUuid();
23872
23931
  const sheetId = getters.getActiveSheetId();
23873
23932
  const size = {
23874
- width: 536,
23875
- height: 335
23933
+ width: DEFAULT_FIGURE_WIDTH,
23934
+ height: DEFAULT_FIGURE_HEIGHT
23876
23935
  };
23877
23936
  const { col, row, offset } = centerFigurePosition(getters, size);
23878
23937
  if (env.model.dispatch("CREATE_CAROUSEL", {
@@ -23922,7 +23981,7 @@ set(value) {
23922
23981
  execute: (env) => {
23923
23982
  const zone = env.model.getters.getSelectedZone();
23924
23983
  const table = env.model.getters.getPivot(pivotId).getExpandedTableStructure();
23925
- if (table.numberOfCells > 5e5) {
23984
+ if (table.numberOfCells > PIVOT_MAX_NUMBER_OF_CELLS) {
23926
23985
  env.notifyUser({
23927
23986
  type: "warning",
23928
23987
  text: getPivotTooBigErrorMessage(table.numberOfCells, env.model.getters.getLocale()),
@@ -24890,7 +24949,7 @@ set(value) {
24890
24949
  }
24891
24950
  get sliderStyle() {
24892
24951
  const hue = this.state.currentHslaColor?.h || 0;
24893
- return cssPropertiesToCss({ "margin-left": `${clip(Math.round(hue / 360 * INNER_GRADIENT_WIDTH), 1, INNER_GRADIENT_WIDTH) - 18 / 2}px` });
24952
+ return cssPropertiesToCss({ "margin-left": `${clip(Math.round(hue / 360 * INNER_GRADIENT_WIDTH), 1, INNER_GRADIENT_WIDTH) - ICON_EDGE_LENGTH / 2}px` });
24894
24953
  }
24895
24954
  get pointerStyle() {
24896
24955
  const { s, l } = this.state.currentHslaColor || {
@@ -25057,6 +25116,11 @@ set(value) {
25057
25116
  rootEditorRef = (0, _odoo_owl.signal)(null);
25058
25117
  valueListRef = (0, _odoo_owl.signal)(null);
25059
25118
  DOMFocusableElementStore;
25119
+ /**
25120
+ * Skips the change event triggered when moving focus out of the input.
25121
+ * The value has already been committed by `onInputKeydown`.
25122
+ */
25123
+ skipNextInputChange = false;
25060
25124
  setup() {
25061
25125
  this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
25062
25126
  useExternalListener(window, "click", this.onExternalClick, { capture: true });
@@ -25091,11 +25155,14 @@ set(value) {
25091
25155
  this.dropdown.isOpen = false;
25092
25156
  }
25093
25157
  setValue(valueStr) {
25094
- const value = clip(Math.floor(parseFloat(valueStr)), this.props.min, this.props.max);
25158
+ const value = clip(Math.round(parseFloat(valueStr)), this.props.min, this.props.max);
25159
+ if (isNaN(value)) return;
25095
25160
  this.props.onValueChange(value);
25096
25161
  this.closeList();
25162
+ return value;
25097
25163
  }
25098
25164
  setValueFromInput(ev) {
25165
+ if (this.skipNextInputChange) return;
25099
25166
  this.setValue(ev.target.value);
25100
25167
  }
25101
25168
  setValueFromList(valueStr) {
@@ -25109,19 +25176,26 @@ set(value) {
25109
25176
  ev.target.select();
25110
25177
  }
25111
25178
  onInputKeydown(ev) {
25112
- if (ev.key === "Enter" || ev.key === "Escape") {
25113
- this.closeList();
25114
- const target = ev.target;
25115
- if (ev.key === "Escape") target.value = `${this.props.currentValue}`;
25116
- this.props.onToggle?.();
25117
- }
25118
- if (ev.key === "Tab") {
25119
- ev.preventDefault();
25120
- ev.stopPropagation();
25121
- this.closeList();
25122
- this.DOMFocusableElementStore.focus();
25123
- return;
25179
+ const target = ev.target;
25180
+ switch (ev.key) {
25181
+ case "Enter":
25182
+ case "Tab": {
25183
+ ev.preventDefault();
25184
+ ev.stopPropagation();
25185
+ const value = this.setValue(target.value);
25186
+ if (value === void 0) return;
25187
+ target.value = `${value}`;
25188
+ break;
25189
+ }
25190
+ case "Escape":
25191
+ target.value = `${this.props.currentValue}`;
25192
+ this.closeList();
25193
+ break;
25194
+ default: return;
25124
25195
  }
25196
+ this.skipNextInputChange = true;
25197
+ this.DOMFocusableElementStore.focus();
25198
+ this.skipNextInputChange = false;
25125
25199
  }
25126
25200
  };
25127
25201
 
@@ -25686,7 +25760,7 @@ set(value) {
25686
25760
  function drawHighlight(renderingContext, highlight, rect) {
25687
25761
  const { x, y, width, height } = rect;
25688
25762
  if (width < 0 || height < 0) return;
25689
- const color = highlight.color || "#017E84";
25763
+ const color = highlight.color || HIGHLIGHT_COLOR$1;
25690
25764
  const { ctx } = renderingContext;
25691
25765
  ctx.save();
25692
25766
  if (!highlight.noBorder) {
@@ -26624,7 +26698,7 @@ set(value) {
26624
26698
  axesList: types.ArrayOf()
26625
26699
  });
26626
26700
  state = (0, _odoo_owl.proxy)({ currentAxis: "x" });
26627
- defaultFontSize = 12;
26701
+ defaultFontSize = CHART_AXIS_TITLE_FONT_SIZE;
26628
26702
  get axisTitleStyle() {
26629
26703
  return this.props.definition.axesDesign?.[this.state.currentAxis]?.title ?? {};
26630
26704
  }
@@ -26855,7 +26929,7 @@ set(value) {
26855
26929
  definition: types.ChartDefinition(),
26856
26930
  canUpdateChart: types.function(),
26857
26931
  updateChart: types.function(),
26858
- defaultChartTitleFontSize: types.number().optional(16)
26932
+ defaultChartTitleFontSize: types.number().optional(CHART_TITLE_FONT_SIZE)
26859
26933
  });
26860
26934
  state;
26861
26935
  setup() {
@@ -27123,11 +27197,11 @@ set(value) {
27123
27197
  return Math.min(10, runtime.chartJsConfig.data.datasets[index].data.length - 1);
27124
27198
  }
27125
27199
  get defaultWindowSize() {
27126
- return 2;
27200
+ return DEFAULT_WINDOW_SIZE;
27127
27201
  }
27128
27202
  onChangeMovingAverageWindow(dataSetId, value) {
27129
- let window = parseInt(value) || 2;
27130
- if (window <= 1) window = 2;
27203
+ let window = parseInt(value) || DEFAULT_WINDOW_SIZE;
27204
+ if (window <= 1) window = DEFAULT_WINDOW_SIZE;
27131
27205
  this.updateTrendLineValue(dataSetId, { window });
27132
27206
  }
27133
27207
  getDataSeriesColor(dataSetId) {
@@ -28266,19 +28340,19 @@ set(value) {
28266
28340
  //#region src/helpers/figures/charts/runtime/chartjs_layout.ts
28267
28341
  function getChartLayout(definition, args) {
28268
28342
  return { padding: {
28269
- left: 20,
28270
- right: 20,
28271
- top: Math.max(15, args.topPadding || 0),
28272
- bottom: 10
28343
+ left: CHART_PADDING,
28344
+ right: CHART_PADDING,
28345
+ top: Math.max(CHART_PADDING_TOP, args.topPadding || 0),
28346
+ bottom: CHART_PADDING_BOTTOM
28273
28347
  } };
28274
28348
  }
28275
28349
  function getCalendarChartLayout(definition, args) {
28276
28350
  const legendPosition = definition.legendPosition;
28277
28351
  return { padding: {
28278
- left: 20 + (legendPosition === "left" ? 70 : 0),
28279
- right: 20 + (legendPosition === "right" ? 70 : 0),
28280
- top: Math.max(15, args.topPadding || 0),
28281
- bottom: 10
28352
+ left: CHART_PADDING + (legendPosition === "left" ? CHART_COLORSCALE_WIDTH : 0),
28353
+ right: CHART_PADDING + (legendPosition === "right" ? CHART_COLORSCALE_WIDTH : 0),
28354
+ top: Math.max(CHART_PADDING_TOP, args.topPadding || 0),
28355
+ bottom: CHART_PADDING_BOTTOM
28282
28356
  } };
28283
28357
  }
28284
28358
 
@@ -28480,9 +28554,9 @@ set(value) {
28480
28554
  }
28481
28555
  function getWaterfallChartLegend(definition, args) {
28482
28556
  const fontColor = chartFontColor(definition.background);
28483
- const negativeColor = definition.negativeValuesColor || "#EA6175";
28484
- const positiveColor = definition.positiveValuesColor || "#4EA7F2";
28485
- const subTotalColor = definition.subTotalValuesColor || "#AAAAAA";
28557
+ const negativeColor = definition.negativeValuesColor || CHART_WATERFALL_NEGATIVE_COLOR;
28558
+ const positiveColor = definition.positiveValuesColor || CHART_WATERFALL_POSITIVE_COLOR;
28559
+ const subTotalColor = definition.subTotalValuesColor || CHART_WATERFALL_SUBTOTAL_COLOR;
28486
28560
  return {
28487
28561
  ...getLegendDisplayOptions(definition),
28488
28562
  labels: {
@@ -28808,11 +28882,11 @@ set(value) {
28808
28882
  color: title?.color ?? fontColor,
28809
28883
  align: title.align === "center" ? "center" : title.align === "right" ? "end" : "start",
28810
28884
  font: {
28811
- size: title.fontSize ?? 16,
28885
+ size: title.fontSize ?? CHART_TITLE_FONT_SIZE,
28812
28886
  weight: title.bold ? "bold" : "normal",
28813
28887
  style: title.italic ? "italic" : "normal"
28814
28888
  },
28815
- padding: { bottom: legendPosition === "top" ? 0 : 20 }
28889
+ padding: { bottom: legendPosition === "top" ? 0 : CHART_PADDING }
28816
28890
  };
28817
28891
  }
28818
28892
 
@@ -29227,7 +29301,7 @@ set(value) {
29227
29301
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
29228
29302
  return {
29229
29303
  ...definition,
29230
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
29304
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
29231
29305
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
29232
29306
  dataSets,
29233
29307
  labelRange,
@@ -29590,7 +29664,7 @@ set(value) {
29590
29664
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
29591
29665
  return {
29592
29666
  ...definition,
29593
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
29667
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
29594
29668
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
29595
29669
  dataSets,
29596
29670
  labelRange,
@@ -29672,7 +29746,7 @@ set(value) {
29672
29746
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
29673
29747
  return {
29674
29748
  ...definition,
29675
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
29749
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
29676
29750
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
29677
29751
  dataSets,
29678
29752
  labelRange
@@ -29794,7 +29868,7 @@ set(value) {
29794
29868
  PieChart: () => PieChart,
29795
29869
  SPREADSHEET_TO_EXCEL_TRENDLINE_TYPE_MAPPING: () => SPREADSHEET_TO_EXCEL_TRENDLINE_TYPE_MAPPING,
29796
29870
  ScorecardChart: () => ScorecardChart$1,
29797
- TREND_LINE_XAXIS_ID: () => "x1",
29871
+ TREND_LINE_XAXIS_ID: () => TREND_LINE_XAXIS_ID,
29798
29872
  WaterfallChart: () => WaterfallChart,
29799
29873
  adaptChartRange: () => adaptChartRange,
29800
29874
  chartFontColor: () => chartFontColor,
@@ -30672,12 +30746,12 @@ set(value) {
30672
30746
  for (let current = it.next(); !current.done; current = it.next()) {
30673
30747
  if (current.value.nodeName === "P" || current.value.nodeName === "DIV" && current.value !== this.el) {
30674
30748
  if (isFirstParagraph) isFirstParagraph = false;
30675
- else text += "\n";
30749
+ else text += NEWLINE;
30676
30750
  emptyParagraph = isEmptyParagraph(current.value);
30677
30751
  continue;
30678
30752
  }
30679
30753
  if (!current.value.hasChildNodes()) {
30680
- if (current.value.nodeName === "BR" && !emptyParagraph) text += "\n";
30754
+ if (current.value.nodeName === "BR" && !emptyParagraph) text += NEWLINE;
30681
30755
  text += current.value.textContent;
30682
30756
  }
30683
30757
  }
@@ -30871,7 +30945,7 @@ set(value) {
30871
30945
  if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) assistantStyle.right = `0px`;
30872
30946
  } else {
30873
30947
  assistantStyle["max-height"] = `${this.spreadsheetRect.height - composerRect.bottom - 1}px`;
30874
- if (composerRect.left + ASSISTANT_WIDTH + 15 + CLOSE_ICON_RADIUS > this.spreadsheetRect.width) assistantStyle.right = `${CLOSE_ICON_RADIUS}px`;
30948
+ if (composerRect.left + ASSISTANT_WIDTH + SCROLLBAR_WIDTH + CLOSE_ICON_RADIUS > this.spreadsheetRect.width) assistantStyle.right = `${CLOSE_ICON_RADIUS}px`;
30875
30949
  }
30876
30950
  return assistantStyle;
30877
30951
  }
@@ -30969,7 +31043,7 @@ set(value) {
30969
31043
  const start = Math.min(selection.start, selection.end);
30970
31044
  const end = Math.max(selection.start, selection.end);
30971
31045
  this.props.composerStore.stopComposerRangeSelection();
30972
- this.props.composerStore.setCurrentContent(content.slice(0, start) + "\n" + content.slice(end), {
31046
+ this.props.composerStore.setCurrentContent(content.slice(0, start) + NEWLINE + content.slice(end), {
30973
31047
  start: start + 1,
30974
31048
  end: start + 1
30975
31049
  });
@@ -31148,7 +31222,7 @@ set(value) {
31148
31222
  const { end, start } = this.props.composerStore.composerSelection;
31149
31223
  for (let index = 0; index < tokens.length; index++) {
31150
31224
  const token = tokens[index];
31151
- let color = token.color || "light-dark(#000000, #ffffff)";
31225
+ let color = token.color || DEFAULT_TOKEN_COLOR;
31152
31226
  if (token.isBlurred) color = setColorAlpha(color, .5);
31153
31227
  const classes = [];
31154
31228
  if (token.type === "REFERENCE" && this.props.composerStore.tokenAtCursor === token && this.props.composerStore.editionMode === "selecting") classes.push("text-decoration-underline");
@@ -31179,8 +31253,8 @@ set(value) {
31179
31253
  splitHtmlContentIntoLines(contents) {
31180
31254
  const contentSplitInLines = [];
31181
31255
  let currentLine = [];
31182
- for (const content of contents) if (content.value.includes("\n")) {
31183
- const lines = content.value.split("\n");
31256
+ for (const content of contents) if (content.value.includes(NEWLINE)) {
31257
+ const lines = content.value.split(NEWLINE);
31184
31258
  const lastLine = lines.pop();
31185
31259
  for (const line of lines) {
31186
31260
  currentLine.push({
@@ -32078,11 +32152,11 @@ set(value) {
32078
32152
  getTokenColor(token) {
32079
32153
  if (token.type === "REFERENCE") {
32080
32154
  const { xc, sheetName } = splitReference(token.value);
32081
- return this.rangeXCColor(xc, sheetName) || "light-dark(#000000, #ffffff)";
32155
+ return this.rangeXCColor(xc, sheetName) || DEFAULT_TOKEN_COLOR;
32082
32156
  }
32083
32157
  if (token.type === "SYMBOL") {
32084
32158
  const namedRange = this.getters.getNamedRange(token.value);
32085
- if (namedRange) return this.rangeColor(namedRange.range) || "light-dark(#000000, #ffffff)";
32159
+ if (namedRange) return this.rangeColor(namedRange.range) || DEFAULT_TOKEN_COLOR;
32086
32160
  const upperCaseValue = token.value.toUpperCase();
32087
32161
  if (upperCaseValue === "TRUE" || upperCaseValue === "FALSE") return tokenColors.NUMBER;
32088
32162
  if (upperCaseValue in functionRegistry.content) return tokenColors.FUNCTION;
@@ -32090,7 +32164,7 @@ set(value) {
32090
32164
  if (["LEFT_PAREN", "RIGHT_PAREN"].includes(token.type)) {
32091
32165
  if (token.parenthesesCode === "") return tokenColors.ORPHAN_RIGHT_PAREN;
32092
32166
  }
32093
- return tokenColors[token.type] || "light-dark(#000000, #ffffff)";
32167
+ return tokenColors[token.type] || DEFAULT_TOKEN_COLOR;
32094
32168
  }
32095
32169
  rangeXCColor(xc, sheetName) {
32096
32170
  const refSheet = sheetName ? this.model.getters.getSheetIdByName(sheetName) : this.sheetId;
@@ -32809,7 +32883,7 @@ set(value) {
32809
32883
  });
32810
32884
  }
32811
32885
  get defaultHoleSize() {
32812
- return 50;
32886
+ return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
32813
32887
  }
32814
32888
  updateEditedValues(selectedIndex) {
32815
32889
  this.state.index = parseInt(selectedIndex);
@@ -32981,7 +33055,7 @@ set(value) {
32981
33055
  return this.props.definition.baselineMode === "progress" ? _t("Progress bar colors") : _t("Baseline colors");
32982
33056
  }
32983
33057
  get defaultScorecardTitleFontSize() {
32984
- return 14;
33058
+ return SCORECARD_CHART_TITLE_FONT_SIZE;
32985
33059
  }
32986
33060
  translate(term) {
32987
33061
  return this.env.model.getters.dynamicTranslate(term);
@@ -33002,14 +33076,14 @@ set(value) {
33002
33076
  get keyStyle() {
33003
33077
  return {
33004
33078
  align: "center",
33005
- fontSize: 32,
33079
+ fontSize: DEFAULT_SCORECARD_KEY_VALUE_FONT_SIZE,
33006
33080
  ...this.props.definition.keyDescr
33007
33081
  };
33008
33082
  }
33009
33083
  get baselineStyle() {
33010
33084
  return {
33011
33085
  align: "center",
33012
- fontSize: 16,
33086
+ fontSize: DEFAULT_SCORECARD_BASELINE_FONT_SIZE,
33013
33087
  ...this.props.definition.baselineDescr
33014
33088
  };
33015
33089
  }
@@ -33252,13 +33326,13 @@ set(value) {
33252
33326
  }];
33253
33327
  }
33254
33328
  get positiveValuesColor() {
33255
- return this.props.definition.positiveValuesColor || "#4EA7F2";
33329
+ return this.props.definition.positiveValuesColor || CHART_WATERFALL_POSITIVE_COLOR;
33256
33330
  }
33257
33331
  get negativeValuesColor() {
33258
- return this.props.definition.negativeValuesColor || "#EA6175";
33332
+ return this.props.definition.negativeValuesColor || CHART_WATERFALL_NEGATIVE_COLOR;
33259
33333
  }
33260
33334
  get subTotalValuesColor() {
33261
- return this.props.definition.subTotalValuesColor || "#AAAAAA";
33335
+ return this.props.definition.subTotalValuesColor || CHART_WATERFALL_SUBTOTAL_COLOR;
33262
33336
  }
33263
33337
  updateVerticalAxisPosition(value) {
33264
33338
  this.props.updateChart(this.props.chartId, { verticalAxisPosition: value });
@@ -35599,7 +35673,7 @@ set(value) {
35599
35673
  get previewGradient() {
35600
35674
  const rule = this.state.rules.colorScale;
35601
35675
  const minColor = colorNumberToHex(rule.minimum.color);
35602
- const midColor = colorNumberToHex(rule.midpoint?.color || 11982760);
35676
+ const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
35603
35677
  const maxColor = colorNumberToHex(rule.maximum.color);
35604
35678
  const baseString = "linear-gradient(to right, ";
35605
35679
  return cssPropertiesToCss({
@@ -37875,7 +37949,7 @@ set(value) {
37875
37949
  return {
37876
37950
  type: measureDisplayType,
37877
37951
  fieldNameWithGranularity,
37878
- value: value ?? "(previous)"
37952
+ value: value ?? PREVIOUS_VALUE
37879
37953
  };
37880
37954
  }
37881
37955
  }
@@ -39379,6 +39453,117 @@ set(value) {
39379
39453
  return false;
39380
39454
  }
39381
39455
 
39456
+ //#endregion
39457
+ //#region src/helpers/pivot/spreadsheet_pivot/data_entries_index_spreadsheet_pivot.ts
39458
+ const EMPTY_DATA_ENTRIES = [];
39459
+ /**
39460
+ * Index of the data entries of a spreadsheet pivot, used to retrieve the
39461
+ * entries matching a pivot domain without scanning all the entries.
39462
+ *
39463
+ * Starting with the row dimensions, one can descend either in the
39464
+ * next row dimension (`rowChildren`) or in the first column dimension
39465
+ * (`colChildren`).
39466
+ *
39467
+ * e.g. with the rows ["continent", "city"] and the columns ["team"]
39468
+ *
39469
+ * root -> all the entries
39470
+ * ├── (col) Team 1 -> [team=Team 1]
39471
+ * ├── (col) Team 2 -> [team=Team 2]
39472
+ * ├── (row) Europe -> [continent=Europe]
39473
+ * │ ├── (col) Team 1 -> [continent=Europe, team=Team 1]
39474
+ * │ ├── (row) Brussels -> [continent=Europe, city=Brussels]
39475
+ * │ │ └── (col) Team 1 -> [continent=Europe, city=Brussels, team=Team 1]
39476
+ * │ └── (row) Paris
39477
+ * │ └── ...
39478
+ * └── (row) North America
39479
+ * └── ...
39480
+ *
39481
+ * Each entry is inserted once per couple (row prefix, column prefix) it belongs
39482
+ * to, which is exactly the number of pivot cells it contributes to.
39483
+ */
39484
+ var PivotDataEntriesIndex = class {
39485
+ rowDimensions;
39486
+ colDimensions;
39487
+ root = createIndexNode();
39488
+ constructor(dataEntries, rowDimensions, colDimensions) {
39489
+ this.rowDimensions = rowDimensions;
39490
+ this.colDimensions = colDimensions;
39491
+ for (const entry of dataEntries) this.addEntry(entry);
39492
+ }
39493
+ /**
39494
+ * Get the data entries matching the given domain.
39495
+ */
39496
+ getDataEntries(domain) {
39497
+ const rowKeys = [];
39498
+ const colKeys = [];
39499
+ for (const domainNode of domain) {
39500
+ const rowDimension = this.rowDimensions[rowKeys.length];
39501
+ if (rowDimension?.nameWithGranularity === domainNode.field) {
39502
+ rowKeys.push(toGroupKey(domainNode.value, rowDimension));
39503
+ continue;
39504
+ }
39505
+ const colDimension = this.colDimensions[colKeys.length];
39506
+ if (colDimension?.nameWithGranularity !== domainNode.field) throw new EvaluationError(_t("Dimension %s does not exist", domainNode.field));
39507
+ colKeys.push(toGroupKey(domainNode.value, colDimension));
39508
+ }
39509
+ let node = this.root;
39510
+ for (const key of rowKeys) {
39511
+ node = node.rowChildren?.get(key);
39512
+ if (!node) return EMPTY_DATA_ENTRIES;
39513
+ }
39514
+ for (const key of colKeys) {
39515
+ node = node.colChildren?.get(key);
39516
+ if (!node) return EMPTY_DATA_ENTRIES;
39517
+ }
39518
+ return node.entries;
39519
+ }
39520
+ addEntry(entry) {
39521
+ let rowNode = this.root;
39522
+ this.addEntryToColumns(rowNode, entry);
39523
+ for (const dimension of this.rowDimensions) {
39524
+ rowNode = getOrCreateChild(rowNode, "rowChildren", getEntryGroupKey(entry, dimension));
39525
+ this.addEntryToColumns(rowNode, entry);
39526
+ }
39527
+ }
39528
+ /**
39529
+ * Add the entry to the given row node, and to each of its column prefixes.
39530
+ */
39531
+ addEntryToColumns(rowNode, entry) {
39532
+ rowNode.entries.push(entry);
39533
+ let node = rowNode;
39534
+ for (const dimension of this.colDimensions) {
39535
+ node = getOrCreateChild(node, "colChildren", getEntryGroupKey(entry, dimension));
39536
+ node.entries.push(entry);
39537
+ }
39538
+ }
39539
+ };
39540
+ function createIndexNode() {
39541
+ return {
39542
+ entries: [],
39543
+ rowChildren: void 0,
39544
+ colChildren: void 0
39545
+ };
39546
+ }
39547
+ function getOrCreateChild(node, axis, key) {
39548
+ let children = node[axis];
39549
+ if (!children) {
39550
+ children = /* @__PURE__ */ new Map();
39551
+ node[axis] = children;
39552
+ }
39553
+ let child = children.get(key);
39554
+ if (!child) {
39555
+ child = createIndexNode();
39556
+ children.set(key, child);
39557
+ }
39558
+ return child;
39559
+ }
39560
+ function getEntryGroupKey(entry, dimension) {
39561
+ return toGroupKey(entry[dimension.nameWithGranularity]?.value, dimension);
39562
+ }
39563
+ function toGroupKey(value, dimension) {
39564
+ return dimension.type === "char" ? String(value) : value;
39565
+ }
39566
+
39382
39567
  //#endregion
39383
39568
  //#region src/helpers/pivot/pivot_domain_helpers.ts
39384
39569
  function getDomainOfParentRow(pivot, domain) {
@@ -39484,7 +39669,7 @@ set(value) {
39484
39669
  if (value === void 0) return;
39485
39670
  const valueIndex = values.indexOf(value);
39486
39671
  if (value === void 0 || valueIndex === -1) return;
39487
- return replaceFieldValueInDomain(domain, fieldNameWithGranularity, values[clip(valueIndex + (direction === "(previous)" ? -1 : 1), 0, values.length - 1)]);
39672
+ return replaceFieldValueInDomain(domain, fieldNameWithGranularity, values[clip(valueIndex + (direction === PREVIOUS_VALUE ? -1 : 1), 0, values.length - 1)]);
39488
39673
  }
39489
39674
  function domainToString(domain) {
39490
39675
  return domain ? domain.map(domainNodeToString).join(", ") : "";
@@ -40140,6 +40325,11 @@ set(value) {
40140
40325
  */
40141
40326
  filteredDataEntries = [];
40142
40327
  /**
40328
+ * This index is used to retrieve the data entries matching a pivot domain
40329
+ * without scanning all the data entries.
40330
+ */
40331
+ dataEntriesIndex = lazy(() => new PivotDataEntriesIndex([], [], []));
40332
+ /**
40143
40333
  * This object contains the pivot table structure. It is created from the
40144
40334
  * data entries and the pivot definition.
40145
40335
  */
@@ -40174,6 +40364,7 @@ set(value) {
40174
40364
  this.filteredDataEntries = this.loadFilteredDataEntries(this.unfilteredDataEntries);
40175
40365
  }
40176
40366
  if (type >= 1) {
40367
+ this.dataEntriesIndex = lazy(() => new PivotDataEntriesIndex(this.filteredDataEntries, this.definition.rows, this.definition.columns));
40177
40368
  this.collapsedTable = void 0;
40178
40369
  this.expandedTable = void 0;
40179
40370
  }
@@ -40251,14 +40442,14 @@ set(value) {
40251
40442
  const lastNode = domain.at(-1);
40252
40443
  if (!lastNode) return { value: _t("Total") };
40253
40444
  const dimension = this.getDimension(lastNode.field);
40254
- const finalCell = this.filterDataEntriesFromDomain(this.filteredDataEntries, domain)[0]?.[dimension.nameWithGranularity];
40255
40445
  if (dimension.type === "datetime") return pivotTimeAdapter(dimension.granularity || "month").toValueAndFormat(lastNode.value, this.getters.getLocale());
40446
+ const finalCell = this.getDataEntriesFromDomain(domain)[0]?.[dimension.nameWithGranularity];
40256
40447
  if (!finalCell) return { value: "" };
40257
40448
  if (finalCell.value === null) return { value: _t("(Undefined)") };
40258
40449
  return finalCell;
40259
40450
  }
40260
40451
  getPivotCellValueAndFormat(measureId, domain) {
40261
- const dataEntries = this.filterDataEntriesFromDomain(this.filteredDataEntries, domain);
40452
+ const dataEntries = this.getDataEntriesFromDomain(domain);
40262
40453
  if (dataEntries.length === 0) return { value: "" };
40263
40454
  const measure = this.getMeasure(measureId);
40264
40455
  const allValues = dataEntries.map((value) => value[measure.fieldName]).filter(isDefined);
@@ -40368,17 +40559,8 @@ set(value) {
40368
40559
  if (!type) throw new Error(`Field ${fieldName} does not exist`);
40369
40560
  return type;
40370
40561
  }
40371
- filterDataEntriesFromDomain(dataEntries, domain) {
40372
- return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
40373
- }
40374
- filterDataEntriesFromDomainNode(dataEntries, domain) {
40375
- const { field, value, type } = domain;
40376
- const { nameWithGranularity } = this.getDimension(field);
40377
- return dataEntries.filter((entry) => {
40378
- const cellValue = entry[nameWithGranularity]?.value;
40379
- if (type === "char") return String(cellValue) === String(value);
40380
- return cellValue === value;
40381
- });
40562
+ getDataEntriesFromDomain(domain) {
40563
+ return this.dataEntriesIndex().getDataEntries(domain);
40382
40564
  }
40383
40565
  getDimension(nameWithGranularity) {
40384
40566
  return this.definition.getDimension(nameWithGranularity);
@@ -40772,7 +40954,7 @@ set(value) {
40772
40954
  }
40773
40955
  const pivot = this.getters.getPivot(this.pivotId);
40774
40956
  const numberOfCells = pivot.isValid() ? pivot.getExpandedTableStructure().numberOfCells : 0;
40775
- if (!this.alreadyNotifiedForPivotSize && numberOfCells > 5e5) {
40957
+ if (!this.alreadyNotifiedForPivotSize && numberOfCells > PIVOT_MAX_NUMBER_OF_CELLS) {
40776
40958
  this.alreadyNotifiedForPivotSize = true;
40777
40959
  this.notification.notifyUser({
40778
40960
  type: "warning",
@@ -42634,7 +42816,7 @@ set(value) {
42634
42816
  },
42635
42817
  {
42636
42818
  label: _t("Line Break"),
42637
- value: "\n"
42819
+ value: NEWLINE
42638
42820
  }
42639
42821
  ];
42640
42822
  var SplitIntoColumnsPanel = class extends Component {
@@ -43179,7 +43361,7 @@ set(value) {
43179
43361
  const newPanelInfo = {
43180
43362
  currentPanelProps,
43181
43363
  componentTag,
43182
- size: 350
43364
+ size: DEFAULT_SIDE_PANEL_SIZE
43183
43365
  };
43184
43366
  const state = this.computeState(newPanelInfo);
43185
43367
  if (!state.isOpen) return;
@@ -43187,8 +43369,8 @@ set(value) {
43187
43369
  this._openPanel("mainPanel", newPanelInfo, state);
43188
43370
  return;
43189
43371
  }
43190
- const nonCollapsedPanelSize = this.mainPanel.isCollapsed ? 350 : this.mainPanel.size;
43191
- if (!this.secondaryPanel && nonCollapsedPanelSize + 350 > this.availableWidth) {
43372
+ const nonCollapsedPanelSize = this.mainPanel.isCollapsed ? DEFAULT_SIDE_PANEL_SIZE : this.mainPanel.size;
43373
+ if (!this.secondaryPanel && nonCollapsedPanelSize + DEFAULT_SIDE_PANEL_SIZE > this.availableWidth) {
43192
43374
  this.get(NotificationStore).notifyUser({
43193
43375
  sticky: false,
43194
43376
  type: "warning",
@@ -43202,7 +43384,7 @@ set(value) {
43202
43384
  const newPanelInfo = {
43203
43385
  currentPanelProps,
43204
43386
  componentTag,
43205
- size: 350
43387
+ size: DEFAULT_SIDE_PANEL_SIZE
43206
43388
  };
43207
43389
  const state = this.computeState(newPanelInfo);
43208
43390
  if (!state.isOpen) return;
@@ -43231,7 +43413,7 @@ set(value) {
43231
43413
  this[panel] = {
43232
43414
  currentPanelProps: state.props ?? {},
43233
43415
  componentTag: newPanel.componentTag,
43234
- size: currentPanel?.size || 350,
43416
+ size: currentPanel?.size || DEFAULT_SIDE_PANEL_SIZE,
43235
43417
  isCollapsed: currentPanel?.isCollapsed || false,
43236
43418
  isPinned: currentPanel && "isPinned" in currentPanel ? currentPanel.isPinned : false
43237
43419
  };
@@ -43261,19 +43443,19 @@ set(value) {
43261
43443
  changePanelSize(panel, size) {
43262
43444
  const panelInfo = this[panel];
43263
43445
  if (!panelInfo || "isCollapsed" in panelInfo && panelInfo.isCollapsed) return;
43264
- size = Math.max(size, 350);
43446
+ size = Math.max(size, DEFAULT_SIDE_PANEL_SIZE);
43265
43447
  let otherPanelSize = panel === "mainPanel" ? this.secondaryPanel?.size || 0 : this.mainPanel?.size || 0;
43266
43448
  if (size > this.availableWidth - otherPanelSize) {
43267
43449
  if (panel === "mainPanel" && this.secondaryPanel) {
43268
- this.secondaryPanel.size = Math.max(this.availableWidth - size, 350);
43450
+ this.secondaryPanel.size = Math.max(this.availableWidth - size, DEFAULT_SIDE_PANEL_SIZE);
43269
43451
  otherPanelSize = this.secondaryPanel.size;
43270
43452
  }
43271
- size = Math.max(this.availableWidth - otherPanelSize, 350);
43453
+ size = Math.max(this.availableWidth - otherPanelSize, DEFAULT_SIDE_PANEL_SIZE);
43272
43454
  }
43273
43455
  panelInfo.size = size;
43274
43456
  }
43275
43457
  resetPanelSize(panel) {
43276
- if (this[panel]) this[panel].size = 350;
43458
+ if (this[panel]) this[panel].size = DEFAULT_SIDE_PANEL_SIZE;
43277
43459
  }
43278
43460
  togglePinPanel() {
43279
43461
  if (!this.mainPanel) return;
@@ -43289,10 +43471,10 @@ set(value) {
43289
43471
  if (!panelInfo) return;
43290
43472
  if (panelInfo.isCollapsed) {
43291
43473
  panelInfo.isCollapsed = false;
43292
- this.changePanelSize(panel, 350);
43474
+ this.changePanelSize(panel, DEFAULT_SIDE_PANEL_SIZE);
43293
43475
  } else {
43294
43476
  panelInfo.isCollapsed = true;
43295
- panelInfo.size = 45;
43477
+ panelInfo.size = COLLAPSED_SIDE_PANEL_SIZE;
43296
43478
  }
43297
43479
  }
43298
43480
  computeState({ componentTag, currentPanelProps: initialPanelProps }) {
@@ -43307,12 +43489,12 @@ set(value) {
43307
43489
  } : state;
43308
43490
  }
43309
43491
  changeSpreadsheetWidth(width) {
43310
- this.availableWidth = width - 150;
43311
- if (this.secondaryPanel && width - this.totalPanelSize < 150) {
43492
+ this.availableWidth = width - MIN_SHEET_VIEW_WIDTH;
43493
+ if (this.secondaryPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
43312
43494
  this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
43313
43495
  this.secondaryPanel = void 0;
43314
43496
  }
43315
- if (this.mainPanel && width - this.totalPanelSize < 150) this.mainPanel.size = Math.max(width - 150, 350);
43497
+ if (this.mainPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) this.mainPanel.size = Math.max(width - MIN_SHEET_VIEW_WIDTH, DEFAULT_SIDE_PANEL_SIZE);
43316
43498
  }
43317
43499
  };
43318
43500
 
@@ -45075,7 +45257,7 @@ set(value) {
45075
45257
  * Returns a timeout delay in milliseconds.
45076
45258
  */
45077
45259
  function scrollDelay(value) {
45078
- return 20 + (140 - 20) * Math.exp(-.035 * (value - 1));
45260
+ return MIN_DELAY + (MAX_DELAY - MIN_DELAY) * Math.exp(-.035 * (value - 1));
45079
45261
  }
45080
45262
 
45081
45263
  //#endregion
@@ -45119,7 +45301,7 @@ set(value) {
45119
45301
  let { scrollX, scrollY } = getters.getActiveSheetScrollInfo();
45120
45302
  const { xSplit, ySplit } = getters.getPaneDivisions(sheetId);
45121
45303
  let canEdgeScroll = false;
45122
- let timeoutDelay = 140;
45304
+ let timeoutDelay = MAX_DELAY;
45123
45305
  const x = zoomedMouseEvent.clientX - position.x;
45124
45306
  let colIndex = getters.getColIndex(x);
45125
45307
  if (scrollDirection !== "vertical") {
@@ -45515,7 +45697,7 @@ set(value) {
45515
45697
  return true;
45516
45698
  }
45517
45699
  function astToDoc(ast) {
45518
- const debugPrefix = ast.debug ? `${"?"}` : "";
45700
+ const debugPrefix = ast.debug ? `${DEBUGGER_CHAR}` : "";
45519
45701
  switch (ast.type) {
45520
45702
  case "NUMBER": return debugPrefix + String(ast.value);
45521
45703
  case "STRING": return debugPrefix + `"${ast.value}"`;
@@ -45594,7 +45776,7 @@ set(value) {
45594
45776
  * Converts an ast formula to the corresponding string
45595
45777
  */
45596
45778
  function astToFormula(ast) {
45597
- const debugPrefix = ast.debug ? `${"?"}` : "";
45779
+ const debugPrefix = ast.debug ? `${DEBUGGER_CHAR}` : "";
45598
45780
  switch (ast.type) {
45599
45781
  case "FUNCALL":
45600
45782
  const args = ast.args.map((arg) => astToFormula(arg));
@@ -46289,19 +46471,19 @@ set(value) {
46289
46471
  position = y;
46290
46472
  break;
46291
46473
  case "bottom":
46292
- position = y + figureUI.height - 1;
46474
+ position = y + figureUI.height - FIGURE_BORDER_WIDTH;
46293
46475
  break;
46294
46476
  case "vCenter":
46295
- position = y + Math.floor(figureUI.height / 2) - 1;
46477
+ position = y + Math.floor(figureUI.height / 2) - FIGURE_BORDER_WIDTH;
46296
46478
  break;
46297
46479
  case "left":
46298
46480
  position = x;
46299
46481
  break;
46300
46482
  case "right":
46301
- position = x + figureUI.width - 1;
46483
+ position = x + figureUI.width - FIGURE_BORDER_WIDTH;
46302
46484
  break;
46303
46485
  case "hCenter":
46304
- position = x + Math.floor(figureUI.width / 2) - 1;
46486
+ position = x + Math.floor(figureUI.width / 2) - FIGURE_BORDER_WIDTH;
46305
46487
  break;
46306
46488
  }
46307
46489
  return {
@@ -46532,7 +46714,7 @@ set(value) {
46532
46714
  };
46533
46715
  const offsetX = Math.abs(currentMousePosition.x - initialMousePosition.x);
46534
46716
  const offsetY = Math.abs(currentMousePosition.y - initialMousePosition.y);
46535
- if (!hasStartedDnd && offsetX < 5 && offsetY < 5) return;
46717
+ if (!hasStartedDnd && offsetX < DRAG_THRESHOLD && offsetY < DRAG_THRESHOLD) return;
46536
46718
  hasStartedDnd = true;
46537
46719
  const selectedFigures = dragFigureForMove(currentMousePosition, initialMousePosition, initialFigures, maxDimensions, initialScrollPosition, getters.getActiveSheetScrollInfo());
46538
46720
  const draggedFigure = selectedFigures.find((f) => f.id === draggedFigureId);
@@ -46601,7 +46783,7 @@ set(value) {
46601
46783
  ev.stopPropagation();
46602
46784
  const initialScrollPosition = this.env.model.getters.getActiveSheetScrollInfo();
46603
46785
  const keepRatio = figureRegistry.get(figureUI.tag).keepRatio || false;
46604
- const minFigSize = figureRegistry.get(figureUI.tag).minFigSize || 80;
46786
+ const minFigSize = figureRegistry.get(figureUI.tag).minFigSize || MIN_FIG_SIZE;
46605
46787
  const zoom = this.env.model.getters.getViewportZoomLevel();
46606
46788
  const sheetId = this.env.model.getters.getActiveSheetId();
46607
46789
  const initialMousePosition = {
@@ -46739,8 +46921,8 @@ set(value) {
46739
46921
  const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
46740
46922
  const { y, height } = this.env.model.getters.getMainViewportRect();
46741
46923
  return cssPropertiesToCss({
46742
- top: `${y + height - scrollY - 46}px`,
46743
- height: `${46}px`
46924
+ top: `${y + height - scrollY - FOOTER_HEIGHT}px`,
46925
+ height: `${FOOTER_HEIGHT}px`
46744
46926
  });
46745
46927
  }
46746
46928
  get errorMessages() {
@@ -47150,7 +47332,7 @@ set(value) {
47150
47332
  get isFooterVisible() {
47151
47333
  const { y } = this.env.model.getters.getMainViewportCoordinates();
47152
47334
  const { height } = this.env.model.getters.getSheetViewDimension();
47153
- return !this.env.model.getters.isReadonly() && height - y > 46;
47335
+ return !this.env.model.getters.isReadonly() && height - y > FOOTER_HEIGHT;
47154
47336
  }
47155
47337
  };
47156
47338
 
@@ -47204,7 +47386,7 @@ set(value) {
47204
47386
  row: hiddenIndex
47205
47387
  }));
47206
47388
  return cssPropertiesToCss({
47207
- top: rect.y + rect.height - 26 - this.props.offset + "px",
47389
+ top: rect.y + rect.height - HEADER_HEIGHT - this.props.offset + "px",
47208
47390
  "margin-right": "1px"
47209
47391
  });
47210
47392
  }
@@ -47213,7 +47395,7 @@ set(value) {
47213
47395
  top: this.env.model.getters.getRect(positionToZone({
47214
47396
  col: 0,
47215
47397
  row: hiddenIndex
47216
- })).y - 26 - this.props.offset + "px",
47398
+ })).y - HEADER_HEIGHT - this.props.offset + "px",
47217
47399
  "margin-right": "1px"
47218
47400
  });
47219
47401
  }
@@ -47246,13 +47428,13 @@ set(value) {
47246
47428
  col: hiddenIndex,
47247
47429
  row: 0
47248
47430
  }));
47249
- return cssPropertiesToCss({ left: rect.x + rect.width - 48 - this.props.offset + "px" });
47431
+ return cssPropertiesToCss({ left: rect.x + rect.width - HEADER_WIDTH - this.props.offset + "px" });
47250
47432
  }
47251
47433
  getUnhideNextButtonStyle(hiddenIndex) {
47252
47434
  return cssPropertiesToCss({ left: this.env.model.getters.getRect(positionToZone({
47253
47435
  col: hiddenIndex,
47254
47436
  row: 0
47255
- })).x - 48 - this.props.offset + "px" });
47437
+ })).x - HEADER_WIDTH - this.props.offset + "px" });
47256
47438
  }
47257
47439
  unhide(hiddenElements) {
47258
47440
  this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
@@ -47475,7 +47657,7 @@ set(value) {
47475
47657
  super.setup();
47476
47658
  this.PADDING = 15;
47477
47659
  this.MAX_SIZE_MARGIN = 90;
47478
- this.MIN_ELEMENT_SIZE = 5;
47660
+ this.MIN_ELEMENT_SIZE = MIN_COL_WIDTH;
47479
47661
  }
47480
47662
  get sheetId() {
47481
47663
  return this.env.model.getters.getActiveSheetId();
@@ -47609,7 +47791,7 @@ set(value) {
47609
47791
  super.setup();
47610
47792
  this.PADDING = 5;
47611
47793
  this.MAX_SIZE_MARGIN = 60;
47612
- this.MIN_ELEMENT_SIZE = 10;
47794
+ this.MIN_ELEMENT_SIZE = MIN_ROW_HEIGHT;
47613
47795
  }
47614
47796
  get sheetId() {
47615
47797
  return this.env.model.getters.getActiveSheetId();
@@ -48045,7 +48227,7 @@ set(value) {
48045
48227
  x,
48046
48228
  y
48047
48229
  }, style.underline, style.strikethrough);
48048
- y += 4 + box.content.fontSizePx;
48230
+ y += MIN_CELL_TEXT_MARGIN + box.content.fontSizePx;
48049
48231
  }
48050
48232
  if (style.rotation) ctx.restore();
48051
48233
  if (box.clipRect) ctx.restore();
@@ -48093,14 +48275,14 @@ set(value) {
48093
48275
  const activeCols = renderingContext.activeCols;
48094
48276
  const activeRows = renderingContext.activeRows;
48095
48277
  const theme = this.getters.getSpreadsheetTheme();
48096
- ctx.font = `400 ${11}px ${DEFAULT_FONT}`;
48278
+ ctx.font = `400 ${HEADER_FONT_SIZE}px ${DEFAULT_FONT}`;
48097
48279
  ctx.textAlign = "center";
48098
48280
  ctx.textBaseline = "middle";
48099
48281
  ctx.lineWidth = thinLineWidth;
48100
48282
  ctx.strokeStyle = theme.headerTextColor;
48101
48283
  ctx.fillStyle = this.getters.getSpreadsheetTheme().backgroundColor;
48102
- ctx.fillRect(0, 0, 48, height);
48103
- ctx.fillRect(0, 0, width, 26);
48284
+ ctx.fillRect(0, 0, HEADER_WIDTH, height);
48285
+ ctx.fillRect(0, 0, width, HEADER_HEIGHT);
48104
48286
  for (const col of visibleCols) {
48105
48287
  const colZone = {
48106
48288
  left: col,
@@ -48114,7 +48296,7 @@ set(value) {
48114
48296
  if (isColActive) ctx.fillStyle = theme.headerActiveBackgroundColor;
48115
48297
  else if (isColSelected) ctx.fillStyle = theme.headerSelectedBackgroundColor;
48116
48298
  else ctx.fillStyle = theme.headerBackgroundColor;
48117
- ctx.fillRect(x, 0, width, 26);
48299
+ ctx.fillRect(x, 0, width, HEADER_HEIGHT);
48118
48300
  }
48119
48301
  for (const row of visibleRows) {
48120
48302
  const rowZone = {
@@ -48129,13 +48311,13 @@ set(value) {
48129
48311
  if (isRowActive) ctx.fillStyle = theme.headerActiveBackgroundColor;
48130
48312
  else if (isRowSelected) ctx.fillStyle = theme.headerSelectedBackgroundColor;
48131
48313
  else ctx.fillStyle = theme.headerBackgroundColor;
48132
- ctx.fillRect(0, y, 48, height);
48314
+ ctx.fillRect(0, y, HEADER_WIDTH, height);
48133
48315
  }
48134
48316
  ctx.beginPath();
48135
- ctx.moveTo(48, 0);
48136
- ctx.lineTo(48, height);
48137
- ctx.moveTo(0, 26);
48138
- ctx.lineTo(width, 26);
48317
+ ctx.moveTo(HEADER_WIDTH, 0);
48318
+ ctx.lineTo(HEADER_WIDTH, height);
48319
+ ctx.moveTo(0, HEADER_HEIGHT);
48320
+ ctx.lineTo(width, HEADER_HEIGHT);
48139
48321
  ctx.strokeStyle = theme.headerBorderColor;
48140
48322
  ctx.stroke();
48141
48323
  for (const col of visibleCols) {
@@ -48151,13 +48333,13 @@ set(value) {
48151
48333
  const { x, width } = viewports.getVisibleRect(sheetId, zone);
48152
48334
  ctx.save();
48153
48335
  ctx.beginPath();
48154
- ctx.rect(x, 0, width, 26);
48336
+ ctx.rect(x, 0, width, HEADER_HEIGHT);
48155
48337
  ctx.clip();
48156
- ctx.fillText(colName, colStart + colSize / 2, 26 / 2);
48338
+ ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
48157
48339
  ctx.restore();
48158
48340
  ctx.beginPath();
48159
48341
  ctx.moveTo(colStart + colSize, 0);
48160
- ctx.lineTo(colStart + colSize, 26);
48342
+ ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
48161
48343
  ctx.stroke();
48162
48344
  }
48163
48345
  for (const row of visibleRows) {
@@ -48172,13 +48354,13 @@ set(value) {
48172
48354
  const { y, height } = viewports.getVisibleRect(sheetId, zone);
48173
48355
  ctx.save();
48174
48356
  ctx.beginPath();
48175
- ctx.rect(0, y, 48, height);
48357
+ ctx.rect(0, y, HEADER_WIDTH, height);
48176
48358
  ctx.clip();
48177
- ctx.fillText(String(row + 1), 48 / 2, rowStart + rowSize / 2);
48359
+ ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
48178
48360
  ctx.restore();
48179
48361
  ctx.beginPath();
48180
48362
  ctx.moveTo(0, rowStart + rowSize);
48181
- ctx.lineTo(48, rowStart + rowSize);
48363
+ ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
48182
48364
  ctx.stroke();
48183
48365
  }
48184
48366
  }
@@ -48321,7 +48503,7 @@ set(value) {
48321
48503
  /** Content */
48322
48504
  const wrapping = style.wrapping || "overflow";
48323
48505
  const wrapText = wrapping === "wrap" && !showFormula;
48324
- const availableWidth = width - 2 * 4;
48506
+ const availableWidth = width - 2 * MIN_CELL_TEXT_MARGIN;
48325
48507
  const maxWidth = style.align ? 0 : availableWidth;
48326
48508
  const wrapWidth = wrapText ? availableWidth : void 0;
48327
48509
  const multiLineText = this.getters.getCellMultiLineText(position, {
@@ -48333,18 +48515,18 @@ set(value) {
48333
48515
  align: "left",
48334
48516
  rotation: 0
48335
48517
  };
48336
- const textWidth = Math.max(...multiLineText.map((line) => this.getters.getTextWidth(line, noRotatationStyle))) + 4;
48518
+ const textWidth = Math.max(...multiLineText.map((line) => this.getters.getTextWidth(line, noRotatationStyle))) + MIN_CELL_TEXT_MARGIN;
48337
48519
  const contentSize = this.getters.getMultilineTextSize(multiLineText, style);
48338
- const chipMargin = chipStyle ? 5 : 0;
48520
+ const chipMargin = chipStyle ? DATA_VALIDATION_CHIP_MARGIN : 0;
48339
48521
  const leftMargin = (box.icons.left ? box.icons.left.size + box.icons.left.margin : 0) + chipMargin;
48340
48522
  const rightMargin = (box.icons.right ? box.icons.right.size + box.icons.right.margin : 0) + chipMargin;
48341
- const contentWidth = leftMargin + contentSize.width + rightMargin + 4;
48523
+ const contentWidth = leftMargin + contentSize.width + rightMargin + MIN_CELL_TEXT_MARGIN;
48342
48524
  const align = this.computeCellAlignment(position, contentWidth > width);
48343
48525
  const numberOfLines = multiLineText.length;
48344
48526
  const contentY = Math.round(this.getters.computeTextYCoordinate(box, fontSizePX, style.verticalAlign, numberOfLines));
48345
48527
  let contentX = box.x;
48346
- if (align === "left") contentX += 4 + leftMargin;
48347
- else if (align === "right") contentX += box.width - 4 - rightMargin;
48528
+ if (align === "left") contentX += MIN_CELL_TEXT_MARGIN + leftMargin;
48529
+ else if (align === "right") contentX += box.width - MIN_CELL_TEXT_MARGIN - rightMargin;
48348
48530
  else contentX += box.width / 2;
48349
48531
  contentX = Math.round(contentX);
48350
48532
  const textHeight = computeTextLinesHeight(fontSizePX, numberOfLines);
@@ -48360,7 +48542,7 @@ set(value) {
48360
48542
  };
48361
48543
  if (chipStyle?.fillColor) {
48362
48544
  const chipMarginLeft = leftMargin;
48363
- const chipMarginRight = 5;
48545
+ const chipMarginRight = DATA_VALIDATION_CHIP_MARGIN;
48364
48546
  box.chip = {
48365
48547
  color: chipStyle.fillColor,
48366
48548
  width: box.width - chipMarginLeft - chipMarginRight,
@@ -48523,7 +48705,7 @@ set(value) {
48523
48705
  continue;
48524
48706
  }
48525
48707
  const elapsedTime = timeStamp - animation.startTime;
48526
- const progress = Math.min(1, elapsedTime / 200);
48708
+ const progress = Math.min(1, elapsedTime / CELL_ANIMATION_DURATION);
48527
48709
  if (progress >= 1) this.animations.delete(boxId);
48528
48710
  animation.progress = progress;
48529
48711
  }
@@ -48648,7 +48830,7 @@ set(value) {
48648
48830
  resetTimeout = setTimeout(() => {
48649
48831
  velocityX = 0;
48650
48832
  velocityY = 0;
48651
- }, 100);
48833
+ }, resetTimeoutDuration);
48652
48834
  updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
48653
48835
  }
48654
48836
  function onTouchEnd(ev) {
@@ -48717,7 +48899,7 @@ set(value) {
48717
48899
  //#region src/components/helpers/wheel_hook.ts
48718
48900
  function useWheelHandler(handler) {
48719
48901
  function normalize(val, deltaMode) {
48720
- return val * (deltaMode === 0 ? 1 : 23);
48902
+ return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
48721
48903
  }
48722
48904
  const onMouseWheel = (ev) => {
48723
48905
  handler(normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode), normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode));
@@ -48827,14 +49009,14 @@ set(value) {
48827
49009
  return cssPropertiesToCss(css);
48828
49010
  }
48829
49011
  getHandlerEdgeLength() {
48830
- return this.env.isMobile() ? MOBILE_HANDLER_WIDTH : 8;
49012
+ return this.env.isMobile() ? MOBILE_HANDLER_WIDTH : AUTOFILL_EDGE_LENGTH;
48831
49013
  }
48832
49014
  get buttonLook() {
48833
49015
  const css = {
48834
49016
  "background-color": this.props.color,
48835
49017
  cursor: `${this.props.orientation}-resize`
48836
49018
  };
48837
- if (this.env.isMobile()) css["border-radius"] = `${8 / 2}px`;
49019
+ if (this.env.isMobile()) css["border-radius"] = `${AUTOFILL_EDGE_LENGTH / 2}px`;
48838
49020
  return cssPropertiesToCss(css);
48839
49021
  }
48840
49022
  onMouseDown(ev) {
@@ -49232,8 +49414,8 @@ set(value) {
49232
49414
  exposeFocus: types.function(),
49233
49415
  getGridSize: types.function()
49234
49416
  });
49235
- HEADER_HEIGHT = 26;
49236
- HEADER_WIDTH = 48;
49417
+ HEADER_HEIGHT = HEADER_HEIGHT;
49418
+ HEADER_WIDTH = HEADER_WIDTH;
49237
49419
  menuState;
49238
49420
  gridRef = (0, _odoo_owl.signal)(null);
49239
49421
  canvasRef = (0, _odoo_owl.signal)(null);
@@ -49304,10 +49486,10 @@ set(value) {
49304
49486
  get gridOverlayDimensions() {
49305
49487
  const scrollbarWidth = this.env.model.getters.getScrollBarWidth();
49306
49488
  return cssPropertiesToCss({
49307
- top: `${26}px`,
49308
- left: `${48}px`,
49309
- height: `calc(100% - ${26 + scrollbarWidth}px)`,
49310
- width: `calc(100% - ${48 + scrollbarWidth}px)`
49489
+ top: `${HEADER_HEIGHT}px`,
49490
+ left: `${HEADER_WIDTH}px`,
49491
+ height: `calc(100% - ${HEADER_HEIGHT + scrollbarWidth}px)`,
49492
+ width: `calc(100% - ${HEADER_WIDTH + scrollbarWidth}px)`
49311
49493
  });
49312
49494
  }
49313
49495
  onClosePopover() {
@@ -49523,8 +49705,8 @@ set(value) {
49523
49705
  const zone = this.env.model.getters.getSelectedZone();
49524
49706
  const rect = this.env.model.getters.getVisibleRect(zone);
49525
49707
  return {
49526
- x: rect.x + rect.width - 8 / 2,
49527
- y: rect.y + rect.height - 8 / 2
49708
+ x: rect.x + rect.width - AUTOFILL_EDGE_LENGTH / 2,
49709
+ y: rect.y + rect.height - AUTOFILL_EDGE_LENGTH / 2
49528
49710
  };
49529
49711
  }
49530
49712
  get isAutofillVisible() {
@@ -49541,10 +49723,10 @@ set(value) {
49541
49723
  onGridResized() {
49542
49724
  const { height, width } = this.props.getGridSize();
49543
49725
  this.env.model.dispatch("RESIZE_SHEETVIEW", {
49544
- width: width - 48,
49545
- height: height - 26,
49546
- gridOffsetX: 48,
49547
- gridOffsetY: 26
49726
+ width: width - HEADER_WIDTH,
49727
+ height: height - HEADER_HEIGHT,
49728
+ gridOffsetX: HEADER_WIDTH,
49729
+ gridOffsetY: HEADER_HEIGHT
49548
49730
  });
49549
49731
  }
49550
49732
  moveCanvas(deltaX, deltaY) {
@@ -49890,7 +50072,7 @@ set(value) {
49890
50072
  return cssPropertiesToCss({
49891
50073
  height: `${size}px`,
49892
50074
  width: `${size}px`,
49893
- color: cellStyle.textColor || "#374151C2",
50075
+ color: cellStyle.textColor || TEXT_BODY_MUTED,
49894
50076
  "background-color": this.getBackgroundColor(cellStyle)
49895
50077
  });
49896
50078
  }
@@ -50743,8 +50925,8 @@ set(value) {
50743
50925
  case "DUPLICATE_SHEET": {
50744
50926
  const sheetFiguresFrom = this.getters.getFigures(cmd.sheetId);
50745
50927
  for (const fig of sheetFiguresFrom) if (fig.tag === "carousel") {
50746
- const figureIdBase = fig.id.split("??").pop();
50747
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
50928
+ const figureIdBase = fig.id.split(FIGURE_ID_SPLITTER).pop();
50929
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
50748
50930
  const carousel = this.getCarousel(fig.id);
50749
50931
  if (carousel) {
50750
50932
  const size = {
@@ -50760,8 +50942,8 @@ set(value) {
50760
50942
  size,
50761
50943
  definition: { items: carousel.items.map((item) => {
50762
50944
  if (item.type === "carouselDataView") return { ...item };
50763
- const chartIdBase = item.chartId.split("??").pop();
50764
- const newChartId = `${cmd.sheetIdTo}${"??"}${chartIdBase}`;
50945
+ const chartIdBase = item.chartId.split(FIGURE_ID_SPLITTER).pop();
50946
+ const newChartId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${chartIdBase}`;
50765
50947
  return {
50766
50948
  ...item,
50767
50949
  chartId: newChartId
@@ -50835,12 +51017,12 @@ set(value) {
50835
51017
  * with references (unless they contain a sheet name that contains the separator). */
50836
51018
  buildResult(numbers, strings, references) {
50837
51019
  const res = {};
50838
- if (numbers.length) res.N = numbers.join("|");
51020
+ if (numbers.length) res.N = numbers.join(SEPARATOR);
50839
51021
  if (strings.length) res.S = strings;
50840
51022
  if (references.length) {
50841
51023
  let referencePattern;
50842
- if (references.some((x) => x.includes("|"))) referencePattern = references;
50843
- else referencePattern = references.join("|");
51024
+ if (references.some((x) => x.includes(SEPARATOR))) referencePattern = references;
51025
+ else referencePattern = references.join(SEPARATOR);
50844
51026
  res.R = referencePattern;
50845
51027
  }
50846
51028
  return res;
@@ -50973,7 +51155,7 @@ set(value) {
50973
51155
  }
50974
51156
  squishOneReference(reference, previousReferences, index, forSheetId) {
50975
51157
  const previousReference = previousReferences[index];
50976
- if (deepEquals(previousReference, reference)) return "=";
51158
+ if (deepEquals(previousReference, reference)) return NO_CHANGE;
50977
51159
  if (previousReference.sheetId !== reference.sheetId || previousReference.prefixSheet !== reference.prefixSheet || previousReference.invalidSheetName !== reference.invalidSheetName || previousReference.invalidXc !== reference.invalidXc || previousReference.parts.length !== reference.parts.length) {
50978
51160
  previousReferences[index] = deepCopy(reference);
50979
51161
  return getRangeString(reference, forSheetId, this.getters.getSheetName, this.rangeToStringOptions);
@@ -51007,7 +51189,7 @@ set(value) {
51007
51189
  * - "=" meaning no change as string
51008
51190
  * */
51009
51191
  squishNumbers(numbers) {
51010
- const result = numbers.map((x) => "=");
51192
+ const result = numbers.map((x) => NO_CHANGE);
51011
51193
  for (let i = 0; i < numbers.length; i++) {
51012
51194
  const previousValue = this.baseFormula.literalValues.numbers[i].value;
51013
51195
  const currentValue = numbers[i].value;
@@ -51021,7 +51203,7 @@ set(value) {
51021
51203
  return result;
51022
51204
  }
51023
51205
  squishStrings(strings) {
51024
- const result = strings.map((x) => "=");
51206
+ const result = strings.map((x) => NO_CHANGE);
51025
51207
  for (let i = 0; i < strings.length; i++) {
51026
51208
  const str = strings[i].value;
51027
51209
  if (str !== this.previousStrings[i]) {
@@ -51294,16 +51476,16 @@ set(value) {
51294
51476
  strings: [],
51295
51477
  dependencies: []
51296
51478
  };
51297
- if (squishedFormula.N !== void 0 && squishedFormula.N.length > 0) current.numbers = squishedFormula.N.split("|").map(this.adjustNumbers);
51479
+ if (squishedFormula.N !== void 0 && squishedFormula.N.length > 0) current.numbers = squishedFormula.N.split(SEPARATOR).map(this.adjustNumbers);
51298
51480
  else current.numbers = this.previousFormula.literalValues.numbers;
51299
51481
  if (squishedFormula.S !== void 0 && squishedFormula.S.length > 0) current.strings = squishedFormula.S.map(this.adjustStrings);
51300
51482
  else current.strings = this.previousFormula.literalValues.strings;
51301
51483
  if (squishedFormula.R !== void 0 && this.previousFormula) {
51302
51484
  let references;
51303
51485
  if (typeof squishedFormula.R !== "string") references = squishedFormula.R;
51304
- else references = squishedFormula.R.split("|");
51486
+ else references = squishedFormula.R.split(SEPARATOR);
51305
51487
  current.dependencies = references.map((refStr, index) => {
51306
- if (refStr === "=") return { ...this.alreadyAppliedReferenceOffset[index] };
51488
+ if (refStr === NO_CHANGE) return { ...this.alreadyAppliedReferenceOffset[index] };
51307
51489
  else if (refStr.startsWith("+") || refStr.startsWith("-")) {
51308
51490
  const offset = parseInt(refStr.slice(2), 10);
51309
51491
  const sign = refStr[0] === "+" ? 1 : -1;
@@ -51339,14 +51521,14 @@ set(value) {
51339
51521
  throw new Error("Invalid squished element or no previous cell to unsquish against");
51340
51522
  }
51341
51523
  adjustStrings = (str, index) => {
51342
- if (str === "=") return { value: this.previousString[index] };
51524
+ if (str === NO_CHANGE) return { value: this.previousString[index] };
51343
51525
  else {
51344
51526
  this.previousString[index] = str;
51345
51527
  return { value: str };
51346
51528
  }
51347
51529
  };
51348
51530
  adjustNumbers = (numStr, index) => {
51349
- if (numStr === "=") return { value: this.alreadyAppliedNumberOffset[index] };
51531
+ if (numStr === NO_CHANGE) return { value: this.alreadyAppliedNumberOffset[index] };
51350
51532
  else {
51351
51533
  const currentOffset = parseFloat(numStr.slice(1));
51352
51534
  const adjustedOffset = (this.alreadyAppliedNumberOffset[index] || 0) + currentOffset;
@@ -51769,10 +51951,10 @@ set(value) {
51769
51951
  if (!chart || !figureId) continue;
51770
51952
  const fig = this.getters.getFigure(cmd.sheetId, figureId);
51771
51953
  if (!fig) continue;
51772
- const figureIdBase = figureId.split("??").pop();
51773
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
51774
- const chartIdBase = chartId.split("??").pop();
51775
- const duplicatedChartId = `${cmd.sheetIdTo}${"??"}${chartIdBase}`;
51954
+ const figureIdBase = figureId.split(FIGURE_ID_SPLITTER).pop();
51955
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
51956
+ const chartIdBase = chartId.split(FIGURE_ID_SPLITTER).pop();
51957
+ const duplicatedChartId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${chartIdBase}`;
51776
51958
  const definition = chart.duplicateInDuplicatedSheet(cmd.sheetId, cmd.sheetIdTo);
51777
51959
  this.dispatch("CREATE_CHART", {
51778
51960
  figureId: duplicatedFigureId,
@@ -51881,8 +52063,8 @@ set(value) {
51881
52063
  * Add a figure with tag chart with the given id at the given position
51882
52064
  */
51883
52065
  addFigure(figureId, sheetId, col, row, offset, size = {
51884
- width: 536,
51885
- height: 335
52066
+ width: DEFAULT_FIGURE_WIDTH,
52067
+ height: DEFAULT_FIGURE_HEIGHT
51886
52068
  }) {
51887
52069
  this.dispatch("CREATE_FIGURE", {
51888
52070
  sheetId,
@@ -53133,8 +53315,8 @@ set(value) {
53133
53315
  const figureId = figure.id;
53134
53316
  const fig = this.figures[cmd.sheetId]?.[figureId];
53135
53317
  if (!fig) continue;
53136
- const figureIdBase = figureId.split("??").pop();
53137
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
53318
+ const figureIdBase = figureId.split(FIGURE_ID_SPLITTER).pop();
53319
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
53138
53320
  this.dispatch("CREATE_FIGURE", {
53139
53321
  figureId: duplicatedFigureId,
53140
53322
  ...fig,
@@ -53172,11 +53354,11 @@ set(value) {
53172
53354
  const numHeader = this.getters.getNumberRows(sheetId);
53173
53355
  const remainingSize = new Array(numHeader + 1);
53174
53356
  remainingSize[numHeader] = 0;
53175
- for (let i = numHeader - 1; i >= 0; i--) remainingSize[i] = remainingSize[i + 1] + (this.getters.getUserRowSize(sheetId, i) ?? 23);
53357
+ for (let i = numHeader - 1; i >= 0; i--) remainingSize[i] = remainingSize[i + 1] + (this.getters.getUserRowSize(sheetId, i) ?? DEFAULT_CELL_HEIGHT);
53176
53358
  for (const figure of this.getFigures(sheetId)) if (figure.offset.y + figure.height > remainingSize[figure.row]) {
53177
53359
  let y = figure.offset.y;
53178
53360
  let row = figure.row;
53179
- for (let row_size = this.getters.getUserRowSize(sheetId, row) ?? 23; row_size < y; row_size = this.getters.getUserRowSize(sheetId, row) ?? 23) {
53361
+ for (let row_size = this.getters.getUserRowSize(sheetId, row) ?? DEFAULT_CELL_HEIGHT; row_size < y; row_size = this.getters.getUserRowSize(sheetId, row) ?? DEFAULT_CELL_HEIGHT) {
53180
53362
  row += 1;
53181
53363
  y -= row_size;
53182
53364
  }
@@ -53201,7 +53383,7 @@ set(value) {
53201
53383
  let rowNum, colNum;
53202
53384
  let { col, row } = figure;
53203
53385
  const offset = { ...figure.offset };
53204
- for (rowNum = numberOfRows; availableHeight < figure.height && rowNum > 0; rowNum--) availableHeight += this.getters.getUserRowSize(sheetId, rowNum - 1) ?? 23;
53386
+ for (rowNum = numberOfRows; availableHeight < figure.height && rowNum > 0; rowNum--) availableHeight += this.getters.getUserRowSize(sheetId, rowNum - 1) ?? DEFAULT_CELL_HEIGHT;
53205
53387
  if (row > rowNum) {
53206
53388
  row = rowNum;
53207
53389
  offset.y = Math.max(availableHeight - figure.height, 0);
@@ -53682,7 +53864,7 @@ set(value) {
53682
53864
  }
53683
53865
  }
53684
53866
  getColSize(sheetId, index) {
53685
- return Math.round(this.sizes[sheetId]?.["COL"][index] || 96);
53867
+ return Math.round(this.sizes[sheetId]?.["COL"][index] || DEFAULT_CELL_WIDTH);
53686
53868
  }
53687
53869
  getUserRowSize(sheetId, index) {
53688
53870
  const rowSize = this.sizes[sheetId]?.["ROW"][index];
@@ -53715,7 +53897,7 @@ set(value) {
53715
53897
  if (sheet.rows === void 0) sheet.rows = {};
53716
53898
  for (const row of range(0, this.getters.getNumberRows(sheet.id))) if (exportDefaults || this.sizes[sheet.id]["ROW"][row]) sheet.rows[row] = {
53717
53899
  ...sheet.rows[row],
53718
- size: this.getUserRowSize(sheet.id, row) ?? 23
53900
+ size: this.getUserRowSize(sheet.id, row) ?? DEFAULT_CELL_HEIGHT
53719
53901
  };
53720
53902
  if (sheet.cols === void 0) sheet.cols = {};
53721
53903
  for (const col of range(0, this.getters.getNumberCols(sheet.id))) if (exportDefaults || this.sizes[sheet.id]["COL"][col]) sheet.cols[col] = {
@@ -53896,8 +54078,8 @@ set(value) {
53896
54078
  case "DUPLICATE_SHEET": {
53897
54079
  const sheetFiguresFrom = this.getters.getFigures(cmd.sheetId);
53898
54080
  for (const fig of sheetFiguresFrom) if (fig.tag === "image") {
53899
- const figureIdBase = fig.id.split("??").pop();
53900
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
54081
+ const figureIdBase = fig.id.split(FIGURE_ID_SPLITTER).pop();
54082
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
53901
54083
  const image = this.getImage(fig.id);
53902
54084
  if (image) {
53903
54085
  const size = {
@@ -57594,8 +57776,8 @@ set(value) {
57594
57776
  hoverSvg,
57595
57777
  priority: 2,
57596
57778
  horizontalAlign: "center",
57597
- size: 17,
57598
- margin: 2,
57779
+ size: GRID_ICON_EDGE_LENGTH,
57780
+ margin: GRID_ICON_MARGIN,
57599
57781
  position,
57600
57782
  type: "data_validation_checkbox",
57601
57783
  onClick: (position, env) => {
@@ -57642,7 +57824,7 @@ set(value) {
57642
57824
  priority: 1,
57643
57825
  horizontalAlign: "left",
57644
57826
  size: computeTextFontSizeInPixels(style),
57645
- margin: 4,
57827
+ margin: MIN_CF_ICON_MARGIN,
57646
57828
  position
57647
57829
  };
57648
57830
  }
@@ -57657,13 +57839,13 @@ set(value) {
57657
57839
  const fields = pivotCell.dimension === "COL" ? definition.columns : definition.rows;
57658
57840
  const hasIcon = !isDashboard && !getters.shouldShowFormulas() && pivotCell.domain.length !== fields.length;
57659
57841
  const isCollapsed = (definition.collapsedDomains?.[pivotCell.dimension] ?? []).some((domain) => deepEquals(domain, pivotCell.domain));
57660
- const indent = pivotCell.dimension === "ROW" ? (pivotCell.domain.length - 1) * 15 : 0;
57842
+ const indent = pivotCell.dimension === "ROW" ? (pivotCell.domain.length - 1) * PIVOT_INDENT : 0;
57661
57843
  return {
57662
57844
  type: "pivot_collapse",
57663
57845
  priority: 4,
57664
57846
  horizontalAlign: "left",
57665
- size: hasIcon || !isDashboard && pivotCell.dimension === "ROW" && definition.rows.length > 1 ? 12 : 0,
57666
- margin: hasIcon ? 2 * 2 + indent : indent,
57847
+ size: hasIcon || !isDashboard && pivotCell.dimension === "ROW" && definition.rows.length > 1 ? PIVOT_COLLAPSE_ICON_SIZE : 0,
57848
+ margin: hasIcon ? GRID_ICON_MARGIN * 2 + indent : indent,
57667
57849
  svg: hasIcon ? getPivotIconSvg(isCollapsed, false) : void 0,
57668
57850
  hoverSvg: hasIcon ? getPivotIconSvg(isCollapsed, true) : void 0,
57669
57851
  position,
@@ -58640,7 +58822,7 @@ set(value) {
58640
58822
  return this.getDataValidationStyle(position);
58641
58823
  }
58642
58824
  getDataValidationChipStyle(position) {
58643
- if (this.hasChip(position)) return this.getDataValidationStyle(position) ?? { fillColor: "#E7E9ED" };
58825
+ if (this.hasChip(position)) return this.getDataValidationStyle(position) ?? { fillColor: GRAY_200 };
58644
58826
  }
58645
58827
  getInvalidDataValidationMessage(cellPosition) {
58646
58828
  const validationResult = this.getValidationResultForCell(cellPosition);
@@ -58869,7 +59051,7 @@ set(value) {
58869
59051
  }
58870
59052
  }
58871
59053
  getRowSize(sheetId, row) {
58872
- return Math.round(this.getters.getUserRowSize(sheetId, row) ?? this.tallestCellInRow[sheetId][row]?.size ?? 23);
59054
+ return Math.round(this.getters.getUserRowSize(sheetId, row) ?? this.tallestCellInRow[sheetId][row]?.size ?? DEFAULT_CELL_HEIGHT);
58873
59055
  }
58874
59056
  getMaxAnchorOffset(sheetId, height, width) {
58875
59057
  let { numberOfRows: row, numberOfCols: col } = this.getters.getSheetSize(sheetId);
@@ -58906,8 +59088,8 @@ set(value) {
58906
59088
  col,
58907
59089
  row
58908
59090
  });
58909
- if (updatedCellHeight <= 23) return;
58910
- if (!tallestCellInRow && updatedCellHeight > 23 || tallestCellInRow && updatedCellHeight > tallestCellInRow.size) {
59091
+ if (updatedCellHeight <= DEFAULT_CELL_HEIGHT) return;
59092
+ if (!tallestCellInRow && updatedCellHeight > DEFAULT_CELL_HEIGHT || tallestCellInRow && updatedCellHeight > tallestCellInRow.size) {
58911
59093
  const newTallestCell = {
58912
59094
  cell: {
58913
59095
  sheetId,
@@ -58932,7 +59114,7 @@ set(value) {
58932
59114
  * merge, or the height of the cell computed based on its style/content.
58933
59115
  */
58934
59116
  getCellHeight(position) {
58935
- if (this.isInMultiRowMerge(position)) return 23;
59117
+ if (this.isInMultiRowMerge(position)) return DEFAULT_CELL_HEIGHT;
58936
59118
  const cell = this.getters.getCell(position);
58937
59119
  const colSize = this.getters.getColSize(position.sheetId, position.col);
58938
59120
  return getDefaultCellHeight(this.ctx, cell, this.getters.getLocale(), colSize);
@@ -58954,7 +59136,7 @@ set(value) {
58954
59136
  if (!cell) continue;
58955
59137
  const position = this.getters.getCellPosition(cell.id);
58956
59138
  const cellHeight = this.getCellHeight(position);
58957
- if (cellHeight > maxHeight && cellHeight > 23) {
59139
+ if (cellHeight > maxHeight && cellHeight > DEFAULT_CELL_HEIGHT) {
58958
59140
  maxHeight = cellHeight;
58959
59141
  tallestCell = {
58960
59142
  cell: position,
@@ -58962,7 +59144,7 @@ set(value) {
58962
59144
  };
58963
59145
  }
58964
59146
  }
58965
- if (tallestCell && tallestCell.size > 23) return tallestCell;
59147
+ if (tallestCell && tallestCell.size > DEFAULT_CELL_HEIGHT) return tallestCell;
58966
59148
  }
58967
59149
  };
58968
59150
 
@@ -59406,14 +59588,14 @@ set(value) {
59406
59588
  * @returns the value of the cell in the pivot with the new domain, or "sameValue" if the domain is the same
59407
59589
  */
59408
59590
  getComparisonValue(measure, domain, fieldNameWithGranularity, valueToCompare) {
59409
- const comparedDomain = valueToCompare === "(previous)" || valueToCompare === "(next)" ? getPreviousOrNextValueDomain(this, domain, fieldNameWithGranularity, valueToCompare) : replaceFieldValueInDomain(domain, fieldNameWithGranularity, valueToCompare);
59591
+ const comparedDomain = valueToCompare === PREVIOUS_VALUE || valueToCompare === NEXT_VALUE ? getPreviousOrNextValueDomain(this, domain, fieldNameWithGranularity, valueToCompare) : replaceFieldValueInDomain(domain, fieldNameWithGranularity, valueToCompare);
59410
59592
  if (deepEquals(comparedDomain, domain)) return "sameValue";
59411
59593
  if (!comparedDomain || !isDomainIsInPivot(this, comparedDomain)) throw new NotAvailableError();
59412
59594
  const comparedValue = this._getPivotCellValueAndFormat(measure.id, comparedDomain);
59413
59595
  return this.strictMeasureValueToNumber(comparedValue);
59414
59596
  }
59415
59597
  getPivotValueCells(measureId) {
59416
- return this.getCollapsedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
59598
+ return this.getExpandedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
59417
59599
  }
59418
59600
  measureValueToNumber(result) {
59419
59601
  if (typeof result.value === "number") return result.value;
@@ -61923,7 +62105,7 @@ set(value) {
61923
62105
  this.trigger("new-local-state-update", { id: revision.id });
61924
62106
  this.sendUpdateMessage({
61925
62107
  type: "REMOTE_REVISION",
61926
- version: 1,
62108
+ version: MESSAGE_VERSION,
61927
62109
  serverRevisionId: this.serverRevisionId,
61928
62110
  nextRevisionId: revision.id,
61929
62111
  clientId: revision.clientId,
@@ -61934,7 +62116,7 @@ set(value) {
61934
62116
  this.waitingUndoRedoAck = true;
61935
62117
  this.sendUpdateMessage({
61936
62118
  type: "REVISION_UNDONE",
61937
- version: 1,
62119
+ version: MESSAGE_VERSION,
61938
62120
  serverRevisionId: this.serverRevisionId,
61939
62121
  nextRevisionId: UuidGenerator.uuidv4(),
61940
62122
  undoneRevisionId: revisionId
@@ -61944,7 +62126,7 @@ set(value) {
61944
62126
  this.waitingUndoRedoAck = true;
61945
62127
  this.sendUpdateMessage({
61946
62128
  type: "REVISION_REDONE",
61947
- version: 1,
62129
+ version: MESSAGE_VERSION,
61948
62130
  serverRevisionId: this.serverRevisionId,
61949
62131
  nextRevisionId: UuidGenerator.uuidv4(),
61950
62132
  redoneRevisionId: revisionId
@@ -61985,7 +62167,7 @@ set(value) {
61985
62167
  await this.sendToTransport({
61986
62168
  type: "CLIENT_LEFT",
61987
62169
  clientId: this.clientId,
61988
- version: 1
62170
+ version: MESSAGE_VERSION
61989
62171
  });
61990
62172
  }
61991
62173
  /**
@@ -62002,7 +62184,7 @@ set(value) {
62002
62184
  ...data,
62003
62185
  revisionId: snapshotId
62004
62186
  },
62005
- version: 1
62187
+ version: MESSAGE_VERSION
62006
62188
  });
62007
62189
  }
62008
62190
  getCurrentClient() {
@@ -62046,7 +62228,7 @@ set(value) {
62046
62228
  };
62047
62229
  this.sendToTransport({
62048
62230
  type,
62049
- version: 1,
62231
+ version: MESSAGE_VERSION,
62050
62232
  client: {
62051
62233
  ...client,
62052
62234
  position
@@ -62126,7 +62308,7 @@ set(value) {
62126
62308
  const { position } = client;
62127
62309
  if (position) this.sendToTransport({
62128
62310
  type: "CLIENT_MOVED",
62129
- version: 1,
62311
+ version: MESSAGE_VERSION,
62130
62312
  client: {
62131
62313
  ...client,
62132
62314
  position
@@ -63484,7 +63666,7 @@ set(value) {
63484
63666
  onNewLocalStateUpdate({ id }) {
63485
63667
  this.undoStack.push(id);
63486
63668
  this.redoStack = [];
63487
- if (this.undoStack.length > 99) this.undoStack.shift();
63669
+ if (this.undoStack.length > MAX_HISTORY_STEPS) this.undoStack.shift();
63488
63670
  }
63489
63671
  /**
63490
63672
  * Fetch the last revision which is not empty and not a repeated command
@@ -63780,7 +63962,7 @@ set(value) {
63780
63962
  }
63781
63963
  getAutoSeparatorForString(str) {
63782
63964
  const separators = [
63783
- "\n",
63965
+ NEWLINE,
63784
63966
  ";",
63785
63967
  ",",
63786
63968
  " ",
@@ -64139,9 +64321,9 @@ set(value) {
64139
64321
  contentWidth += computeMultilineTextSize(this.ctx, multiLineText, style).width;
64140
64322
  }
64141
64323
  for (const icon of this.getters.getCellIcons(position)) contentWidth += icon.margin + icon.size;
64142
- if (this.getters.getDataValidationChipStyle(position)) contentWidth += 5 * 2;
64324
+ if (this.getters.getDataValidationChipStyle(position)) contentWidth += DATA_VALIDATION_CHIP_MARGIN * 2;
64143
64325
  if (contentWidth === 0) return 0;
64144
- contentWidth += 2 * 4;
64326
+ contentWidth += 2 * PADDING_AUTORESIZE_HORIZONTAL;
64145
64327
  if (style.wrapping === "wrap") {
64146
64328
  const colWidth = this.getters.getColSize(position.sheetId, position.col);
64147
64329
  return Math.min(colWidth, contentWidth);
@@ -64192,11 +64374,11 @@ set(value) {
64192
64374
  computeTextYCoordinate(cellRect, textLineHeight, verticalAlign = DEFAULT_VERTICAL_ALIGN, numberOfLines = 1) {
64193
64375
  const y = cellRect.y + 1;
64194
64376
  const textHeight = computeTextLinesHeight(textLineHeight, numberOfLines);
64195
- if (cellRect.height > textHeight + 4 * 2) {
64377
+ if (cellRect.height > textHeight + MIN_CELL_TEXT_MARGIN * 2) {
64196
64378
  if (verticalAlign === "middle") return Math.ceil(y + (cellRect.height - textHeight) / 2);
64197
- if (verticalAlign === "bottom") return y + cellRect.height - textHeight - 4;
64379
+ if (verticalAlign === "bottom") return y + cellRect.height - textHeight - MIN_CELL_TEXT_MARGIN;
64198
64380
  }
64199
- return y + 4;
64381
+ return y + MIN_CELL_TEXT_MARGIN;
64200
64382
  }
64201
64383
  /**
64202
64384
  * Expands the given zone until bordered by empty cells or reached the sheet boundaries.
@@ -64301,11 +64483,11 @@ set(value) {
64301
64483
  if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
64302
64484
  const content = this.getters.getEvaluatedCell(position).formattedValue;
64303
64485
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
64304
- if (evaluatedSize > evaluatedRowSize && evaluatedSize > 23) evaluatedRowSize = evaluatedSize;
64486
+ if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) evaluatedRowSize = evaluatedSize;
64305
64487
  } else {
64306
64488
  const content = cell.content;
64307
64489
  const dynamicRowSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
64308
- if (dynamicRowSize >= evaluatedRowSize && dynamicRowSize > 23) evaluatedRowSize = 0;
64490
+ if (dynamicRowSize >= evaluatedRowSize && dynamicRowSize > DEFAULT_CELL_HEIGHT) evaluatedRowSize = 0;
64309
64491
  }
64310
64492
  }
64311
64493
  rowSizes.push(evaluatedRowSize || null);
@@ -65006,7 +65188,7 @@ set(value) {
65006
65188
  const imageUrl = this.getters.getImage(figureId).path;
65007
65189
  file = await this.fileStore?.getFile(imageUrl);
65008
65190
  if (file.type !== "image/png") {
65009
- if (file.size > 5242880) {
65191
+ if (file.size > MAX_FILE_SIZE) {
65010
65192
  this.ui.notifyUI({
65011
65193
  text: _t("The file you are trying to copy is too large (>%sMB).\nIt will not be added to your OS clipboard.\nYou can download it directly instead.", Math.round(MAX_FILE_SIZE / (1024 * 1024))),
65012
65194
  sticky: false,
@@ -66179,7 +66361,7 @@ set(value) {
66179
66361
  let height = lastRowEnd - this.offsetCorrectionY;
66180
66362
  if (this.canScrollVertically) {
66181
66363
  height = Math.max(height, this.viewportHeight);
66182
- if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
66364
+ if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly() && this.viewportHeight > FOOTER_HEIGHT) height += FOOTER_HEIGHT;
66183
66365
  }
66184
66366
  return {
66185
66367
  width,
@@ -66531,7 +66713,7 @@ set(value) {
66531
66713
  return this.getSubViewports(sheetId).some((pane) => pane.isZoneVisible(zone));
66532
66714
  }
66533
66715
  getScrollBarWidth() {
66534
- return 15 / this.zoomLevel;
66716
+ return SCROLLBAR_WIDTH / this.zoomLevel;
66535
66717
  }
66536
66718
  getEdgeScrollCol(sheetId, x, previousX, startingX) {
66537
66719
  let canEdgeScroll = false;
@@ -67058,7 +67240,7 @@ set(value) {
67058
67240
  return this.chainValidations(() => this.viewports.checkScrollingDirection(sheetId, cmd), () => this.viewports.checkIfViewportsWillChange(sheetId, cmd))(cmd);
67059
67241
  }
67060
67242
  case "RESIZE_SHEETVIEW": return this.chainValidations(() => this.viewports.checkValuesAreDifferent(cmd), () => this.viewports.checkPositiveDimension(cmd))(cmd);
67061
- case "SET_ZOOM": if (cmd.zoom > 2 || cmd.zoom < .5) return "InvalidZoomLevel";
67243
+ case "SET_ZOOM": if (isNaN(cmd.zoom) || cmd.zoom > MAX_ZOOM_LEVEL || cmd.zoom < MIN_ZOOM_LEVEL) return "InvalidZoomLevel";
67062
67244
  else return "Success";
67063
67245
  default: return "Success";
67064
67246
  }
@@ -67262,7 +67444,7 @@ set(value) {
67262
67444
  return this.viewports.isVisibleInViewport(cellPosition);
67263
67445
  }
67264
67446
  getScrollBarWidth() {
67265
- return 15 / this.viewports.getZoomLevel();
67447
+ return SCROLLBAR_WIDTH / this.viewports.getZoomLevel();
67266
67448
  }
67267
67449
  getEdgeScrollCol(x, previousX, startingX) {
67268
67450
  const sheetId = this.getters.getActiveSheetId();
@@ -69509,16 +69691,16 @@ set(value) {
69509
69691
  const startCoordinates = this.env.model.getters.getRowDimensions(sheetId, startRow).start;
69510
69692
  const endCoordinates = this.env.model.getters.getRowDimensions(sheetId, endRow).end;
69511
69693
  let groupHeaderY = 0;
69512
- let groupHeaderHeight = 26;
69694
+ let groupHeaderHeight = HEADER_HEIGHT;
69513
69695
  if (startRow !== 0) {
69514
69696
  const headerRowDims = this.env.model.getters.getRowDimensions(sheetId, startRow - 1);
69515
- groupHeaderY = 26 + headerRowDims.start;
69697
+ groupHeaderY = HEADER_HEIGHT + headerRowDims.start;
69516
69698
  groupHeaderHeight = headerRowDims.end - headerRowDims.start;
69517
69699
  }
69518
69700
  const headerRect = {
69519
69701
  x: this.props.layerOffset,
69520
69702
  y: groupHeaderY,
69521
- width: 21,
69703
+ width: GROUP_LAYER_WIDTH,
69522
69704
  height: groupHeaderHeight
69523
69705
  };
69524
69706
  return {
@@ -69526,7 +69708,7 @@ set(value) {
69526
69708
  groupRect: {
69527
69709
  x: this.props.layerOffset,
69528
69710
  y: headerRect.y,
69529
- width: 21,
69711
+ width: GROUP_LAYER_WIDTH,
69530
69712
  height: headerRect.height + (endCoordinates - startCoordinates)
69531
69713
  },
69532
69714
  isEndHidden: this.env.model.getters.isRowHidden(sheetId, endRow)
@@ -69559,17 +69741,17 @@ set(value) {
69559
69741
  const startCoordinates = this.env.model.getters.getColDimensions(sheetId, startCol).start;
69560
69742
  const endCoordinates = this.env.model.getters.getColDimensions(sheetId, endCol).end;
69561
69743
  let groupHeaderX = 0;
69562
- let groupHeaderWidth = 48;
69744
+ let groupHeaderWidth = HEADER_WIDTH;
69563
69745
  if (startCol !== 0) {
69564
69746
  const headerRowDims = this.env.model.getters.getColDimensions(sheetId, startCol - 1);
69565
- groupHeaderX = 48 + headerRowDims.start;
69747
+ groupHeaderX = HEADER_WIDTH + headerRowDims.start;
69566
69748
  groupHeaderWidth = headerRowDims.end - headerRowDims.start;
69567
69749
  }
69568
69750
  const headerRect = {
69569
69751
  x: groupHeaderX,
69570
69752
  y: this.props.layerOffset,
69571
69753
  width: groupHeaderWidth,
69572
- height: 21
69754
+ height: GROUP_LAYER_WIDTH
69573
69755
  };
69574
69756
  return {
69575
69757
  headerRect,
@@ -69577,7 +69759,7 @@ set(value) {
69577
69759
  x: headerRect.x,
69578
69760
  y: this.props.layerOffset,
69579
69761
  width: headerRect.width + (endCoordinates - startCoordinates),
69580
- height: 21
69762
+ height: GROUP_LAYER_WIDTH
69581
69763
  },
69582
69764
  isEndHidden: this.env.model.getters.isColHidden(sheetId, endCol)
69583
69765
  };
@@ -69603,7 +69785,7 @@ set(value) {
69603
69785
  menuItems: []
69604
69786
  });
69605
69787
  getLayerOffset(layerIndex) {
69606
- return layerIndex * 21;
69788
+ return layerIndex * GROUP_LAYER_WIDTH;
69607
69789
  }
69608
69790
  onContextMenu(event) {
69609
69791
  const sheetId = this.env.model.getters.getActiveSheetId();
@@ -69651,8 +69833,8 @@ set(value) {
69651
69833
  get frozenPaneContainerSize() {
69652
69834
  if (!this.hasFrozenPane) return 0;
69653
69835
  const viewportCoordinates = this.env.model.getters.getMainViewportCoordinates();
69654
- if (this.props.dimension === "COL") return 48 + viewportCoordinates.x;
69655
- else return 26 + viewportCoordinates.y;
69836
+ if (this.props.dimension === "COL") return HEADER_WIDTH + viewportCoordinates.x;
69837
+ else return HEADER_HEIGHT + viewportCoordinates.y;
69656
69838
  }
69657
69839
  };
69658
69840
 
@@ -69661,7 +69843,7 @@ set(value) {
69661
69843
  function useScreenWidth() {
69662
69844
  const spreadsheetRect = useSpreadsheetRect();
69663
69845
  return { get isSmall() {
69664
- return spreadsheetRect.width < 768;
69846
+ return spreadsheetRect.width < MOBILE_WIDTH_BREAKPOINT;
69665
69847
  } };
69666
69848
  }
69667
69849
 
@@ -70452,7 +70634,7 @@ set(value) {
70452
70634
  "line-height": "24px"
70453
70635
  };
70454
70636
  if (this.env.model.getters.isCurrentSheetLocked()) style["pointer-events"] = "none";
70455
- style.height = this.focus === "inactive" ? `${34}px` : "fit-content";
70637
+ style.height = this.focus === "inactive" ? `${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px` : "fit-content";
70456
70638
  return cssPropertiesToCss(style);
70457
70639
  }
70458
70640
  onFocus(selection) {
@@ -71106,14 +71288,17 @@ set(value) {
71106
71288
  props = (0, _odoo_owl.useProps)({ class: types.string() });
71107
71289
  topBarToolStore;
71108
71290
  valueList = ZOOM_VALUES;
71291
+ minZoom = MIN_ZOOM_LEVEL * 100;
71292
+ maxZoom = MAX_ZOOM_LEVEL * 100;
71109
71293
  setup() {
71110
71294
  this.topBarToolStore = useToolBarDropdownStore();
71111
71295
  }
71112
- get currentFontSize() {
71113
- return (this.env.model.getters.getViewportZoomLevel() || 1) * 100;
71296
+ getZoomLevel() {
71297
+ const zoom = this.env.model.getters.getViewportZoomLevel() || 1;
71298
+ return Math.round(zoom * 100);
71114
71299
  }
71115
- setZoom(fontSize) {
71116
- this.env.model.dispatch("SET_ZOOM", { zoom: fontSize / 100 });
71300
+ setZoom(zoomPercentage) {
71301
+ this.env.model.dispatch("SET_ZOOM", { zoom: zoomPercentage / 100 });
71117
71302
  }
71118
71303
  toggle() {
71119
71304
  if (this.topBarToolStore.isActive) this.topBarToolStore.closeDropdowns();
@@ -71647,7 +71832,7 @@ set(value) {
71647
71832
  else {
71648
71833
  if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
71649
71834
  else properties["grid-template-rows"] = `min-content auto min-content`;
71650
- properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || 350}px` : "auto"}`;
71835
+ properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || DEFAULT_SIDE_PANEL_SIZE}px` : "auto"}`;
71651
71836
  }
71652
71837
  return cssPropertiesToCss(properties);
71653
71838
  }
@@ -71753,7 +71938,7 @@ set(value) {
71753
71938
  checkViewportSize() {
71754
71939
  const { xRatio, yRatio } = this.env.model.getters.getFrozenSheetViewRatio(this.env.model.getters.getActiveSheetId());
71755
71940
  if (!isFinite(xRatio) || !isFinite(yRatio)) return;
71756
- if (yRatio > .85 || xRatio > .85) {
71941
+ if (yRatio > MAXIMAL_FREEZABLE_RATIO || xRatio > MAXIMAL_FREEZABLE_RATIO) {
71757
71942
  if (this.isViewportTooSmall) return;
71758
71943
  this.notificationStore.notifyUser({
71759
71944
  text: _t("The current window is too small to display this sheet properly. Consider resizing your browser window or adjusting frozen rows and columns."),
@@ -71771,8 +71956,8 @@ set(value) {
71771
71956
  return this.env.model.getters.getSheetViewDimension().height;
71772
71957
  }
71773
71958
  get gridContainerStyle() {
71774
- const gridColSize = 21 * this.rowLayers.length;
71775
- const gridRowSize = 21 * this.colLayers.length;
71959
+ const gridColSize = GROUP_LAYER_WIDTH * this.rowLayers.length;
71960
+ const gridRowSize = GROUP_LAYER_WIDTH * this.colLayers.length;
71776
71961
  const zoom = this.env.model.getters.getViewportZoomLevel();
71777
71962
  return cssPropertiesToCss({
71778
71963
  "grid-template-columns": `${gridColSize ? gridColSize + 2 : 0}px auto`,
@@ -73728,7 +73913,7 @@ set(value) {
73728
73913
  let title = escapeXml``;
73729
73914
  if (chart.data.title?.text) {
73730
73915
  const titleColor = chart.data.title.color ? toXlsxHexColor(chart.data.title.color) : toXlsxHexColor(chartMutedFontColor(chart.data.backgroundColor));
73731
- const fontSize = chart.data.title.fontSize ?? 16;
73916
+ const fontSize = chart.data.title.fontSize ?? CHART_TITLE_FONT_SIZE;
73732
73917
  title = escapeXml`
73733
73918
  <c:title>
73734
73919
  ${insertText(chart.data.title.text, titleColor, fontSize, chart.data.title)}
@@ -73819,7 +74004,7 @@ set(value) {
73819
74004
  </a:ln>
73820
74005
  `;
73821
74006
  }
73822
- function insertText(text, fontColor = "000000", fontsize = 16, style = {}) {
74007
+ function insertText(text, fontColor = "000000", fontsize = CHART_TITLE_FONT_SIZE, style = {}) {
73823
74008
  return escapeXml`
73824
74009
  <c:tx>
73825
74010
  <c:rich>
@@ -74400,7 +74585,7 @@ set(value) {
74400
74585
  return escapeXml`
74401
74586
  <c:doughnutChart>
74402
74587
  <c:varyColors val="1" />
74403
- <c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? 50 : 0)}" />
74588
+ <c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
74404
74589
  ${joinXmlNodes(dataSetsNodes)}
74405
74590
  ${insertDataLabels({ showValues: chart.showValues })}
74406
74591
  </c:doughnutChart>
@@ -74424,7 +74609,7 @@ set(value) {
74424
74609
  }
74425
74610
  function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
74426
74611
  const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
74427
- const fontSize = title?.fontSize ?? 12;
74612
+ const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
74428
74613
  const crossBetweenEl = axisName === "c:valAx" ? escapeXml`<c:crossBetween val="between" />` : "";
74429
74614
  const maxValueEl = maxValue ? escapeXml`<c:max val="${maxValue}" />` : "";
74430
74615
  const minValueEl = maxValue ? escapeXml`<c:min val="${-maxValue}" />` : "";
@@ -75052,12 +75237,12 @@ set(value) {
75052
75237
  let currentPosition = 0;
75053
75238
  for (const [headerIndex, header] of headers.slice(anchor).entries()) if (currentPosition <= offset && offset < currentPosition + header.size) return {
75054
75239
  index: anchor + headerIndex,
75055
- offset: convertDotValueToEMU(offset - currentPosition + 1)
75240
+ offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH)
75056
75241
  };
75057
75242
  else if (headerIndex < headers.length - 1) currentPosition += header.size;
75058
75243
  return {
75059
75244
  index: headers.length - 1,
75060
- offset: convertDotValueToEMU(offset - currentPosition + 1)
75245
+ offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH)
75061
75246
  };
75062
75247
  }
75063
75248
  function createChartDrawing(figure, sheet, chartRelId, construct) {
@@ -75163,7 +75348,7 @@ set(value) {
75163
75348
  function addNumberFormats(numFmts) {
75164
75349
  const numFmtNodes = [];
75165
75350
  for (const [index, numFmt] of Object.entries(numFmts)) {
75166
- const numFmtAttrs = [["numFmtId", parseInt(index) + 164], ["formatCode", numFmt.format]];
75351
+ const numFmtAttrs = [["numFmtId", parseInt(index) + FIRST_NUMFMT_ID], ["formatCode", numFmt.format]];
75167
75352
  numFmtNodes.push(escapeXml`
75168
75353
  <numFmt ${formatAttributes(numFmtAttrs)}/>
75169
75354
  `);
@@ -75399,7 +75584,7 @@ set(value) {
75399
75584
  const attributes = [
75400
75585
  ["min", parseInt(id) + 1],
75401
75586
  ["max", parseInt(id) + 1],
75402
- ["width", convertWidthToExcel(col.size || 96)],
75587
+ ["width", convertWidthToExcel(col.size || DEFAULT_CELL_WIDTH)],
75403
75588
  ["customWidth", 1],
75404
75589
  ["hidden", col.isHidden ? 1 : 0]
75405
75590
  ];
@@ -75425,7 +75610,7 @@ set(value) {
75425
75610
  for (let r = 0; r < sheet.rowNumber; r++) {
75426
75611
  const rowAttrs = [["r", r + 1]];
75427
75612
  const row = sheet.rows[r] || {};
75428
- if (row.size && row.size !== 23) rowAttrs.push(["ht", convertHeightToExcel(row.size)], ["customHeight", 1]);
75613
+ if (row.size && row.size !== DEFAULT_CELL_HEIGHT) rowAttrs.push(["ht", convertHeightToExcel(row.size)], ["customHeight", 1]);
75429
75614
  if (row.isHidden) rowAttrs.push(["hidden", 1]);
75430
75615
  if (row.outlineLevel) rowAttrs.push(["outlineLevel", row.outlineLevel]);
75431
75616
  if (row.collapsed) rowAttrs.push(["collapsed", 1]);
@@ -75476,7 +75661,7 @@ set(value) {
75476
75661
  </c>`);
75477
75662
  }
75478
75663
  }
75479
- if (cellNodes.length || row.size !== 23 || row.isHidden || row.outlineLevel || row.collapsed || rowStyle || rowFormat) rowNodes.push(escapeXml`
75664
+ if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden || row.outlineLevel || row.collapsed || rowStyle || rowFormat) rowNodes.push(escapeXml`
75480
75665
  <row ${formatAttributes(rowAttrs)}>
75481
75666
  ${joinXmlNodes(cellNodes)}
75482
75667
  </row>
@@ -75666,7 +75851,7 @@ set(value) {
75666
75851
  let currentTableIndex = 1;
75667
75852
  for (const [sheetIndex, sheet] of Object.entries(data.sheets)) {
75668
75853
  const namespaces = [["xmlns", NAMESPACE["worksheet"]], ["xmlns:r", RELATIONSHIP_NSR]];
75669
- const sheetFormatAttributes = [["defaultRowHeight", convertHeightToExcel(23)], ["defaultColWidth", convertWidthToExcel(96)]];
75854
+ const sheetFormatAttributes = [["defaultRowHeight", convertHeightToExcel(DEFAULT_CELL_HEIGHT)], ["defaultColWidth", convertWidthToExcel(DEFAULT_CELL_WIDTH)]];
75670
75855
  const tablesNode = createTablesForSheet(sheet, sheetIndex, currentTableIndex, construct, files);
75671
75856
  currentTableIndex += sheet.tables.length;
75672
75857
  let drawingNode = escapeXml``;
@@ -76368,7 +76553,7 @@ set(value) {
76368
76553
  _exportData(shouldSquish) {
76369
76554
  let data = createEmptyWorkbookData();
76370
76555
  for (const handler of this.handlers) if (handler instanceof CorePlugin) handler.export(data, shouldSquish);
76371
- data.revisionId = this.session.getRevisionId() || "START_REVISION";
76556
+ data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
76372
76557
  data = deepCopy(data);
76373
76558
  return data;
76374
76559
  }
@@ -77768,7 +77953,7 @@ set(value) {
77768
77953
  col,
77769
77954
  row
77770
77955
  });
77771
- const textColor = style?.textColor === "#017E84" ? void 0 : style?.textColor;
77956
+ const textColor = style?.textColor === LINK_COLOR ? void 0 : style?.textColor;
77772
77957
  this.env.model.dispatch("UPDATE_CELL", {
77773
77958
  col,
77774
77959
  row,
@@ -78282,8 +78467,8 @@ set(value) {
78282
78467
  text: value.value,
78283
78468
  htmlContent: [{
78284
78469
  value: value.label,
78285
- color: chipTextColor(color || "#E7E9ED"),
78286
- backgroundColor: color || "#E7E9ED",
78470
+ color: chipTextColor(color || GRAY_200),
78471
+ backgroundColor: color || GRAY_200,
78287
78472
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"]
78288
78473
  }],
78289
78474
  fuzzySearchKey: value.label
@@ -78826,7 +79011,7 @@ set(value) {
78826
79011
  legend: getBubbleChartLegend(definition, chartData),
78827
79012
  tooltip: getBubbleChartTooltip(definition, chartData),
78828
79013
  chartShowValuesPlugin: getChartShowValues(definition, chartData),
78829
- background: { color: definition.background }
79014
+ background: { color: chartData.background }
78830
79015
  }
78831
79016
  }
78832
79017
  } };
@@ -78937,7 +79122,7 @@ set(value) {
78937
79122
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
78938
79123
  return {
78939
79124
  ...definition,
78940
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79125
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
78941
79126
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
78942
79127
  dataSets,
78943
79128
  labelRange,
@@ -79182,7 +79367,7 @@ set(value) {
79182
79367
  return {
79183
79368
  ...definition,
79184
79369
  horizontal: true,
79185
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79370
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79186
79371
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79187
79372
  dataSets,
79188
79373
  labelRange,
@@ -79266,7 +79451,7 @@ set(value) {
79266
79451
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
79267
79452
  return {
79268
79453
  ...definition,
79269
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79454
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79270
79455
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79271
79456
  dataSets,
79272
79457
  labelRange
@@ -79345,7 +79530,7 @@ set(value) {
79345
79530
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
79346
79531
  return {
79347
79532
  ...definition,
79348
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79533
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79349
79534
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79350
79535
  dataSets,
79351
79536
  labelRange,
@@ -79752,8 +79937,8 @@ set(value) {
79752
79937
  hoverSvg: getDataFilterIcon(isFilterActive, isHighContrast, true),
79753
79938
  priority: 3,
79754
79939
  horizontalAlign: "right",
79755
- size: 17,
79756
- margin: 2,
79940
+ size: GRID_ICON_EDGE_LENGTH,
79941
+ margin: GRID_ICON_MARGIN,
79757
79942
  position,
79758
79943
  onClick: (position, env) => {
79759
79944
  const cellPopovers = env.getStore(CellPopoverStore);
@@ -85785,7 +85970,7 @@ set(value) {
85785
85970
  const error = pivot.assertIsValid({ throwOnError: false });
85786
85971
  if (error) return error;
85787
85972
  const table = pivot.getCollapsedTableStructure();
85788
- if (table.numberOfCells > 5e5) return new EvaluationError(getPivotTooBigErrorMessage(table.numberOfCells, this.locale));
85973
+ if (table.numberOfCells > PIVOT_MAX_NUMBER_OF_CELLS) return new EvaluationError(getPivotTooBigErrorMessage(table.numberOfCells, this.locale));
85789
85974
  const cells = table.getPivotCells(pivotStyle);
85790
85975
  const pivotTitle = this.getters.getPivotName(pivotId);
85791
85976
  const { numberOfCols, numberOfRows } = table.getPivotTableDimensions(pivotStyle);
@@ -87483,14 +87668,14 @@ set(value) {
87483
87668
  */
87484
87669
  const __info__ = {};
87485
87670
  const SPREADSHEET_DIMENSIONS = {
87486
- MIN_ROW_HEIGHT: 10,
87487
- MIN_COL_WIDTH: 5,
87488
- HEADER_HEIGHT: 26,
87489
- HEADER_WIDTH: 48,
87490
- DESKTOP_BOTTOMBAR_HEIGHT: 36,
87491
- DEFAULT_CELL_WIDTH: 96,
87492
- DEFAULT_CELL_HEIGHT: 23,
87493
- SCROLLBAR_WIDTH: 15
87671
+ MIN_ROW_HEIGHT,
87672
+ MIN_COL_WIDTH,
87673
+ HEADER_HEIGHT,
87674
+ HEADER_WIDTH,
87675
+ DESKTOP_BOTTOMBAR_HEIGHT,
87676
+ DEFAULT_CELL_WIDTH,
87677
+ DEFAULT_CELL_HEIGHT,
87678
+ SCROLLBAR_WIDTH
87494
87679
  };
87495
87680
  const registries = {
87496
87681
  autoCompleteProviders,
@@ -87730,9 +87915,9 @@ set(value) {
87730
87915
  PIVOT_STATIC_TABLE_CONFIG,
87731
87916
  PIVOT_INSERT_TABLE_STYLE_ID,
87732
87917
  ChartTerms,
87733
- FIGURE_ID_SPLITTER: "??",
87734
- GRID_ICON_EDGE_LENGTH: 17,
87735
- GRID_ICON_MARGIN: 2,
87918
+ FIGURE_ID_SPLITTER,
87919
+ GRID_ICON_EDGE_LENGTH,
87920
+ GRID_ICON_MARGIN,
87736
87921
  CHART_TYPES,
87737
87922
  DARK_MODE_FILTER_STRING
87738
87923
  };
@@ -87838,8 +88023,8 @@ exports.stores = stores;
87838
88023
  exports.tokenColors = tokenColors;
87839
88024
  exports.tokenize = tokenize;
87840
88025
 
87841
- __info__.version = "19.4.12";
87842
- __info__.date = "2026-09-10T05:38:01.898Z";
87843
- __info__.hash = "cdb63b4";
88026
+ __info__.version = "19.4.14";
88027
+ __info__.date = "2026-10-01T07:47:35.933Z";
88028
+ __info__.hash = "67c7fe5";
87844
88029
 
87845
88030
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);