@odoo/o-spreadsheet 18.5.0-alpha.4 → 18.5.0-alpha.5

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 18.5.0-alpha.4
6
- * @date 2025-07-30T11:23:18.805Z
7
- * @hash 34a4ab3
5
+ * @version 18.5.0-alpha.5
6
+ * @date 2025-08-04T06:53:29.412Z
7
+ * @hash 71c9a36
8
8
  */
9
9
 
10
10
  'use strict';
@@ -1058,16 +1058,21 @@ const colors = [
1058
1058
  "#001f3f",
1059
1059
  ];
1060
1060
  /*
1061
- * transform a color number (R * 256^2 + G * 256 + B) into classic hex6 value
1061
+ * transform a color number (R * 256^2 + G * 256 + B) into classic hex (+alpha) value
1062
1062
  * */
1063
- function colorNumberString(color) {
1064
- return toHex(color.toString(16).padStart(6, "0"));
1063
+ function colorNumberToHex(color, alpha = 1) {
1064
+ const alphaHex = alpha !== 1
1065
+ ? Math.round(alpha * 255)
1066
+ .toString(16)
1067
+ .padStart(2, "0")
1068
+ : "";
1069
+ return toHex(color.toString(16).padStart(6, "0")) + alphaHex;
1065
1070
  }
1066
1071
  function colorToNumber(color) {
1067
1072
  if (typeof color === "number") {
1068
1073
  return color;
1069
1074
  }
1070
- return Number.parseInt(toHex(color).slice(1), 16);
1075
+ return Number.parseInt(toHex(color).slice(1, 7), 16);
1071
1076
  }
1072
1077
  /**
1073
1078
  * Converts any CSS color value to a standardized hex6 value.
@@ -1326,6 +1331,12 @@ function hslaToHex(hsla) {
1326
1331
  function hexToHSLA(hex) {
1327
1332
  return rgbaToHSLA(colorToRGBA(hex));
1328
1333
  }
1334
+ function colorOrNumberToRGBA(color) {
1335
+ if (typeof color === "number") {
1336
+ return colorToRGBA(colorNumberToHex(color));
1337
+ }
1338
+ return colorToRGBA(color);
1339
+ }
1329
1340
  /**
1330
1341
  * Will compare two color strings
1331
1342
  * A tolerance can be provided to account for small differences that could
@@ -1607,6 +1618,8 @@ function getColorScale(colorScalePoints) {
1607
1618
  const sortedColorScalePoints = [...colorScalePoints.sort((a, b) => a.value - b.value)];
1608
1619
  const thresholds = [];
1609
1620
  for (let i = 1; i < sortedColorScalePoints.length; i++) {
1621
+ const minColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i - 1].color).a;
1622
+ const maxColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i].color).a;
1610
1623
  const minColor = colorToNumber(sortedColorScalePoints[i - 1].color);
1611
1624
  const maxColor = colorToNumber(sortedColorScalePoints[i].color);
1612
1625
  thresholds.push({
@@ -1614,19 +1627,21 @@ function getColorScale(colorScalePoints) {
1614
1627
  max: sortedColorScalePoints[i].value,
1615
1628
  minColor,
1616
1629
  maxColor,
1630
+ minColorAlpha: minColorAlpha,
1631
+ maxColorAlpha: maxColorAlpha,
1617
1632
  colorDiff: computeColorDiffUnits(sortedColorScalePoints[i - 1].value, sortedColorScalePoints[i].value, minColor, maxColor),
1618
1633
  });
1619
1634
  }
1620
1635
  return (value) => {
1621
1636
  if (value < thresholds[0].min) {
1622
- return colorNumberString(thresholds[0].minColor);
1637
+ return colorNumberToHex(thresholds[0].minColor, thresholds[0].minColorAlpha);
1623
1638
  }
1624
1639
  for (const threshold of thresholds) {
1625
1640
  if (value >= threshold.min && value <= threshold.max) {
1626
- return colorNumberString(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff));
1641
+ return colorNumberToHex(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff), threshold.maxColorAlpha);
1627
1642
  }
1628
1643
  }
1629
- return colorNumberString(thresholds[thresholds.length - 1].maxColor);
1644
+ return colorNumberToHex(thresholds[thresholds.length - 1].maxColor, thresholds[thresholds.length - 1].maxColorAlpha);
1630
1645
  };
1631
1646
  }
1632
1647
  function computeColorDiffUnits(minValue, maxValue, minColor, maxColor) {
@@ -20478,6 +20493,54 @@ const PROPER = {
20478
20493
  },
20479
20494
  isExported: true,
20480
20495
  };
20496
+ const REGEXEXTRACT_DEFAULT_MODE = 0;
20497
+ const REGEXEXTRACT_DEFAULT_CASE_SENSITIVITY = 0;
20498
+ // -----------------------------------------------------------------------------
20499
+ // REGEXEXTRACT
20500
+ // -----------------------------------------------------------------------------
20501
+ const REGEXEXTRACT = {
20502
+ description: _t("Extract text from a string based on the supplied regular expression."),
20503
+ args: [
20504
+ arg("text (string)", _t("The string on which you want to extract text.")),
20505
+ arg("pattern (string)", _t("The regular expression pattern to match against the text.")),
20506
+ arg(`return_mode (number, default=${REGEXEXTRACT_DEFAULT_MODE})`, _t("0 = first match, 1 = all matches as an array, 2 = capturing groups from the first match as an array.")),
20507
+ arg(`case_sensitivity (number, default=${REGEXEXTRACT_DEFAULT_CASE_SENSITIVITY})`, _t("0 = case-sensitive, 1 = case-insensitive.")),
20508
+ ],
20509
+ compute: function (text, pattern, return_mode = { value: REGEXEXTRACT_DEFAULT_MODE }, newText = { value: REGEXEXTRACT_DEFAULT_CASE_SENSITIVITY }) {
20510
+ const _text = toString(text);
20511
+ const _pattern = toString(pattern);
20512
+ const _returnMode = toNumber(return_mode, this.locale);
20513
+ const _caseSensitivity = toNumber(newText, this.locale);
20514
+ if (_text === "" || _pattern === "") {
20515
+ return { value: "" };
20516
+ }
20517
+ if (_returnMode < 0 || _returnMode > 2) {
20518
+ return new EvaluationError(_t("The return_mode (%s) must be 0, 1 or 2.", _returnMode));
20519
+ }
20520
+ if (_caseSensitivity !== 0 && _caseSensitivity !== 1) {
20521
+ return new EvaluationError(_t("The case_sensitivity (%s) must be 0 or 1.", _caseSensitivity));
20522
+ }
20523
+ const flags = _caseSensitivity === 1 ? "gi" : "g";
20524
+ const regex = new RegExp(_pattern, flags);
20525
+ const matches = [..._text.matchAll(regex)];
20526
+ if (matches.length === 0) {
20527
+ return { value: CellErrorType.NotAvailable, message: _t("No matches found.") };
20528
+ }
20529
+ if (_returnMode === 0) {
20530
+ return matches[0][0];
20531
+ }
20532
+ else if (_returnMode === 1) {
20533
+ return matches.map((match) => [match[0]]);
20534
+ }
20535
+ else {
20536
+ if (matches[0].length < 2) {
20537
+ return new EvaluationError(_t("No capturing groups found."));
20538
+ }
20539
+ return matches[0].slice(1).map((s) => [s]);
20540
+ }
20541
+ },
20542
+ isExported: true,
20543
+ };
20481
20544
  // -----------------------------------------------------------------------------
20482
20545
  // REPLACE
20483
20546
  // -----------------------------------------------------------------------------
@@ -20754,6 +20817,105 @@ const VALUE = {
20754
20817
  },
20755
20818
  isExported: true,
20756
20819
  };
20820
+ // -----------------------------------------------------------------------------
20821
+ // TEXTAFTER
20822
+ // -----------------------------------------------------------------------------
20823
+ const TEXT_FN_DEFAULT_INSTANCE = 1;
20824
+ const TEXT_FN_DEFAULT_MATCH_MODE = 0;
20825
+ const TEXT_FN_DEFAULT_MATCH_END = 0;
20826
+ const TEXTAFTER = {
20827
+ description: _t("Returns text that occurs after a given substring or delimiter."),
20828
+ args: [
20829
+ arg("text (string)", _t("The source text.")),
20830
+ arg("delimiter (string)", _t("The substring after which text will be returned.")),
20831
+ arg(`instance_num (number, default=${TEXT_FN_DEFAULT_INSTANCE})`, _t("The desired instance of the delimiter after which we extract the text. A negative number searches from the end.")),
20832
+ arg(`match_mode (number, default=${TEXT_FN_DEFAULT_MATCH_MODE})`, _t("0 = case-sensitive, 1 = case-insensitive.")),
20833
+ arg(`match_end (number, default=${TEXT_FN_DEFAULT_MATCH_END}))`, _t("Whether to treat the end of text as a delimiter.")),
20834
+ arg(`if_not_found (string, default="${CellErrorType.NotAvailable}")`, _t("Value to return if the delimiter is not found.")),
20835
+ ],
20836
+ compute: function (text, delimiter, matchIndex = { value: TEXT_FN_DEFAULT_INSTANCE }, matchMode = { value: TEXT_FN_DEFAULT_MATCH_MODE }, matchEnd = { value: TEXT_FN_DEFAULT_MATCH_END }, ifNotFound = new NotAvailableError()) {
20837
+ const _text = toString(text);
20838
+ const _matchIndex = toNumber(matchIndex, this.locale);
20839
+ const _matchMode = toNumber(matchMode, this.locale);
20840
+ const _matchEnd = toNumber(matchEnd, this.locale);
20841
+ if (_matchIndex === 0) {
20842
+ return new EvaluationError(_t("The instance_num (%s) must not be zero.", _matchIndex));
20843
+ }
20844
+ if (_matchMode !== 0 && _matchMode !== 1) {
20845
+ return new EvaluationError(_t("match_mode should have a value of 0 or 1."));
20846
+ }
20847
+ if (_matchEnd !== 0 && _matchEnd !== 1) {
20848
+ return new EvaluationError(_t("match_end should have a value of 0 or 1."));
20849
+ }
20850
+ const _delimiter = toString(delimiter);
20851
+ if (_delimiter === "") {
20852
+ return Math.sign(_matchIndex) > 0 ? { value: _text } : { value: "" };
20853
+ }
20854
+ const flags = _matchMode === 1 ? "gi" : "g";
20855
+ const pattern = escapeRegExp(_delimiter);
20856
+ const regexp = new RegExp(pattern, flags);
20857
+ let matchIndices = [..._text.matchAll(regexp)].map((match) => match.index + pattern.length);
20858
+ if (_matchIndex < 0) {
20859
+ matchIndices = matchIndices.reverse();
20860
+ }
20861
+ // If _matchEnd, we act like the text is appended by the delimiter (or prepended if negative index)
20862
+ if (_matchEnd && Math.abs(_matchIndex) === matchIndices.length + 1) {
20863
+ return Math.sign(_matchIndex) > 0 ? { value: "" } : { value: _text };
20864
+ }
20865
+ const targetIndex = matchIndices[Math.abs(_matchIndex) - 1];
20866
+ return targetIndex === undefined ? ifNotFound : { value: _text.substring(targetIndex) };
20867
+ },
20868
+ isExported: true,
20869
+ };
20870
+ // -----------------------------------------------------------------------------
20871
+ // TEXTBEFORE
20872
+ // -----------------------------------------------------------------------------
20873
+ const TEXTBEFORE = {
20874
+ description: _t("Returns text that occurs before a given substring or delimiter."),
20875
+ args: [
20876
+ arg("text (string)", _t("The source text.")),
20877
+ arg("delimiter (string)", _t("The substring after which text will be returned.")),
20878
+ arg(`instance_num (number, default=${TEXT_FN_DEFAULT_INSTANCE})`, _t("The desired instance of the delimiter before which we extract the text. A negative number searches from the end.")),
20879
+ arg(`match_mode (number, default=${TEXT_FN_DEFAULT_MATCH_MODE})`, _t("0 = case-sensitive, 1 = case-insensitive.")),
20880
+ arg(`match_end (number, default=${TEXT_FN_DEFAULT_MATCH_END}))`, _t("Whether to match a delimiter against the end of the text.")),
20881
+ arg(`if_not_found (string, default="${CellErrorType.NotAvailable}")`, _t("Value to return if the delimiter is not found.")),
20882
+ ],
20883
+ compute: function (text, delimiter, matchIndex = { value: TEXT_FN_DEFAULT_INSTANCE }, matchMode = { value: TEXT_FN_DEFAULT_MATCH_MODE }, matchEnd = { value: TEXT_FN_DEFAULT_MATCH_END }, ifNotFound = new NotAvailableError()) {
20884
+ const _text = toString(text);
20885
+ const _matchIndex = toNumber(matchIndex, this.locale);
20886
+ const _matchMode = toNumber(matchMode, this.locale);
20887
+ const _matchEnd = toNumber(matchEnd, this.locale);
20888
+ if (_matchIndex === 0) {
20889
+ return new EvaluationError(_t("The instance_num (%s) must not be zero.", _matchIndex));
20890
+ }
20891
+ if (_matchMode !== 0 && _matchMode !== 1) {
20892
+ return new EvaluationError(_t("match_mode should have a value of 0 or 1."));
20893
+ }
20894
+ if (_matchEnd !== 0 && _matchEnd !== 1) {
20895
+ return new EvaluationError(_t("match_end should have a value of 0 or 1."));
20896
+ }
20897
+ const _delimiter = toString(delimiter);
20898
+ if (_delimiter === "") {
20899
+ return Math.sign(_matchIndex) > 0 ? { value: "" } : { value: _text };
20900
+ }
20901
+ const flags = _matchMode === 1 ? "gi" : "g";
20902
+ const pattern = escapeRegExp(_delimiter);
20903
+ const regexp = new RegExp(pattern, flags);
20904
+ let matchIndices = [..._text.matchAll(regexp)].map((match) => match.index + pattern.length);
20905
+ if (_matchIndex < 0) {
20906
+ matchIndices = matchIndices.reverse();
20907
+ }
20908
+ // If _matchEnd, we act like the text is appended by the delimiter (or prepended if negative index)
20909
+ if (_matchEnd && Math.abs(_matchIndex) === matchIndices.length + 1) {
20910
+ return Math.sign(_matchIndex) > 0 ? { value: _text } : { value: "" };
20911
+ }
20912
+ const targetIndex = matchIndices[Math.abs(_matchIndex) - 1];
20913
+ return targetIndex === undefined
20914
+ ? ifNotFound
20915
+ : { value: _text.substring(0, targetIndex - _delimiter.length) };
20916
+ },
20917
+ isExported: true,
20918
+ };
20757
20919
 
20758
20920
  var text = /*#__PURE__*/Object.freeze({
20759
20921
  __proto__: null,
@@ -20768,12 +20930,15 @@ var text = /*#__PURE__*/Object.freeze({
20768
20930
  LOWER: LOWER,
20769
20931
  MID: MID,
20770
20932
  PROPER: PROPER,
20933
+ REGEXEXTRACT: REGEXEXTRACT,
20771
20934
  REPLACE: REPLACE,
20772
20935
  RIGHT: RIGHT,
20773
20936
  SEARCH: SEARCH,
20774
20937
  SPLIT: SPLIT,
20775
20938
  SUBSTITUTE: SUBSTITUTE,
20776
20939
  TEXT: TEXT,
20940
+ TEXTAFTER: TEXTAFTER,
20941
+ TEXTBEFORE: TEXTBEFORE,
20777
20942
  TEXTJOIN: TEXTJOIN,
20778
20943
  TEXTSPLIT: TEXTSPLIT,
20779
20944
  TRIM: TRIM,
@@ -22777,6 +22942,7 @@ class ChartJsComponent extends owl.Component {
22777
22942
  this.animationStore = useStore(ChartAnimationStore);
22778
22943
  }
22779
22944
  owl.onMounted(() => {
22945
+ registerChartJSExtensions();
22780
22946
  const runtime = this.chartRuntime;
22781
22947
  this.currentRuntime = runtime;
22782
22948
  // Note: chartJS modify the runtime in place, so it's important to give it a copy
@@ -32179,40 +32345,6 @@ function compareContentToSpanElement(content, node) {
32179
32345
  return sameColor && sameClass && sameContent;
32180
32346
  }
32181
32347
 
32182
- // -----------------------------------------------------------------------------
32183
- // Formula Assistant component
32184
- // -----------------------------------------------------------------------------
32185
- css /* scss */ `
32186
- .o-formula-assistant {
32187
- background: #ffffff;
32188
- .o-formula-assistant-head {
32189
- background-color: #f2f2f2;
32190
- padding: 10px;
32191
- }
32192
- .collapsed {
32193
- transform: rotate(180deg);
32194
- }
32195
- .o-formula-assistant-core {
32196
- border-bottom: 1px solid gray;
32197
- }
32198
- .o-formula-assistant-arg-description {
32199
- font-size: 85%;
32200
- }
32201
- .o-formula-assistant-focus {
32202
- div:first-child,
32203
- span {
32204
- color: ${COMPOSER_ASSISTANT_COLOR};
32205
- text-shadow: 0px 0px 1px ${COMPOSER_ASSISTANT_COLOR};
32206
- }
32207
- div:last-child {
32208
- color: black;
32209
- }
32210
- }
32211
- .o-formula-assistant-gray {
32212
- color: gray;
32213
- }
32214
- }
32215
- `;
32216
32348
  class FunctionDescriptionProvider extends owl.Component {
32217
32349
  static template = "o-spreadsheet-FunctionDescriptionProvider";
32218
32350
  static props = {
@@ -51925,16 +52057,16 @@ class ConditionalFormatPreview extends owl.Component {
51925
52057
  return cssPropertiesToCss(cellStyleToCss(rule.style));
51926
52058
  }
51927
52059
  else if (rule.type === "ColorScaleRule") {
51928
- const minColor = colorNumberString(rule.minimum.color);
51929
- const midColor = rule.midpoint ? colorNumberString(rule.midpoint.color) : null;
51930
- const maxColor = colorNumberString(rule.maximum.color);
52060
+ const minColor = colorNumberToHex(rule.minimum.color);
52061
+ const midColor = rule.midpoint ? colorNumberToHex(rule.midpoint.color) : null;
52062
+ const maxColor = colorNumberToHex(rule.maximum.color);
51931
52063
  const baseString = "background-image: linear-gradient(to right, ";
51932
52064
  return midColor
51933
52065
  ? baseString + minColor + ", " + midColor + ", " + maxColor + ")"
51934
52066
  : baseString + minColor + ", " + maxColor + ")";
51935
52067
  }
51936
52068
  else if (rule.type === "DataBarRule") {
51937
- const color = colorNumberString(rule.color);
52069
+ const color = colorNumberToHex(rule.color);
51938
52070
  return `background-image: linear-gradient(to right, ${color} 50%, white 50%)`;
51939
52071
  }
51940
52072
  return "";
@@ -52142,7 +52274,7 @@ class ConditionalFormattingEditor extends owl.Component {
52142
52274
  icons = ICONS;
52143
52275
  iconSets = ICON_SETS;
52144
52276
  getTextDecoration = getTextDecoration;
52145
- colorNumberString = colorNumberString;
52277
+ colorNumberToHex = colorNumberToHex;
52146
52278
  state;
52147
52279
  setup() {
52148
52280
  this.state = owl.useState({
@@ -52393,9 +52525,9 @@ class ConditionalFormattingEditor extends owl.Component {
52393
52525
  }
52394
52526
  getPreviewGradient() {
52395
52527
  const rule = this.state.rules.colorScale;
52396
- const minColor = colorNumberString(rule.minimum.color);
52397
- const midColor = colorNumberString(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52398
- const maxColor = colorNumberString(rule.maximum.color);
52528
+ const minColor = colorNumberToHex(rule.minimum.color);
52529
+ const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52530
+ const maxColor = colorNumberToHex(rule.maximum.color);
52399
52531
  const baseString = "background-image: linear-gradient(to right, ";
52400
52532
  return rule.midpoint === undefined
52401
52533
  ? baseString + minColor + ", " + maxColor + ")"
@@ -52403,8 +52535,8 @@ class ConditionalFormattingEditor extends owl.Component {
52403
52535
  }
52404
52536
  getThresholdColor(threshold) {
52405
52537
  return threshold
52406
- ? colorNumberString(threshold.color)
52407
- : colorNumberString(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52538
+ ? colorNumberToHex(threshold.color)
52539
+ : colorNumberToHex(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
52408
52540
  }
52409
52541
  onMidpointChange(ev) {
52410
52542
  const type = ev.target.value;
@@ -66628,9 +66760,9 @@ class CustomColorsPlugin extends CoreViewPlugin {
66628
66760
  formatColors.push(rule.style.fillColor);
66629
66761
  }
66630
66762
  else if (rule.type === "ColorScaleRule") {
66631
- formatColors.push(colorNumberString(rule.minimum.color));
66632
- formatColors.push(rule.midpoint ? colorNumberString(rule.midpoint.color) : undefined);
66633
- formatColors.push(colorNumberString(rule.maximum.color));
66763
+ formatColors.push(colorNumberToHex(rule.minimum.color));
66764
+ formatColors.push(rule.midpoint ? colorNumberToHex(rule.midpoint.color) : undefined);
66765
+ formatColors.push(colorNumberToHex(rule.maximum.color));
66634
66766
  }
66635
66767
  }
66636
66768
  return formatColors.filter(isDefined);
@@ -67001,7 +67133,7 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
67001
67133
  if (!computedDataBars[col])
67002
67134
  computedDataBars[col] = [];
67003
67135
  computedDataBars[col][row] = {
67004
- color: colorNumberString(color),
67136
+ color: colorNumberToHex(color),
67005
67137
  percentage: (cell.value * 100) / max,
67006
67138
  };
67007
67139
  }
@@ -80025,7 +80157,6 @@ css /* scss */ `
80025
80157
  }
80026
80158
  }
80027
80159
 
80028
- .o-spreadsheet-topbar-wrapper,
80029
80160
  .o-spreadsheet-bottombar-wrapper {
80030
80161
  z-index: ${ComponentsImportance.ScrollBar + 1};
80031
80162
  }
@@ -80140,7 +80271,6 @@ class Spreadsheet extends owl.Component {
80140
80271
  this.checkViewportSize();
80141
80272
  stores.on("store-updated", this, render);
80142
80273
  resizeObserver.observe(this.spreadsheetRef.el);
80143
- registerChartJSExtensions();
80144
80274
  });
80145
80275
  owl.onWillUnmount(() => {
80146
80276
  this.unbindModelEvents();
@@ -82786,7 +82916,7 @@ function addDataBarRule(cf, rule) {
82786
82916
  <dataBar>
82787
82917
  <cfvo type="min" val="0"/>
82788
82918
  <cfvo type="max" val="100"/>
82789
- <color rgb="${toXlsxHexColor(colorNumberString(rule.color))}"/>
82919
+ <color rgb="${toXlsxHexColor(colorNumberToHex(rule.color))}"/>
82790
82920
  </dataBar>
82791
82921
  </cfRule>
82792
82922
  </conditionalFormatting>
@@ -82814,7 +82944,7 @@ function addColorScaleRule(cf, rule) {
82814
82944
  continue;
82815
82945
  }
82816
82946
  cfValueObject.push(thresholdAttributes(threshold, position));
82817
- colors.push([["rgb", toXlsxHexColor(colorNumberString(threshold.color))]]);
82947
+ colors.push([["rgb", toXlsxHexColor(colorNumberToHex(threshold.color))]]);
82818
82948
  }
82819
82949
  if (!canExport) {
82820
82950
  console.warn("Conditional formats with formula rules are not supported at the moment. The rule is therefore skipped.");
@@ -84876,6 +85006,6 @@ exports.tokenColors = tokenColors;
84876
85006
  exports.tokenize = tokenize;
84877
85007
 
84878
85008
 
84879
- __info__.version = "18.5.0-alpha.4";
84880
- __info__.date = "2025-07-30T11:23:18.805Z";
84881
- __info__.hash = "34a4ab3";
85009
+ __info__.version = "18.5.0-alpha.5";
85010
+ __info__.date = "2025-08-04T06:53:29.412Z";
85011
+ __info__.hash = "71c9a36";