@odoo/o-spreadsheet 16.1.6 → 16.1.7
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.
- package/dist/o-spreadsheet.cjs.js +269 -179
- package/dist/o-spreadsheet.d.ts +79 -49
- package/dist/o-spreadsheet.esm.js +269 -179
- package/dist/o-spreadsheet.iife.js +269 -179
- package/dist/o-spreadsheet.iife.min.js +239 -237
- package/package.json +2 -2
|
@@ -111,88 +111,88 @@ const LINK_COLOR = "#01666b";
|
|
|
111
111
|
const FILTERS_COLOR = "#188038";
|
|
112
112
|
const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
|
|
113
113
|
const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
|
|
114
|
-
// Color picker
|
|
114
|
+
// Color picker defaults as upper case HEX to match `toHex`helper
|
|
115
115
|
const COLOR_PICKER_DEFAULTS = [
|
|
116
116
|
"#000000",
|
|
117
117
|
"#434343",
|
|
118
118
|
"#666666",
|
|
119
119
|
"#999999",
|
|
120
|
-
"#
|
|
121
|
-
"#
|
|
122
|
-
"#
|
|
123
|
-
"#
|
|
124
|
-
"#
|
|
125
|
-
"#
|
|
120
|
+
"#B7B7B7",
|
|
121
|
+
"#CCCCCC",
|
|
122
|
+
"#D9D9D9",
|
|
123
|
+
"#EFEFEF",
|
|
124
|
+
"#F3F3F3",
|
|
125
|
+
"#FFFFFF",
|
|
126
126
|
"#980000",
|
|
127
|
-
"#
|
|
128
|
-
"#
|
|
129
|
-
"#
|
|
130
|
-
"#
|
|
131
|
-
"#
|
|
132
|
-
"#
|
|
133
|
-
"#
|
|
134
|
-
"#
|
|
135
|
-
"#
|
|
136
|
-
"#
|
|
137
|
-
"#
|
|
138
|
-
"#
|
|
139
|
-
"#
|
|
140
|
-
"#
|
|
141
|
-
"#
|
|
142
|
-
"#
|
|
143
|
-
"#
|
|
144
|
-
"#
|
|
145
|
-
"#
|
|
146
|
-
"#
|
|
147
|
-
"#
|
|
148
|
-
"#
|
|
149
|
-
"#
|
|
150
|
-
"#
|
|
151
|
-
"#
|
|
152
|
-
"#
|
|
153
|
-
"#
|
|
154
|
-
"#
|
|
155
|
-
"#
|
|
156
|
-
"#
|
|
157
|
-
"#
|
|
158
|
-
"#
|
|
159
|
-
"#
|
|
160
|
-
"#
|
|
161
|
-
"#
|
|
162
|
-
"#
|
|
163
|
-
"#
|
|
164
|
-
"#
|
|
165
|
-
"#
|
|
166
|
-
"#
|
|
167
|
-
"#
|
|
168
|
-
"#
|
|
169
|
-
"#
|
|
170
|
-
"#
|
|
171
|
-
"#
|
|
172
|
-
"#
|
|
173
|
-
"#
|
|
174
|
-
"#
|
|
175
|
-
"#
|
|
176
|
-
"#
|
|
127
|
+
"#FF0000",
|
|
128
|
+
"#FF9900",
|
|
129
|
+
"#FFFF00",
|
|
130
|
+
"#00FF00",
|
|
131
|
+
"#00FFFF",
|
|
132
|
+
"#4A86E8",
|
|
133
|
+
"#0000FF",
|
|
134
|
+
"#9900FF",
|
|
135
|
+
"#FF00FF",
|
|
136
|
+
"#E6B8AF",
|
|
137
|
+
"#F4CCCC",
|
|
138
|
+
"#FCE5CD",
|
|
139
|
+
"#FFF2CC",
|
|
140
|
+
"#D9EAD3",
|
|
141
|
+
"#D0E0E3",
|
|
142
|
+
"#C9DAF8",
|
|
143
|
+
"#CFE2F3",
|
|
144
|
+
"#D9D2E9",
|
|
145
|
+
"#EAD1DC",
|
|
146
|
+
"#DD7E6B",
|
|
147
|
+
"#EA9999",
|
|
148
|
+
"#F9CB9C",
|
|
149
|
+
"#FFE599",
|
|
150
|
+
"#B6D7A8",
|
|
151
|
+
"#A2C4C9",
|
|
152
|
+
"#A4C2F4",
|
|
153
|
+
"#9FC5E8",
|
|
154
|
+
"#B4A7D6",
|
|
155
|
+
"#D5A6BD",
|
|
156
|
+
"#CC4125",
|
|
157
|
+
"#E06666",
|
|
158
|
+
"#F6B26B",
|
|
159
|
+
"#FFD966",
|
|
160
|
+
"#93C47D",
|
|
161
|
+
"#76A5AF",
|
|
162
|
+
"#6D9EEB",
|
|
163
|
+
"#6FA8DC",
|
|
164
|
+
"#8E7CC3",
|
|
165
|
+
"#C27BA0",
|
|
166
|
+
"#A61C00",
|
|
167
|
+
"#CC0000",
|
|
168
|
+
"#E69138",
|
|
169
|
+
"#F1C232",
|
|
170
|
+
"#6AA84F",
|
|
171
|
+
"#45818E",
|
|
172
|
+
"#3C78D8",
|
|
173
|
+
"#3D85C6",
|
|
174
|
+
"#674EA7",
|
|
175
|
+
"#A64D79",
|
|
176
|
+
"#85200C",
|
|
177
177
|
"#990000",
|
|
178
|
-
"#
|
|
179
|
-
"#
|
|
180
|
-
"#
|
|
181
|
-
"#
|
|
182
|
-
"#
|
|
183
|
-
"#
|
|
184
|
-
"#
|
|
185
|
-
"#
|
|
186
|
-
"#
|
|
178
|
+
"#B45F06",
|
|
179
|
+
"#BF9000",
|
|
180
|
+
"#38761D",
|
|
181
|
+
"#134F5C",
|
|
182
|
+
"#1155CC",
|
|
183
|
+
"#0B5394",
|
|
184
|
+
"#351C75",
|
|
185
|
+
"#741B47",
|
|
186
|
+
"#5B0F00",
|
|
187
187
|
"#660000",
|
|
188
|
-
"#
|
|
189
|
-
"#
|
|
190
|
-
"#
|
|
191
|
-
"#
|
|
192
|
-
"#
|
|
188
|
+
"#783F04",
|
|
189
|
+
"#7F6000",
|
|
190
|
+
"#274E13",
|
|
191
|
+
"#0C343D",
|
|
192
|
+
"#1C4587",
|
|
193
193
|
"#073763",
|
|
194
|
-
"#
|
|
195
|
-
"#
|
|
194
|
+
"#20124D",
|
|
195
|
+
"#4C1130",
|
|
196
196
|
];
|
|
197
197
|
// Dimensions
|
|
198
198
|
const MIN_ROW_HEIGHT = 10;
|
|
@@ -231,7 +231,7 @@ const DEFAULT_FONT = "'Roboto', arial";
|
|
|
231
231
|
const DEFAULT_BORDER_DESC = ["thin", "#000"];
|
|
232
232
|
const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
|
|
233
233
|
// DateTimeRegex
|
|
234
|
-
const DATETIME_FORMAT = /[
|
|
234
|
+
const DATETIME_FORMAT = /[ymdhs:]/;
|
|
235
235
|
// Ranges
|
|
236
236
|
const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
|
|
237
237
|
// Max Number of history steps kept in memory
|
|
@@ -268,11 +268,13 @@ var ComponentsImportance;
|
|
|
268
268
|
ComponentsImportance[ComponentsImportance["Highlight"] = 5] = "Highlight";
|
|
269
269
|
ComponentsImportance[ComponentsImportance["Figure"] = 10] = "Figure";
|
|
270
270
|
ComponentsImportance[ComponentsImportance["ScrollBar"] = 15] = "ScrollBar";
|
|
271
|
-
ComponentsImportance[ComponentsImportance["
|
|
272
|
-
ComponentsImportance[ComponentsImportance["
|
|
271
|
+
ComponentsImportance[ComponentsImportance["GridPopover"] = 19] = "GridPopover";
|
|
272
|
+
ComponentsImportance[ComponentsImportance["GridComposer"] = 20] = "GridComposer";
|
|
273
|
+
ComponentsImportance[ComponentsImportance["Dropdown"] = 21] = "Dropdown";
|
|
273
274
|
ComponentsImportance[ComponentsImportance["ColorPicker"] = 25] = "ColorPicker";
|
|
274
275
|
ComponentsImportance[ComponentsImportance["IconPicker"] = 25] = "IconPicker";
|
|
275
|
-
ComponentsImportance[ComponentsImportance["
|
|
276
|
+
ComponentsImportance[ComponentsImportance["TopBarComposer"] = 30] = "TopBarComposer";
|
|
277
|
+
ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
|
|
276
278
|
ComponentsImportance[ComponentsImportance["ChartAnchor"] = 1000] = "ChartAnchor";
|
|
277
279
|
})(ComponentsImportance || (ComponentsImportance = {}));
|
|
278
280
|
const DEFAULT_SHEETVIEW_SIZE = 1000;
|
|
@@ -1035,6 +1037,8 @@ function transpose2dArray(matrix) {
|
|
|
1035
1037
|
return matrix[0].map((_, i) => matrix.map((row) => row[i]));
|
|
1036
1038
|
}
|
|
1037
1039
|
|
|
1040
|
+
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
1041
|
+
const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
|
|
1038
1042
|
const colors$1 = [
|
|
1039
1043
|
"#eb6d00",
|
|
1040
1044
|
"#0074d9",
|
|
@@ -1060,7 +1064,10 @@ function colorNumberString(color) {
|
|
|
1060
1064
|
}
|
|
1061
1065
|
/**
|
|
1062
1066
|
* Converts any CSS color value to a standardized hex6 value.
|
|
1063
|
-
* Accepts: hex3, hex6, hex8 and
|
|
1067
|
+
* Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
|
|
1068
|
+
*
|
|
1069
|
+
* [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
|
|
1070
|
+
* with r,g,b ∈ [0, 255] and a ∈ [0, 1]
|
|
1064
1071
|
*
|
|
1065
1072
|
* toHex("#ABC")
|
|
1066
1073
|
* >> "#AABBCC"
|
|
@@ -1071,27 +1078,31 @@ function colorNumberString(color) {
|
|
|
1071
1078
|
* toHex("rgb(30, 80, 16)")
|
|
1072
1079
|
* >> "#1E5010"
|
|
1073
1080
|
*
|
|
1081
|
+
* * toHex("rgb(30, 80, 16, 0.5)")
|
|
1082
|
+
* >> "#1E501080"
|
|
1083
|
+
*
|
|
1074
1084
|
*/
|
|
1075
1085
|
function toHex(color) {
|
|
1076
|
-
|
|
1077
|
-
|
|
1086
|
+
let hexColor = color;
|
|
1087
|
+
if (color.startsWith("rgb")) {
|
|
1088
|
+
hexColor = rgbaStringToHex(color);
|
|
1078
1089
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1090
|
+
else {
|
|
1091
|
+
hexColor = color.replace("#", "").toUpperCase();
|
|
1092
|
+
if (hexColor.length === 3 || hexColor.length === 4) {
|
|
1093
|
+
hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
|
|
1094
|
+
}
|
|
1095
|
+
hexColor = `#${hexColor}`;
|
|
1085
1096
|
}
|
|
1086
|
-
if (
|
|
1087
|
-
throw new Error(
|
|
1097
|
+
if (!hexColor.match(HEX_MATCH)) {
|
|
1098
|
+
throw new Error(`invalid color input: ${color}`);
|
|
1088
1099
|
}
|
|
1089
|
-
return
|
|
1100
|
+
return hexColor;
|
|
1090
1101
|
}
|
|
1091
1102
|
function isColorValid(color) {
|
|
1092
1103
|
try {
|
|
1093
|
-
|
|
1094
|
-
return
|
|
1104
|
+
toHex(color);
|
|
1105
|
+
return true;
|
|
1095
1106
|
}
|
|
1096
1107
|
catch (error) {
|
|
1097
1108
|
return false;
|
|
@@ -1124,15 +1135,29 @@ function relativeLuminance(color) {
|
|
|
1124
1135
|
/**
|
|
1125
1136
|
* Convert a CSS rgb color string to a standardized hex6 color value.
|
|
1126
1137
|
*
|
|
1127
|
-
*
|
|
1138
|
+
* rgbaStringToHex("rgb(30, 80, 16)")
|
|
1128
1139
|
* >> "#1E5010"
|
|
1140
|
+
*
|
|
1141
|
+
* rgbaStringToHex("rgba(30, 80, 16, 0.5)")
|
|
1142
|
+
* >> "#1E501080"
|
|
1143
|
+
*
|
|
1144
|
+
* DOES NOT SUPPORT NON INTEGER RGB VALUES
|
|
1129
1145
|
*/
|
|
1130
|
-
function
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1146
|
+
function rgbaStringToHex(color) {
|
|
1147
|
+
const stringVals = color.replace(RBA_REGEX, "").split(",");
|
|
1148
|
+
let alphaHex = 255;
|
|
1149
|
+
if (stringVals.length !== 3 && stringVals.length !== 4) {
|
|
1150
|
+
throw new Error("invalid color");
|
|
1151
|
+
}
|
|
1152
|
+
else if (stringVals.length === 4) {
|
|
1153
|
+
const alpha = parseFloat(stringVals.pop() || "1");
|
|
1154
|
+
alphaHex = Math.round((alpha || 1) * 255);
|
|
1155
|
+
}
|
|
1156
|
+
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
1157
|
+
if (alphaHex !== 255) {
|
|
1158
|
+
vals.push(alphaHex);
|
|
1159
|
+
}
|
|
1160
|
+
return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
|
|
1136
1161
|
}
|
|
1137
1162
|
/**
|
|
1138
1163
|
* RGBA to HEX representation (#RRGGBBAA).
|
|
@@ -1154,7 +1179,7 @@ function rgbaToHex(rgba) {
|
|
|
1154
1179
|
a = "0" + a;
|
|
1155
1180
|
if (a === "ff")
|
|
1156
1181
|
a = "";
|
|
1157
|
-
return "#" + r + g + b + a;
|
|
1182
|
+
return ("#" + r + g + b + a).toUpperCase();
|
|
1158
1183
|
}
|
|
1159
1184
|
/**
|
|
1160
1185
|
* Color string to RGBA representation
|
|
@@ -1275,6 +1300,9 @@ function rgbaToHSLA(rgba) {
|
|
|
1275
1300
|
s = +(s * 100).toFixed(1);
|
|
1276
1301
|
l = +(l * 100).toFixed(1);
|
|
1277
1302
|
return { a: rgba.a, h, s, l };
|
|
1303
|
+
}
|
|
1304
|
+
function isSameColor(color1, color2) {
|
|
1305
|
+
return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
|
|
1278
1306
|
}
|
|
1279
1307
|
|
|
1280
1308
|
/** Reference of a cell (eg. A1, $B$5) */
|
|
@@ -1426,7 +1454,7 @@ function scrollDelay(value) {
|
|
|
1426
1454
|
* formula, commas are used to separate arguments
|
|
1427
1455
|
* - it does not support % symbol, in formulas % is an operator
|
|
1428
1456
|
*/
|
|
1429
|
-
const formulaNumberRegexp =
|
|
1457
|
+
const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
|
|
1430
1458
|
const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
|
|
1431
1459
|
const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
|
|
1432
1460
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -3021,6 +3049,7 @@ const CHART_PADDING_RATIO = 0.02;
|
|
|
3021
3049
|
const LINE_HEIGHT = 1.2;
|
|
3022
3050
|
css /* scss */ `
|
|
3023
3051
|
div.o-scorecard {
|
|
3052
|
+
font-family: ${DEFAULT_FONT};
|
|
3024
3053
|
user-select: none;
|
|
3025
3054
|
background-color: white;
|
|
3026
3055
|
display: flex;
|
|
@@ -5645,6 +5674,11 @@ class Popover extends Component {
|
|
|
5645
5674
|
this.currentPosition = newPosition;
|
|
5646
5675
|
});
|
|
5647
5676
|
}
|
|
5677
|
+
get popoverStyle() {
|
|
5678
|
+
return cssPropertiesToCss({
|
|
5679
|
+
"z-index": `${this.props.zIndex}`,
|
|
5680
|
+
});
|
|
5681
|
+
}
|
|
5648
5682
|
}
|
|
5649
5683
|
Popover.template = "o-spreadsheet-Popover";
|
|
5650
5684
|
Popover.defaultProps = {
|
|
@@ -5653,6 +5687,7 @@ Popover.defaultProps = {
|
|
|
5653
5687
|
onMouseWheel: () => { },
|
|
5654
5688
|
onPopoverMoved: () => { },
|
|
5655
5689
|
onPopoverHidden: () => { },
|
|
5690
|
+
zIndex: ComponentsImportance.Popover,
|
|
5656
5691
|
};
|
|
5657
5692
|
Popover.props = {
|
|
5658
5693
|
anchorRect: Object,
|
|
@@ -5664,6 +5699,7 @@ Popover.props = {
|
|
|
5664
5699
|
onMouseWheel: { type: Function, optional: true },
|
|
5665
5700
|
onPopoverHidden: { type: Function, optional: true },
|
|
5666
5701
|
onPopoverMoved: { type: Function, optional: true },
|
|
5702
|
+
zIndex: { type: Number, optional: true },
|
|
5667
5703
|
slots: Object,
|
|
5668
5704
|
};
|
|
5669
5705
|
class PopoverPositionContext {
|
|
@@ -17034,10 +17070,10 @@ css /* scss */ `
|
|
|
17034
17070
|
padding: 0;
|
|
17035
17071
|
margin: 0;
|
|
17036
17072
|
border: 0;
|
|
17037
|
-
z-index: ${ComponentsImportance.Composer};
|
|
17038
17073
|
flex-grow: 1;
|
|
17039
17074
|
max-height: inherit;
|
|
17040
17075
|
.o-composer {
|
|
17076
|
+
font-family: ${DEFAULT_FONT};
|
|
17041
17077
|
caret-color: black;
|
|
17042
17078
|
padding-left: 3px;
|
|
17043
17079
|
padding-right: 3px;
|
|
@@ -17072,6 +17108,10 @@ css /* scss */ `
|
|
|
17072
17108
|
.o-topbar-toolbar .o-composer-container:focus-within {
|
|
17073
17109
|
border: 1px solid ${SELECTION_BORDER_COLOR};
|
|
17074
17110
|
}
|
|
17111
|
+
|
|
17112
|
+
.o-topbar-toolbar .o-composer-container {
|
|
17113
|
+
z-index: ${ComponentsImportance.TopBarComposer};
|
|
17114
|
+
}
|
|
17075
17115
|
`;
|
|
17076
17116
|
class Composer extends Component {
|
|
17077
17117
|
constructor() {
|
|
@@ -17520,7 +17560,7 @@ const SCROLLBAR_HIGHT = 15;
|
|
|
17520
17560
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
17521
17561
|
css /* scss */ `
|
|
17522
17562
|
div.o-grid-composer {
|
|
17523
|
-
z-index: ${ComponentsImportance.
|
|
17563
|
+
z-index: ${ComponentsImportance.GridComposer};
|
|
17524
17564
|
box-sizing: border-box;
|
|
17525
17565
|
position: absolute;
|
|
17526
17566
|
border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
|
|
@@ -20056,6 +20096,9 @@ class ColorPicker extends Component {
|
|
|
20056
20096
|
const { display, background, left, top } = this.state.style;
|
|
20057
20097
|
return `display:${display};${display === "block" ? `background-color:${background};left:${left};top:${top};` : ""}`;
|
|
20058
20098
|
}
|
|
20099
|
+
isSameColor(color1, color2) {
|
|
20100
|
+
return isSameColor(color1, color2);
|
|
20101
|
+
}
|
|
20059
20102
|
}
|
|
20060
20103
|
ColorPicker.template = "o-spreadsheet-ColorPicker";
|
|
20061
20104
|
ColorPicker.defaultProps = {
|
|
@@ -20200,6 +20243,12 @@ class GaugeChartDesignPanel extends Component {
|
|
|
20200
20243
|
const cancelledReasons = [...(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.reasons) || [])];
|
|
20201
20244
|
return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
|
|
20202
20245
|
}
|
|
20246
|
+
onClick(ev) {
|
|
20247
|
+
this.state.openedMenu = undefined;
|
|
20248
|
+
}
|
|
20249
|
+
setup() {
|
|
20250
|
+
useExternalListener(window, "click", this.onClick);
|
|
20251
|
+
}
|
|
20203
20252
|
updateBackgroundColor(color) {
|
|
20204
20253
|
this.state.openedMenu = undefined;
|
|
20205
20254
|
this.props.updateChart({
|
|
@@ -20383,6 +20432,12 @@ class ScorecardChartDesignPanel extends Component {
|
|
|
20383
20432
|
openedColorPicker: undefined,
|
|
20384
20433
|
});
|
|
20385
20434
|
}
|
|
20435
|
+
onClick(ev) {
|
|
20436
|
+
this.state.openedColorPicker = undefined;
|
|
20437
|
+
}
|
|
20438
|
+
setup() {
|
|
20439
|
+
useExternalListener(window, "click", this.onClick);
|
|
20440
|
+
}
|
|
20386
20441
|
updateTitle(ev) {
|
|
20387
20442
|
this.props.updateChart({
|
|
20388
20443
|
title: ev.target.value,
|
|
@@ -22345,6 +22400,10 @@ GridOverlay.props = {
|
|
|
22345
22400
|
};
|
|
22346
22401
|
|
|
22347
22402
|
class GridPopover extends Component {
|
|
22403
|
+
constructor() {
|
|
22404
|
+
super(...arguments);
|
|
22405
|
+
this.zIndex = ComponentsImportance.GridPopover;
|
|
22406
|
+
}
|
|
22348
22407
|
get cellPopover() {
|
|
22349
22408
|
const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
|
|
22350
22409
|
if (!popover.isOpen) {
|
|
@@ -24562,6 +24621,70 @@ function fixXlsxUnicode(str) {
|
|
|
24562
24621
|
});
|
|
24563
24622
|
}
|
|
24564
24623
|
|
|
24624
|
+
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
|
|
24625
|
+
/**
|
|
24626
|
+
* Convert excel format to o_spreadsheet format
|
|
24627
|
+
*
|
|
24628
|
+
* Excel format are defined in openXML §18.8.31
|
|
24629
|
+
*/
|
|
24630
|
+
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
24631
|
+
var _a, _b, _c;
|
|
24632
|
+
if (numFmtId === 0) {
|
|
24633
|
+
return undefined;
|
|
24634
|
+
}
|
|
24635
|
+
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
24636
|
+
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
|
|
24637
|
+
if (format) {
|
|
24638
|
+
try {
|
|
24639
|
+
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
|
|
24640
|
+
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
24641
|
+
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
|
|
24642
|
+
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
|
|
24643
|
+
const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
24644
|
+
const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
|
|
24645
|
+
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
|
|
24646
|
+
throw new Error("Multiple escaped blocks in format");
|
|
24647
|
+
}
|
|
24648
|
+
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
|
|
24649
|
+
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
|
|
24650
|
+
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
|
|
24651
|
+
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
|
|
24652
|
+
convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
|
|
24653
|
+
if (isXlsxDateFormat(convertedFormat)) {
|
|
24654
|
+
convertedFormat = convertDateFormat$1(convertedFormat);
|
|
24655
|
+
}
|
|
24656
|
+
if (isFormatSupported(convertedFormat)) {
|
|
24657
|
+
return convertedFormat;
|
|
24658
|
+
}
|
|
24659
|
+
}
|
|
24660
|
+
catch (e) { }
|
|
24661
|
+
}
|
|
24662
|
+
warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
|
|
24663
|
+
return undefined;
|
|
24664
|
+
}
|
|
24665
|
+
function isFormatSupported(format) {
|
|
24666
|
+
try {
|
|
24667
|
+
formatValue(0, format);
|
|
24668
|
+
return true;
|
|
24669
|
+
}
|
|
24670
|
+
catch (e) {
|
|
24671
|
+
return false;
|
|
24672
|
+
}
|
|
24673
|
+
}
|
|
24674
|
+
function isXlsxDateFormat(format) {
|
|
24675
|
+
return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
|
|
24676
|
+
}
|
|
24677
|
+
function convertDateFormat$1(format) {
|
|
24678
|
+
// Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
|
|
24679
|
+
// but can still occur and are supported by Excel/Google sheets
|
|
24680
|
+
format = format.toLowerCase();
|
|
24681
|
+
format = format.replace(/mmmmm/g, "mmm");
|
|
24682
|
+
format = format.replace(/am\/pm|a\/m/g, "a");
|
|
24683
|
+
format = format.replace(/hhhh/g, "hh");
|
|
24684
|
+
format = format.replace(/\bh\b/g, "hh");
|
|
24685
|
+
return format;
|
|
24686
|
+
}
|
|
24687
|
+
|
|
24565
24688
|
function convertBorders(data, warningManager) {
|
|
24566
24689
|
const borderArray = data.borders.map((border) => {
|
|
24567
24690
|
addBorderWarnings(border, warningManager);
|
|
@@ -24626,41 +24749,6 @@ function convertFormats(data, warningManager) {
|
|
|
24626
24749
|
}
|
|
24627
24750
|
return arrayToObject(formats, 1);
|
|
24628
24751
|
}
|
|
24629
|
-
/**
|
|
24630
|
-
* Convert excel format to o_spreadsheet format
|
|
24631
|
-
*
|
|
24632
|
-
* Excel format are defined in openXML §18.8.31
|
|
24633
|
-
*/
|
|
24634
|
-
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
24635
|
-
var _a, _b, _c;
|
|
24636
|
-
if (numFmtId === 0) {
|
|
24637
|
-
return undefined;
|
|
24638
|
-
}
|
|
24639
|
-
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
24640
|
-
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
|
|
24641
|
-
if (format) {
|
|
24642
|
-
try {
|
|
24643
|
-
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
|
|
24644
|
-
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
24645
|
-
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
|
|
24646
|
-
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
|
|
24647
|
-
const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
24648
|
-
const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
|
|
24649
|
-
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
|
|
24650
|
-
throw new Error("Multiple escaped blocks in format");
|
|
24651
|
-
}
|
|
24652
|
-
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
|
|
24653
|
-
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
|
|
24654
|
-
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
|
|
24655
|
-
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
|
|
24656
|
-
formatValue(0, convertedFormat);
|
|
24657
|
-
return convertedFormat;
|
|
24658
|
-
}
|
|
24659
|
-
catch (e) { }
|
|
24660
|
-
}
|
|
24661
|
-
warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
|
|
24662
|
-
return undefined;
|
|
24663
|
-
}
|
|
24664
24752
|
/**
|
|
24665
24753
|
* We currently only support only a set of font sizes, we cannot define new font sizes.
|
|
24666
24754
|
* This function adapts an arbitrary font size to the closest supported font size.
|
|
@@ -31827,9 +31915,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
31827
31915
|
// remove duplicates first to check validity on a reduced
|
|
31828
31916
|
// set of colors, then normalize to HEX and remove duplicates
|
|
31829
31917
|
// again
|
|
31830
|
-
[...new Set([...usedColors, ...this.customColors])]
|
|
31831
|
-
.filter(isColorValid)
|
|
31832
|
-
.map((c) => toHex(c).toLowerCase())),
|
|
31918
|
+
[...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
|
|
31833
31919
|
]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
|
|
31834
31920
|
}
|
|
31835
31921
|
getColorsFromCells(cells) {
|
|
@@ -31890,7 +31976,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
31890
31976
|
return [...chartsColors];
|
|
31891
31977
|
}
|
|
31892
31978
|
tryToAddColor(color) {
|
|
31893
|
-
const formattedColor = toHex(color)
|
|
31979
|
+
const formattedColor = toHex(color);
|
|
31894
31980
|
if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
|
|
31895
31981
|
this.customColors.add(formattedColor);
|
|
31896
31982
|
}
|
|
@@ -32895,8 +32981,8 @@ class InternalViewport {
|
|
|
32895
32981
|
this.getters = getters;
|
|
32896
32982
|
this.sheetId = sheetId;
|
|
32897
32983
|
this.boundaries = boundaries;
|
|
32898
|
-
this.
|
|
32899
|
-
this.
|
|
32984
|
+
this.viewportWidth = sizeInGrid.width;
|
|
32985
|
+
this.viewportHeight = sizeInGrid.height;
|
|
32900
32986
|
this.offsetScrollbarX = offsets.x;
|
|
32901
32987
|
this.offsetScrollbarY = offsets.y;
|
|
32902
32988
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -32907,6 +32993,10 @@ class InternalViewport {
|
|
|
32907
32993
|
this.adjustViewportOffsetY();
|
|
32908
32994
|
}
|
|
32909
32995
|
// PUBLIC
|
|
32996
|
+
/** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
|
|
32997
|
+
* When the viewport grid size is smaller than its client width (resp. height), it will return
|
|
32998
|
+
* the client width (resp. height).
|
|
32999
|
+
*/
|
|
32910
33000
|
getMaxSize() {
|
|
32911
33001
|
const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
|
|
32912
33002
|
first: this.boundaries.left,
|
|
@@ -32918,20 +33008,24 @@ class InternalViewport {
|
|
|
32918
33008
|
});
|
|
32919
33009
|
const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
|
|
32920
33010
|
const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
|
|
32921
|
-
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.
|
|
33011
|
+
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
|
|
32922
33012
|
const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
|
|
32923
|
-
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.
|
|
33013
|
+
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
|
|
32924
33014
|
const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
|
|
32925
|
-
|
|
32926
|
-
|
|
32927
|
-
(
|
|
32928
|
-
|
|
32929
|
-
|
|
32930
|
-
|
|
32931
|
-
|
|
32932
|
-
|
|
32933
|
-
|
|
32934
|
-
|
|
33015
|
+
let width = lastColEnd - this.offsetCorrectionX;
|
|
33016
|
+
if (this.canScrollHorizontally) {
|
|
33017
|
+
width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
|
|
33018
|
+
Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
|
|
33019
|
+
);
|
|
33020
|
+
width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
|
|
33021
|
+
}
|
|
33022
|
+
let height = lastRowEnd - this.offsetCorrectionY;
|
|
33023
|
+
if (this.canScrollVertically) {
|
|
33024
|
+
height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
|
|
33025
|
+
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
33026
|
+
);
|
|
33027
|
+
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
33028
|
+
}
|
|
32935
33029
|
return { width, height };
|
|
32936
33030
|
}
|
|
32937
33031
|
/**
|
|
@@ -32940,7 +33034,7 @@ class InternalViewport {
|
|
|
32940
33034
|
* It returns -1 if no column is found.
|
|
32941
33035
|
*/
|
|
32942
33036
|
getColIndex(x, absolute = false) {
|
|
32943
|
-
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.
|
|
33037
|
+
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
|
|
32944
33038
|
return -1;
|
|
32945
33039
|
}
|
|
32946
33040
|
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
|
|
@@ -32951,7 +33045,7 @@ class InternalViewport {
|
|
|
32951
33045
|
* It returns -1 if no row is found.
|
|
32952
33046
|
*/
|
|
32953
33047
|
getRowIndex(y, absolute = false) {
|
|
32954
|
-
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.
|
|
33048
|
+
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
|
|
32955
33049
|
return -1;
|
|
32956
33050
|
}
|
|
32957
33051
|
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
|
|
@@ -32978,7 +33072,7 @@ class InternalViewport {
|
|
|
32978
33072
|
adjustPositionX(col) {
|
|
32979
33073
|
const sheetId = this.sheetId;
|
|
32980
33074
|
const { start, end } = this.getters.getColDimensions(sheetId, col);
|
|
32981
|
-
while (end > this.offsetX + this.offsetCorrectionX + this.
|
|
33075
|
+
while (end > this.offsetX + this.offsetCorrectionX + this.viewportWidth &&
|
|
32982
33076
|
this.offsetX + this.offsetCorrectionX < start) {
|
|
32983
33077
|
this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
|
|
32984
33078
|
this.offsetScrollbarX = this.offsetX;
|
|
@@ -33000,7 +33094,7 @@ class InternalViewport {
|
|
|
33000
33094
|
adjustPositionY(row) {
|
|
33001
33095
|
const sheetId = this.sheetId;
|
|
33002
33096
|
while (this.getters.getRowDimensions(sheetId, row).end >
|
|
33003
|
-
this.offsetY + this.
|
|
33097
|
+
this.offsetY + this.viewportHeight + this.offsetCorrectionY &&
|
|
33004
33098
|
this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
|
|
33005
33099
|
this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
|
|
33006
33100
|
this.offsetScrollbarY = this.offsetY;
|
|
@@ -33038,8 +33132,8 @@ class InternalViewport {
|
|
|
33038
33132
|
const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
|
|
33039
33133
|
this.offsetCorrectionX;
|
|
33040
33134
|
const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
|
|
33041
|
-
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.
|
|
33042
|
-
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.
|
|
33135
|
+
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
|
|
33136
|
+
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
|
|
33043
33137
|
return {
|
|
33044
33138
|
x,
|
|
33045
33139
|
y,
|
|
@@ -33102,12 +33196,12 @@ class InternalViewport {
|
|
|
33102
33196
|
adjustViewportOffsetX() {
|
|
33103
33197
|
if (this.canScrollHorizontally) {
|
|
33104
33198
|
const { width: viewportWidth } = this.getMaxSize();
|
|
33105
|
-
if (this.
|
|
33106
|
-
this.offsetScrollbarX = Math.max(0, viewportWidth - this.
|
|
33199
|
+
if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
|
|
33200
|
+
this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
|
|
33107
33201
|
}
|
|
33108
33202
|
}
|
|
33109
33203
|
this.left = this.getColIndex(this.offsetScrollbarX, true);
|
|
33110
|
-
this.right = this.getColIndex(this.offsetScrollbarX + this.
|
|
33204
|
+
this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
|
|
33111
33205
|
if (this.right === -1) {
|
|
33112
33206
|
this.right = this.boundaries.right;
|
|
33113
33207
|
}
|
|
@@ -33119,12 +33213,12 @@ class InternalViewport {
|
|
|
33119
33213
|
adjustViewportOffsetY() {
|
|
33120
33214
|
if (this.canScrollVertically) {
|
|
33121
33215
|
const { height: paneHeight } = this.getMaxSize();
|
|
33122
|
-
if (this.
|
|
33123
|
-
this.offsetScrollbarY = Math.max(0, paneHeight - this.
|
|
33216
|
+
if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
|
|
33217
|
+
this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
|
|
33124
33218
|
}
|
|
33125
33219
|
}
|
|
33126
33220
|
this.top = this.getRowIndex(this.offsetScrollbarY, true);
|
|
33127
|
-
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.
|
|
33221
|
+
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
|
|
33128
33222
|
if (this.bottom === -1) {
|
|
33129
33223
|
this.bottom = this.boundaries.bottom;
|
|
33130
33224
|
}
|
|
@@ -33135,7 +33229,7 @@ class InternalViewport {
|
|
|
33135
33229
|
adjustViewportZoneX() {
|
|
33136
33230
|
const sheetId = this.sheetId;
|
|
33137
33231
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
33138
|
-
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.
|
|
33232
|
+
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
33139
33233
|
if (this.right === -1) {
|
|
33140
33234
|
this.right = this.getters.getNumberCols(sheetId) - 1;
|
|
33141
33235
|
}
|
|
@@ -33148,7 +33242,7 @@ class InternalViewport {
|
|
|
33148
33242
|
adjustViewportZoneY() {
|
|
33149
33243
|
const sheetId = this.sheetId;
|
|
33150
33244
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
33151
|
-
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.
|
|
33245
|
+
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
33152
33246
|
if (this.bottom === -1) {
|
|
33153
33247
|
this.bottom = this.getters.getNumberRows(sheetId) - 1;
|
|
33154
33248
|
}
|
|
@@ -33410,8 +33504,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
33410
33504
|
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
33411
33505
|
}
|
|
33412
33506
|
/**
|
|
33413
|
-
* Return the main viewport maximum size
|
|
33414
|
-
* with some bottom and right padding.
|
|
33507
|
+
* Return the main viewport maximum size relative to the client size.
|
|
33415
33508
|
*/
|
|
33416
33509
|
getMainViewportRect() {
|
|
33417
33510
|
const sheetId = this.getters.getActiveSheetId();
|
|
@@ -33427,8 +33520,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
33427
33520
|
const { width, height } = this.getMainViewportRect();
|
|
33428
33521
|
const viewport = this.getMainInternalViewport(sheetId);
|
|
33429
33522
|
return {
|
|
33430
|
-
maxOffsetX: Math.max(0, width - viewport.
|
|
33431
|
-
maxOffsetY: Math.max(0, height - viewport.
|
|
33523
|
+
maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
|
|
33524
|
+
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
33432
33525
|
};
|
|
33433
33526
|
}
|
|
33434
33527
|
getColRowOffsetInViewport(dimension, referenceIndex, index) {
|
|
@@ -40132,9 +40225,6 @@ css /* scss */ `
|
|
|
40132
40225
|
color: #333;
|
|
40133
40226
|
}
|
|
40134
40227
|
|
|
40135
|
-
* {
|
|
40136
|
-
font-family: "Roboto", "RobotoDraft", Helvetica, Arial, sans-serif;
|
|
40137
|
-
}
|
|
40138
40228
|
&,
|
|
40139
40229
|
*,
|
|
40140
40230
|
*:before,
|
|
@@ -43902,6 +43992,6 @@ function addFunction(functionName, functionDescription) {
|
|
|
43902
43992
|
export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
|
|
43903
43993
|
|
|
43904
43994
|
|
|
43905
|
-
__info__.version = '16.1.
|
|
43906
|
-
__info__.date = '2023-
|
|
43907
|
-
__info__.hash = '
|
|
43995
|
+
__info__.version = '16.1.7';
|
|
43996
|
+
__info__.date = '2023-04-13T08:29:52.140Z';
|
|
43997
|
+
__info__.hash = '3141a6d';
|