@silurus/ooxml 0.14.1 → 0.15.0
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 +107 -101
- package/dist/{docx-Q9meJO2G.js → docx-C_zG3e0V.js} +3 -2
- package/dist/{docx-DOf7BLnj.cjs → docx-DKPVLT6O.cjs} +1 -1
- package/dist/docx.cjs +1 -1
- package/dist/docx.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{pptx-DVyrqUyw.js → pptx-B76oTVMe.js} +3 -1
- package/dist/{pptx-BMJO4Oqg.cjs → pptx-BiUBfZZA.cjs} +1 -1
- package/dist/pptx.cjs +1 -1
- package/dist/pptx.mjs +1 -1
- package/dist/types/docx.d.ts +3 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/pptx.d.ts +2 -0
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@silurus/ooxml)
|
|
6
6
|
[](https://www.npmjs.com/package/@silurus/ooxml)
|
|
7
|
+
[](https://marketplace.visualstudio.com/items?itemName=silurus.office-open-xml-viewer)
|
|
8
|
+
[](https://marketplace.visualstudio.com/items?itemName=silurus.office-open-xml-viewer)
|
|
7
9
|
[](./LICENSE)
|
|
8
10
|
|
|
9
11
|
**[Demo (Storybook)](https://ooxml.silurus.dev)**
|
|
10
12
|
|
|
11
13
|
A browser-based viewer for Office Open XML documents that renders to an HTML Canvas element.
|
|
12
14
|
The parsers are written in Rust and compiled to WebAssembly; the renderers use the Canvas 2D API.
|
|
13
|
-
Each format also exposes a headless engine (`
|
|
15
|
+
Each format also exposes a headless engine (`DocxDocument` / `XlsxWorkbook` / `PptxPresentation`) that renders into any caller-supplied canvas, so you can compose your own UI — scroll views, thumbnail grids, master-detail panes — instead of being locked into the built-in viewer. See the `Examples` section in [the Storybook demo](https://ooxml.silurus.dev).
|
|
14
16
|
|
|
15
|
-
|
|
|
17
|
+
| DOCX | XLSX | PPTX |
|
|
16
18
|
|:---:|:---:|:---:|
|
|
17
|
-
|  |  |  |
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
22
|
npm install @silurus/ooxml
|
|
@@ -31,25 +33,25 @@ pnpm add @silurus/ooxml
|
|
|
31
33
|
## Quick Start
|
|
32
34
|
|
|
33
35
|
```typescript
|
|
34
|
-
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
35
|
-
import { XlsxViewer } from '@silurus/ooxml/xlsx';
|
|
36
36
|
import { DocxViewer } from '@silurus/ooxml/docx';
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const pptx = new PptxViewer(document.getElementById('pptx-container')!);
|
|
40
|
-
const buf = await fetch('/deck.pptx').then(r => r.arrayBuffer());
|
|
41
|
-
await pptx.load(buf);
|
|
42
|
-
pptx.nextSlide();
|
|
43
|
-
|
|
44
|
-
// XLSX — viewer manages its own <canvas> + tab bar
|
|
45
|
-
const xlsx = new XlsxViewer(document.getElementById('xlsx-container')!);
|
|
46
|
-
await xlsx.load('/workbook.xlsx');
|
|
37
|
+
import { XlsxViewer } from '@silurus/ooxml/xlsx';
|
|
38
|
+
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
47
39
|
|
|
48
40
|
// DOCX — caller provides the <canvas>
|
|
49
41
|
const canvas = document.getElementById('docx-canvas') as HTMLCanvasElement;
|
|
50
42
|
const docx = new DocxViewer(canvas);
|
|
51
43
|
await docx.load('/document.docx');
|
|
52
44
|
docx.nextPage();
|
|
45
|
+
|
|
46
|
+
// XLSX — viewer manages its own <canvas> + tab bar
|
|
47
|
+
const xlsx = new XlsxViewer(document.getElementById('xlsx-container')!);
|
|
48
|
+
await xlsx.load('/workbook.xlsx');
|
|
49
|
+
|
|
50
|
+
// PPTX — viewer manages its own <canvas>
|
|
51
|
+
const pptx = new PptxViewer(document.getElementById('pptx-container')!);
|
|
52
|
+
const buf = await fetch('/deck.pptx').then(r => r.arrayBuffer());
|
|
53
|
+
await pptx.load(buf);
|
|
54
|
+
pptx.nextSlide();
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
---
|
|
@@ -61,35 +63,35 @@ docx.nextPage();
|
|
|
61
63
|
flowchart TB
|
|
62
64
|
subgraph build["🦀 Build-time (Rust → WebAssembly)"]
|
|
63
65
|
direction LR
|
|
64
|
-
pptx_rs["packages/pptx/parser/src/lib.rs"]
|
|
65
|
-
xlsx_rs["packages/xlsx/parser/src/lib.rs"]
|
|
66
66
|
docx_rs["packages/docx/parser/src/lib.rs"]
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
xlsx_rs["packages/xlsx/parser/src/lib.rs"]
|
|
68
|
+
pptx_rs["packages/pptx/parser/src/lib.rs"]
|
|
69
69
|
docx_rs -- wasm-pack --> docx_wasm["docx_parser.wasm"]
|
|
70
|
+
xlsx_rs -- wasm-pack --> xlsx_wasm["xlsx_parser.wasm"]
|
|
71
|
+
pptx_rs -- wasm-pack --> pptx_wasm["pptx_parser.wasm"]
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
subgraph browser["🌐 Runtime (Browser)"]
|
|
73
|
-
subgraph
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
PP --> PR["renderer.ts\n〈Canvas 2D — main thread〉"]
|
|
75
|
+
subgraph docx_pkg["@silurus/ooxml · docx"]
|
|
76
|
+
DV["DocxViewer"] --> DD["DocxDocument"]
|
|
77
|
+
DD --> DR["renderer.ts\n〈Canvas 2D〉"]
|
|
77
78
|
end
|
|
78
79
|
subgraph xlsx_pkg["@silurus/ooxml · xlsx"]
|
|
79
80
|
XV["XlsxViewer"] --> XR["renderer.ts\n〈Canvas 2D〉"]
|
|
80
81
|
end
|
|
81
|
-
subgraph
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
subgraph pptx_pkg["@silurus/ooxml · pptx"]
|
|
83
|
+
PV["PptxViewer"] --> PP["PptxPresentation"]
|
|
84
|
+
PP --> PW["worker.ts\n〈Web Worker — parse only〉"]
|
|
85
|
+
PP --> PR["renderer.ts\n〈Canvas 2D — main thread〉"]
|
|
84
86
|
end
|
|
85
87
|
end
|
|
86
88
|
|
|
87
|
-
pptx_wasm --> PW
|
|
88
|
-
xlsx_wasm --> XV
|
|
89
89
|
docx_wasm --> DD
|
|
90
|
-
|
|
90
|
+
xlsx_wasm --> XV
|
|
91
|
+
pptx_wasm --> PW
|
|
92
|
+
DR --> canvas["<canvas>"]
|
|
91
93
|
XR --> canvas
|
|
92
|
-
|
|
94
|
+
PR --> canvas
|
|
93
95
|
```
|
|
94
96
|
|
|
95
97
|
The pptx worker parses the `.pptx` archive via WASM and returns a JSON model to the main thread. Rendering runs on the main thread so the canvas shares the document's `FontFaceSet` — an `OffscreenCanvas` in a worker has its own font registry and would silently fall back to a system font, producing subtly different text measurements (and wrap positions) from the installed theme webfonts.
|
|
@@ -98,12 +100,12 @@ The pptx worker parses the `.pptx` archive via WASM and returns a JSON model to
|
|
|
98
100
|
|
|
99
101
|
| File | Role |
|
|
100
102
|
|------|------|
|
|
101
|
-
| `packages/pptx/parser/src/lib.rs` | Rust WASM parser — PPTX ZIP → `Presentation` JSON |
|
|
102
|
-
| `packages/xlsx/parser/src/lib.rs` | Rust WASM parser — XLSX ZIP → `Workbook` JSON |
|
|
103
103
|
| `packages/docx/parser/src/lib.rs` | Rust WASM parser — DOCX ZIP → `Document` JSON |
|
|
104
|
-
| `packages/
|
|
105
|
-
| `packages/
|
|
104
|
+
| `packages/xlsx/parser/src/lib.rs` | Rust WASM parser — XLSX ZIP → `Workbook` JSON |
|
|
105
|
+
| `packages/pptx/parser/src/lib.rs` | Rust WASM parser — PPTX ZIP → `Presentation` JSON |
|
|
106
106
|
| `packages/docx/src/renderer.ts` | Canvas 2D rendering engine with text layout |
|
|
107
|
+
| `packages/xlsx/src/renderer.ts` | Canvas 2D rendering engine with virtual scroll |
|
|
108
|
+
| `packages/pptx/src/renderer.ts` | Canvas 2D rendering engine (runs on main thread) |
|
|
107
109
|
| `packages/pptx/src/worker.ts` | Web Worker: WASM init and parsing only |
|
|
108
110
|
| `packages/*/src/viewer.ts` | Public Viewer API — canvas lifecycle, navigation |
|
|
109
111
|
|
|
@@ -354,6 +356,72 @@ export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
|
354
356
|
|
|
355
357
|
## Feature Support
|
|
356
358
|
|
|
359
|
+
### Word (.docx)
|
|
360
|
+
|
|
361
|
+
| Category | Feature | Status |
|
|
362
|
+
|----------|---------|--------|
|
|
363
|
+
| **Document** | Page rendering | ✅ |
|
|
364
|
+
| | Page size and margins | ✅ |
|
|
365
|
+
| | Headers / footers (default / first / even) | ✅ |
|
|
366
|
+
| | Section breaks | ❌ |
|
|
367
|
+
| **Text** | Paragraphs | ✅ |
|
|
368
|
+
| | Bold, italic, underline, strikethrough | ✅ |
|
|
369
|
+
| | Font family, size, color | ✅ |
|
|
370
|
+
| | Hyperlinks | ✅ |
|
|
371
|
+
| | Superscript / subscript (`w:vertAlign`) | ✅ |
|
|
372
|
+
| **Formatting** | Paragraph alignment (left/center/right/justify) | ✅ |
|
|
373
|
+
| | Line spacing (auto / atLeast / exact) | ✅ |
|
|
374
|
+
| | Line grid (`w:docGrid`, §17.6.5) | ✅ |
|
|
375
|
+
| | Margin collapsing between paragraphs | ✅ |
|
|
376
|
+
| | Indents and tab stops | ✅ |
|
|
377
|
+
| | Lists (bullet and numbered) | ✅ |
|
|
378
|
+
| | Paragraph styles (Heading 1–9, Normal, custom) | ✅ |
|
|
379
|
+
| | Table style `w:pPr` cascade (§17.7.6) | ✅ |
|
|
380
|
+
| | keepNext / keepLines / widowControl | ✅ |
|
|
381
|
+
| **Elements** | Tables (with borders, fills, merges) | ✅ |
|
|
382
|
+
| | Images (inline and anchored, with text wrap) | ✅ |
|
|
383
|
+
| | Text boxes / drawing shapes | ✅ |
|
|
384
|
+
| **Advanced** | Footnote / endnote reference markers | ✅ |
|
|
385
|
+
| | Track changes / comments | ❌ |
|
|
386
|
+
| | Mail merge fields | ❌ Not planned |
|
|
387
|
+
| **Interaction** | Text selection (transparent overlay, native copy) | ✅ |
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
### Excel (.xlsx)
|
|
392
|
+
|
|
393
|
+
| Category | Feature | Status |
|
|
394
|
+
|----------|---------|--------|
|
|
395
|
+
| **Workbook** | Multiple sheets, sheet names | ✅ |
|
|
396
|
+
| **Cells** | Text, number, boolean, error values | ✅ |
|
|
397
|
+
| | Formula results (from cached `<v>`) | ✅ |
|
|
398
|
+
| | Dates (ECMA-376 date format codes) | ✅ |
|
|
399
|
+
| | Rich text (per-run formatting) | ✅ |
|
|
400
|
+
| **Formatting** | Bold, italic, underline, strikethrough | ✅ |
|
|
401
|
+
| | Font family, size, color | ✅ |
|
|
402
|
+
| | Cell background color | ✅ |
|
|
403
|
+
| | Borders | ✅ |
|
|
404
|
+
| | Horizontal / vertical alignment | ✅ |
|
|
405
|
+
| | Text wrapping | ✅ |
|
|
406
|
+
| | Number formats (`0.00`, `%`, `#,##0`, custom date/time) | ✅ |
|
|
407
|
+
| **Structure** | Merged cells | ✅ |
|
|
408
|
+
| | Frozen panes | ✅ |
|
|
409
|
+
| | Row / column sizing (custom widths and heights) | ✅ |
|
|
410
|
+
| | Hidden rows / columns | ✅ |
|
|
411
|
+
| **Elements** | Images (`<xdr:twoCellAnchor>`) | ✅ |
|
|
412
|
+
| | Charts (bar, line, area, radar) | ✅ |
|
|
413
|
+
| | Sparklines | ❌ Not planned |
|
|
414
|
+
| **Advanced** | Conditional formatting (`cellIs`, `colorScale`, `dataBar`, `iconSet`, `top10`, `aboveAverage`) | ✅ |
|
|
415
|
+
| | Slicers (static, Office 2010 extension) | ✅ |
|
|
416
|
+
| | Pivot tables | ❌ Not planned |
|
|
417
|
+
| | Data validation / comments | ❌ Not planned |
|
|
418
|
+
| **Interaction** | Cell selection (single / range / row / column / all) | ✅ |
|
|
419
|
+
| | Shift+click to extend, Ctrl+C to copy as TSV | ✅ |
|
|
420
|
+
| | Text selection inside cells (transparent overlay) | ✅ |
|
|
421
|
+
| | `onSelectionChange` callback, `getCellAt(x, y)` API | ✅ |
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
357
425
|
### PowerPoint (.pptx)
|
|
358
426
|
|
|
359
427
|
| Category | Feature | Status |
|
|
@@ -421,76 +489,14 @@ export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
|
421
489
|
|
|
422
490
|
---
|
|
423
491
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
| Category | Feature | Status |
|
|
427
|
-
|----------|---------|--------|
|
|
428
|
-
| **Document** | Page rendering | ✅ |
|
|
429
|
-
| | Page size and margins | ✅ |
|
|
430
|
-
| | Headers / footers (default / first / even) | ✅ |
|
|
431
|
-
| | Section breaks | ❌ |
|
|
432
|
-
| **Text** | Paragraphs | ✅ |
|
|
433
|
-
| | Bold, italic, underline, strikethrough | ✅ |
|
|
434
|
-
| | Font family, size, color | ✅ |
|
|
435
|
-
| | Hyperlinks | ✅ |
|
|
436
|
-
| | Superscript / subscript (`w:vertAlign`) | ✅ |
|
|
437
|
-
| **Formatting** | Paragraph alignment (left/center/right/justify) | ✅ |
|
|
438
|
-
| | Line spacing (auto / atLeast / exact) | ✅ |
|
|
439
|
-
| | Line grid (`w:docGrid`, §17.6.5) | ✅ |
|
|
440
|
-
| | Margin collapsing between paragraphs | ✅ |
|
|
441
|
-
| | Indents and tab stops | ✅ |
|
|
442
|
-
| | Lists (bullet and numbered) | ✅ |
|
|
443
|
-
| | Paragraph styles (Heading 1–9, Normal, custom) | ✅ |
|
|
444
|
-
| | Table style `w:pPr` cascade (§17.7.6) | ✅ |
|
|
445
|
-
| | keepNext / keepLines / widowControl | ✅ |
|
|
446
|
-
| **Elements** | Tables (with borders, fills, merges) | ✅ |
|
|
447
|
-
| | Images (inline and anchored, with text wrap) | ✅ |
|
|
448
|
-
| | Text boxes / drawing shapes | ✅ |
|
|
449
|
-
| **Advanced** | Footnote / endnote reference markers | ✅ |
|
|
450
|
-
| | Track changes / comments | ❌ |
|
|
451
|
-
| | Mail merge fields | ❌ Not planned |
|
|
452
|
-
| **Interaction** | Text selection (transparent overlay, native copy) | ✅ |
|
|
453
|
-
|
|
454
|
-
---
|
|
455
|
-
|
|
456
|
-
### Excel (.xlsx)
|
|
457
|
-
|
|
458
|
-
| Category | Feature | Status |
|
|
459
|
-
|----------|---------|--------|
|
|
460
|
-
| **Workbook** | Multiple sheets, sheet names | ✅ |
|
|
461
|
-
| **Cells** | Text, number, boolean, error values | ✅ |
|
|
462
|
-
| | Formula results (from cached `<v>`) | ✅ |
|
|
463
|
-
| | Dates (ECMA-376 date format codes) | ✅ |
|
|
464
|
-
| | Rich text (per-run formatting) | ✅ |
|
|
465
|
-
| **Formatting** | Bold, italic, underline, strikethrough | ✅ |
|
|
466
|
-
| | Font family, size, color | ✅ |
|
|
467
|
-
| | Cell background color | ✅ |
|
|
468
|
-
| | Borders | ✅ |
|
|
469
|
-
| | Horizontal / vertical alignment | ✅ |
|
|
470
|
-
| | Text wrapping | ✅ |
|
|
471
|
-
| | Number formats (`0.00`, `%`, `#,##0`, custom date/time) | ✅ |
|
|
472
|
-
| **Structure** | Merged cells | ✅ |
|
|
473
|
-
| | Frozen panes | ✅ |
|
|
474
|
-
| | Row / column sizing (custom widths and heights) | ✅ |
|
|
475
|
-
| | Hidden rows / columns | ✅ |
|
|
476
|
-
| **Elements** | Images (`<xdr:twoCellAnchor>`) | ✅ |
|
|
477
|
-
| | Charts (bar, line, area, radar) | ✅ |
|
|
478
|
-
| | Sparklines | ❌ Not planned |
|
|
479
|
-
| **Advanced** | Conditional formatting (`cellIs`, `colorScale`, `dataBar`, `iconSet`, `top10`, `aboveAverage`) | ✅ |
|
|
480
|
-
| | Slicers (static, Office 2010 extension) | ✅ |
|
|
481
|
-
| | Pivot tables | ❌ Not planned |
|
|
482
|
-
| | Data validation / comments | ❌ Not planned |
|
|
483
|
-
| **Interaction** | Cell selection (single / range / row / column / all) | ✅ |
|
|
484
|
-
| | Shift+click to extend, Ctrl+C to copy as TSV | ✅ |
|
|
485
|
-
| | Text selection inside cells (transparent overlay) | ✅ |
|
|
486
|
-
| | `onSelectionChange` callback, `getCellAt(x, y)` API | ✅ |
|
|
492
|
+
> **A note on text selection.** Across DOCX / PPTX / XLSX, text selection is currently implemented by rendering glyphs to the canvas while overlaying a transparent DOM layer that mirrors the canvas text positions for native browser selection. This dual-layer approach is a deliberate stop-gap: once the Canvas [`drawElement` API](https://chromestatus.com/feature/6051647656558592) (proposed in [WICG/html-in-canvas](https://github.com/WICG/html-in-canvas), currently in Chromium Origin Trial) ships across browsers, the project plans to migrate to a single DOM-as-source-of-truth pipeline where the canvas mirrors the DOM directly — eliminating the duplication while keeping z-order correctness and native selection / a11y.
|
|
487
493
|
|
|
488
494
|
---
|
|
489
495
|
|
|
490
496
|
## Companion packages
|
|
491
497
|
|
|
492
|
-
- **[`packages/vscode-extension/`](packages/vscode-extension/)** — VS Code extension (`ooxml-viewer`) that registers `CustomEditorProvider`s for `.
|
|
493
|
-
- **[`packages/mcp-server/`](packages/mcp-server/)** — Rust MCP server (`ooxml-mcp-server`) exposing the parsers as tools for AI agents (Claude, Copilot, Codex, etc.). Provides structured queries (`
|
|
498
|
+
- **[`packages/vscode-extension/`](packages/vscode-extension/)** — VS Code extension (`ooxml-viewer`) that registers `CustomEditorProvider`s for `.docx`, `.xlsx`, and `.pptx`. Open Office files directly in the editor with the same Canvas renderer plus selection/copy.
|
|
499
|
+
- **[`packages/mcp-server/`](packages/mcp-server/)** — Rust MCP server (`ooxml-mcp-server`) exposing the parsers as tools for AI agents (Claude, Copilot, Codex, etc.). Provides structured queries (`docx_get_structure`, `xlsx_get_cell_range`, `pptx_get_slide_structure`, …) so agents can inspect OOXML files without shelling out to `unzip`.
|
|
494
500
|
|
|
495
501
|
---
|
|
496
502
|
|
|
@@ -519,9 +525,9 @@ pnpm build
|
|
|
519
525
|
### WASM build (individual packages)
|
|
520
526
|
|
|
521
527
|
```bash
|
|
522
|
-
cd packages/pptx/parser && wasm-pack build --target web && cp pkg/pptx_parser_bg.wasm pkg/pptx_parser.js ../src/wasm/
|
|
523
|
-
cd packages/xlsx/parser && wasm-pack build --target web && cp pkg/xlsx_parser_bg.wasm pkg/xlsx_parser.js ../src/wasm/
|
|
524
528
|
cd packages/docx/parser && wasm-pack build --target web && cp pkg/docx_parser_bg.wasm pkg/docx_parser.js ../src/wasm/
|
|
529
|
+
cd packages/xlsx/parser && wasm-pack build --target web && cp pkg/xlsx_parser_bg.wasm pkg/xlsx_parser.js ../src/wasm/
|
|
530
|
+
cd packages/pptx/parser && wasm-pack build --target web && cp pkg/pptx_parser_bg.wasm pkg/pptx_parser.js ../src/wasm/
|
|
525
531
|
```
|
|
526
532
|
|
|
527
533
|
## Security & Privacy
|
|
@@ -302,7 +302,8 @@ function T(e, t, n = !1) {
|
|
|
302
302
|
y: t.y,
|
|
303
303
|
w: u.measuredWidth,
|
|
304
304
|
h: d,
|
|
305
|
-
fontSize: e
|
|
305
|
+
fontSize: e,
|
|
306
|
+
font: r.font
|
|
306
307
|
});
|
|
307
308
|
let a = u.color ? `#${u.color}` : s, o = Math.max(.5, e * .05), l = r.measureText(u.text).width;
|
|
308
309
|
if (u.underline) {
|
|
@@ -840,7 +841,7 @@ var Q = class e {
|
|
|
840
841
|
t.innerHTML = "", t.style.width = `${this._canvas.style.width || this._canvas.width + "px"}`, t.style.height = `${this._canvas.style.height || this._canvas.height + "px"}`;
|
|
841
842
|
for (let n of e) {
|
|
842
843
|
let e = document.createElement("span");
|
|
843
|
-
e.textContent = n.text, e.style.cssText = `position:absolute;left:${n.x}px;top:${n.y}px;font
|
|
844
|
+
e.textContent = n.text, e.style.cssText = `position:absolute;left:${n.x}px;top:${n.y}px;font:${n.font};line-height:${n.h}px;letter-spacing:0;white-space:pre;color:transparent;cursor:text;pointer-events:all;`, t.appendChild(e);
|
|
844
845
|
}
|
|
845
846
|
}
|
|
846
847
|
}, re = /* @__PURE__ */ e({
|