@odoo/o-spreadsheet 15.2.12 → 15.2.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.
- package/dist/o-spreadsheet.cjs.js +111 -60
- package/dist/o-spreadsheet.d.ts +2 -3
- package/dist/o-spreadsheet.esm.js +111 -60
- package/dist/o-spreadsheet.iife.js +111 -60
- package/dist/o-spreadsheet.iife.min.js +24 -24
- package/package.json +1 -1
|
@@ -128,14 +128,72 @@
|
|
|
128
128
|
// -----------------------------------------------------------------------------
|
|
129
129
|
// Date Type
|
|
130
130
|
// -----------------------------------------------------------------------------
|
|
131
|
+
/**
|
|
132
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
133
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
134
|
+
* and it is timezone-agnostic.
|
|
135
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
136
|
+
*/
|
|
137
|
+
class DateTime {
|
|
138
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
139
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
140
|
+
}
|
|
141
|
+
static fromTimestamp(timestamp) {
|
|
142
|
+
const date = new Date(timestamp);
|
|
143
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
144
|
+
}
|
|
145
|
+
static now() {
|
|
146
|
+
const now = new Date();
|
|
147
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
148
|
+
}
|
|
149
|
+
toString() {
|
|
150
|
+
return this.jsDate.toString();
|
|
151
|
+
}
|
|
152
|
+
getTime() {
|
|
153
|
+
return this.jsDate.getTime();
|
|
154
|
+
}
|
|
155
|
+
getFullYear() {
|
|
156
|
+
return this.jsDate.getUTCFullYear();
|
|
157
|
+
}
|
|
158
|
+
getMonth() {
|
|
159
|
+
return this.jsDate.getUTCMonth();
|
|
160
|
+
}
|
|
161
|
+
getDate() {
|
|
162
|
+
return this.jsDate.getUTCDate();
|
|
163
|
+
}
|
|
164
|
+
getDay() {
|
|
165
|
+
return this.jsDate.getUTCDay();
|
|
166
|
+
}
|
|
167
|
+
getHours() {
|
|
168
|
+
return this.jsDate.getUTCHours();
|
|
169
|
+
}
|
|
170
|
+
getMinutes() {
|
|
171
|
+
return this.jsDate.getUTCMinutes();
|
|
172
|
+
}
|
|
173
|
+
getSeconds() {
|
|
174
|
+
return this.jsDate.getUTCSeconds();
|
|
175
|
+
}
|
|
176
|
+
setDate(date) {
|
|
177
|
+
this.jsDate.setUTCDate(date);
|
|
178
|
+
}
|
|
179
|
+
setHours(hours) {
|
|
180
|
+
this.jsDate.setUTCHours(hours);
|
|
181
|
+
}
|
|
182
|
+
setMinutes(minutes) {
|
|
183
|
+
this.jsDate.setUTCMinutes(minutes);
|
|
184
|
+
}
|
|
185
|
+
setSeconds(seconds) {
|
|
186
|
+
this.jsDate.setUTCSeconds(seconds);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
131
189
|
// -----------------------------------------------------------------------------
|
|
132
190
|
// Parsing
|
|
133
191
|
// -----------------------------------------------------------------------------
|
|
134
192
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
135
|
-
const CURRENT_YEAR =
|
|
136
|
-
const INITIAL_1900_DAY$1 = new
|
|
137
|
-
const INITIAL_JS_DAY =
|
|
138
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY$1;
|
|
193
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
194
|
+
const INITIAL_1900_DAY$1 = new DateTime(1899, 11, 30);
|
|
195
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
196
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY$1.getTime();
|
|
139
197
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
140
198
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
141
199
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
@@ -175,7 +233,7 @@
|
|
|
175
233
|
return {
|
|
176
234
|
value: date.value + time.value,
|
|
177
235
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
178
|
-
jsDate: new
|
|
236
|
+
jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
|
|
179
237
|
};
|
|
180
238
|
}
|
|
181
239
|
return date || time;
|
|
@@ -192,13 +250,13 @@
|
|
|
192
250
|
const day = Number(parts[dayIndex]);
|
|
193
251
|
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
|
|
194
252
|
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
|
|
195
|
-
const jsDate = new
|
|
253
|
+
const jsDate = new DateTime(year, month - 1, day);
|
|
196
254
|
const sep = str.match(/\/|-|\s/)[0];
|
|
197
255
|
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
|
|
198
256
|
// invalid date
|
|
199
257
|
return null;
|
|
200
258
|
}
|
|
201
|
-
const delta = jsDate - INITIAL_1900_DAY$1;
|
|
259
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY$1.getTime();
|
|
202
260
|
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
|
|
203
261
|
if (parts[yearIndex]) {
|
|
204
262
|
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
|
|
@@ -258,7 +316,7 @@
|
|
|
258
316
|
if (hours >= 24) {
|
|
259
317
|
format = "hhhh:mm:ss";
|
|
260
318
|
}
|
|
261
|
-
const jsDate = new
|
|
319
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
262
320
|
return {
|
|
263
321
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
264
322
|
format: format,
|
|
@@ -272,7 +330,7 @@
|
|
|
272
330
|
// -----------------------------------------------------------------------------
|
|
273
331
|
function numberToJsDate(value) {
|
|
274
332
|
const truncValue = Math.trunc(value);
|
|
275
|
-
let date =
|
|
333
|
+
let date = DateTime.fromTimestamp(truncValue * 86400 * 1000 - DATE_JS_1900_OFFSET);
|
|
276
334
|
let time = value - truncValue;
|
|
277
335
|
time = time < 0 ? 1 + time : time;
|
|
278
336
|
const hours = Math.round(time * 24);
|
|
@@ -345,7 +403,7 @@
|
|
|
345
403
|
.map((p) => {
|
|
346
404
|
switch (p) {
|
|
347
405
|
case "hhhh":
|
|
348
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY$1) / (60 * 60 * 1000));
|
|
406
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY$1.getTime()) / (60 * 60 * 1000));
|
|
349
407
|
return helapsedHours.toString();
|
|
350
408
|
case "hh":
|
|
351
409
|
return hours.toString().padStart(2, "0");
|
|
@@ -2706,13 +2764,6 @@
|
|
|
2706
2764
|
}
|
|
2707
2765
|
|
|
2708
2766
|
//------------------------------------------------------------------------------
|
|
2709
|
-
/**
|
|
2710
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
2711
|
-
* is ordered.
|
|
2712
|
-
*/
|
|
2713
|
-
function stringify(obj) {
|
|
2714
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
2715
|
-
}
|
|
2716
2767
|
/**
|
|
2717
2768
|
* Remove quotes from a quoted string
|
|
2718
2769
|
* ```js
|
|
@@ -2871,7 +2922,7 @@
|
|
|
2871
2922
|
function isDateTime(str) {
|
|
2872
2923
|
return parseDateTime(str) !== null;
|
|
2873
2924
|
}
|
|
2874
|
-
const MARKDOWN_LINK_REGEX = /^\[(
|
|
2925
|
+
const MARKDOWN_LINK_REGEX = /^\[(.+)\]\((.+)\)$/;
|
|
2875
2926
|
//link must start with http or https
|
|
2876
2927
|
//https://stackoverflow.com/a/3809435/4760614
|
|
2877
2928
|
const WEB_LINK_REGEX = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;
|
|
@@ -2937,7 +2988,7 @@
|
|
|
2937
2988
|
*/
|
|
2938
2989
|
function getItemId(item, itemsDic) {
|
|
2939
2990
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
2940
|
-
if (
|
|
2991
|
+
if (deepEquals(value, item)) {
|
|
2941
2992
|
return parseInt(key, 10);
|
|
2942
2993
|
}
|
|
2943
2994
|
}
|
|
@@ -4747,7 +4798,7 @@
|
|
|
4747
4798
|
DVARP: DVARP
|
|
4748
4799
|
});
|
|
4749
4800
|
|
|
4750
|
-
const INITIAL_1900_DAY = new
|
|
4801
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
4751
4802
|
const DEFAULT_TYPE = 1;
|
|
4752
4803
|
const DEFAULT_WEEKEND = 1;
|
|
4753
4804
|
function isLeapYear(year) {
|
|
@@ -4776,7 +4827,7 @@
|
|
|
4776
4827
|
if (_year < 1900) {
|
|
4777
4828
|
_year += 1900;
|
|
4778
4829
|
}
|
|
4779
|
-
const jsDate = new
|
|
4830
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
4780
4831
|
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
4781
4832
|
assert(() => delta >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
|
|
4782
4833
|
return Math.round(delta / 86400000);
|
|
@@ -4849,7 +4900,7 @@
|
|
|
4849
4900
|
const yStart = _startDate.getFullYear();
|
|
4850
4901
|
const mStart = _startDate.getMonth();
|
|
4851
4902
|
const dStart = _startDate.getDate();
|
|
4852
|
-
const jsDate = new
|
|
4903
|
+
const jsDate = new DateTime(yStart, mStart + _months, dStart);
|
|
4853
4904
|
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
4854
4905
|
return Math.round(delta / 86400000);
|
|
4855
4906
|
},
|
|
@@ -4871,7 +4922,7 @@
|
|
|
4871
4922
|
const _months = Math.trunc(toNumber(months));
|
|
4872
4923
|
const yStart = _startDate.getFullYear();
|
|
4873
4924
|
const mStart = _startDate.getMonth();
|
|
4874
|
-
const jsDate = new
|
|
4925
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
4875
4926
|
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
4876
4927
|
return Math.round(delta / 86400000);
|
|
4877
4928
|
},
|
|
@@ -4911,17 +4962,17 @@
|
|
|
4911
4962
|
// The first week of the year is the week that contains the first
|
|
4912
4963
|
// Thursday of the year.
|
|
4913
4964
|
let firstThursday = 1;
|
|
4914
|
-
while (new
|
|
4965
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
4915
4966
|
firstThursday += 1;
|
|
4916
4967
|
}
|
|
4917
|
-
const firstDayOfFirstWeek = new
|
|
4968
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
4918
4969
|
// The last week of the year is the week that contains the last Thursday of
|
|
4919
4970
|
// the year.
|
|
4920
4971
|
let lastThursday = 31;
|
|
4921
|
-
while (new
|
|
4972
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
4922
4973
|
lastThursday -= 1;
|
|
4923
4974
|
}
|
|
4924
|
-
const lastDayOfLastWeek = new
|
|
4975
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
4925
4976
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
4926
4977
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
4927
4978
|
let offsetYear;
|
|
@@ -4947,17 +4998,17 @@
|
|
|
4947
4998
|
case 1:
|
|
4948
4999
|
// firstDay is the 1st day of the 1st week of the year after
|
|
4949
5000
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
4950
|
-
firstDay = new
|
|
5001
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
4951
5002
|
break;
|
|
4952
5003
|
case -1:
|
|
4953
5004
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
4954
5005
|
// The first week of the previous year is the week that contains the
|
|
4955
5006
|
// first Thursday of the previous year.
|
|
4956
5007
|
let firstThursdayPreviousYear = 1;
|
|
4957
|
-
while (new
|
|
5008
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
4958
5009
|
firstThursdayPreviousYear += 1;
|
|
4959
5010
|
}
|
|
4960
|
-
firstDay = new
|
|
5011
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
4961
5012
|
break;
|
|
4962
5013
|
}
|
|
4963
5014
|
const dif = (_date.getTime() - firstDay.getTime()) / 86400000;
|
|
@@ -5096,8 +5147,8 @@
|
|
|
5096
5147
|
});
|
|
5097
5148
|
}
|
|
5098
5149
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
5099
|
-
const stopDate =
|
|
5100
|
-
let stepDate =
|
|
5150
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
5151
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
5101
5152
|
const timeStopDate = stopDate.getTime();
|
|
5102
5153
|
let timeStepDate = stepDate.getTime();
|
|
5103
5154
|
let netWorkingDay = 0;
|
|
@@ -5121,8 +5172,7 @@
|
|
|
5121
5172
|
returns: ["DATE"],
|
|
5122
5173
|
returnFormat: { specificFormat: "m/d/yyyy hh:mm:ss" },
|
|
5123
5174
|
compute: function () {
|
|
5124
|
-
let today =
|
|
5125
|
-
today.setMilliseconds(0);
|
|
5175
|
+
let today = DateTime.now();
|
|
5126
5176
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
5127
5177
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
5128
5178
|
return Math.floor(delta / 86400000) + time;
|
|
@@ -5196,8 +5246,8 @@
|
|
|
5196
5246
|
returns: ["DATE"],
|
|
5197
5247
|
returnFormat: { specificFormat: "m/d/yyyy" },
|
|
5198
5248
|
compute: function () {
|
|
5199
|
-
const today =
|
|
5200
|
-
const jsDate = new
|
|
5249
|
+
const today = DateTime.now();
|
|
5250
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
5201
5251
|
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
5202
5252
|
return Math.round(delta / 86400000);
|
|
5203
5253
|
},
|
|
@@ -5253,10 +5303,10 @@
|
|
|
5253
5303
|
}
|
|
5254
5304
|
const y = _date.getFullYear();
|
|
5255
5305
|
let dayStart = 1;
|
|
5256
|
-
let startDayOfFirstWeek = new
|
|
5306
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
5257
5307
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
5258
5308
|
dayStart += 1;
|
|
5259
|
-
startDayOfFirstWeek = new
|
|
5309
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
5260
5310
|
}
|
|
5261
5311
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / 86400000;
|
|
5262
5312
|
if (dif < 0) {
|
|
@@ -5310,7 +5360,7 @@
|
|
|
5310
5360
|
timesHoliday.add(holiday.getTime());
|
|
5311
5361
|
});
|
|
5312
5362
|
}
|
|
5313
|
-
let stepDate =
|
|
5363
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
5314
5364
|
let timeStepDate = stepDate.getTime();
|
|
5315
5365
|
const unitDay = Math.sign(_numDays);
|
|
5316
5366
|
let stepDay = Math.abs(_numDays);
|
|
@@ -9402,7 +9452,7 @@
|
|
|
9402
9452
|
*/
|
|
9403
9453
|
function getBorderId(border) {
|
|
9404
9454
|
for (let [key, value] of Object.entries(borders)) {
|
|
9405
|
-
if (
|
|
9455
|
+
if (deepEquals(value, border)) {
|
|
9406
9456
|
return parseInt(key, 10);
|
|
9407
9457
|
}
|
|
9408
9458
|
}
|
|
@@ -9640,12 +9690,10 @@
|
|
|
9640
9690
|
* starting an async evaluation even if it has been moved or re-allocated
|
|
9641
9691
|
*/
|
|
9642
9692
|
getCellById(cellId) {
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
}
|
|
9648
|
-
return undefined;
|
|
9693
|
+
// this must be as fast as possible
|
|
9694
|
+
const position = this.getters.getCellPosition(cellId);
|
|
9695
|
+
const sheet = this.cells[position.sheetId];
|
|
9696
|
+
return sheet[cellId];
|
|
9649
9697
|
}
|
|
9650
9698
|
/**
|
|
9651
9699
|
* Try to infer the cell format based on the formula dependencies.
|
|
@@ -23410,9 +23458,9 @@
|
|
|
23410
23458
|
* Apply the changes of the given HistoryChange to the state
|
|
23411
23459
|
*/
|
|
23412
23460
|
function applyChange(change, target) {
|
|
23413
|
-
let val = change.
|
|
23414
|
-
|
|
23415
|
-
for (let pathIndex =
|
|
23461
|
+
let val = change.path[0];
|
|
23462
|
+
const key = change.path[change.path.length - 1];
|
|
23463
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
23416
23464
|
const p = change.path[pathIndex];
|
|
23417
23465
|
if (val[p] === undefined) {
|
|
23418
23466
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -23868,13 +23916,14 @@
|
|
|
23868
23916
|
}
|
|
23869
23917
|
addChange(...args) {
|
|
23870
23918
|
const val = args.pop();
|
|
23871
|
-
const
|
|
23919
|
+
const root = args[0];
|
|
23872
23920
|
let value = root;
|
|
23873
|
-
let key =
|
|
23874
|
-
|
|
23875
|
-
|
|
23921
|
+
let key = args[args.length - 1];
|
|
23922
|
+
const pathLength = args.length - 2;
|
|
23923
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
23924
|
+
const p = args[pathIndex];
|
|
23876
23925
|
if (value[p] === undefined) {
|
|
23877
|
-
const nextPath =
|
|
23926
|
+
const nextPath = args[pathIndex + 1];
|
|
23878
23927
|
value[p] = createEmptyStructure(nextPath);
|
|
23879
23928
|
}
|
|
23880
23929
|
value = value[p];
|
|
@@ -23883,8 +23932,7 @@
|
|
|
23883
23932
|
return;
|
|
23884
23933
|
}
|
|
23885
23934
|
this.changes.push({
|
|
23886
|
-
|
|
23887
|
-
path,
|
|
23935
|
+
path: args,
|
|
23888
23936
|
before: value[key],
|
|
23889
23937
|
after: val,
|
|
23890
23938
|
});
|
|
@@ -25924,7 +25972,10 @@
|
|
|
25924
25972
|
*/
|
|
25925
25973
|
checkDispatchAllowed(command) {
|
|
25926
25974
|
const results = this.handlers.map((handler) => handler.allowDispatch(command));
|
|
25927
|
-
|
|
25975
|
+
if (results.some((r) => r !== 0 /* Success */)) {
|
|
25976
|
+
return new DispatchResult(results.flat());
|
|
25977
|
+
}
|
|
25978
|
+
return DispatchResult.Success;
|
|
25928
25979
|
}
|
|
25929
25980
|
finalize() {
|
|
25930
25981
|
this.status = 3 /* Finalizing */;
|
|
@@ -31388,9 +31439,9 @@
|
|
|
31388
31439
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
31389
31440
|
|
|
31390
31441
|
|
|
31391
|
-
__info__.version = '15.2.
|
|
31392
|
-
__info__.date = '
|
|
31393
|
-
__info__.hash = '
|
|
31442
|
+
__info__.version = '15.2.14';
|
|
31443
|
+
__info__.date = '2024-01-12T13:37:05.872Z';
|
|
31444
|
+
__info__.hash = '6515f7c';
|
|
31394
31445
|
|
|
31395
31446
|
|
|
31396
31447
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|