@odoo/o-spreadsheet 16.4.0-alpha.1 → 16.4.0-alpha.2
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 +379 -277
- package/dist/o-spreadsheet.d.ts +26 -6
- package/dist/o-spreadsheet.esm.js +378 -278
- package/dist/o-spreadsheet.iife.js +379 -277
- package/dist/o-spreadsheet.iife.min.js +35 -34
- package/package.json +1 -1
|
@@ -2214,249 +2214,6 @@ function splitReference(ref) {
|
|
|
2214
2214
|
return { sheetName, xc };
|
|
2215
2215
|
}
|
|
2216
2216
|
|
|
2217
|
-
class RangeImpl {
|
|
2218
|
-
getSheetSize;
|
|
2219
|
-
_zone;
|
|
2220
|
-
parts;
|
|
2221
|
-
invalidXc;
|
|
2222
|
-
prefixSheet = false;
|
|
2223
|
-
sheetId; // the sheet on which the range is defined
|
|
2224
|
-
invalidSheetName; // the name of any sheet that is invalid
|
|
2225
|
-
constructor(args, getSheetSize) {
|
|
2226
|
-
this.getSheetSize = getSheetSize;
|
|
2227
|
-
this._zone = args.zone;
|
|
2228
|
-
this.parts = args.parts;
|
|
2229
|
-
this.prefixSheet = args.prefixSheet;
|
|
2230
|
-
this.invalidXc = args.invalidXc;
|
|
2231
|
-
this.sheetId = args.sheetId;
|
|
2232
|
-
this.invalidSheetName = args.invalidSheetName;
|
|
2233
|
-
}
|
|
2234
|
-
static fromRange(range, getters) {
|
|
2235
|
-
if (range instanceof RangeImpl) {
|
|
2236
|
-
return range;
|
|
2237
|
-
}
|
|
2238
|
-
return new RangeImpl(range, getters.getSheetSize);
|
|
2239
|
-
}
|
|
2240
|
-
get unboundedZone() {
|
|
2241
|
-
return this._zone;
|
|
2242
|
-
}
|
|
2243
|
-
get zone() {
|
|
2244
|
-
const { left, top, bottom, right } = this._zone;
|
|
2245
|
-
if (right !== undefined && bottom !== undefined)
|
|
2246
|
-
return { left, top, right, bottom };
|
|
2247
|
-
else if (bottom === undefined && right !== undefined) {
|
|
2248
|
-
return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
|
|
2249
|
-
}
|
|
2250
|
-
else if (right === undefined && bottom !== undefined) {
|
|
2251
|
-
return { bottom, left, top, right: this.getSheetSize(this.sheetId).numberOfCols - 1 };
|
|
2252
|
-
}
|
|
2253
|
-
throw new Error(_lt("Bad zone format"));
|
|
2254
|
-
}
|
|
2255
|
-
static getRangeParts(xc, zone) {
|
|
2256
|
-
const parts = xc.split(":").map((p) => {
|
|
2257
|
-
const isFullRow = isRowReference(p);
|
|
2258
|
-
return {
|
|
2259
|
-
colFixed: isFullRow ? false : p.startsWith("$"),
|
|
2260
|
-
rowFixed: isFullRow ? p.startsWith("$") : p.includes("$", 1),
|
|
2261
|
-
};
|
|
2262
|
-
});
|
|
2263
|
-
const isFullCol = zone.bottom === undefined;
|
|
2264
|
-
const isFullRow = zone.right === undefined;
|
|
2265
|
-
if (isFullCol) {
|
|
2266
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2267
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2268
|
-
if (zone.left === zone.right) {
|
|
2269
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2270
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
if (isFullRow) {
|
|
2274
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2275
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2276
|
-
if (zone.top === zone.bottom) {
|
|
2277
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2278
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
return parts;
|
|
2282
|
-
}
|
|
2283
|
-
get isFullCol() {
|
|
2284
|
-
return this._zone.bottom === undefined;
|
|
2285
|
-
}
|
|
2286
|
-
get isFullRow() {
|
|
2287
|
-
return this._zone.right === undefined;
|
|
2288
|
-
}
|
|
2289
|
-
get rangeData() {
|
|
2290
|
-
return {
|
|
2291
|
-
_zone: this._zone,
|
|
2292
|
-
_sheetId: this.sheetId,
|
|
2293
|
-
};
|
|
2294
|
-
}
|
|
2295
|
-
/**
|
|
2296
|
-
* Check that a zone is valid regarding the order of top-bottom and left-right.
|
|
2297
|
-
* Left should be smaller than right, top should be smaller than bottom.
|
|
2298
|
-
* If it's not the case, simply invert them, and invert the linked parts
|
|
2299
|
-
*/
|
|
2300
|
-
orderZone() {
|
|
2301
|
-
const zone = { ...this._zone };
|
|
2302
|
-
let parts = this.parts;
|
|
2303
|
-
if (zone.right !== undefined && zone.right < zone.left) {
|
|
2304
|
-
let right = zone.right;
|
|
2305
|
-
zone.right = zone.left;
|
|
2306
|
-
zone.left = right;
|
|
2307
|
-
parts = [
|
|
2308
|
-
{
|
|
2309
|
-
colFixed: parts[1]?.colFixed || false,
|
|
2310
|
-
rowFixed: parts[0]?.rowFixed || false,
|
|
2311
|
-
},
|
|
2312
|
-
{
|
|
2313
|
-
colFixed: parts[0]?.colFixed || false,
|
|
2314
|
-
rowFixed: parts[1]?.rowFixed || false,
|
|
2315
|
-
},
|
|
2316
|
-
];
|
|
2317
|
-
}
|
|
2318
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2319
|
-
let bottom = zone.bottom;
|
|
2320
|
-
zone.bottom = zone.top;
|
|
2321
|
-
zone.top = bottom;
|
|
2322
|
-
parts = [
|
|
2323
|
-
{
|
|
2324
|
-
colFixed: parts[0]?.colFixed || false,
|
|
2325
|
-
rowFixed: parts[1]?.rowFixed || false,
|
|
2326
|
-
},
|
|
2327
|
-
{
|
|
2328
|
-
colFixed: parts[1]?.colFixed || false,
|
|
2329
|
-
rowFixed: parts[0]?.rowFixed || false,
|
|
2330
|
-
},
|
|
2331
|
-
];
|
|
2332
|
-
}
|
|
2333
|
-
return this.clone({ zone, parts });
|
|
2334
|
-
}
|
|
2335
|
-
/**
|
|
2336
|
-
*
|
|
2337
|
-
* @param rangeParams optional, values to put in the cloned range instead of the current values of the range
|
|
2338
|
-
*/
|
|
2339
|
-
clone(rangeParams) {
|
|
2340
|
-
return new RangeImpl({
|
|
2341
|
-
zone: rangeParams?.zone ? rangeParams.zone : { ...this._zone },
|
|
2342
|
-
sheetId: rangeParams?.sheetId ? rangeParams.sheetId : this.sheetId,
|
|
2343
|
-
invalidSheetName: rangeParams && "invalidSheetName" in rangeParams // 'attr in obj' instead of just 'obj.attr' because we accept undefined values
|
|
2344
|
-
? rangeParams.invalidSheetName
|
|
2345
|
-
: this.invalidSheetName,
|
|
2346
|
-
invalidXc: rangeParams && "invalidXc" in rangeParams ? rangeParams.invalidXc : this.invalidXc,
|
|
2347
|
-
parts: rangeParams?.parts
|
|
2348
|
-
? rangeParams.parts
|
|
2349
|
-
: this.parts.map((part) => {
|
|
2350
|
-
return { rowFixed: part.rowFixed, colFixed: part.colFixed };
|
|
2351
|
-
}),
|
|
2352
|
-
prefixSheet: rangeParams?.prefixSheet ? rangeParams.prefixSheet : this.prefixSheet,
|
|
2353
|
-
}, this.getSheetSize);
|
|
2354
|
-
}
|
|
2355
|
-
}
|
|
2356
|
-
/**
|
|
2357
|
-
* Copy a range. If the range is on the sheetIdFrom, the range will target
|
|
2358
|
-
* sheetIdTo.
|
|
2359
|
-
*/
|
|
2360
|
-
function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
2361
|
-
const sheetId = range.sheetId === sheetIdFrom ? sheetIdTo : range.sheetId;
|
|
2362
|
-
return range.clone({ sheetId });
|
|
2363
|
-
}
|
|
2364
|
-
/**
|
|
2365
|
-
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
2366
|
-
*/
|
|
2367
|
-
function createRange(getters, sheetId, range) {
|
|
2368
|
-
return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
|
|
2369
|
-
}
|
|
2370
|
-
|
|
2371
|
-
/** Methods from Odoo Web Utils */
|
|
2372
|
-
/**
|
|
2373
|
-
* This function computes a score that represent the fact that the
|
|
2374
|
-
* string contains the pattern, or not
|
|
2375
|
-
*
|
|
2376
|
-
* - If the score is 0, the string does not contain the letters of the pattern in
|
|
2377
|
-
* the correct order.
|
|
2378
|
-
* - if the score is > 0, it actually contains the letters.
|
|
2379
|
-
*
|
|
2380
|
-
* Better matches will get a higher score: consecutive letters are better,
|
|
2381
|
-
* and a match closer to the beginning of the string is also scored higher.
|
|
2382
|
-
*/
|
|
2383
|
-
function fuzzyMatch(pattern, str) {
|
|
2384
|
-
pattern = pattern.toLocaleLowerCase();
|
|
2385
|
-
str = str.toLocaleLowerCase();
|
|
2386
|
-
let totalScore = 0;
|
|
2387
|
-
let currentScore = 0;
|
|
2388
|
-
let len = str.length;
|
|
2389
|
-
let patternIndex = 0;
|
|
2390
|
-
for (let i = 0; i < len; i++) {
|
|
2391
|
-
if (str[i] === pattern[patternIndex]) {
|
|
2392
|
-
patternIndex++;
|
|
2393
|
-
currentScore += 100 + currentScore - i / 200;
|
|
2394
|
-
}
|
|
2395
|
-
else {
|
|
2396
|
-
currentScore = 0;
|
|
2397
|
-
}
|
|
2398
|
-
totalScore = totalScore + currentScore;
|
|
2399
|
-
}
|
|
2400
|
-
return patternIndex === pattern.length ? totalScore : 0;
|
|
2401
|
-
}
|
|
2402
|
-
/**
|
|
2403
|
-
* Return a list of things that matches a pattern, ordered by their 'score' (
|
|
2404
|
-
* higher score first). An higher score means that the match is better. For
|
|
2405
|
-
* example, consecutive letters are considered a better match.
|
|
2406
|
-
*/
|
|
2407
|
-
function fuzzyLookup(pattern, list, fn) {
|
|
2408
|
-
const results = [];
|
|
2409
|
-
list.forEach((data) => {
|
|
2410
|
-
const score = fuzzyMatch(pattern, fn(data));
|
|
2411
|
-
if (score > 0) {
|
|
2412
|
-
results.push({ score, elem: data });
|
|
2413
|
-
}
|
|
2414
|
-
});
|
|
2415
|
-
// we want better matches first
|
|
2416
|
-
results.sort((a, b) => b.score - a.score);
|
|
2417
|
-
return results.map((r) => r.elem);
|
|
2418
|
-
}
|
|
2419
|
-
|
|
2420
|
-
function createDefaultRows(rowNumber) {
|
|
2421
|
-
const rows = [];
|
|
2422
|
-
for (let i = 0; i < rowNumber; i++) {
|
|
2423
|
-
const row = {
|
|
2424
|
-
cells: {},
|
|
2425
|
-
};
|
|
2426
|
-
rows.push(row);
|
|
2427
|
-
}
|
|
2428
|
-
return rows;
|
|
2429
|
-
}
|
|
2430
|
-
|
|
2431
|
-
/*
|
|
2432
|
-
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
|
|
2433
|
-
* */
|
|
2434
|
-
class UuidGenerator {
|
|
2435
|
-
isFastIdStrategy = false;
|
|
2436
|
-
fastIdStart = 0;
|
|
2437
|
-
setIsFastStrategy(isFast) {
|
|
2438
|
-
this.isFastIdStrategy = isFast;
|
|
2439
|
-
}
|
|
2440
|
-
uuidv4() {
|
|
2441
|
-
if (this.isFastIdStrategy) {
|
|
2442
|
-
this.fastIdStart++;
|
|
2443
|
-
return String(this.fastIdStart);
|
|
2444
|
-
//@ts-ignore
|
|
2445
|
-
}
|
|
2446
|
-
else if (window.crypto && window.crypto.getRandomValues) {
|
|
2447
|
-
//@ts-ignore
|
|
2448
|
-
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
|
|
2449
|
-
}
|
|
2450
|
-
else {
|
|
2451
|
-
// mainly for jest and other browsers that do not have the crypto functionality
|
|
2452
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
2453
|
-
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
2454
|
-
return v.toString(16);
|
|
2455
|
-
});
|
|
2456
|
-
}
|
|
2457
|
-
}
|
|
2458
|
-
}
|
|
2459
|
-
|
|
2460
2217
|
/**
|
|
2461
2218
|
* Convert from a cartesian reference to a Zone
|
|
2462
2219
|
* The range boundaries will be kept in the same order as the
|
|
@@ -3063,6 +2820,287 @@ function getZonesRows(zones) {
|
|
|
3063
2820
|
return set;
|
|
3064
2821
|
}
|
|
3065
2822
|
|
|
2823
|
+
class RangeImpl {
|
|
2824
|
+
getSheetSize;
|
|
2825
|
+
_zone;
|
|
2826
|
+
parts;
|
|
2827
|
+
invalidXc;
|
|
2828
|
+
prefixSheet = false;
|
|
2829
|
+
sheetId; // the sheet on which the range is defined
|
|
2830
|
+
invalidSheetName; // the name of any sheet that is invalid
|
|
2831
|
+
constructor(args, getSheetSize) {
|
|
2832
|
+
this.getSheetSize = getSheetSize;
|
|
2833
|
+
this._zone = args.zone;
|
|
2834
|
+
this.parts = args.parts;
|
|
2835
|
+
this.prefixSheet = args.prefixSheet;
|
|
2836
|
+
this.invalidXc = args.invalidXc;
|
|
2837
|
+
this.sheetId = args.sheetId;
|
|
2838
|
+
this.invalidSheetName = args.invalidSheetName;
|
|
2839
|
+
}
|
|
2840
|
+
static fromRange(range, getters) {
|
|
2841
|
+
if (range instanceof RangeImpl) {
|
|
2842
|
+
return range;
|
|
2843
|
+
}
|
|
2844
|
+
return new RangeImpl(range, getters.getSheetSize);
|
|
2845
|
+
}
|
|
2846
|
+
get unboundedZone() {
|
|
2847
|
+
return this._zone;
|
|
2848
|
+
}
|
|
2849
|
+
get zone() {
|
|
2850
|
+
const { left, top, bottom, right } = this._zone;
|
|
2851
|
+
if (right !== undefined && bottom !== undefined)
|
|
2852
|
+
return { left, top, right, bottom };
|
|
2853
|
+
else if (bottom === undefined && right !== undefined) {
|
|
2854
|
+
return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
|
|
2855
|
+
}
|
|
2856
|
+
else if (right === undefined && bottom !== undefined) {
|
|
2857
|
+
return { bottom, left, top, right: this.getSheetSize(this.sheetId).numberOfCols - 1 };
|
|
2858
|
+
}
|
|
2859
|
+
throw new Error(_lt("Bad zone format"));
|
|
2860
|
+
}
|
|
2861
|
+
static getRangeParts(xc, zone) {
|
|
2862
|
+
const parts = xc.split(":").map((p) => {
|
|
2863
|
+
const isFullRow = isRowReference(p);
|
|
2864
|
+
return {
|
|
2865
|
+
colFixed: isFullRow ? false : p.startsWith("$"),
|
|
2866
|
+
rowFixed: isFullRow ? p.startsWith("$") : p.includes("$", 1),
|
|
2867
|
+
};
|
|
2868
|
+
});
|
|
2869
|
+
const isFullCol = zone.bottom === undefined;
|
|
2870
|
+
const isFullRow = zone.right === undefined;
|
|
2871
|
+
if (isFullCol) {
|
|
2872
|
+
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2873
|
+
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2874
|
+
if (zone.left === zone.right) {
|
|
2875
|
+
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2876
|
+
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
if (isFullRow) {
|
|
2880
|
+
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2881
|
+
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2882
|
+
if (zone.top === zone.bottom) {
|
|
2883
|
+
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2884
|
+
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
return parts;
|
|
2888
|
+
}
|
|
2889
|
+
get isFullCol() {
|
|
2890
|
+
return this._zone.bottom === undefined;
|
|
2891
|
+
}
|
|
2892
|
+
get isFullRow() {
|
|
2893
|
+
return this._zone.right === undefined;
|
|
2894
|
+
}
|
|
2895
|
+
get rangeData() {
|
|
2896
|
+
return {
|
|
2897
|
+
_zone: this._zone,
|
|
2898
|
+
_sheetId: this.sheetId,
|
|
2899
|
+
};
|
|
2900
|
+
}
|
|
2901
|
+
/**
|
|
2902
|
+
* Check that a zone is valid regarding the order of top-bottom and left-right.
|
|
2903
|
+
* Left should be smaller than right, top should be smaller than bottom.
|
|
2904
|
+
* If it's not the case, simply invert them, and invert the linked parts
|
|
2905
|
+
*/
|
|
2906
|
+
orderZone() {
|
|
2907
|
+
const zone = { ...this._zone };
|
|
2908
|
+
let parts = this.parts;
|
|
2909
|
+
if (zone.right !== undefined && zone.right < zone.left) {
|
|
2910
|
+
let right = zone.right;
|
|
2911
|
+
zone.right = zone.left;
|
|
2912
|
+
zone.left = right;
|
|
2913
|
+
parts = [
|
|
2914
|
+
{
|
|
2915
|
+
colFixed: parts[1]?.colFixed || false,
|
|
2916
|
+
rowFixed: parts[0]?.rowFixed || false,
|
|
2917
|
+
},
|
|
2918
|
+
{
|
|
2919
|
+
colFixed: parts[0]?.colFixed || false,
|
|
2920
|
+
rowFixed: parts[1]?.rowFixed || false,
|
|
2921
|
+
},
|
|
2922
|
+
];
|
|
2923
|
+
}
|
|
2924
|
+
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2925
|
+
let bottom = zone.bottom;
|
|
2926
|
+
zone.bottom = zone.top;
|
|
2927
|
+
zone.top = bottom;
|
|
2928
|
+
parts = [
|
|
2929
|
+
{
|
|
2930
|
+
colFixed: parts[0]?.colFixed || false,
|
|
2931
|
+
rowFixed: parts[1]?.rowFixed || false,
|
|
2932
|
+
},
|
|
2933
|
+
{
|
|
2934
|
+
colFixed: parts[1]?.colFixed || false,
|
|
2935
|
+
rowFixed: parts[0]?.rowFixed || false,
|
|
2936
|
+
},
|
|
2937
|
+
];
|
|
2938
|
+
}
|
|
2939
|
+
return this.clone({ zone, parts });
|
|
2940
|
+
}
|
|
2941
|
+
/**
|
|
2942
|
+
*
|
|
2943
|
+
* @param rangeParams optional, values to put in the cloned range instead of the current values of the range
|
|
2944
|
+
*/
|
|
2945
|
+
clone(rangeParams) {
|
|
2946
|
+
return new RangeImpl({
|
|
2947
|
+
zone: rangeParams?.zone ? rangeParams.zone : { ...this._zone },
|
|
2948
|
+
sheetId: rangeParams?.sheetId ? rangeParams.sheetId : this.sheetId,
|
|
2949
|
+
invalidSheetName: rangeParams && "invalidSheetName" in rangeParams // 'attr in obj' instead of just 'obj.attr' because we accept undefined values
|
|
2950
|
+
? rangeParams.invalidSheetName
|
|
2951
|
+
: this.invalidSheetName,
|
|
2952
|
+
invalidXc: rangeParams && "invalidXc" in rangeParams ? rangeParams.invalidXc : this.invalidXc,
|
|
2953
|
+
parts: rangeParams?.parts
|
|
2954
|
+
? rangeParams.parts
|
|
2955
|
+
: this.parts.map((part) => {
|
|
2956
|
+
return { rowFixed: part.rowFixed, colFixed: part.colFixed };
|
|
2957
|
+
}),
|
|
2958
|
+
prefixSheet: rangeParams?.prefixSheet ? rangeParams.prefixSheet : this.prefixSheet,
|
|
2959
|
+
}, this.getSheetSize);
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
/**
|
|
2963
|
+
* Copy a range. If the range is on the sheetIdFrom, the range will target
|
|
2964
|
+
* sheetIdTo.
|
|
2965
|
+
*/
|
|
2966
|
+
function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
2967
|
+
const sheetId = range.sheetId === sheetIdFrom ? sheetIdTo : range.sheetId;
|
|
2968
|
+
return range.clone({ sheetId });
|
|
2969
|
+
}
|
|
2970
|
+
/**
|
|
2971
|
+
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
2972
|
+
*/
|
|
2973
|
+
function createRange(getters, sheetId, range) {
|
|
2974
|
+
return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
|
|
2975
|
+
}
|
|
2976
|
+
/**
|
|
2977
|
+
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
2978
|
+
* For example, A1:B4 will become [A1:A4, B1:B4]
|
|
2979
|
+
*/
|
|
2980
|
+
function spreadRange(ranges) {
|
|
2981
|
+
const postProcessedRanges = [];
|
|
2982
|
+
for (const range of ranges) {
|
|
2983
|
+
const { sheetName } = splitReference(range);
|
|
2984
|
+
const sheetPrefix = sheetName ? `${sheetName}!` : "";
|
|
2985
|
+
const zone = toUnboundedZone(range);
|
|
2986
|
+
if (zone.bottom !== zone.top && zone.left != zone.right) {
|
|
2987
|
+
if (zone.right) {
|
|
2988
|
+
for (let j = zone.left; j <= zone.right; ++j) {
|
|
2989
|
+
postProcessedRanges.push(`${sheetPrefix}${zoneToXc({
|
|
2990
|
+
left: j,
|
|
2991
|
+
right: j,
|
|
2992
|
+
top: zone.top,
|
|
2993
|
+
bottom: zone.bottom,
|
|
2994
|
+
})}`);
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
else {
|
|
2998
|
+
for (let j = zone.top; j <= zone.bottom; ++j) {
|
|
2999
|
+
postProcessedRanges.push(`${sheetPrefix}${zoneToXc({
|
|
3000
|
+
left: zone.left,
|
|
3001
|
+
right: zone.right,
|
|
3002
|
+
top: j,
|
|
3003
|
+
bottom: j,
|
|
3004
|
+
})}`);
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
else {
|
|
3009
|
+
postProcessedRanges.push(range);
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
return postProcessedRanges;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
/** Methods from Odoo Web Utils */
|
|
3016
|
+
/**
|
|
3017
|
+
* This function computes a score that represent the fact that the
|
|
3018
|
+
* string contains the pattern, or not
|
|
3019
|
+
*
|
|
3020
|
+
* - If the score is 0, the string does not contain the letters of the pattern in
|
|
3021
|
+
* the correct order.
|
|
3022
|
+
* - if the score is > 0, it actually contains the letters.
|
|
3023
|
+
*
|
|
3024
|
+
* Better matches will get a higher score: consecutive letters are better,
|
|
3025
|
+
* and a match closer to the beginning of the string is also scored higher.
|
|
3026
|
+
*/
|
|
3027
|
+
function fuzzyMatch(pattern, str) {
|
|
3028
|
+
pattern = pattern.toLocaleLowerCase();
|
|
3029
|
+
str = str.toLocaleLowerCase();
|
|
3030
|
+
let totalScore = 0;
|
|
3031
|
+
let currentScore = 0;
|
|
3032
|
+
let len = str.length;
|
|
3033
|
+
let patternIndex = 0;
|
|
3034
|
+
for (let i = 0; i < len; i++) {
|
|
3035
|
+
if (str[i] === pattern[patternIndex]) {
|
|
3036
|
+
patternIndex++;
|
|
3037
|
+
currentScore += 100 + currentScore - i / 200;
|
|
3038
|
+
}
|
|
3039
|
+
else {
|
|
3040
|
+
currentScore = 0;
|
|
3041
|
+
}
|
|
3042
|
+
totalScore = totalScore + currentScore;
|
|
3043
|
+
}
|
|
3044
|
+
return patternIndex === pattern.length ? totalScore : 0;
|
|
3045
|
+
}
|
|
3046
|
+
/**
|
|
3047
|
+
* Return a list of things that matches a pattern, ordered by their 'score' (
|
|
3048
|
+
* higher score first). An higher score means that the match is better. For
|
|
3049
|
+
* example, consecutive letters are considered a better match.
|
|
3050
|
+
*/
|
|
3051
|
+
function fuzzyLookup(pattern, list, fn) {
|
|
3052
|
+
const results = [];
|
|
3053
|
+
list.forEach((data) => {
|
|
3054
|
+
const score = fuzzyMatch(pattern, fn(data));
|
|
3055
|
+
if (score > 0) {
|
|
3056
|
+
results.push({ score, elem: data });
|
|
3057
|
+
}
|
|
3058
|
+
});
|
|
3059
|
+
// we want better matches first
|
|
3060
|
+
results.sort((a, b) => b.score - a.score);
|
|
3061
|
+
return results.map((r) => r.elem);
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
function createDefaultRows(rowNumber) {
|
|
3065
|
+
const rows = [];
|
|
3066
|
+
for (let i = 0; i < rowNumber; i++) {
|
|
3067
|
+
const row = {
|
|
3068
|
+
cells: {},
|
|
3069
|
+
};
|
|
3070
|
+
rows.push(row);
|
|
3071
|
+
}
|
|
3072
|
+
return rows;
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
/*
|
|
3076
|
+
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
|
|
3077
|
+
* */
|
|
3078
|
+
class UuidGenerator {
|
|
3079
|
+
isFastIdStrategy = false;
|
|
3080
|
+
fastIdStart = 0;
|
|
3081
|
+
setIsFastStrategy(isFast) {
|
|
3082
|
+
this.isFastIdStrategy = isFast;
|
|
3083
|
+
}
|
|
3084
|
+
uuidv4() {
|
|
3085
|
+
if (this.isFastIdStrategy) {
|
|
3086
|
+
this.fastIdStart++;
|
|
3087
|
+
return String(this.fastIdStart);
|
|
3088
|
+
//@ts-ignore
|
|
3089
|
+
}
|
|
3090
|
+
else if (window.crypto && window.crypto.getRandomValues) {
|
|
3091
|
+
//@ts-ignore
|
|
3092
|
+
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
|
|
3093
|
+
}
|
|
3094
|
+
else {
|
|
3095
|
+
// mainly for jest and other browsers that do not have the crypto functionality
|
|
3096
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
3097
|
+
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
3098
|
+
return v.toString(16);
|
|
3099
|
+
});
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3066
3104
|
class ChartJsComponent extends Component {
|
|
3067
3105
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
3068
3106
|
canvas = useRef("graphContainer");
|
|
@@ -17642,50 +17680,51 @@ const uuidGenerator$1 = new UuidGenerator();
|
|
|
17642
17680
|
css /* scss */ `
|
|
17643
17681
|
.o-selection {
|
|
17644
17682
|
.o-selection-input {
|
|
17645
|
-
|
|
17646
|
-
flex-direction: row;
|
|
17683
|
+
padding: 2px 0px;
|
|
17647
17684
|
|
|
17648
17685
|
input {
|
|
17649
17686
|
padding: 4px 6px;
|
|
17650
17687
|
border-radius: 4px;
|
|
17651
17688
|
box-sizing: border-box;
|
|
17652
|
-
flex-grow: 2;
|
|
17653
17689
|
}
|
|
17654
17690
|
input:focus {
|
|
17655
17691
|
outline: none;
|
|
17656
17692
|
}
|
|
17657
17693
|
input.o-required,
|
|
17658
17694
|
input.o-focused {
|
|
17659
|
-
border
|
|
17660
|
-
padding: 3px 5px;
|
|
17695
|
+
border: 1px solid;
|
|
17661
17696
|
}
|
|
17662
17697
|
input.o-focused {
|
|
17663
|
-
border-
|
|
17698
|
+
border-width: 2px;
|
|
17699
|
+
padding: 3px 5px;
|
|
17664
17700
|
}
|
|
17665
17701
|
input.o-invalid {
|
|
17666
|
-
|
|
17702
|
+
/* The background-color is similar to the bootstrap alert-danger class but, because of the commit 0358a76d,
|
|
17703
|
+
* which avoids being parasitized by the dark-mode in spreadsheet, we cannot use this class.
|
|
17704
|
+
* TODO: Replace with the bootstrap alert-danger class when we support dark mode
|
|
17705
|
+
*/
|
|
17706
|
+
background-color: #ffdddd;
|
|
17707
|
+
border-width: 2px;
|
|
17667
17708
|
}
|
|
17668
17709
|
button.o-btn {
|
|
17669
|
-
background: transparent;
|
|
17670
|
-
border: none;
|
|
17671
17710
|
color: #333;
|
|
17672
|
-
cursor: pointer;
|
|
17673
17711
|
}
|
|
17674
17712
|
button.o-btn-action {
|
|
17675
17713
|
margin: 8px 1px;
|
|
17676
17714
|
border-radius: 4px;
|
|
17677
|
-
background: transparent;
|
|
17678
17715
|
border: 1px solid #dadce0;
|
|
17679
17716
|
color: #188038;
|
|
17680
|
-
font-weight: bold;
|
|
17681
17717
|
font-size: 14px;
|
|
17682
17718
|
height: 25px;
|
|
17683
17719
|
}
|
|
17720
|
+
.error-icon {
|
|
17721
|
+
right: 7px;
|
|
17722
|
+
top: 7px;
|
|
17723
|
+
}
|
|
17684
17724
|
}
|
|
17685
17725
|
/** Make the character a bit bigger
|
|
17686
17726
|
compared to its neighbor INPUT box */
|
|
17687
17727
|
.o-remove-selection {
|
|
17688
|
-
font-weight: bold;
|
|
17689
17728
|
font-size: calc(100% + 4px);
|
|
17690
17729
|
}
|
|
17691
17730
|
}
|
|
@@ -17701,7 +17740,7 @@ css /* scss */ `
|
|
|
17701
17740
|
class SelectionInput extends Component {
|
|
17702
17741
|
static template = "o-spreadsheet-SelectionInput";
|
|
17703
17742
|
id = uuidGenerator$1.uuidv4();
|
|
17704
|
-
previousRanges = this.props.ranges || [];
|
|
17743
|
+
previousRanges = this.props.ranges() || [];
|
|
17705
17744
|
originSheet = this.env.model.getters.getActiveSheetId();
|
|
17706
17745
|
state = useState({
|
|
17707
17746
|
isMissing: false,
|
|
@@ -17709,11 +17748,11 @@ class SelectionInput extends Component {
|
|
|
17709
17748
|
});
|
|
17710
17749
|
focusedInput = useRef("focusedInput");
|
|
17711
17750
|
get ranges() {
|
|
17712
|
-
const
|
|
17713
|
-
const ranges =
|
|
17714
|
-
?
|
|
17715
|
-
: this.props.ranges
|
|
17716
|
-
? this.props.ranges.map((xc, id) => ({
|
|
17751
|
+
const existingSelectionRanges = this.env.model.getters.getSelectionInput(this.id);
|
|
17752
|
+
const ranges = existingSelectionRanges.length
|
|
17753
|
+
? existingSelectionRanges
|
|
17754
|
+
: this.props.ranges()
|
|
17755
|
+
? this.props.ranges().map((xc, id) => ({
|
|
17717
17756
|
xc,
|
|
17718
17757
|
id,
|
|
17719
17758
|
isFocused: false,
|
|
@@ -17733,6 +17772,12 @@ class SelectionInput extends Component {
|
|
|
17733
17772
|
get isInvalid() {
|
|
17734
17773
|
return this.props.isInvalid || this.state.isMissing;
|
|
17735
17774
|
}
|
|
17775
|
+
get isConfirmable() {
|
|
17776
|
+
return this.hasFocus && this.ranges.every((range) => range.isValidRange);
|
|
17777
|
+
}
|
|
17778
|
+
get isResettable() {
|
|
17779
|
+
return this.previousRanges.join() !== this.ranges.map((r) => r.xc).join();
|
|
17780
|
+
}
|
|
17736
17781
|
setup() {
|
|
17737
17782
|
useEffect(() => this.focusedInput.el?.focus(), () => [this.focusedInput.el]);
|
|
17738
17783
|
onMounted(() => this.enableNewSelectionInput());
|
|
@@ -17742,7 +17787,7 @@ class SelectionInput extends Component {
|
|
|
17742
17787
|
enableNewSelectionInput() {
|
|
17743
17788
|
this.env.model.dispatch("ENABLE_NEW_SELECTION_INPUT", {
|
|
17744
17789
|
id: this.id,
|
|
17745
|
-
initialRanges: this.props.ranges,
|
|
17790
|
+
initialRanges: this.props.ranges(),
|
|
17746
17791
|
hasSingleRange: this.props.hasSingleRange,
|
|
17747
17792
|
});
|
|
17748
17793
|
}
|
|
@@ -17751,7 +17796,8 @@ class SelectionInput extends Component {
|
|
|
17751
17796
|
}
|
|
17752
17797
|
checkChange() {
|
|
17753
17798
|
const value = this.env.model.getters.getSelectionInputValue(this.id);
|
|
17754
|
-
|
|
17799
|
+
const valid = !this.isInvalid && this.ranges.every((range) => range.isValidRange);
|
|
17800
|
+
if (valid && this.previousRanges.join() !== value.join()) {
|
|
17755
17801
|
this.triggerChange();
|
|
17756
17802
|
}
|
|
17757
17803
|
}
|
|
@@ -17762,7 +17808,6 @@ class SelectionInput extends Component {
|
|
|
17762
17808
|
triggerChange() {
|
|
17763
17809
|
const ranges = this.env.model.getters.getSelectionInputValue(this.id);
|
|
17764
17810
|
this.props.onSelectionChanged?.(ranges);
|
|
17765
|
-
this.previousRanges = ranges;
|
|
17766
17811
|
}
|
|
17767
17812
|
onKeydown(ev) {
|
|
17768
17813
|
if (ev.key === "F2") {
|
|
@@ -17812,10 +17857,37 @@ class SelectionInput extends Component {
|
|
|
17812
17857
|
});
|
|
17813
17858
|
this.triggerChange();
|
|
17814
17859
|
}
|
|
17860
|
+
reset() {
|
|
17861
|
+
const existingSelectionRanges = this.env.model.getters.getSelectionInput(this.id);
|
|
17862
|
+
for (const range of existingSelectionRanges) {
|
|
17863
|
+
this.env.model.dispatch("REMOVE_RANGE", {
|
|
17864
|
+
id: this.id,
|
|
17865
|
+
rangeId: range.id,
|
|
17866
|
+
});
|
|
17867
|
+
}
|
|
17868
|
+
for (const range of this.previousRanges) {
|
|
17869
|
+
this.env.model.dispatch("ADD_RANGE", { id: this.id, value: range });
|
|
17870
|
+
}
|
|
17871
|
+
this.confirm();
|
|
17872
|
+
}
|
|
17815
17873
|
confirm() {
|
|
17816
|
-
|
|
17817
|
-
const
|
|
17818
|
-
|
|
17874
|
+
let anyValidInput = false;
|
|
17875
|
+
const existingSelectionRanges = this.env.model.getters.getSelectionInput(this.id);
|
|
17876
|
+
const existingSelectionXcs = [];
|
|
17877
|
+
for (const range of existingSelectionRanges) {
|
|
17878
|
+
if (range.xc === "") {
|
|
17879
|
+
this.env.model.dispatch("REMOVE_RANGE", {
|
|
17880
|
+
id: this.id,
|
|
17881
|
+
rangeId: range.id,
|
|
17882
|
+
});
|
|
17883
|
+
continue;
|
|
17884
|
+
}
|
|
17885
|
+
existingSelectionXcs.push(range.xc);
|
|
17886
|
+
if (this.env.model.getters.isRangeValid(range.xc)) {
|
|
17887
|
+
anyValidInput = true;
|
|
17888
|
+
}
|
|
17889
|
+
}
|
|
17890
|
+
if (this.props.required && !anyValidInput) {
|
|
17819
17891
|
this.state.isMissing = true;
|
|
17820
17892
|
}
|
|
17821
17893
|
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -17825,11 +17897,17 @@ class SelectionInput extends Component {
|
|
|
17825
17897
|
sheetIdTo: this.originSheet,
|
|
17826
17898
|
});
|
|
17827
17899
|
}
|
|
17900
|
+
this.props.onSelectionChanged?.(existingSelectionXcs);
|
|
17828
17901
|
this.props.onSelectionConfirmed?.();
|
|
17902
|
+
this.previousRanges = this.props.ranges();
|
|
17903
|
+
if (existingSelectionXcs.join() !== this.previousRanges.join()) {
|
|
17904
|
+
this.enableNewSelectionInput();
|
|
17905
|
+
}
|
|
17906
|
+
this.env.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
17829
17907
|
}
|
|
17830
17908
|
}
|
|
17831
17909
|
SelectionInput.props = {
|
|
17832
|
-
ranges:
|
|
17910
|
+
ranges: Function,
|
|
17833
17911
|
hasSingleRange: { type: Boolean, optional: true },
|
|
17834
17912
|
required: { type: Boolean, optional: true },
|
|
17835
17913
|
isInvalid: { type: Boolean, optional: true },
|
|
@@ -17877,10 +17955,14 @@ class LineBarPieConfigPanel extends Component {
|
|
|
17877
17955
|
this.dataSeriesRanges = ranges;
|
|
17878
17956
|
}
|
|
17879
17957
|
onDataSeriesConfirmed() {
|
|
17958
|
+
this.dataSeriesRanges = spreadRange(this.dataSeriesRanges);
|
|
17880
17959
|
this.state.datasetDispatchResult = this.props.updateChart({
|
|
17881
17960
|
dataSets: this.dataSeriesRanges,
|
|
17882
17961
|
});
|
|
17883
17962
|
}
|
|
17963
|
+
getDataSeriesRanges() {
|
|
17964
|
+
return this.dataSeriesRanges;
|
|
17965
|
+
}
|
|
17884
17966
|
/**
|
|
17885
17967
|
* Change the local labelRange. The model should be updated when the
|
|
17886
17968
|
* button "confirm" is clicked
|
|
@@ -17893,6 +17975,9 @@ class LineBarPieConfigPanel extends Component {
|
|
|
17893
17975
|
labelRange: this.labelRange,
|
|
17894
17976
|
});
|
|
17895
17977
|
}
|
|
17978
|
+
getLabelRange() {
|
|
17979
|
+
return this.labelRange || "";
|
|
17980
|
+
}
|
|
17896
17981
|
onUpdateAggregated(ev) {
|
|
17897
17982
|
this.props.updateChart({
|
|
17898
17983
|
aggregated: ev.target.checked,
|
|
@@ -18313,6 +18398,9 @@ class GaugeChartConfigPanel extends Component {
|
|
|
18313
18398
|
dataRange: this.dataRange,
|
|
18314
18399
|
});
|
|
18315
18400
|
}
|
|
18401
|
+
getDataRange() {
|
|
18402
|
+
return this.dataRange || "";
|
|
18403
|
+
}
|
|
18316
18404
|
}
|
|
18317
18405
|
GaugeChartConfigPanel.props = {
|
|
18318
18406
|
figureId: String,
|
|
@@ -18511,6 +18599,9 @@ class ScorecardChartConfigPanel extends Component {
|
|
|
18511
18599
|
keyValue: this.keyValue,
|
|
18512
18600
|
});
|
|
18513
18601
|
}
|
|
18602
|
+
getKeyValueRange() {
|
|
18603
|
+
return this.keyValue || "";
|
|
18604
|
+
}
|
|
18514
18605
|
onBaselineRangeChanged(ranges) {
|
|
18515
18606
|
this.baseline = ranges[0];
|
|
18516
18607
|
}
|
|
@@ -18519,6 +18610,9 @@ class ScorecardChartConfigPanel extends Component {
|
|
|
18519
18610
|
baseline: this.baseline,
|
|
18520
18611
|
});
|
|
18521
18612
|
}
|
|
18613
|
+
getBaselineRange() {
|
|
18614
|
+
return this.baseline || "";
|
|
18615
|
+
}
|
|
18522
18616
|
updateBaselineMode(ev) {
|
|
18523
18617
|
this.props.updateChart({ baselineMode: ev.target.value });
|
|
18524
18618
|
}
|
|
@@ -28851,11 +28945,9 @@ class BasePlugin {
|
|
|
28851
28945
|
*/
|
|
28852
28946
|
class CorePlugin extends BasePlugin {
|
|
28853
28947
|
getters;
|
|
28854
|
-
range;
|
|
28855
28948
|
uuidGenerator;
|
|
28856
28949
|
constructor({ getters, stateObserver, range, dispatch, uuidGenerator }) {
|
|
28857
28950
|
super(stateObserver, dispatch);
|
|
28858
|
-
this.range = range;
|
|
28859
28951
|
range.addRangeProvider(this.adaptRanges.bind(this));
|
|
28860
28952
|
this.getters = getters;
|
|
28861
28953
|
this.uuidGenerator = uuidGenerator;
|
|
@@ -38618,6 +38710,7 @@ class SelectionInputPlugin extends UIPlugin {
|
|
|
38618
38710
|
// ---------------------------------------------------------------------------
|
|
38619
38711
|
allowDispatch(cmd) {
|
|
38620
38712
|
switch (cmd.type) {
|
|
38713
|
+
case "ADD_RANGE":
|
|
38621
38714
|
case "ADD_EMPTY_RANGE":
|
|
38622
38715
|
if (this.inputHasSingleRange && this.ranges.length === 1) {
|
|
38623
38716
|
return 30 /* CommandResult.MaximumRangesReached */;
|
|
@@ -38662,6 +38755,10 @@ class SelectionInputPlugin extends UIPlugin {
|
|
|
38662
38755
|
this.insertNewRange(this.ranges.length, [""]);
|
|
38663
38756
|
this.focusLast();
|
|
38664
38757
|
break;
|
|
38758
|
+
case "ADD_RANGE":
|
|
38759
|
+
this.insertNewRange(this.ranges.length, [cmd.value]);
|
|
38760
|
+
this.focusLast();
|
|
38761
|
+
break;
|
|
38665
38762
|
case "REMOVE_RANGE":
|
|
38666
38763
|
const index = this.getIndex(cmd.rangeId);
|
|
38667
38764
|
if (index !== null) {
|
|
@@ -38873,6 +38970,7 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
38873
38970
|
case "UNFOCUS_SELECTION_INPUT":
|
|
38874
38971
|
this.unfocus();
|
|
38875
38972
|
break;
|
|
38973
|
+
case "ADD_RANGE":
|
|
38876
38974
|
case "ADD_EMPTY_RANGE":
|
|
38877
38975
|
case "REMOVE_RANGE":
|
|
38878
38976
|
if (cmd.id !== this.focusedInputId) {
|
|
@@ -38886,9 +38984,11 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
38886
38984
|
if (cmd.id !== this.focusedInputId) {
|
|
38887
38985
|
const input = this.inputs[cmd.id];
|
|
38888
38986
|
const range = input.ranges.find((range) => range.id === cmd.rangeId);
|
|
38889
|
-
|
|
38890
|
-
|
|
38891
|
-
|
|
38987
|
+
if (this.isRangeValid(range?.xc || "A1")) {
|
|
38988
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
38989
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
|
|
38990
|
+
this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, { handleEvent: input.handleEvent.bind(input) });
|
|
38991
|
+
}
|
|
38892
38992
|
this.focusedInputId = cmd.id;
|
|
38893
38993
|
}
|
|
38894
38994
|
break;
|
|
@@ -48167,9 +48267,9 @@ function addFunction(functionName, functionDescription) {
|
|
|
48167
48267
|
functionRegistry.add(functionName, functionDescription);
|
|
48168
48268
|
}
|
|
48169
48269
|
|
|
48170
|
-
export { AbstractChart, CommandResult, CorePlugin, 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, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
48270
|
+
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
48171
48271
|
|
|
48172
48272
|
|
|
48173
|
-
__info__.version = '16.4.0-alpha.
|
|
48174
|
-
__info__.date = '2023-05-
|
|
48175
|
-
__info__.hash = '
|
|
48273
|
+
__info__.version = '16.4.0-alpha.2';
|
|
48274
|
+
__info__.date = '2023-05-26T13:40:49.561Z';
|
|
48275
|
+
__info__.hash = '82328ad';
|