reamkit 1.14.0 → 1.15.1
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/README.md +34 -8
- package/dist/esm/core/converter/facade.d.ts +8 -1
- package/dist/esm/core/converter/facade.js +34 -8
- package/dist/esm/core/converter/ream.d.ts +1 -0
- package/dist/esm/core/converter/ream.js +13 -8
- package/dist/esm/core/ir/features.d.ts +1 -0
- package/dist/esm/core/ir/features.js +1 -0
- package/dist/esm/core/ir/sheet.d.ts +7 -0
- package/dist/esm/core/ole/cfb.d.ts +19 -0
- package/dist/esm/core/ole/cfb.js +188 -0
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +20 -1
- package/dist/esm/excel/activex-parser.d.ts +9 -0
- package/dist/esm/excel/activex-parser.js +188 -0
- package/dist/esm/excel/conditional-format.d.ts +4 -2
- package/dist/esm/excel/conditional-format.js +138 -4
- package/dist/esm/excel/formula/context.d.ts +11 -0
- package/dist/esm/excel/formula/dates.d.ts +11 -0
- package/dist/esm/excel/formula/dates.js +46 -0
- package/dist/esm/excel/formula/eval.d.ts +11 -0
- package/dist/esm/excel/formula/eval.js +196 -0
- package/dist/esm/excel/formula/functions.d.ts +7 -0
- package/dist/esm/excel/formula/functions.js +1359 -0
- package/dist/esm/excel/formula/index.d.ts +14 -0
- package/dist/esm/excel/formula/index.js +17 -0
- package/dist/esm/excel/formula/lexer.d.ts +8 -0
- package/dist/esm/excel/formula/lexer.js +163 -0
- package/dist/esm/excel/formula/parser.d.ts +57 -0
- package/dist/esm/excel/formula/parser.js +274 -0
- package/dist/esm/excel/formula/value.d.ts +52 -0
- package/dist/esm/excel/formula/value.js +102 -0
- package/dist/esm/excel/number-format.d.ts +2 -0
- package/dist/esm/excel/number-format.js +5 -1
- package/dist/esm/excel/print-model.d.ts +3 -0
- package/dist/esm/excel/print-model.js +1 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +4 -1
- package/dist/esm/excel/sheet-to-flow.js +46 -2
- package/dist/esm/excel/worksheet-parser.js +66 -0
- package/dist/esm/excel/xls/biff-chart.d.ts +8 -0
- package/dist/esm/excel/xls/biff-chart.js +121 -0
- package/dist/esm/excel/xls/biff-reader.d.ts +4 -0
- package/dist/esm/excel/xls/biff-reader.js +1418 -0
- package/dist/esm/excel/xls/biff-styles.d.ts +8 -0
- package/dist/esm/excel/xls/biff-styles.js +299 -0
- package/dist/esm/excel/xls/escher.d.ts +24 -0
- package/dist/esm/excel/xls/escher.js +171 -0
- package/dist/esm/excel/xls/xls-reader.d.ts +3 -0
- package/dist/esm/excel/xls/xls-reader.js +30 -0
- package/dist/esm/excel/xlsx-reader.d.ts +2 -1
- package/dist/esm/excel/xlsx-reader.js +28 -3
- package/dist/esm/excel/xlsx-to-pdf.d.ts +1 -0
- package/dist/esm/excel/xlsx-to-pdf.js +2 -2
- package/dist/esm/excel/xlsx-writer.js +2 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +4 -2
- package/dist/esm/pdf-reader/flow-build.js +25 -2
- package/dist/esm/pdf-reader/layout.js +2 -2
- package/dist/esm/pdf-reader/tagged.js +2 -2
- package/dist/esm/pptx/ppt/ppt-reader.d.ts +4 -0
- package/dist/esm/pptx/ppt/ppt-reader.js +337 -0
- package/dist/esm/pptx/ppt/ppt-text.d.ts +69 -0
- package/dist/esm/pptx/ppt/ppt-text.js +756 -0
- package/dist/esm/pptx/pptx-reader.js +16 -1
- package/dist/esm/word/doc/doc-reader.d.ts +4 -0
- package/dist/esm/word/doc/doc-reader.js +427 -0
- package/dist/esm/word/doc/doc-text.d.ts +83 -0
- package/dist/esm/word/doc/doc-text.js +731 -0
- package/package.json +1 -1
|
@@ -18,8 +18,11 @@ interface PrintModelOptions {
|
|
|
18
18
|
readonly endRow: number;
|
|
19
19
|
};
|
|
20
20
|
readonly sheetGrids?: ReadonlyMap<string, ParsedWorksheet>;
|
|
21
|
+
readonly sheetName?: string;
|
|
22
|
+
readonly definedNames?: ReadonlyArray<DefinedName>;
|
|
21
23
|
readonly hyperlinks?: ReadonlyArray<SheetHyperlink>;
|
|
22
24
|
readonly sharedStringRuns?: ReadonlyArray<ReadonlyArray<SheetRichRun> | undefined>;
|
|
25
|
+
readonly now?: Date;
|
|
23
26
|
}
|
|
24
27
|
export declare function worksheetToBody(worksheet: ParsedWorksheet, sharedStrings: ReadonlyArray<string>, styles: XlsxStyles, date1904: boolean, print: PrintModelOptions): Array<BodyElement>;
|
|
25
28
|
export declare function resolveCellText(cell: WorksheetCell, sharedStrings: ReadonlyArray<string>, styles: XlsxStyles, date1904: boolean): string;
|
|
@@ -192,7 +192,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
192
192
|
}
|
|
193
193
|
return props;
|
|
194
194
|
};
|
|
195
|
-
const cfFormatter = buildConditionalFormatter(worksheet.conditionalFormats, styles, worksheet.cells, (cell) => resolveCellText(cell, sharedStrings, styles, date1904));
|
|
195
|
+
const cfFormatter = buildConditionalFormatter(worksheet.conditionalFormats, styles, worksheet.cells, (cell) => resolveCellText(cell, sharedStrings, styles, date1904), date1904, print.now, print.sheetGrids, print.sheetName, print.definedNames);
|
|
196
196
|
const sparklineByCell = buildSparklineLookup(worksheet, print);
|
|
197
197
|
const tableFormatByCell = buildTableFormatLookup(worksheet);
|
|
198
198
|
const dropdownRanges = listDropdownRanges(worksheet.dataValidations);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { FlowDoc } from '../core/ir/flow.js';
|
|
2
2
|
import { SheetDoc } from '../core/ir/sheet.js';
|
|
3
|
-
export
|
|
3
|
+
export interface ProjectSheetOptions {
|
|
4
|
+
readonly now?: Date;
|
|
5
|
+
}
|
|
6
|
+
export declare function projectSheetDoc(sheet: SheetDoc, options?: ProjectSheetOptions): FlowDoc;
|
|
@@ -6,7 +6,7 @@ import { buildHeaderFooterContent } from "./header-footer.js";
|
|
|
6
6
|
//#region src/excel/sheet-to-flow.ts
|
|
7
7
|
var HEADER_REL = "_xlsxHeaderDefault";
|
|
8
8
|
var FOOTER_REL = "_xlsxFooterDefault";
|
|
9
|
-
function projectSheetDoc(sheet) {
|
|
9
|
+
function projectSheetDoc(sheet, options = {}) {
|
|
10
10
|
const body = [];
|
|
11
11
|
let firstSheetSection;
|
|
12
12
|
const headersFooters = /* @__PURE__ */ new Map();
|
|
@@ -29,8 +29,11 @@ function projectSheetDoc(sheet) {
|
|
|
29
29
|
...titleRows ? { titleRows } : {},
|
|
30
30
|
gridLines,
|
|
31
31
|
sheetGrids,
|
|
32
|
+
sheetName: ws.name,
|
|
33
|
+
definedNames: sheet.definedNames,
|
|
32
34
|
...ws.hyperlinks ? { hyperlinks: ws.hyperlinks } : {},
|
|
33
|
-
...sheet.sharedStringRuns ? { sharedStringRuns: sheet.sharedStringRuns } : {}
|
|
35
|
+
...sheet.sharedStringRuns ? { sharedStringRuns: sheet.sharedStringRuns } : {},
|
|
36
|
+
...options.now ? { now: options.now } : {}
|
|
34
37
|
}));
|
|
35
38
|
for (const ref of ws.charts ?? []) body.push({
|
|
36
39
|
kind: "chart",
|
|
@@ -60,6 +63,7 @@ function projectSheetDoc(sheet) {
|
|
|
60
63
|
});
|
|
61
64
|
if (ws.comments && ws.comments.length > 0) body.push(...commentBlocks(ws.comments));
|
|
62
65
|
if (ws.formControls && ws.formControls.length > 0) body.push(...formControlBlocks(ws.formControls));
|
|
66
|
+
if (ws.activeXControls && ws.activeXControls.length > 0) body.push(...activeXBlocks(ws.activeXControls));
|
|
63
67
|
}
|
|
64
68
|
return {
|
|
65
69
|
kind: "flow",
|
|
@@ -139,6 +143,46 @@ function formControlLabel(c) {
|
|
|
139
143
|
default: return c.objectType ? `${name} (${c.objectType})` : name;
|
|
140
144
|
}
|
|
141
145
|
}
|
|
146
|
+
function activeXBlocks(controls) {
|
|
147
|
+
const out = [{
|
|
148
|
+
kind: "paragraph",
|
|
149
|
+
paragraph: {
|
|
150
|
+
properties: {},
|
|
151
|
+
runs: [{
|
|
152
|
+
text: "ActiveX controls",
|
|
153
|
+
properties: { bold: true }
|
|
154
|
+
}]
|
|
155
|
+
}
|
|
156
|
+
}];
|
|
157
|
+
for (const c of controls) out.push({
|
|
158
|
+
kind: "paragraph",
|
|
159
|
+
paragraph: {
|
|
160
|
+
properties: {},
|
|
161
|
+
runs: [{
|
|
162
|
+
text: activeXLabel(c),
|
|
163
|
+
properties: {}
|
|
164
|
+
}]
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
function activeXLabel(c) {
|
|
170
|
+
const label = c.caption && c.caption.length > 0 ? c.caption : c.type;
|
|
171
|
+
const on = c.value === "1" || c.value?.toLowerCase() === "true";
|
|
172
|
+
switch (c.type) {
|
|
173
|
+
case "checkbox": return `${on ? "[x]" : "[ ]"} ${label}`;
|
|
174
|
+
case "option": return `${on ? "(o)" : "( )"} ${label}`;
|
|
175
|
+
case "button":
|
|
176
|
+
case "toggle": return `[ ${label} ]`;
|
|
177
|
+
case "textbox": return `[ ${c.value ?? c.caption ?? ""} ]`;
|
|
178
|
+
case "combo":
|
|
179
|
+
case "list": return `${label} (list)`;
|
|
180
|
+
case "spin":
|
|
181
|
+
case "scroll": return c.value !== void 0 ? `${label} (value ${c.value})` : label;
|
|
182
|
+
case "label": return c.caption ?? "Label";
|
|
183
|
+
default: return label;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
142
186
|
function withHeaderFooter(section, ws, headersFooters) {
|
|
143
187
|
const hf = ws.grid.headerFooter;
|
|
144
188
|
if (!hf || !hf.oddHeader && !hf.oddFooter) return section;
|
|
@@ -41,6 +41,7 @@ function parseWorksheet(data) {
|
|
|
41
41
|
const hyperlinks = parseHyperlinks(wsObj);
|
|
42
42
|
const headerFooter = parseHeaderFooter(wsObj);
|
|
43
43
|
const formControls = parseFormControls(wsObj);
|
|
44
|
+
const oleObjects = parseOleObjects(wsObj);
|
|
44
45
|
const sparklines = parseSparklines(wsObj);
|
|
45
46
|
const tablePartRelIds = parseTableParts(wsObj);
|
|
46
47
|
const printModel = {
|
|
@@ -57,6 +58,7 @@ function parseWorksheet(data) {
|
|
|
57
58
|
...hyperlinks.length > 0 ? { hyperlinks } : {},
|
|
58
59
|
...headerFooter ? { headerFooter } : {},
|
|
59
60
|
...formControls.length > 0 ? { formControls } : {},
|
|
61
|
+
...oleObjects.length > 0 ? { oleObjects } : {},
|
|
60
62
|
...sparklines.length > 0 ? { sparklines } : {},
|
|
61
63
|
...tablePartRelIds.length > 0 ? { tablePartRelIds } : {}
|
|
62
64
|
};
|
|
@@ -435,9 +437,49 @@ function parseCfRule(obj) {
|
|
|
435
437
|
case "notContainsText":
|
|
436
438
|
case "beginsWith":
|
|
437
439
|
case "endsWith": return parseTextRule(type, obj, priority);
|
|
440
|
+
case "expression": return parseExpressionRule(obj, priority);
|
|
441
|
+
case "timePeriod": return parseTimePeriodRule(obj, priority);
|
|
438
442
|
default: return;
|
|
439
443
|
}
|
|
440
444
|
}
|
|
445
|
+
var TIME_PERIODS = new Set([
|
|
446
|
+
"today",
|
|
447
|
+
"yesterday",
|
|
448
|
+
"tomorrow",
|
|
449
|
+
"last7Days",
|
|
450
|
+
"thisWeek",
|
|
451
|
+
"lastWeek",
|
|
452
|
+
"nextWeek",
|
|
453
|
+
"thisMonth",
|
|
454
|
+
"lastMonth",
|
|
455
|
+
"nextMonth"
|
|
456
|
+
]);
|
|
457
|
+
function parseExpressionRule(obj, priority) {
|
|
458
|
+
const dxfId = parseNumericAttr(obj, "dxfId");
|
|
459
|
+
if (dxfId === void 0) return void 0;
|
|
460
|
+
const formula = formulaText(obj["formula"]);
|
|
461
|
+
if (formula === void 0) return void 0;
|
|
462
|
+
return {
|
|
463
|
+
type: "expression",
|
|
464
|
+
priority,
|
|
465
|
+
formula,
|
|
466
|
+
dxfId
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
function parseTimePeriodRule(obj, priority) {
|
|
470
|
+
const dxfId = parseNumericAttr(obj, "dxfId");
|
|
471
|
+
if (dxfId === void 0) return void 0;
|
|
472
|
+
const period = strAttr(obj, "timePeriod");
|
|
473
|
+
if (period === void 0 || !TIME_PERIODS.has(period)) return void 0;
|
|
474
|
+
const formula = formulaText(obj["formula"]);
|
|
475
|
+
return {
|
|
476
|
+
type: "timePeriod",
|
|
477
|
+
priority,
|
|
478
|
+
timePeriod: period,
|
|
479
|
+
dxfId,
|
|
480
|
+
...formula !== void 0 ? { formula } : {}
|
|
481
|
+
};
|
|
482
|
+
}
|
|
441
483
|
function parseTop10Rule(obj, priority) {
|
|
442
484
|
const dxfId = parseNumericAttr(obj, "dxfId");
|
|
443
485
|
if (dxfId === void 0) return void 0;
|
|
@@ -669,6 +711,30 @@ function collectControls(node, out, seen) {
|
|
|
669
711
|
});
|
|
670
712
|
}
|
|
671
713
|
}
|
|
714
|
+
function parseOleObjects(ws) {
|
|
715
|
+
const out = [];
|
|
716
|
+
const seen = /* @__PURE__ */ new Set();
|
|
717
|
+
collectOleObjects(asObjectNode(ws["oleObjects"]), out, seen);
|
|
718
|
+
for (const ext of toArray(asObjectNode(ws["extLst"])?.["ext"])) collectOleObjects(asObjectNode(asObjectNode(ext)?.["oleObjects"]), out, seen);
|
|
719
|
+
return out;
|
|
720
|
+
}
|
|
721
|
+
function collectOleObjects(node, out, seen) {
|
|
722
|
+
if (!node) return;
|
|
723
|
+
const direct = toArray(node["oleObject"]);
|
|
724
|
+
const fromChoice = toArray(asObjectNode(node["AlternateContent"])?.["Choice"]).flatMap((c) => toArray(asObjectNode(c)?.["oleObject"]));
|
|
725
|
+
for (const o of [...direct, ...fromChoice]) {
|
|
726
|
+
const obj = asObjectNode(o);
|
|
727
|
+
if (!obj) continue;
|
|
728
|
+
const relId = strAttr(obj, "id");
|
|
729
|
+
if (!relId || seen.has(relId)) continue;
|
|
730
|
+
seen.add(relId);
|
|
731
|
+
const progId = strAttr(obj, "progId");
|
|
732
|
+
out.push({
|
|
733
|
+
relId,
|
|
734
|
+
...progId ? { progId } : {}
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
}
|
|
672
738
|
function asObjectNode(v) {
|
|
673
739
|
return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
674
740
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Chart } from '../../core/document-model/index.js';
|
|
2
|
+
import { WorksheetCell } from '../../core/spreadsheet-model/index.js';
|
|
3
|
+
interface Rec {
|
|
4
|
+
readonly type: number;
|
|
5
|
+
readonly data: Uint8Array;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseBiffChart(records: ReadonlyArray<Rec>, cells: ReadonlyArray<WorksheetCell>, sharedStrings: ReadonlyArray<string>): Chart | undefined;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
//#region src/excel/xls/biff-chart.ts
|
|
2
|
+
var REC_BAR = 4119;
|
|
3
|
+
var REC_LINE = 4120;
|
|
4
|
+
var REC_PIE = 4121;
|
|
5
|
+
var REC_AREA = 4122;
|
|
6
|
+
var REC_SCATTER = 4123;
|
|
7
|
+
var REC_SERIES = 4099;
|
|
8
|
+
var REC_AI = 4177;
|
|
9
|
+
var REC_SERIESTEXT = 4109;
|
|
10
|
+
var COLS = 16384;
|
|
11
|
+
function parseBiffChart(records, cells, sharedStrings) {
|
|
12
|
+
let type = "unknown";
|
|
13
|
+
let barDir;
|
|
14
|
+
const accs = [];
|
|
15
|
+
let current;
|
|
16
|
+
for (const rec of records) switch (rec.type) {
|
|
17
|
+
case REC_BAR:
|
|
18
|
+
type = "bar";
|
|
19
|
+
barDir = (u16(rec.data, 4) & 1) !== 0 ? "bar" : "col";
|
|
20
|
+
break;
|
|
21
|
+
case REC_LINE:
|
|
22
|
+
type = "line";
|
|
23
|
+
break;
|
|
24
|
+
case REC_PIE:
|
|
25
|
+
type = "pie";
|
|
26
|
+
break;
|
|
27
|
+
case REC_AREA:
|
|
28
|
+
type = "area";
|
|
29
|
+
break;
|
|
30
|
+
case REC_SCATTER:
|
|
31
|
+
type = "scatter";
|
|
32
|
+
break;
|
|
33
|
+
case REC_SERIES:
|
|
34
|
+
current = {};
|
|
35
|
+
accs.push(current);
|
|
36
|
+
break;
|
|
37
|
+
case REC_AI: {
|
|
38
|
+
if (!current) break;
|
|
39
|
+
const id = rec.data[0] ?? 0;
|
|
40
|
+
const cce = u16(rec.data, 6);
|
|
41
|
+
const range = parseAreaPtg(rec.data.subarray(8, 8 + cce));
|
|
42
|
+
if (range) {
|
|
43
|
+
if (id === 1) current.values = range;
|
|
44
|
+
else if (id === 2) current.categories = range;
|
|
45
|
+
else if (id === 0) current.nameRef = range;
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case REC_SERIESTEXT:
|
|
50
|
+
if (current) current.nameText = parseSeriesText(rec.data);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
if (accs.length === 0) return void 0;
|
|
54
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
55
|
+
for (const c of cells) byKey.set(c.row * COLS + c.column, c);
|
|
56
|
+
const numAt = (r, c) => {
|
|
57
|
+
const cell = byKey.get(r * COLS + c);
|
|
58
|
+
if (cell?.type !== "n") return 0;
|
|
59
|
+
const n = Number(cell.rawValue);
|
|
60
|
+
return Number.isFinite(n) ? n : 0;
|
|
61
|
+
};
|
|
62
|
+
const textAt = (r, c) => {
|
|
63
|
+
const cell = byKey.get(r * COLS + c);
|
|
64
|
+
if (!cell) return "";
|
|
65
|
+
if (cell.type === "s") return sharedStrings[Number(cell.rawValue)] ?? "";
|
|
66
|
+
if (cell.type === "inlineStr") return cell.inlineText ?? "";
|
|
67
|
+
return cell.rawValue;
|
|
68
|
+
};
|
|
69
|
+
let categories = [];
|
|
70
|
+
const series = [];
|
|
71
|
+
for (const acc of accs) {
|
|
72
|
+
const values = acc.values ? rangeCells(acc.values).map(([r, c]) => numAt(r, c)) : [];
|
|
73
|
+
if (acc.categories && categories.length === 0) categories = rangeCells(acc.categories).map(([r, c]) => textAt(r, c));
|
|
74
|
+
const name = acc.nameText ?? (acc.nameRef ? textAt(acc.nameRef.r0, acc.nameRef.c0) : void 0);
|
|
75
|
+
series.push({
|
|
76
|
+
values,
|
|
77
|
+
...name ? { name } : {}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (series.every((s) => s.values.length === 0)) return void 0;
|
|
81
|
+
return {
|
|
82
|
+
type,
|
|
83
|
+
categories,
|
|
84
|
+
series,
|
|
85
|
+
hasLegend: true,
|
|
86
|
+
...barDir ? { barDir } : {}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function rangeCells(range) {
|
|
90
|
+
const out = [];
|
|
91
|
+
for (let r = range.r0; r <= range.r1; r++) for (let c = range.c0; c <= range.c1; c++) out.push([r, c]);
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
function parseAreaPtg(rgce) {
|
|
95
|
+
if (rgce.length < 1) return void 0;
|
|
96
|
+
const base = rgce[0] & 31;
|
|
97
|
+
let off = 1;
|
|
98
|
+
if (base === 27) off = 3;
|
|
99
|
+
else if (base !== 5) return void 0;
|
|
100
|
+
if (off + 8 > rgce.length) return void 0;
|
|
101
|
+
return {
|
|
102
|
+
r0: u16(rgce, off),
|
|
103
|
+
r1: u16(rgce, off + 2),
|
|
104
|
+
c0: u16(rgce, off + 4) & 16383,
|
|
105
|
+
c1: u16(rgce, off + 6) & 16383
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function parseSeriesText(d) {
|
|
109
|
+
if (d.length < 4) return "";
|
|
110
|
+
const cch = d[2];
|
|
111
|
+
const high = (d[3] & 1) !== 0;
|
|
112
|
+
let s = "";
|
|
113
|
+
if (high) for (let i = 0; i < cch && 4 + i * 2 + 1 < d.length; i++) s += String.fromCharCode(d[4 + i * 2] | d[4 + i * 2 + 1] << 8);
|
|
114
|
+
else for (let i = 0; i < cch && 4 + i < d.length; i++) s += String.fromCharCode(d[4 + i]);
|
|
115
|
+
return s;
|
|
116
|
+
}
|
|
117
|
+
function u16(d, off) {
|
|
118
|
+
return (d[off] ?? 0) | (d[off + 1] ?? 0) << 8;
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
export { parseBiffChart };
|