@trebco/treb 28.17.5 → 29.1.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.
Files changed (87) hide show
  1. package/dist/treb-spreadsheet-light.mjs +12 -12
  2. package/dist/treb-spreadsheet.mjs +12 -12
  3. package/dist/treb.d.ts +121 -82
  4. package/eslint.config.js +21 -0
  5. package/package.json +6 -6
  6. package/treb-base-types/src/area.ts +4 -2
  7. package/treb-base-types/src/cell.ts +1 -1
  8. package/treb-base-types/src/cells.ts +16 -7
  9. package/treb-base-types/src/dom-utilities.ts +4 -2
  10. package/treb-base-types/src/import.ts +2 -2
  11. package/treb-base-types/src/rectangle.ts +5 -5
  12. package/treb-base-types/src/union.ts +6 -1
  13. package/treb-base-types/src/value-type.ts +1 -1
  14. package/treb-calculator/src/calculator.ts +114 -165
  15. package/treb-calculator/src/dag/calculation_leaf_vertex.ts +1 -2
  16. package/treb-calculator/src/dag/graph.ts +3 -3
  17. package/treb-calculator/src/dag/spreadsheet_vertex.ts +2 -2
  18. package/treb-calculator/src/dag/state_leaf_vertex.ts +2 -4
  19. package/treb-calculator/src/descriptors.ts +28 -2
  20. package/treb-calculator/src/expression-calculator.ts +25 -34
  21. package/treb-calculator/src/function-error.ts +2 -2
  22. package/treb-calculator/src/function-library.ts +16 -0
  23. package/treb-calculator/src/functions/base-functions.ts +185 -211
  24. package/treb-calculator/src/functions/checkbox.ts +0 -1
  25. package/treb-calculator/src/functions/complex-functions.ts +49 -47
  26. package/treb-calculator/src/functions/finance-functions.ts +10 -10
  27. package/treb-calculator/src/functions/function-utilities.ts +26 -0
  28. package/treb-calculator/src/functions/information-functions.ts +21 -41
  29. package/treb-calculator/src/functions/matrix-functions.ts +8 -1
  30. package/treb-calculator/src/functions/sparkline.ts +6 -4
  31. package/treb-calculator/src/functions/statistics-functions.ts +21 -17
  32. package/treb-calculator/src/functions/text-functions.ts +14 -13
  33. package/treb-calculator/src/primitives.ts +48 -37
  34. package/treb-calculator/src/utilities.ts +117 -134
  35. package/treb-charts/src/chart-functions.ts +3 -3
  36. package/treb-charts/src/chart-types.ts +42 -1
  37. package/treb-charts/src/chart-utils.ts +155 -113
  38. package/treb-charts/src/chart.ts +6 -5
  39. package/treb-charts/src/default-chart-renderer.ts +6 -5
  40. package/treb-charts/src/renderer.ts +12 -11
  41. package/treb-charts/src/util.ts +25 -36
  42. package/treb-data-model/package.json +5 -0
  43. package/{treb-grid/src/types → treb-data-model/src}/annotation.ts +2 -2
  44. package/{treb-grid/src/types → treb-data-model/src}/conditional_format.ts +20 -0
  45. package/{treb-grid/src/types → treb-data-model/src}/data_model.ts +231 -133
  46. package/treb-data-model/src/index.ts +45 -0
  47. package/{treb-grid/src/types/named_range.ts → treb-data-model/src/named.ts} +459 -376
  48. package/{treb-grid/src/types → treb-data-model/src}/sheet.ts +13 -5
  49. package/treb-data-model/src/sheet_collection.ts +114 -0
  50. package/{treb-grid/src/types → treb-data-model/src}/sheet_types.ts +6 -3
  51. package/treb-embed/modern.tsconfig.json +1 -0
  52. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +2 -2
  53. package/treb-embed/src/embedded-spreadsheet.ts +125 -270
  54. package/treb-embed/src/selection-state.ts +1 -1
  55. package/treb-embed/src/toolbar-message.ts +1 -1
  56. package/treb-embed/src/types.ts +13 -5
  57. package/treb-export/src/export-worker/export-worker.ts +22 -7
  58. package/treb-export/src/export2.ts +110 -41
  59. package/treb-export/src/import2.ts +6 -5
  60. package/treb-export/src/workbook2.ts +31 -13
  61. package/treb-export/src/xml-utils.ts +5 -1
  62. package/treb-format/src/format.ts +8 -6
  63. package/treb-grid/src/editors/autocomplete.ts +2 -2
  64. package/treb-grid/src/editors/autocomplete_matcher.ts +57 -19
  65. package/treb-grid/src/editors/editor.ts +27 -25
  66. package/treb-grid/src/editors/formula_bar.ts +5 -5
  67. package/treb-grid/src/editors/overlay_editor.ts +1 -2
  68. package/treb-grid/src/index.ts +0 -11
  69. package/treb-grid/src/layout/base_layout.ts +20 -8
  70. package/treb-grid/src/layout/grid_layout.ts +2 -2
  71. package/treb-grid/src/layout/mock-layout.ts +5 -6
  72. package/treb-grid/src/render/selection-renderer.ts +2 -3
  73. package/treb-grid/src/render/tile_renderer.ts +1 -1
  74. package/treb-grid/src/types/grid.ts +95 -66
  75. package/treb-grid/src/types/grid_base.ts +76 -60
  76. package/treb-grid/src/types/grid_command.ts +3 -2
  77. package/treb-grid/src/types/grid_events.ts +12 -6
  78. package/treb-grid/src/types/tab_bar.ts +1 -2
  79. package/treb-parser/src/parser-types.ts +2 -1
  80. package/treb-parser/src/parser.ts +7 -5
  81. package/treb-utils/src/event_source.ts +1 -1
  82. package/treb-utils/src/serialize_html.ts +31 -6
  83. package/.eslintignore +0 -8
  84. package/.eslintrc.cjs +0 -168
  85. package/treb-grid/src/layout/rectangle_cache.ts +0 -86
  86. /package/{treb-grid/src/types → treb-data-model/src}/serialize_options.ts +0 -0
  87. /package/{treb-grid/src/types/grid_selection.ts → treb-data-model/src/sheet_selection.ts} +0 -0
@@ -20,8 +20,11 @@
20
20
  */
21
21
 
22
22
  import type { IArea, Table, TableTheme } from 'treb-base-types';
23
- import type { SerializedNamedExpression, SerializedSheet } from 'treb-grid';
24
- import type { SerializedMacroFunction } from 'treb-grid/src/types/data_model';
23
+ import type {
24
+ SerializedNamedExpression,
25
+ SerializedSheet,
26
+ SerializedMacroFunction,
27
+ SerializedNamed } from 'treb-data-model';
25
28
 
26
29
  export enum SaveFileType {
27
30
  json = 'json',
@@ -66,7 +69,7 @@ export interface TREBDocument {
66
69
  * opaque user data. we don't read or parse this, but applications can
67
70
  * use it to store arbitrary data.
68
71
  */
69
- user_data?: any;
72
+ user_data?: unknown;
70
73
 
71
74
  /**
72
75
  * per-sheet data. this should be an array, but for historical reasons
@@ -86,12 +89,17 @@ export interface TREBDocument {
86
89
  */
87
90
  rendered_values?: boolean;
88
91
 
89
- /** document named ranges */
92
+ /** document named ranges @deprecated */
90
93
  named_ranges?: Record<string, IArea>;
91
94
 
92
- /** document named expressions */
95
+ /** document named expressions @deprecated */
93
96
  named_expressions?: SerializedNamedExpression[];
94
97
 
98
+ /**
99
+ * new consolidated named ranges & expressions
100
+ */
101
+ named?: SerializedNamed[];
102
+
95
103
  /** document macro functions */
96
104
  macro_functions?: SerializedMacroFunction[];
97
105
 
@@ -19,15 +19,19 @@
19
19
  *
20
20
  */
21
21
 
22
- import type { ImportedSheetData } from 'treb-base-types/src';
22
+ import type { ImportedSheetData } from 'treb-base-types';
23
+ import type { SerializedModel } from 'treb-data-model';
23
24
 
24
25
  import { Exporter } from '../export2';
25
26
  import { Importer } from '../import2';
26
27
 
27
- const ctx: Worker = self as any;
28
+ const ctx: Worker = self as unknown as Worker;
28
29
  const exporter = new Exporter();
29
30
 
30
- const ExportSheets = (data: any) => {
31
+ const ExportSheets = (data: {
32
+ sheet: SerializedModel,
33
+ decorated: Record<string, string>,
34
+ }) => {
31
35
 
32
36
  if (data.sheet) {
33
37
  exporter.Init(data.decorated || []);
@@ -37,17 +41,19 @@ const ExportSheets = (data: any) => {
37
41
 
38
42
  };
39
43
 
40
- const ImportSheet = (data: any) => {
44
+ const ImportSheet = (data: { data: ArrayBuffer }) => {
41
45
 
42
46
  const importer = new Importer();
43
47
 
44
48
  try {
45
49
  importer.Init(data.data);
46
50
 
51
+ const named = importer.workbook?.GetNamedRanges();
52
+
47
53
  const count = importer.SheetCount();
48
54
  const results = {
49
55
  sheets: [] as ImportedSheetData[],
50
- names: importer.workbook?.GetNamedRanges(),
56
+ named,
51
57
  active_tab: importer.workbook?.active_tab,
52
58
  };
53
59
 
@@ -58,6 +64,15 @@ const ImportSheet = (data: any) => {
58
64
  }
59
65
  }
60
66
 
67
+ for (const entry of named || []) {
68
+ if (typeof entry.local_scope === 'number') {
69
+ const sheet = results.sheets[entry.local_scope];
70
+ if (sheet) {
71
+ entry.scope = sheet.name;
72
+ }
73
+ }
74
+ }
75
+
61
76
  ctx.postMessage({ status: 'complete', results });
62
77
 
63
78
  }
@@ -72,9 +87,9 @@ const ImportSheet = (data: any) => {
72
87
  // initialize message handler
73
88
  ctx.addEventListener('message', (event) => {
74
89
  if (event.data && event.data.command === 'export'){
75
- ExportSheets(event.data);
90
+ ExportSheets(event.data as { sheet: SerializedModel, decorated: Record<string, string>});
76
91
  }
77
92
  else if (event.data && event.data.command === 'import'){
78
- ImportSheet(event.data);
93
+ ImportSheet(event.data as { data: ArrayBuffer });
79
94
  }
80
95
  });
@@ -27,7 +27,6 @@
27
27
 
28
28
  // import JSZip from 'jszip';
29
29
 
30
- import UZip from 'uzip';
31
30
  import * as Base64JS from 'base64-js';
32
31
 
33
32
  import { PixelsToColumnWidth } from './column-width';
@@ -35,7 +34,7 @@ import { PixelsToColumnWidth } from './column-width';
35
34
  const XMLDeclaration = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
36
35
 
37
36
  import { template } from './template-2';
38
- import type { SerializedSheet } from 'treb-grid';
37
+ import type { SerializedModel, SerializedSheet } from 'treb-data-model';
39
38
 
40
39
  import type { IArea, ICellAddress, CellValue, DataValidation, CellStyle,
41
40
  AnnotationLayout, Corner as LayoutCorner, Cell, Rectangle } from 'treb-base-types';
@@ -52,7 +51,7 @@ import { Theme } from './workbook-theme2';
52
51
 
53
52
  import type { RelationshipMap} from './relationship';
54
53
  import { AddRel } from './relationship';
55
- import { XMLOptions2 } from './xml-utils';
54
+ import { type DOMContent, XMLOptions2 } from './xml-utils';
56
55
 
57
56
  import type { UnitAddress, UnitRange, ExpressionUnit} from 'treb-parser';
58
57
  import { Parser, QuotedSheetNameRegex } from 'treb-parser';
@@ -64,9 +63,15 @@ import type { ImageOptions } from './drawing2/embedded-image';
64
63
  import type { TwoCellAnchor } from './drawing2/drawing2';
65
64
  import { Drawing } from './drawing2/drawing2';
66
65
  import { ConditionalFormatOperators, type TableDescription, type TableFooterType } from './workbook2';
67
- import type { AnnotationData } from 'treb-grid/src/types/annotation';
66
+ import type { AnnotationData } from 'treb-data-model/src/annotation';
68
67
  import { ZipWrapper } from './zip-wrapper';
69
68
 
69
+ /*
70
+ interface NestedDOMType {
71
+ [index: string]: string|number|NestedDOMType|NestedDOMType[];
72
+ }
73
+ */
74
+
70
75
  export class Exporter {
71
76
 
72
77
  // public zip?: JSZip;
@@ -153,14 +158,14 @@ export class Exporter {
153
158
 
154
159
  const keys = Object.keys(rels);
155
160
 
156
- const dom = {
161
+ const dom: DOMContent = {
157
162
  Relationships: {
158
163
  a$: {
159
164
  xmlns: 'http://schemas.openxmlformats.org/package/2006/relationships',
160
165
  },
161
166
  Relationship: keys.map(key => {
162
167
  const rel = rels[key];
163
- const a$: any = {
168
+ const a$: DOMContent = {
164
169
  Id: rel.id,
165
170
  Target: rel.target,
166
171
  Type: rel.type,
@@ -198,7 +203,8 @@ export class Exporter {
198
203
 
199
204
  // we could just pass through except that we have argb and excel has rgb
200
205
 
201
- const attrs: any = {};
206
+ const attrs: XlColor & { rgb?: string } = {};
207
+
202
208
  if (color.indexed !== undefined) {
203
209
  attrs.indexed = color.indexed;
204
210
  }
@@ -212,10 +218,11 @@ export class Exporter {
212
218
  attrs.rgb = color.argb;
213
219
  }
214
220
  return attrs;
221
+
215
222
  };
216
223
 
217
224
  const xfs = style_cache.cell_xfs.map(xf => {
218
- const block: any = {
225
+ const block: DOMContent = {
219
226
  a$: {
220
227
  numFmtId: xf.number_format,
221
228
  fontId: xf.font,
@@ -225,22 +232,24 @@ export class Exporter {
225
232
  };
226
233
 
227
234
  if (xf.horizontal_alignment || xf.vertical_alignment || xf.wrap_text || xf.indent) {
228
- // block.a$.applyAlignment = 1;
229
- block.alignment = { a$: {}};
235
+
236
+ const attrs: DOMContent = {};
230
237
 
231
238
  if (xf.horizontal_alignment) {
232
- block.alignment.a$.horizontal = xf.horizontal_alignment;
239
+ attrs.horizontal = xf.horizontal_alignment;
233
240
  }
234
241
  if (xf.vertical_alignment) {
235
- block.alignment.a$.vertical = xf.vertical_alignment;
242
+ attrs.vertical = xf.vertical_alignment;
236
243
  }
237
244
  if (xf.wrap_text) {
238
- block.alignment.a$.wrapText = 1;
245
+ attrs.wrapText = 1;
239
246
  }
240
247
  if (xf.indent && xf.horizontal_alignment !== 'center') {
241
- block.alignment.a$.indent = xf.indent;
248
+ attrs.indent = xf.indent;
242
249
  }
243
250
 
251
+ block.alignment = { a$: attrs };
252
+
244
253
  }
245
254
 
246
255
  return block;
@@ -377,7 +386,7 @@ export class Exporter {
377
386
  return block;
378
387
  });
379
388
 
380
- const dom: any = {
389
+ const dom: DOMContent = {
381
390
  styleSheet: {
382
391
  a$: {
383
392
  'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
@@ -396,14 +405,14 @@ export class Exporter {
396
405
 
397
406
  if (style_cache.number_formats.length) {
398
407
 
399
- dom.styleSheet.numFmts = {
408
+ (dom.styleSheet as DOMContent).numFmts = {
400
409
  a$: { count: style_cache.number_formats.length },
401
410
  numFmt: style_cache.number_formats.map(format => {
402
411
  return {
403
412
  a$: {
404
413
  numFmtId: format.id,
405
414
  formatCode: format.format,
406
- },
415
+ } as DOMContent,
407
416
  };
408
417
  }),
409
418
  };
@@ -414,21 +423,21 @@ export class Exporter {
414
423
  }
415
424
 
416
425
  if (fonts.length) {
417
- dom.styleSheet.fonts = {
426
+ (dom.styleSheet as DOMContent).fonts = {
418
427
  a$: { count: fonts.length },
419
428
  font: fonts,
420
429
  };
421
430
  }
422
431
 
423
432
  if (fills.length) {
424
- dom.styleSheet.fills = {
433
+ (dom.styleSheet as DOMContent).fills = {
425
434
  a$: { count: fills.length },
426
435
  fill: fills,
427
436
  };
428
437
  }
429
438
 
430
439
  if (borders.length) {
431
- dom.styleSheet.borders = {
440
+ (dom.styleSheet as DOMContent).borders = {
432
441
  a$: { count: borders.length },
433
442
  border: borders,
434
443
  };
@@ -437,27 +446,27 @@ export class Exporter {
437
446
  // console.info("B", borders, JSON.stringify(dom.styleSheet.borders, undefined, 2))
438
447
 
439
448
  if (xfs.length) {
440
- dom.styleSheet.cellXfs = {
449
+ (dom.styleSheet as DOMContent).cellXfs = {
441
450
  a$: { count: xfs.length },
442
451
  xf: xfs,
443
452
  };
444
453
  }
445
454
 
446
455
  if (style_cache.dxf_styles.length) {
447
- const dxf: any[] = [];
456
+ const dxf: DOMContent[] = [];
448
457
  for (const style of style_cache.dxf_styles) {
449
- const entry: any = {};
458
+ const entry: DOMContent = {};
450
459
  if (style.text || style.bold || style.italic || style.underline) {
451
- const font: any = {};
460
+ const font: DOMContent = {};
452
461
  if (style.text) {
453
462
  font.color = { a$: {}};
454
463
  if (style.text.text) {
455
- font.color.a$.rgb = `FF` + style.text.text.substring(1);
464
+ (font.color.a$ as DOMContent).rgb = `FF` + style.text.text.substring(1);
456
465
  }
457
466
  else if (style.text.theme) {
458
- font.color.a$.theme = style.text.theme;
467
+ (font.color.a$ as DOMContent).theme = style.text.theme;
459
468
  if (style.text.tint) {
460
- font.color.a$.tint = style.text.tint;
469
+ (font.color.a$ as DOMContent).tint = style.text.tint;
461
470
  }
462
471
  }
463
472
  }
@@ -476,23 +485,24 @@ export class Exporter {
476
485
  entry.font = font;
477
486
  }
478
487
  if (style.fill) {
479
- const color: any = { a$: {}};
488
+ const attrs: DOMContent = {};
480
489
  if (style.fill.text) {
481
- color.a$.rgb = `FF` + style.fill.text.substring(1);
490
+ attrs.rgb = `FF` + style.fill.text.substring(1);
482
491
  }
483
492
  else if (style.fill.theme) {
484
- color.a$.theme = style.fill.theme;
493
+ attrs.theme = style.fill.theme;
485
494
  if (style.fill.tint) {
486
- color.a$.tint = style.fill.tint;
495
+ attrs.tint = style.fill.tint;
487
496
  }
488
497
  }
498
+ const color: DOMContent = { a$: attrs };
489
499
  entry.fill = { patternFill: { bgColor: color }};
490
500
  }
491
501
  dxf.push(entry);
492
502
  }
493
503
 
494
504
  if (dxf.length) {
495
- dom.styleSheet.dxfs = {
505
+ (dom.styleSheet as DOMContent).dxfs = {
496
506
  a$: { count: dxf.length },
497
507
  dxf,
498
508
  };
@@ -527,7 +537,7 @@ export class Exporter {
527
537
  throw new Error('missing zip');
528
538
  }
529
539
 
530
- const dom: any = {
540
+ const dom: DOMContent = {
531
541
  sst: {
532
542
  a$: {
533
543
  'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
@@ -1206,13 +1216,7 @@ export class Exporter {
1206
1216
 
1207
1217
  }
1208
1218
 
1209
- public Export(source: {
1210
- sheet_data: SerializedSheet[];
1211
- active_sheet?: number;
1212
- named_ranges?: {[index: string]: IArea};
1213
- named_expressions?: Array<{ name: string, expression: string }>;
1214
- decimal_mark: ','|'.';
1215
- }) {
1219
+ public Export(source: SerializedModel) {
1216
1220
 
1217
1221
  // --- create a map --------------------------------------------------------
1218
1222
 
@@ -2443,6 +2447,68 @@ export class Exporter {
2443
2447
  this.WriteRels(workbook_rels, `xl/_rels/workbook.xml.rels`);
2444
2448
 
2445
2449
  let definedNames: any = {definedName: []};
2450
+
2451
+ if (source.named) {
2452
+ for (const entry of source.named) {
2453
+
2454
+ let scope: string|undefined = undefined;
2455
+
2456
+ if (entry.scope) {
2457
+
2458
+ const test = entry.scope.toLowerCase();
2459
+ for (const [index, sheet] of source.sheet_data.entries()) {
2460
+ if (sheet.name?.toLowerCase() === test) {
2461
+ scope = index.toString();
2462
+ break;
2463
+ }
2464
+ }
2465
+ }
2466
+
2467
+ if (entry.area) {
2468
+ let sheet_name = '';
2469
+ const area = new Area(entry.area.start, entry.area.end);
2470
+ area.start.absolute_column = area.start.absolute_row = true;
2471
+ area.end.absolute_column = area.end.absolute_row = true;
2472
+
2473
+ if (entry.area.start.sheet) {
2474
+ sheet_name = entry.area.start.sheet;
2475
+ }
2476
+ else if (entry.area.start.sheet_id) {
2477
+ for (const sheet of source.sheet_data) {
2478
+ if (sheet.id === area.start.sheet_id) {
2479
+ sheet_name = sheet.name || '';
2480
+ break;
2481
+ }
2482
+ }
2483
+ }
2484
+
2485
+ if (sheet_name) {
2486
+ if (QuotedSheetNameRegex.test(sheet_name)) {
2487
+ sheet_name = `'${sheet_name}'`;
2488
+ }
2489
+ sheet_name += '!';
2490
+ }
2491
+
2492
+ // console.info({key, area, lx: area.spreadsheet_label, sheet_name });
2493
+ definedNames.definedName.push({
2494
+ a$: { name: entry.name, localSheetId: scope },
2495
+ t$: sheet_name + area.spreadsheet_label,
2496
+ });
2497
+
2498
+ }
2499
+ else if (entry.expression) {
2500
+ definedNames.definedName.push({
2501
+ a$: { name: entry.name, localSheetId: scope },
2502
+ t$: entry.expression,
2503
+ });
2504
+ }
2505
+
2506
+ }
2507
+ }
2508
+
2509
+ console.info("DB", definedNames);
2510
+
2511
+ /*
2446
2512
  if (source.named_ranges) {
2447
2513
  const keys = Object.keys(source.named_ranges);
2448
2514
  for (const key of keys) {
@@ -2483,10 +2549,13 @@ export class Exporter {
2483
2549
  });
2484
2550
  }
2485
2551
  }
2552
+ */
2553
+
2486
2554
  if (!definedNames.definedName.length) {
2487
2555
  definedNames = undefined;
2488
2556
  }
2489
-
2557
+ // else { console.info({definedNames}); }
2558
+
2490
2559
  const workbook_dom: any = {
2491
2560
  workbook: {
2492
2561
  a$: {
@@ -21,7 +21,7 @@
21
21
 
22
22
  // import JSZip from 'jszip';
23
23
 
24
- import UZip from 'uzip';
24
+ // import UZip from 'uzip';
25
25
  import Base64JS from 'base64-js';
26
26
 
27
27
  import type { AnchoredChartDescription, AnchoredImageDescription, AnchoredTextBoxDescription} from './workbook2';
@@ -31,7 +31,7 @@ import { Parser } from 'treb-parser';
31
31
  import type { RangeType, AddressType, HyperlinkType } from './address-type';
32
32
  import { is_range, ShiftRange, InRange, is_address } from './address-type';
33
33
  import type { ImportedSheetData, AnchoredAnnotation, CellParseResult, AnnotationLayout, Corner as LayoutCorner, ICellAddress, DataValidation, IArea, GradientStop, Color } from 'treb-base-types/src';
34
- import { type ValueType, ValidationType, type SerializedValueType } from 'treb-base-types/src';
34
+ import { ValidationType, type SerializedValueType } from 'treb-base-types/src';
35
35
  import type { Sheet} from './workbook-sheet2';
36
36
  import { VisibleState } from './workbook-sheet2';
37
37
  import type { CellAnchor } from './drawing2/drawing2';
@@ -39,8 +39,9 @@ import { XMLUtils } from './xml-utils';
39
39
 
40
40
  // import { one_hundred_pixels } from './constants';
41
41
  import { ColumnWidthToPixels } from './column-width';
42
- import type { AnnotationType, ConditionalFormat } from 'treb-grid';
42
+ import type { AnnotationType } from 'treb-data-model';
43
43
  import { ZipWrapper } from './zip-wrapper';
44
+ import type { ConditionalFormat } from 'treb-data-model';
44
45
 
45
46
  interface SharedFormula {
46
47
  row: number;
@@ -146,7 +147,7 @@ export class Importer {
146
147
 
147
148
  if (element.a$?.t && element.a$.t === 's') {
148
149
  type = 'string'; // ValueType.string;
149
- if (typeof element.v !== undefined) {
150
+ if (typeof element.v !== 'undefined') {
150
151
  const index = Number(element.v);
151
152
  if (!isNaN(index) && sheet.shared_strings) {
152
153
  value = sheet.shared_strings.Get(index) || '';
@@ -934,7 +935,7 @@ export class Importer {
934
935
  br: AnchorToCorner(descriptor.anchor.to),
935
936
  };
936
937
 
937
- let type: AnnotationType = 'image';
938
+ const type: AnnotationType = 'image';
938
939
  const data = Base64JS.fromByteArray(descriptor.image);
939
940
  let imagetype: string = '';
940
941
 
@@ -19,12 +19,6 @@
19
19
  *
20
20
  */
21
21
 
22
- import UZip from 'uzip';
23
-
24
- // import type JSZip from 'jszip';
25
- // import * as xmlparser from 'fast-xml-parser';
26
-
27
-
28
22
  import { XMLParser } from 'fast-xml-parser';
29
23
  import { XMLUtils, XMLOptions, XMLOptions2 } from './xml-utils';
30
24
 
@@ -45,6 +39,7 @@ import { Sheet, VisibleState } from './workbook-sheet2';
45
39
  import type { RelationshipMap } from './relationship';
46
40
  import { ZipWrapper } from './zip-wrapper';
47
41
  import type { CellStyle } from 'treb-base-types';
42
+ import type { CompositeNamed } from 'treb-data-model';
48
43
 
49
44
 
50
45
  /*
@@ -157,8 +152,10 @@ export class Workbook {
157
152
  /** theme */
158
153
  public theme = new Theme();
159
154
 
160
- /** defined names. these can be ranges or expressions. */
161
- public defined_names: Record<string, string> = {};
155
+ /* * defined names. these can be ranges or expressions. */
156
+ // public defined_names: Record<string, string> = {};
157
+
158
+ public named: Array<CompositeNamed & {local_scope?: number}> = [];
162
159
 
163
160
  /** the workbook "rels" */
164
161
  public rels: RelationshipMap = {};
@@ -229,15 +226,34 @@ export class Workbook {
229
226
  xml = xmlparser2.parse(data);
230
227
 
231
228
  // defined names
232
- this.defined_names = {};
229
+ this.named = [];
233
230
  const defined_names = XMLUtils.FindAll(xml, 'workbook/definedNames/definedName');
234
231
  for (const defined_name of defined_names) {
235
232
  const name = defined_name.a$?.name;
236
233
  const expression = defined_name.t$ || '';
234
+ const sheet_index = (defined_name.a$?.localSheetId) ? Number(defined_name.a$.localSheetId) : undefined;
235
+
236
+ // console.info({defined_name, name, expression, sheet_index});
237
+ this.named.push({
238
+ name,
239
+ expression: typeof expression === 'string' ? expression : expression?.toString() || '',
240
+ local_scope: sheet_index,
241
+ });
242
+
243
+ }
244
+
245
+ /*
246
+ this.defined_names = {};
247
+ const defined_names = XMLUtils.FindAll(xml, 'workbook/definedNames/definedName');
248
+
249
+ console.info({defined_names});
250
+
251
+ for (const defined_name of defined_names) {
237
252
  if (name && expression) {
238
253
  this.defined_names[name] = expression;
239
254
  }
240
255
  }
256
+ */
241
257
 
242
258
  const workbook_views = XMLUtils.FindAll(xml, 'workbook/bookViews/workbookView');
243
259
 
@@ -390,7 +406,7 @@ export class Workbook {
390
406
  const fill = sppr['a:solidFill'];
391
407
  if (fill) {
392
408
  if (fill['a:schemeClr']?.a$?.val) {
393
- let m = (fill['a:schemeClr'].a$.val).match(/accent(\d+)/);
409
+ const m = (fill['a:schemeClr'].a$.val).match(/accent(\d+)/);
394
410
  if (m) {
395
411
  style.fill = { theme: Number(m[1]) + 3 }
396
412
  if (fill['a:schemeClr']['a:lumOff']?.a$?.val) {
@@ -428,7 +444,7 @@ export class Workbook {
428
444
  const para: { text: string, style?: CellStyle }[] = [];
429
445
  let style: CellStyle|undefined;
430
446
 
431
- let appr = paragraph['a:pPr'];
447
+ const appr = paragraph['a:pPr'];
432
448
  if (appr) {
433
449
  style = {};
434
450
  if (appr.a$?.algn === 'r') {
@@ -673,13 +689,15 @@ export class Workbook {
673
689
  }
674
690
 
675
691
  /** FIXME: accessor */
676
- public GetNamedRanges(): Record<string, string> {
692
+ public GetNamedRanges() {
677
693
 
678
694
  // ... what does this do, not do, or what is it supposed to do?
679
695
  // note that this is called by the import routine, so it probably
680
696
  // expects to do something
681
697
 
682
- return this.defined_names;
698
+ // return this.defined_names;
699
+
700
+ return this.named;
683
701
 
684
702
  }
685
703
 
@@ -24,6 +24,10 @@ import type { X2jOptions } from 'fast-xml-parser';
24
24
 
25
25
  export const XMLTagProcessor = (name: string, value: string): string => Unescape(value);
26
26
 
27
+ export interface DOMContent {
28
+ [index: string]: string|DOMContent|string[]|DOMContent[]|number|number[];
29
+ }
30
+
27
31
  export const XMLOptions: Partial<X2jOptions> = {
28
32
  ignoreAttributes: false,
29
33
  attributeNamePrefix: '__',
@@ -48,7 +52,7 @@ export const XMLOptions2: Partial<X2jOptions> = {
48
52
 
49
53
  // arrayMode: false, // this was removed in FXP, but false is default anyway
50
54
 
51
- isArray: (tagName: string, jPath: string, isLeafNode: boolean, isAttribute: boolean) => {
55
+ isArray: (tagName: string) => {
52
56
  return /Relationship$/.test(tagName);
53
57
  },
54
58
 
@@ -19,6 +19,8 @@
19
19
  *
20
20
  */
21
21
 
22
+ /* eslint-disable no-irregular-whitespace */
23
+
22
24
  import { FormatParser } from './format_parser';
23
25
  import { NumberFormatSection } from './number_format_section';
24
26
  import type { TextPart, Complex, DimensionedQuantity, CellValue} from 'treb-base-types';
@@ -534,7 +536,7 @@ export class NumberFormat {
534
536
  if (has_imaginary_value) {
535
537
 
536
538
  // also has imaginary part
537
- const i = Math.abs(value.imaginary);
539
+ // const i = Math.abs(value.imaginary);
538
540
  parts.push({ text: value.imaginary < 0 ? ` ${NumberFormat.minus_character} ` : ' + ' });
539
541
 
540
542
  const reformatted_imaginary = drop_imaginary_coefficient ?
@@ -559,7 +561,7 @@ export class NumberFormat {
559
561
  * states. it's intended for graphical representation where things
560
562
  * like hidden characters and padding require multiple passes or measurement.
561
563
  */
562
- public FormatParts(value: any): TextPart[] {
564
+ public FormatParts(value: CellValue): TextPart[] {
563
565
 
564
566
  // new, shortcut
565
567
  if (typeof value !== 'number' && !this.sections[3]) {
@@ -567,7 +569,7 @@ export class NumberFormat {
567
569
  // NOTE: that note (next line) seems to be incorrect, not sure why
568
570
  // ofc if that was true there'd be no point to this block...
569
571
 
570
- return [{ text: value.toString() }] as TextPart[]; // unreachable because we ensure 4 sections
572
+ return [{ text: (value??'').toString() }] as TextPart[]; // unreachable because we ensure 4 sections
571
573
  }
572
574
 
573
575
  const { parts, section } = this.BaseFormat(value);
@@ -621,7 +623,7 @@ export class NumberFormat {
621
623
  * FIXME: date, string (this is lagging)
622
624
  * UPDATE: unifying, basing this on the text part functionality
623
625
  */
624
- public Format(value: any, text_width = 0): string {
626
+ public Format(value: CellValue, text_width = 0): string {
625
627
 
626
628
  /*
627
629
  const parts = this.FormatParts(value);
@@ -857,14 +859,14 @@ export class NumberFormat {
857
859
 
858
860
  }
859
861
 
860
- public BaseFormat(value: any) {
862
+ public BaseFormat(value: CellValue) {
861
863
 
862
864
  if (this.sections[0].date_format) {
863
865
  return this.DateFormat(Number(value));
864
866
  }
865
867
 
866
868
  if (typeof value !== 'number') {
867
- return this.StringFormat(value.toString(), this.sections[3]);
869
+ return this.StringFormat((value??'').toString(), this.sections[3]);
868
870
  }
869
871
 
870
872
  let section = this.sections[0];