@reportwright/engine 0.13.1 → 0.13.2-rc.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/CHANGELOG.md +51 -0
- package/README.md +186 -2
- package/dist/index.js +111 -88
- package/dist/types/src/engine/index.d.ts +1 -1
- package/dist/types/src/engine/schema/validate.d.ts +2 -2
- package/dist/types/src/importers/xml.d.ts +4 -0
- package/examples/stream-1m.mjs +1 -1
- package/package.json +2 -2
- package/report.d.ts +5 -5
- package/schema.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
All `@reportwright/*` packages (formerly `@pagewrightjs/*`) share one version. The versioning policy is in [CONTRIBUTING.md](CONTRIBUTING.md#versioning-semver).
|
|
4
4
|
|
|
5
|
+
## 0.13.2-rc.2 — 2026-10-09 (release candidate)
|
|
6
|
+
|
|
7
|
+
### Fixed (from the rc.1 release gate)
|
|
8
|
+
- **E11 Viewer accessibility:** the scrolling page area (`div.vpages`) is keyboard-focusable (`tabindex="0"`), a named `region`, with a visible inset focus ring; the arrow keys scroll it (axe `scrollable-region-focusable`).
|
|
9
|
+
- **E12 Designer arrow keys on pages with margins:** Arrow and Shift+Arrow move the selection by the whole step (1/10 pt, or 1/10 grid steps with Snap to grid). The step used to be clamped to the band's leftover width, so an item as wide as an A4 body with 36 pt margins (523.28 pt) moved 0.28 pt and then not at all. A keyboard nudge still stops at the band's start; overflow past its end shows in the Issues panel. Dragging still keeps items inside the band.
|
|
10
|
+
- **E10 webpack and Next.js builds:** `@reportwright/viewer` (`dist/`, `dist/peer/`) and `@reportwright/cli` ship `pdfstreamworker.js` next to the bundles that name it with `new URL('./pdfstreamworker.js', import.meta.url)`, so bundlers resolve it. The parallel PDF paint worker itself is `@reportwright/engine`'s (Node only); the stand-ins answer that `exportPdfStream` with `parallel` needs the engine.
|
|
11
|
+
- **E13 missing HarfBuzz subset WASM:** when `harfbuzz-subset.wasm` cannot be loaded (fonts then embed in full, PDFs many times larger), `exportPdf` and `exportPdfStream` warn once on the console and add a warning to the result (the model's `warnings`, the stream result's `warnings`), naming the expected path (`@reportwright/fonts/public/harfbuzz-subset.wasm`) and the fix: install `@reportwright/fonts`, or pass `subset: createSubsetter(() => wasmBytes)`.
|
|
12
|
+
- **E09 importer:**
|
|
13
|
+
- files are read in their own encoding: a UTF-16 LE/BE or UTF-8 byte-order mark, else the XML declaration's `encoding` (ISO-8859-1, Latin-1, windows-1252, …), else UTF-8. `Straße` and `Grüße` survive. Applies to `pw import`, `pw import <folder>` and `POST /api/reports/import`.
|
|
14
|
+
- a compiled `.jasper` file gets "This is a compiled JasperReports file; import the .jrxml source instead."
|
|
15
|
+
- `pw import` prints each error once (it printed it twice, the second time cut short).
|
|
16
|
+
- **E07 SQL connection pool:** a PostgreSQL or MySQL query that cannot get a pooled connection within `PW_DB_ACQUIRE_MS` (default 5000) fails with 503 and `Retry-After` instead of a 500; a connection that frees later goes back to the pool. A streaming query whose reader aborts frees its connection at once (the backend is terminated and the connection discarded) instead of holding it until the deadline. PostgreSQL queries run under `statement_timeout` from their first statement.
|
|
17
|
+
|
|
18
|
+
## 0.13.2-rc.1 — 2026-10-09 (release candidate)
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **The rename to ReportWright is finished; every old Pagewright name keeps working until 1.0.** New names, with the old one kept as a deprecated alias:
|
|
22
|
+
- report schema: `reportwright/report@1` is now what new and saved reports carry; `pagewright/report@1` is read as the same format (a server before 0.9 cannot open a report saved by 0.13.2).
|
|
23
|
+
- HTTP headers: `x-reportwright-pages`, `-ms`, `-warnings`, `-snapshot`, `-pending`, `-signature` (webhooks and the audit SIEM webhook) and `-idempotency-key` (mail) are sent together with the old `x-pagewright-*` header; the proxy secret is read from `x-reportwright-proxy-secret`, else `x-pagewright-proxy-secret`.
|
|
24
|
+
- Prometheus metrics: `/api/v1/metrics` emits every family as `reportwright_*` and again as `pagewright_*` (the old ones go in 1.0: move dashboards and alerts). `scripts/uptime-check.mjs` reads either.
|
|
25
|
+
- one console warning per page for `definePagewrightElements`, the `<pagewright-viewer>` / `<pagewright-designer>` tags, the Svelte `pagewrightViewer` / `pagewrightDesigner` actions, `window.Pagewright` and `/embed/pagewright-viewer.js` (and `-viewer.full.js`). The React and Vue `PagewrightViewer` / `PagewrightDesigner` stay the same components, without a warning; all are typed `@deprecated`.
|
|
26
|
+
- the live demo moved to https://mrarun005.github.io/reportwright-demo/ (the site build's default base is `/reportwright-demo/`).
|
|
27
|
+
- kept as they are, since changing them would break stored data: the `.pw.json` extension, the designer clipboard format `pagewright/items@1`, and the salts of the TOTP secret key and the audit checkpoint chain.
|
|
28
|
+
- **The render worker is minified.** `engine.worker.js` (and `engine.worker.bwip.js`) in `@reportwright/viewer` and the embed builds are minified, still one file with no chunk imports, with a linked source map (`engine.worker.js.map`) beside it so worker stack traces stay readable. `engine.worker.js` 2,195,290 → 1,218,659 bytes (608 → 503 KB gzipped); `engine.worker.bwip.js` 1,651,602 → 973,261 bytes (315 → 267 KB gzipped). The size budget in tests/engine/b10-bundle-size.test.js is now 504 KB gzipped (was 600).
|
|
29
|
+
- **Publishing verifies before `latest` moves.** The publish workflow publishes to the `next` dist-tag, installs all nine packages from the registry and smoke-tests them (imports, PDF/XLSX/DOCX export, `qpdf --check`, `pw render`, the viewer's files, the wrappers' peer), and only then moves `latest`.
|
|
30
|
+
|
|
31
|
+
### Performance
|
|
32
|
+
- **Trade-off made by 0.13.1: less memory, about 10–14% slower.** The 0.13.1 fixes for grouped sorts (N44: sort runs spill to disk in smaller runs, about 8 MB) and for streamed tagged PDFs (N44: tagged structure flushed per page) cost time for the memory they save: about 10–14% slower on the tester's 2 vCPU machine (not measured here). Memory: a 200,000-row grouped ledger peaks at 232 MB instead of 280 MB, and the same with 50 runs (1,000,000 rows' run count) 240 MB instead of 296 MB; a tagged streamed PDF at 50k/100k/200k rows holds 6.7/7.3/9.3 MB off-heap instead of 16.8/29.1/36.6 MB. `spillSorter({ runMB, mergeMB })` sets the sort's run size if speed matters more than memory.
|
|
33
|
+
### Added
|
|
34
|
+
- **`pw import <folder>`: bulk import.** Every `.rdl`, `.rdlc`, `.jrxml`, `.rptdesign` and `.rdlx-json` report in a folder (`--recursive` for subfolders) is imported into `-o <outDir>`, which mirrors the folder.
|
|
35
|
+
- One bad file never stops the batch. Exit 0 means all were imported, 2 some failed, 1 none.
|
|
36
|
+
- Subreports, SSRS shared data sources (`.rds`), JasperReports style templates (`.jrtx`) and images are resolved across the batch. Images are copied once per content. Unresolved references are listed per file.
|
|
37
|
+
- `import-report.json` and a standalone, escaped `import-report.html` give for each file the mapped, approximated and dropped counts, each item's reason, and every expression that was not translated with its line and column.
|
|
38
|
+
- `.pw-import.json` holds the hash of each written file, and a re-run skips an output the user edited unless `--force`.
|
|
39
|
+
- `--verify` renders each report with its embedded or sample data and compares it with the output it replaced.
|
|
40
|
+
- Paths from the folder are untrusted. Links that point outside it are refused, outputs stay in `outDir`, and `--max-files` and `--max-bytes` cap the input.
|
|
41
|
+
- The importers now return structured `items` (each item's notes, untranslated expressions and source position) and take a `resolve` option for shared data sources and style templates.
|
|
42
|
+
- Docs: the CLI README, "Bulk import". Test: tests/engine/c132-import-batch.test.js.
|
|
43
|
+
- **`pw --version` / `pw -v`** prints the CLI version (from its package.json) and the version of the engine it carries.
|
|
44
|
+
- **`showWarnings`** (viewer option, default `false`): shows the render's warnings under the pages; the designer's Preview always shows them. Documented in the viewer README and typed in `ViewerOptions`.
|
|
45
|
+
- **ⓘ help tooltips in the designer.** Long help paragraphs (the Outline, Layers and Parts panels, field hints over 90 characters) sit behind an ⓘ button that opens on hover, keyboard focus or click and closes with Esc; the button is described by the text (`aria-describedby`).
|
|
46
|
+
### Fixed
|
|
47
|
+
- **An unchecked check box has no tick on the designer canvas.** The canvas drew ✓ in every check box; it now follows the value as the renderer does (`false`, `=False`, a missing value: empty), and dims the tick of a value only the data decides.
|
|
48
|
+
- **Selecting an item no longer moves the canvas.** The canvas toolbar grew a second row (24 px) when the align buttons of a selection appeared; it now has one fixed height (it scrolls sideways when narrow) and its hint moved to the status bar.
|
|
49
|
+
- **Keyboard nudge steps.** Arrow moves the selection 1 pt, or one grid step with Snap to grid on (a cell in cell mode); Shift+Arrow moves ten of them (it was 4 grid steps); positions stay rounded to 2 decimals.
|
|
50
|
+
- **Render warnings in the viewer read as words.** The count says "8 warnings" or "1 warning", not "warning(s)".
|
|
51
|
+
- **The Data panel lists a data set's fields when it declares none.** It said "No fields" next to 300 rows; it now detects them from inline JSON or the first rows of fetched data with the engine's own detection (`detectFields`, the one streaming uses) and marks them as detected.
|
|
52
|
+
- **No cut-off text in the Inspector and the Outline.** The Regional "Division by zero" choice gets the full width ("Infinity (as SSRS)" was cut); a long name in the Outline wraps inside the panel, with the full name as its tooltip, and the item type and buttons move under it together.
|
|
53
|
+
- **The parameter dialog's help matches the viewer.** The live-parameters option no longer says that turning it off adds a View report button (the button is always there), and the panel-columns help says the grid applies on a wide screen.
|
|
54
|
+
- **Export options icon.** The sun-like gear is a sliders icon; the button keeps its name, Export options.
|
|
55
|
+
|
|
5
56
|
## 0.13.1 — 2026-10-09
|
|
6
57
|
|
|
7
58
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
# @reportwright/engine
|
|
2
2
|
|
|
3
|
+
Turn a JSON report definition and your data into paged PDF, Excel, Word, PowerPoint, HTML or CSV, in Node or the browser, with no Chromium.
|
|
4
|
+
|
|
3
5
|
[](https://www.npmjs.com/package/@reportwright/engine) [](https://github.com/MrArun005/reportwright/blob/main/LICENSE) [](https://socket.dev/npm/package/@reportwright/engine)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**Live demo:** [mrarun005.github.io/reportwright-demo](https://mrarun005.github.io/reportwright-demo) (the [live gallery](https://mrarun005.github.io/reportwright-demo/#gallery) renders real definitions with this engine; [benchmarks](https://mrarun005.github.io/reportwright-demo/bench.html) compares it with pdfmake, react-pdf, PDFKit and Puppeteer on the same reports).
|
|
8
|
+
|
|
9
|
+
The engine lays out pages from a definition (bands, tables with groups, matrices, charts, barcodes, subreports) and the exporters write the files. The command line is [`@reportwright/cli`](https://github.com/MrArun005/reportwright/tree/main/packages/cli) (`pw`); the in-browser viewer and designer are [`@reportwright/viewer`](https://github.com/MrArun005/reportwright/tree/main/packages/viewer).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
6
12
|
|
|
7
13
|
```bash
|
|
8
14
|
npm i @reportwright/engine @reportwright/fonts
|
|
9
15
|
```
|
|
10
16
|
|
|
17
|
+
`@reportwright/fonts` is a peer dependency: it holds the fonts, the HarfBuzz text shaper, the PDF font subsetter and the PDF/A colour profile.
|
|
18
|
+
|
|
19
|
+
## Quick start (30 seconds)
|
|
20
|
+
|
|
11
21
|
Save this as `statement.pw.json` (a minimal report; the repository's `examples/` has more):
|
|
12
22
|
|
|
13
23
|
```json
|
|
14
24
|
{
|
|
15
|
-
"$schema": "
|
|
25
|
+
"$schema": "reportwright/report@1",
|
|
16
26
|
"name": "Statement",
|
|
17
27
|
"page": { "size": "A4", "margins": [36, 36, 36, 36] },
|
|
18
28
|
"parameters": [{ "name": "accountId", "type": "string" }],
|
|
@@ -30,6 +40,7 @@ Save this as `statement.pw.json` (a minimal report; the repository's `examples/`
|
|
|
30
40
|
```
|
|
31
41
|
|
|
32
42
|
```js
|
|
43
|
+
// render.mjs: node render.mjs
|
|
33
44
|
import { render, defaultFontStore, exportPdf } from '@reportwright/engine';
|
|
34
45
|
import fs from 'node:fs';
|
|
35
46
|
// the fonts, the text shaper (Arabic, Hebrew, Indic, Thai…) and the PDF subsetter come from @reportwright/fonts;
|
|
@@ -46,6 +57,179 @@ const bundledFonts = defaultFontStore({ fontsUrl: '/pw/fonts/' }); // a missing
|
|
|
46
57
|
// only when asked: render(def, { exportData: true }) (needsExportData(format) says which formats need it)
|
|
47
58
|
```
|
|
48
59
|
|
|
60
|
+
## Examples
|
|
61
|
+
|
|
62
|
+
Every example below was run against this version in Node 20. They use this report, `orders.pw.json`: a title and a
|
|
63
|
+
table of customers and amounts with a total (it is `examples/report.pw.json` in the repository):
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"$schema": "reportwright/report@1",
|
|
68
|
+
"name": "Orders",
|
|
69
|
+
"page": { "size": "A4", "margins": [36, 36, 36, 36] },
|
|
70
|
+
"dataSources": [{ "name": "orders", "type": "json", "data": { "rows": [] } }],
|
|
71
|
+
"dataSets": [{ "name": "Lines", "source": "orders", "path": "$.rows" }],
|
|
72
|
+
"sections": { "body": { "items": [
|
|
73
|
+
{ "type": "textbox", "name": "Title", "x": 0, "y": 0, "w": 300, "h": 24, "value": "Orders", "style": { "fontSize": 18, "fontWeight": "bold" } },
|
|
74
|
+
{ "type": "table", "name": "Table", "x": 0, "y": 40, "w": 400, "h": 60, "dataSet": "Lines",
|
|
75
|
+
"columns": [{ "width": 250 }, { "width": 150 }],
|
|
76
|
+
"header": [{ "height": 18, "cells": [{ "value": "Customer" }, { "value": "Amount", "style": { "textAlign": "right" } }] }],
|
|
77
|
+
"detail": [{ "height": 18, "cells": [{ "value": "=Fields.customer" }, { "value": "=Fields.amount", "style": { "format": "C2", "textAlign": "right" } }] }],
|
|
78
|
+
"footer": [{ "height": 18, "cells": [{ "value": "Total" }, { "value": "=Sum(Fields.amount)", "style": { "format": "C2", "textAlign": "right", "fontWeight": "bold" } }] }] }
|
|
79
|
+
] } }
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 1. Bind your own data, then write PDF, Excel, Word, PowerPoint, HTML and CSV
|
|
84
|
+
|
|
85
|
+
`sources` replaces a data source's data by name. The data set reads `$.rows`, so the JSON has a `rows` array; a
|
|
86
|
+
mismatch gives an empty table, not an error.
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
import fs from 'node:fs';
|
|
90
|
+
import { render, defaultFontStore, validate, exportPdf, exportXlsx, exportDocx, exportPptx, exportHtml, exportCsv } from '@reportwright/engine';
|
|
91
|
+
|
|
92
|
+
const def = JSON.parse(fs.readFileSync('orders.pw.json', 'utf8'));
|
|
93
|
+
const orders = { rows: [{ customer: 'Asha Rao', amount: 1200.5 }, { customer: 'Ben Ode', amount: 80 }] };
|
|
94
|
+
|
|
95
|
+
const { errors } = validate(def); // { errors, warnings, exprErrors, checkOnly }
|
|
96
|
+
if (errors.length) throw new Error(errors.join('\n'));
|
|
97
|
+
|
|
98
|
+
const fonts = defaultFontStore();
|
|
99
|
+
const model = await render(def, { fontStore: fonts, sources: { orders }, exportData: true });
|
|
100
|
+
fs.writeFileSync('orders.pdf', await exportPdf(model, { fonts, title: 'Orders' }));
|
|
101
|
+
fs.writeFileSync('orders.xlsx', await exportXlsx(model, { fonts }));
|
|
102
|
+
fs.writeFileSync('orders.docx', await exportDocx(model, { fonts }));
|
|
103
|
+
fs.writeFileSync('orders.pptx', await exportPptx(model, { fonts }));
|
|
104
|
+
fs.writeFileSync('orders.html', await exportHtml(model, { fonts, title: 'Orders' }));
|
|
105
|
+
fs.writeFileSync('orders.csv', exportCsv(model)); // Customer,Amount / Asha Rao,1200.5 / Ben Ode,80
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 2. Parameters and a filter
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
def.parameters = [{ name: 'minAmount', type: 'float', default: 0 }];
|
|
112
|
+
def.dataSets[0].filters = [{ expr: '=Fields.amount', op: '>=', value: '=Parameters.minAmount' }];
|
|
113
|
+
def.sections.body.items[0].value = '="Orders over " & Parameters.minAmount';
|
|
114
|
+
|
|
115
|
+
const model = await render(def, { fontStore: fonts, sources: { orders }, parameters: { minAmount: 100 } });
|
|
116
|
+
// one row (Asha Rao) under the title "Orders over 100"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 3. Archival and accessible PDF
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
const model = await render(def, { fontStore: fonts, sources: { orders }, exportData: true });
|
|
123
|
+
fs.writeFileSync('orders-pdfa.pdf', await exportPdf(model, { fonts, pdfa: true })); // PDF/A-2b, sRGB profile from @reportwright/fonts
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
From the command line, `pw render orders.pw.json --pdfa --ua` writes PDF/A-2a with PDF/UA-1 tagging.
|
|
127
|
+
|
|
128
|
+
### 4. Stream a large report to a file
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
import { exportPdfStream } from '@reportwright/engine';
|
|
132
|
+
const out = fs.createWriteStream('orders.pdf');
|
|
133
|
+
const r = await exportPdfStream(def, { sources: { orders }, title: 'Orders' }, out);
|
|
134
|
+
out.end();
|
|
135
|
+
console.log(r.streamed, r.pages); // true 1
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Details, memory figures and what streams are under [Streaming PDF for large reports](#streaming-pdf-for-large-reports).
|
|
139
|
+
|
|
140
|
+
### 5. Many reports in parallel (Node worker pool)
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
import { createPool } from '@reportwright/engine/pool';
|
|
144
|
+
const pool = createPool({ workers: 2 });
|
|
145
|
+
const pdf = await pool.render(def, { format: 'pdf' }); // Uint8Array
|
|
146
|
+
await pool.close();
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Features
|
|
150
|
+
|
|
151
|
+
| Area | What the engine does |
|
|
152
|
+
|---|---|
|
|
153
|
+
| Layout | Page header and footer, body bands, absolutely placed items; tables with groups, subtotals, keep-together and page breaks; matrices (pivot); lists; subreports (nested up to 3 levels) |
|
|
154
|
+
| Items | Text and rich text, images, lines and shapes, charts (incl. sparklines and data bars), barcodes, maps |
|
|
155
|
+
| Expressions | `=Fields.x`, `=Parameters.x`, aggregates (`Sum`, `Count`, `Avg`, `Min`, `Max`, `CountRows()`), `RowNumber()`, lookups; an expression that does not parse draws `#Error` with a warning |
|
|
156
|
+
| Data | Inline JSON, `sources` passed to `render()`, REST, GraphQL, SOAP, OData, CSV, XML; SQL through your own `sql` / `sqlRows` callback |
|
|
157
|
+
| Text | HarfBuzz shaping (Arabic, Hebrew, Indic, Thai), bidi; CJK and emoji with [`@reportwright/fonts-cjk`](https://github.com/MrArun005/reportwright/tree/main/packages/fonts-cjk) |
|
|
158
|
+
| PDF | Font subsetting, PDF/A-2b, PDF/A-2a and PDF/UA-1 (validated with veraPDF), AES-256 passwords and permissions |
|
|
159
|
+
| Scale | Streaming PDF, Word and Excel export; disk-spilling sort; worker pool and opt-in worker threads |
|
|
160
|
+
| Safety | SSRF guard on data fetches, per-fetch time and size limits, render `timeoutMs`, misspelled options reported |
|
|
161
|
+
|
|
162
|
+
## Supported formats
|
|
163
|
+
|
|
164
|
+
| Direction | Formats |
|
|
165
|
+
|---|---|
|
|
166
|
+
| Export | PDF (`exportPdf`, `exportPdfStream`), PDF/A-2b and PDF/A-2a, PDF/UA-1, Excel `.xlsx` (`exportXlsx`, `exportXlsxStream`), Word `.docx` (`exportDocx`, `exportDocxStream`), PowerPoint `.pptx` (`exportPptx`), HTML (`exportHtml`, with a sortable Tables view unless `static`), CSV (`exportCsv`), SVG per page (`pageToSvg`) |
|
|
167
|
+
| Import | JasperReports `.jrxml`, SSRS `.rdl` / `.rdlc`, BIRT `.rptdesign`, ActiveReports `.rdlx-json`: with `pw import` in [`@reportwright/cli`](https://github.com/MrArun005/reportwright/tree/main/packages/cli) |
|
|
168
|
+
|
|
169
|
+
## Options reference
|
|
170
|
+
|
|
171
|
+
From the package's types (`index.d.ts`); the JSDoc in `dist/` has every option.
|
|
172
|
+
|
|
173
|
+
**`render(definition, options)`** → page model
|
|
174
|
+
|
|
175
|
+
| Option | Meaning |
|
|
176
|
+
|---|---|
|
|
177
|
+
| `fontStore` | the `FontStore`; share one across renders |
|
|
178
|
+
| `parameters` | report parameter values by name (invariant form: `1234.5`, `2026-03-05`) |
|
|
179
|
+
| `sources` | data already loaded, by data source name (skips loading them) |
|
|
180
|
+
| `exportData` | keep the table data Excel, CSV, Word, interactive HTML and accessible PDF need |
|
|
181
|
+
| `now`, `timeZone` | the render's clock and the zone dates show in |
|
|
182
|
+
| `fetch`, `baseUrl`, `allowHosts`, `unsafeFetch` | how data requests are made (see the network notes below) |
|
|
183
|
+
| `fetchTimeoutMs`, `maxFetchBytes` | per-fetch limits (30 s, 64 MB) |
|
|
184
|
+
| `sql`, `loadReport` | callbacks for SQL sources and for subreports / masters by id |
|
|
185
|
+
| `timeoutMs`, `deadline` | stop with status 504 when the render runs longer |
|
|
186
|
+
| `largeReportRows` | rows past which a data set warns (100,000; `0` or `false` turns it off) |
|
|
187
|
+
|
|
188
|
+
**`exportPdf(model, options)`** → `Uint8Array`: `fonts`, `title`, `subset` (`false` embeds full fonts), `pdfa`
|
|
189
|
+
(`true` or `{ icc }`), `tagged`, `encrypt`, `onWarning`, `timeoutMs`.
|
|
190
|
+
|
|
191
|
+
**`exportXlsx` / `exportDocx` / `exportPptx(model, options)`** → `Promise<Uint8Array>`: `fonts`, plus `currency` and
|
|
192
|
+
`formulas` for Excel.
|
|
193
|
+
|
|
194
|
+
**`exportHtml(model, options)`**: `fonts`, `title`, `static`, `locale`, `currency`, `lang`, `timeoutMs`.
|
|
195
|
+
**`exportCsv(model, options)`**: `all`, `layout` (the printed layout instead of the data), `locale`, `currency`.
|
|
196
|
+
|
|
197
|
+
**`exportPdfStream` / `exportDocxStream` / `exportXlsxStream(definition, options, sink)`**: `render()`'s and
|
|
198
|
+
`exportPdf`'s options plus `window`, `maxRows`, `presorted`, `spill`, `parallel`, `signal`, `sqlRows`.
|
|
199
|
+
|
|
200
|
+
Other exports: `validate`, `blankReport`, `blankDashboard`, `FontStore`, `fontFile`, `defaultFontStore`,
|
|
201
|
+
`needsExportData`, `parameterOptions`, `resolveParameters`, `createSubsetter`, `pageToSvg`. Types for the definition
|
|
202
|
+
format: `import type { Report } from '@reportwright/engine/report'`; JSON Schema: `@reportwright/engine/schema.json`.
|
|
203
|
+
|
|
204
|
+
## Runtime support
|
|
205
|
+
|
|
206
|
+
- **Node** 20.9 or later (`engines`). The SSRF guard pins the checked address on Node 20.16+ / 22.3+.
|
|
207
|
+
- **Browsers**: the package is ES modules built for ES2022, for modern evergreen browsers through a bundler. In a
|
|
208
|
+
browser, pass `defaultFontStore({ fontsUrl })` (see the quick start). Sorted or grouped exports hold their rows in
|
|
209
|
+
memory there (keep them under about 100,000 rows).
|
|
210
|
+
|
|
211
|
+
## Limits
|
|
212
|
+
|
|
213
|
+
| Limit | Default | Option |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| Rows read by a streamed export | 5,000,000 | `maxRows` |
|
|
216
|
+
| Time per data fetch | 30 s | `fetchTimeoutMs` |
|
|
217
|
+
| Size per data fetch (decoded) | 64 MB | `maxFetchBytes` |
|
|
218
|
+
| Redirects per fetch | 5 | none |
|
|
219
|
+
| Subreport nesting | 3 levels | none |
|
|
220
|
+
| Disk used by a spilled sort | 2 GB | `spill: { maxMB }` |
|
|
221
|
+
| Warning threshold for a large data set | 100,000 rows | `largeReportRows` |
|
|
222
|
+
|
|
223
|
+
## Related packages
|
|
224
|
+
|
|
225
|
+
| Package | What it is |
|
|
226
|
+
|---|---|
|
|
227
|
+
| [`@reportwright/fonts`](https://github.com/MrArun005/reportwright/tree/main/packages/fonts) | fonts, shaper, subsetter and colour profile (required) |
|
|
228
|
+
| [`@reportwright/fonts-cjk`](https://github.com/MrArun005/reportwright/tree/main/packages/fonts-cjk) | optional Chinese, Japanese, Korean and emoji fonts |
|
|
229
|
+
| [`@reportwright/cli`](https://github.com/MrArun005/reportwright/tree/main/packages/cli) | `pw`: render, test, diff and import reports from the command line |
|
|
230
|
+
| [`@reportwright/viewer`](https://github.com/MrArun005/reportwright/tree/main/packages/viewer) | the in-browser viewer and designer |
|
|
231
|
+
| [`@reportwright/react`](https://github.com/MrArun005/reportwright/tree/main/packages/react), [`/vue`](https://github.com/MrArun005/reportwright/tree/main/packages/vue), [`/svelte`](https://github.com/MrArun005/reportwright/tree/main/packages/svelte), [`/angular`](https://github.com/MrArun005/reportwright/tree/main/packages/angular) | framework wrappers for the viewer and designer |
|
|
232
|
+
|
|
49
233
|
## Implicit behaviour, and how to switch it
|
|
50
234
|
|
|
51
235
|
- **ISO dates.** When a data set has no `fields`, they are detected from the rows, and a string that looks like an ISO
|
package/dist/index.js
CHANGED
|
@@ -9885,7 +9885,8 @@ function parseXml(src, limits = {}) {
|
|
|
9885
9885
|
const L = { ...XML_LIMITS, ...limits };
|
|
9886
9886
|
if (typeof src !== "string") throw new XmlError("The file is not text");
|
|
9887
9887
|
if (src.length > L.maxChars) throw new XmlError(`The file is too large (more than ${L.maxChars} characters)`);
|
|
9888
|
-
|
|
9888
|
+
const bom = src.charCodeAt(0) === 65279 ? 1 : 0;
|
|
9889
|
+
if (bom) src = src.slice(1);
|
|
9889
9890
|
const stack2 = [];
|
|
9890
9891
|
const nsStack = [Object.assign(/* @__PURE__ */ Object.create(null), { xml: "http://www.w3.org/XML/1998/namespace" })];
|
|
9891
9892
|
let root = null;
|
|
@@ -10001,7 +10002,7 @@ function parseXml(src, limits = {}) {
|
|
|
10001
10002
|
const colon = qname.indexOf(":");
|
|
10002
10003
|
const prefix = colon < 0 ? "" : qname.slice(0, colon);
|
|
10003
10004
|
const ns = scope[prefix] ?? (prefix ? fail(`The prefix "${prefix}" is not declared`) : "");
|
|
10004
|
-
const el = { name: colon < 0 ? qname : qname.slice(colon + 1), ns, attrs: attrsOut, children: [], text: "" };
|
|
10005
|
+
const el = { name: colon < 0 ? qname : qname.slice(colon + 1), ns, attrs: attrsOut, children: [], text: "", pos: i + bom };
|
|
10005
10006
|
if (stack2.length) stack2[stack2.length - 1].children.push(el);
|
|
10006
10007
|
else root = el;
|
|
10007
10008
|
if (!selfClose) {
|
|
@@ -13631,8 +13632,8 @@ function paintXY(type, g) {
|
|
|
13631
13632
|
out.push(tag2(e2, anim && { k: anim === "grow" ? "scale" : "fade", i: j }));
|
|
13632
13633
|
const isClipped = clipped && beyond(p) || pastAxis(p);
|
|
13633
13634
|
if (isClipped) out.push({ t: "ellipse", cx: e2.cx, cy: e2.cy, rx: r + 1.6, ry: r + 1.6, fill: "none", stroke: col3, strokeWidth: 0.9 });
|
|
13634
|
-
if (item.tooltips !== false && (type === "bubble" || multi || isClipped)) g.links.push({ t: "link", x: e2.cx - r, y: e2.cy - r, w: r * 2, h: r * 2, action: null, tip: `${multi ? `${s.name}: ` : ""}${fmtX(p.x)}, ${fmtY(p.y)}${type === "bubble" ? ` (${toText(p.size, null, ctx)})` : ""}${isClipped ? clipped && beyond(p) ? " (outlier, drawn at the edge)" : " (outside the axis range you set, draw
|
|
13635
|
-
n at the edge)" : ""}` });
|
|
13635
|
+
if (item.tooltips !== false && (type === "bubble" || multi || isClipped)) g.links.push({ t: "link", x: e2.cx - r, y: e2.cy - r, w: r * 2, h: r * 2, action: null, tip: `${multi ? `${s.name}: ` : ""}${fmtX(p.x)}, ${fmtY(p.y)}${type === "bubble" ? ` (${toText(p.size, null, ctx)})` : ""}${isClipped ? clipped && beyond(p) ? " (outlier, drawn at the edge)" : (" (outside the axis range you set, draw"+
|
|
13636
|
+
"n at the edge)") : ""}` });
|
|
13636
13637
|
if (labelsOn) {
|
|
13637
13638
|
const str = item.labelTemplate ? String(item.labelTemplate).slice(0, 500).replace(/\{(\w+)\}/g, (all, k) => ({ value: fmtY(p.y), x: fmtX(p.x), series: s.name, size: toText(p.size, null, ctx) })[k.toLowerCase()] ?? all) : fmtY(p.y);
|
|
13638
13639
|
label(str, e2.cx, e2.cy - r - 2, { size: fs * 0.85 });
|
|
@@ -20233,14 +20234,14 @@ var REPORT_SCHEMA = {
|
|
|
20233
20234
|
"additionalProperties": true
|
|
20234
20235
|
},
|
|
20235
20236
|
"Report": {
|
|
20236
|
-
"description": "A ReportWright report definition (
|
|
20237
|
+
"description": "A ReportWright report definition (reportwright/report@1).",
|
|
20237
20238
|
"type": "object",
|
|
20238
20239
|
"properties": {
|
|
20239
20240
|
"$schema": {
|
|
20240
|
-
"description": "
|
|
20241
|
+
"description": "reportwright/report@1; pagewright/report@1 (deprecated, the name before the rename) is the same format.",
|
|
20241
20242
|
"enum": [
|
|
20242
|
-
"
|
|
20243
|
-
"
|
|
20243
|
+
"reportwright/report@1",
|
|
20244
|
+
"pagewright/report@1"
|
|
20244
20245
|
]
|
|
20245
20246
|
},
|
|
20246
20247
|
"name": {
|
|
@@ -20358,7 +20359,7 @@ var REPORT_SCHEMA = {
|
|
|
20358
20359
|
],
|
|
20359
20360
|
"examples": [
|
|
20360
20361
|
{
|
|
20361
|
-
"$schema": "
|
|
20362
|
+
"$schema": "reportwright/report@1",
|
|
20362
20363
|
"name": "Invoice",
|
|
20363
20364
|
"page": {
|
|
20364
20365
|
"size": "A4",
|
|
@@ -20474,11 +20475,11 @@ var REPORT_SCHEMA = {
|
|
|
20474
20475
|
};
|
|
20475
20476
|
|
|
20476
20477
|
// src/engine/schema/validate.js
|
|
20477
|
-
var SCHEMA_ID = "
|
|
20478
|
-
var SCHEMA_ALIAS = "
|
|
20479
|
-
var ITEM_KEYS = new Set("id type name x y w h style styleName items hidden layer locked label alt value dataSet canGrow canShrink action bookmark tooltip keepTogether pageBreakBefore pageBreakAfter pageBreakBetween newSection filters sort groups groupBy groupAdjacent inheritRows columns header detail footer repeatHeader widowControl noRowsText pageBreakEvery cells rows rowGroup rowGroups columnGro
|
|
20480
|
-
up columnGroups values value valueFormat rowSort columnSort rowTotals columnTotals cellStyle headerStyle totalStyle corner partProps library part properties overflow overflowTo src fit headingLevel rotate shrinkToFit minFontSize shrinkStep tocDots tocLink tocPage format chartType series seriesGroup category title legend palette stacked valueAxis xTitle maxCategories outliers categorySort categoryF
|
|
20481
|
-
ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description".split(" "));
|
|
20478
|
+
var SCHEMA_ID = "reportwright/report@1";
|
|
20479
|
+
var SCHEMA_ALIAS = "pagewright/report@1";
|
|
20480
|
+
var ITEM_KEYS = new Set(("id type name x y w h style styleName items hidden layer locked label alt value dataSet canGrow canShrink action bookmark tooltip keepTogether pageBreakBefore pageBreakAfter pageBreakBetween newSection filters sort groups groupBy groupAdjacent inheritRows columns header detail footer repeatHeader widowControl noRowsText pageBreakEvery cells rows rowGroup rowGroups columnGro"+
|
|
20481
|
+
"up columnGroups values value valueFormat rowSort columnSort rowTotals columnTotals cellStyle headerStyle totalStyle corner partProps library part properties overflow overflowTo src fit headingLevel rotate shrinkToFit minFontSize shrinkStep tocDots tocLink tocPage format chartType series seriesGroup category title legend palette stacked valueAxis xTitle maxCategories outliers categorySort categoryF"+
|
|
20482
|
+
"ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description").split(" "));
|
|
20482
20483
|
var NO_SERIES_CHARTS = /* @__PURE__ */ new Set(["gantt"]);
|
|
20483
20484
|
function looksLikeLink(it) {
|
|
20484
20485
|
if (it.type !== "textbox" || it.action && it.action.type && it.action.type !== "none") return false;
|
|
@@ -20489,8 +20490,8 @@ function looksLikeLink(it) {
|
|
|
20489
20490
|
const [r, g, b] = m.slice(1).map((h) => parseInt(h, 16));
|
|
20490
20491
|
return b > 150 && b > r + 60 && b > g + 30;
|
|
20491
20492
|
}
|
|
20492
|
-
var DEF_KEYS = new Set("$schema name description locale currency timeZone page parameters dataSources dataSets styles sections functions layers images theme themeDef master nullPropagation caseSensitive naturalSort nullOrder collation arithmetic bandRows version id tags author folder stylesheet parts partProperties dashboard comment notes customCode libraries liveParameters parameterLayout drafts
|
|
20493
|
-
history nonFinite".split(" "));
|
|
20493
|
+
var DEF_KEYS = new Set(("$schema name description locale currency timeZone page parameters dataSources dataSets styles sections functions layers images theme themeDef master nullPropagation caseSensitive naturalSort nullOrder collation arithmetic bandRows version id tags author folder stylesheet parts partProperties dashboard comment notes customCode libraries liveParameters parameterLayout drafts "+
|
|
20494
|
+
"history nonFinite").split(" "));
|
|
20494
20495
|
for (const k of Object.keys(REPORT_SCHEMA.$defs.Report.properties)) DEF_KEYS.add(k);
|
|
20495
20496
|
var lev = (a, b) => {
|
|
20496
20497
|
if (Math.abs(a.length - b.length) > 2) return 3;
|
|
@@ -20553,6 +20554,18 @@ function sortIssues(sort, label, out) {
|
|
|
20553
20554
|
if (s.dir != null && !["asc", "desc"].includes(s.dir)) out.push(`${at}: "dir" is ${JSON.stringify(s.dir)}; expected "asc" or "desc"`);
|
|
20554
20555
|
});
|
|
20555
20556
|
}
|
|
20557
|
+
var FILTER_KEYS = ["expr", "op", "value", "value2", "skipBlank"];
|
|
20558
|
+
var FILTER_ALIAS = { expression: "expr", field: "expr", by: "expr", operator: "op", comparison: "op", values: "value", value1: "value" };
|
|
20559
|
+
function filterIssues(filters, label, out) {
|
|
20560
|
+
filters.forEach((f4, i) => {
|
|
20561
|
+
if (!f4 || typeof f4 !== "object" || Array.isArray(f4)) return;
|
|
20562
|
+
for (const k of Object.keys(f4)) {
|
|
20563
|
+
if (FILTER_KEYS.includes(k) || k.startsWith("_")) continue;
|
|
20564
|
+
const g = FILTER_ALIAS[k] || didYouMean(k, FILTER_KEYS);
|
|
20565
|
+
out.push(`${label}, filter ${i + 1}: "${k}" is ignored; a filter is {${FILTER_KEYS.join(", ")}}${g ? ` (did you mean "${g}"?)` : ""}`);
|
|
20566
|
+
}
|
|
20567
|
+
});
|
|
20568
|
+
}
|
|
20556
20569
|
var SCHEMA_ITEMS = (() => {
|
|
20557
20570
|
const defs = (
|
|
20558
20571
|
/** @type {Record<string, any>} */
|
|
@@ -20635,6 +20648,7 @@ function validate(def) {
|
|
|
20635
20648
|
} else if (!srcNames.has(d.source)) errors.push(`Data set "${d.name}" uses the source "${d.source}", which does not exist`);
|
|
20636
20649
|
dsNames.add(d.name);
|
|
20637
20650
|
if (Array.isArray(d.sort)) sortIssues(d.sort, `Data set "${d.name}"`, warnings);
|
|
20651
|
+
if (Array.isArray(d.filters)) filterIssues(d.filters, `Data set "${d.name}"`, warnings);
|
|
20638
20652
|
}
|
|
20639
20653
|
const names = /* @__PURE__ */ new Set();
|
|
20640
20654
|
const check = (where, v, label) => {
|
|
@@ -20697,6 +20711,7 @@ function validate(def) {
|
|
|
20697
20711
|
warnings.push(`${label}: there is no named style "${it.styleName}"${g ? ` (did you mean "${g}"?)` : ""}; it is ignored`);
|
|
20698
20712
|
}
|
|
20699
20713
|
if (Array.isArray(it.sort)) sortIssues(it.sort, label, warnings);
|
|
20714
|
+
if (Array.isArray(it.filters)) filterIssues(it.filters, label, warnings);
|
|
20700
20715
|
if (it.type === "chart" && it.legend != null && it.legend !== "bottom" && it.legend !== "none") {
|
|
20701
20716
|
const shown2 = typeof it.legend === "object" ? `is an object (${JSON.stringify(it.legend).slice(0, 60)})` : `is ${JSON.stringify(it.legend)}`;
|
|
20702
20717
|
warnings.push(`${label}: "legend" ${shown2}; only "bottom" (show the legend) or "none" (hide it) is supported, and the legend is drawn at the bottom`);
|
|
@@ -21879,7 +21894,7 @@ function resolveParameters(def, given, o = {}) {
|
|
|
21879
21894
|
function blankReport(name = "Untitled report") {
|
|
21880
21895
|
const W2 = 523.28;
|
|
21881
21896
|
return {
|
|
21882
|
-
$schema: "
|
|
21897
|
+
$schema: "reportwright/report@1",
|
|
21883
21898
|
name,
|
|
21884
21899
|
page: { size: "A4", orientation: "portrait", margins: [36, 36, 36, 36] },
|
|
21885
21900
|
parameters: [],
|
|
@@ -21906,7 +21921,7 @@ function blankDashboard(name = "Dashboard") {
|
|
|
21906
21921
|
{ type: "textbox", name: n5, x, y: 54, w: 216, h: 30, value, style: { fontSize: 20, fontWeight: "bold" } }
|
|
21907
21922
|
];
|
|
21908
21923
|
return {
|
|
21909
|
-
$schema: "
|
|
21924
|
+
$schema: "reportwright/report@1",
|
|
21910
21925
|
name,
|
|
21911
21926
|
page: { size: "Pageless", width: 960, margins: [24, 24, 24, 24], minHeight: 540 },
|
|
21912
21927
|
parameters: [],
|
|
@@ -21984,9 +21999,9 @@ ${pdfa ? `<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/n
|
|
|
21984
21999
|
</x:xmpmeta>
|
|
21985
22000
|
<?xpacket end="w"?>`;
|
|
21986
22001
|
}
|
|
21987
|
-
var PDFUA_SCHEMA = `<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"><pdfaExtension:schemas><rdf:Bag><rdf:li rdf:parseType="Resource"><pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema><pdfaSchema:namespaceURI>http://www.aiim.or
|
|
21988
|
-
g/pdfua/ns/id/</pdfaSchema:namespaceURI><pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix><pdfaSchema:property><rdf:Seq><rdf:li rdf:parseType="Resource"><pdfaProperty:name>part</pdfaProperty:name><pdfaProperty:valueType>Integer</pdfaProperty:valueType><pdfaProperty:category>internal</pdfaProperty:category><pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description></rdf:li></rdf:Seq
|
|
21989
|
-
</pdfaSchema:property></rdf:li></rdf:Bag></pdfaExtension:schemas></rdf:Description>
|
|
22002
|
+
var PDFUA_SCHEMA = `<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"><pdfaExtension:schemas><rdf:Bag><rdf:li rdf:parseType="Resource"><pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema><pdfaSchema:namespaceURI>http://www.aiim.or${
|
|
22003
|
+
""}g/pdfua/ns/id/</pdfaSchema:namespaceURI><pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix><pdfaSchema:property><rdf:Seq><rdf:li rdf:parseType="Resource"><pdfaProperty:name>part</pdfaProperty:name><pdfaProperty:valueType>Integer</pdfaProperty:valueType><pdfaProperty:category>internal</pdfaProperty:category><pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description></rdf:li></rdf:Seq>${
|
|
22004
|
+
""}</pdfaSchema:property></rdf:li></rdf:Bag></pdfaExtension:schemas></rdf:Description>
|
|
21990
22005
|
`;
|
|
21991
22006
|
function setMetadata(doc, xmp) {
|
|
21992
22007
|
const ctx = doc.context;
|
|
@@ -22317,8 +22332,8 @@ function imageHref(src, proxyBase = "") {
|
|
|
22317
22332
|
return "";
|
|
22318
22333
|
}
|
|
22319
22334
|
var n = (v) => Math.round(v * 100) / 100;
|
|
22320
|
-
var ANIM_CSS = "<style>@media (prefers-reduced-motion:no-preference){.pw-a{transform-box:fill-box;animation:pw-fade .55s ease-out both}.pw-a-growY{animation-name:pw-growY}.pw-a-growX{animation-name:pw-growX}.pw-a-scale{animation-name:pw-scale}@keyframes pw-fade{from{opacity:0}}@keyframes pw-growY{from{transform:scaleY(0)}}@keyframes pw-growX{from{transform:scaleX(0)}}@keyframes pw-scale{from{trans
|
|
22321
|
-
form:scale(0);opacity:0}}}</style>";
|
|
22335
|
+
var ANIM_CSS = ("<style>@media (prefers-reduced-motion:no-preference){.pw-a{transform-box:fill-box;animation:pw-fade .55s ease-out both}.pw-a-growY{animation-name:pw-growY}.pw-a-growX{animation-name:pw-growX}.pw-a-scale{animation-name:pw-scale}@keyframes pw-fade{from{opacity:0}}@keyframes pw-growY{from{transform:scaleY(0)}}@keyframes pw-growX{from{transform:scaleX(0)}}@keyframes pw-scale{from{trans"+
|
|
22336
|
+
"form:scale(0);opacity:0}}}</style>");
|
|
22322
22337
|
var ANIM_KINDS = /* @__PURE__ */ new Set(["growY", "growX", "scale", "fade"]);
|
|
22323
22338
|
var ANIM_ORIGIN = { bottom: "center bottom", top: "center top", left: "left center", right: "right center" };
|
|
22324
22339
|
function pageToSvg(page, w, h, { background = true, animate = false, box = void 0, outline: outline2 = null, proxyBase = "" } = {}) {
|
|
@@ -27368,8 +27383,8 @@ function chartXml(spec, sheet) {
|
|
|
27368
27383
|
const per = t === "bubble" ? 3 : 2;
|
|
27369
27384
|
const body = spec.series.map((s, i) => {
|
|
27370
27385
|
const c = 1 + i * per, n5 = s.x.length;
|
|
27371
|
-
return `<c:ser><c:idx val="${i}"/><c:order val="${i}"/><c:tx><c:strRef><c:f>${ref(sheet, c + 1, 1, c + 1, 1)}</c:f>${strCache([s.name])}</c:strRef></c:tx>${t === "bubble" ? fill(s.color) : `<c:spPr><a:ln w="19050"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="5"/>${fill(s.color)}</c:marker>`}<c:xVal><c:numRef><c:f>${ref(sheet, c, 2, c, n5 + 1)}</c:f>${numCache(s.x)}
|
|
27372
|
-
</c:numRef></c:xVal><c:yVal><c:numRef><c:f>${ref(sheet, c + 1, 2, c + 1, n5 + 1)}</c:f>${numCache(s.y, fmt2)}</c:numRef></c:yVal>` + (t === "bubble" ? `<c:bubbleSize><c:numRef><c:f>${ref(sheet, c + 2, 2, c + 2, n5 + 1)}</c:f>${numCache(s.size || [])}</c:numRef></c:bubbleSize><c:bubble3D val="0"/>` : '<c:smooth val="0"/>') + "</c:ser>";
|
|
27386
|
+
return `<c:ser><c:idx val="${i}"/><c:order val="${i}"/><c:tx><c:strRef><c:f>${ref(sheet, c + 1, 1, c + 1, 1)}</c:f>${strCache([s.name])}</c:strRef></c:tx>${t === "bubble" ? fill(s.color) : `<c:spPr><a:ln w="19050"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="5"/>${fill(s.color)}</c:marker>`}<c:xVal><c:numRef><c:f>${ref(sheet, c, 2, c, n5 + 1)}</c:f>${numCache(s.x)}${
|
|
27387
|
+
""}</c:numRef></c:xVal><c:yVal><c:numRef><c:f>${ref(sheet, c + 1, 2, c + 1, n5 + 1)}</c:f>${numCache(s.y, fmt2)}</c:numRef></c:yVal>` + (t === "bubble" ? `<c:bubbleSize><c:numRef><c:f>${ref(sheet, c + 2, 2, c + 2, n5 + 1)}</c:f>${numCache(s.size || [])}</c:numRef></c:bubbleSize><c:bubble3D val="0"/>` : '<c:smooth val="0"/>') + "</c:ser>";
|
|
27373
27388
|
}).join("");
|
|
27374
27389
|
plot = t === "bubble" ? `<c:bubbleChart><c:varyColors val="0"/>${body}<c:bubbleScale val="100"/>${axIds(false)}</c:bubbleChart>` : `<c:scatterChart><c:scatterStyle val="lineMarker"/><c:varyColors val="0"/>${body}${axIds(false)}</c:scatterChart>`;
|
|
27375
27390
|
axes = valAx(AX.cat, AX.val, "b", false, "General", spec.xTitle) + valAx(AX.val, AX.cat, "l", false, fmt2, spec.yTitle);
|
|
@@ -27380,18 +27395,18 @@ function chartXml(spec, sheet) {
|
|
|
27380
27395
|
}
|
|
27381
27396
|
var axTitle = (t) => t ? title(t) : "";
|
|
27382
27397
|
function catAx(id, cross, pos, second, t) {
|
|
27383
|
-
return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${second ? 1 : 0}"/><c:axPos val="${pos}"/>${axTitle(t)}<c:numFmt formatCode="General" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffs
|
|
27384
|
-
et val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
|
|
27398
|
+
return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${second ? 1 : 0}"/><c:axPos val="${pos}"/>${axTitle(t)}<c:numFmt formatCode="General" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffs${
|
|
27399
|
+
""}et val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
|
|
27385
27400
|
}
|
|
27386
27401
|
function valAx(id, cross, pos, second, fmt2, t) {
|
|
27387
|
-
return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="${pos}"/>${second ? "" : "<c:majorGridlines/>"}${axTitle(t)}<c:numFmt formatCode="${esc4(fmt2)}" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${second ? "max" : "autoZero"}"
|
|
27388
|
-
><c:crossBetween val="between"/></c:valAx>`;
|
|
27402
|
+
return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="${pos}"/>${second ? "" : "<c:majorGridlines/>"}${axTitle(t)}<c:numFmt formatCode="${esc4(fmt2)}" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${second ? "max" : "autoZero"}"/${
|
|
27403
|
+
""}><c:crossBetween val="between"/></c:valAx>`;
|
|
27389
27404
|
}
|
|
27390
27405
|
var PALETTE2 = ["#2563eb", "#16a34a", "#f59e0b", "#dc2626", "#7c3aed", "#0891b2", "#db2777", "#65a30d", "#ea580c", "#475569"];
|
|
27391
27406
|
var drawingXml = (c0, r0, cols, rows) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
27392
|
-
<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><xdr:twoCellAnchor editAs="oneCell"><xdr:from><xdr:col>${c0}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:to><xdr:col>${c0 + cols}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0 + rows}</x
|
|
27393
|
-
dr:row><xdr:rowOff>0</xdr:rowOff></xdr:to><xdr:graphicFrame macro=""><xdr:nvGraphicFramePr><xdr:cNvPr id="2" name="Chart 1"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmln
|
|
27394
|
-
s:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:twoCellAnchor></xdr:wsDr>`;
|
|
27407
|
+
<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><xdr:twoCellAnchor editAs="oneCell"><xdr:from><xdr:col>${c0}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:to><xdr:col>${c0 + cols}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0 + rows}</x${
|
|
27408
|
+
""}dr:row><xdr:rowOff>0</xdr:rowOff></xdr:to><xdr:graphicFrame macro=""><xdr:nvGraphicFramePr><xdr:cNvPr id="2" name="Chart 1"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmln${
|
|
27409
|
+
""}s:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:twoCellAnchor></xdr:wsDr>`;
|
|
27395
27410
|
var rels = (list) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
27396
27411
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${list.join("")}</Relationships>`;
|
|
27397
27412
|
var rel = (id, type, target) => `<Relationship Id="${id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/${type}" Target="${target}"/>`;
|
|
@@ -27543,9 +27558,9 @@ var Book = class {
|
|
|
27543
27558
|
const [fmt2, bold, fill3] = k.split("|").map(Number);
|
|
27544
27559
|
return `<xf numFmtId="${fmt2 || 0}" fontId="${bold ? 1 : 0}" fillId="${fill3 ? 2 : 0}" borderId="0" xfId="0"${fmt2 ? ' applyNumberFormat="1"' : ""}${bold ? ' applyFont="1"' : ""}${fill3 ? ' applyFill="1"' : ""}/>`;
|
|
27545
27560
|
}).join("");
|
|
27546
|
-
return `${XML}<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${fmts ? `<numFmts count="${this.numFmts.size}">${fmts}</numFmts>` : ""}<fonts count="2"><font><sz val="11"/><name val="Calibri"/><family val="2"/></font><font><b/><sz val="11"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><pat
|
|
27547
|
-
ternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="${HEADER_FILL}"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${this.styles.size}">${xfs}</cellXfs><cellSt
|
|
27548
|
-
yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
|
|
27561
|
+
return `${XML}<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${fmts ? `<numFmts count="${this.numFmts.size}">${fmts}</numFmts>` : ""}<fonts count="2"><font><sz val="11"/><name val="Calibri"/><family val="2"/></font><font><b/><sz val="11"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><pat${
|
|
27562
|
+
""}ternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="${HEADER_FILL}"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${this.styles.size}">${xfs}</cellXfs><cellSt${
|
|
27563
|
+
""}yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
|
|
27549
27564
|
}
|
|
27550
27565
|
/** The .xlsx bytes. */
|
|
27551
27566
|
write() {
|
|
@@ -27565,8 +27580,8 @@ yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></s
|
|
|
27565
27580
|
const anchors = sh.images.map((im, k) => {
|
|
27566
27581
|
img++;
|
|
27567
27582
|
put(`xl/media/image${img}.${im.ext}`, im.bytes);
|
|
27568
|
-
return `<xdr:oneCellAnchor><xdr:from><xdr:col>${im.col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${im.row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="${k + 2}" name="Picture ${k + 1}"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill
|
|
27569
|
-
a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor>`;
|
|
27583
|
+
return `<xdr:oneCellAnchor><xdr:from><xdr:col>${im.col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${im.row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="${k + 2}" name="Picture ${k + 1}"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><${
|
|
27584
|
+
""}a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor>`;
|
|
27570
27585
|
});
|
|
27571
27586
|
let first = img - sh.images.length;
|
|
27572
27587
|
put(`xl/drawings/_rels/drawing${n5}.xml.rels`, rels2(sh.images.map((im, k) => [`rId${k + 1}`, "image", `../media/image${++first}.${im.ext}`])));
|
|
@@ -27587,12 +27602,12 @@ a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill
|
|
|
27587
27602
|
put("xl/styles.xml", this.stylesXml());
|
|
27588
27603
|
put("xl/workbook.xml", `${XML}<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="${R}"><bookViews><workbookView/></bookViews><sheets>${this.sheets.map((s, i) => `<sheet name="${esc4(s.name)}" sheetId="${i + 1}" r:id="rId${i + 1}"/>`).join("")}</sheets><calcPr calcId="171027"${this.fullCalcOnLoad ? ' fullCalcOnLoad="1"' : ""}/></workbook>`);
|
|
27589
27604
|
put("xl/_rels/workbook.xml.rels", rels2([...this.sheets.map((s, i) => [`rId${i + 1}`, "worksheet", `worksheets/sheet${i + 1}.xml`]), [`rId${this.sheets.length + 1}`, "styles", "styles.xml"]]));
|
|
27590
|
-
put("docProps/core.xml", `${XML}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc4(this.title)}</dc:title><dc:creator>${esc4(this.creator)}</dc:creator><dcterms:created xsi:type="dcterms:W
|
|
27591
|
-
3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z")}</dcterms:created></cp:coreProperties>`);
|
|
27605
|
+
put("docProps/core.xml", `${XML}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc4(this.title)}</dc:title><dc:creator>${esc4(this.creator)}</dc:creator><dcterms:created xsi:type="dcterms:W${
|
|
27606
|
+
""}3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z")}</dcterms:created></cp:coreProperties>`);
|
|
27592
27607
|
put("_rels/.rels", rels2([["rId1", "officeDocument", "xl/workbook.xml"], ["rId2", "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", "docProps/core.xml"]]));
|
|
27593
|
-
put("[Content_Types].xml", `${XML}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Override PartName="/xl/workbo
|
|
27594
|
-
ok.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>${over.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}
|
|
27595
|
-
"/>`).join("")}</Types>`);
|
|
27608
|
+
put("[Content_Types].xml", `${XML}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Override PartName="/xl/workbo${
|
|
27609
|
+
""}ok.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>${over.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}${
|
|
27610
|
+
""}"/>`).join("")}</Types>`);
|
|
27596
27611
|
return out;
|
|
27597
27612
|
}
|
|
27598
27613
|
};
|
|
@@ -27867,8 +27882,8 @@ import { Zip, ZipDeflate, strToU8 as strToU83 } from "fflate";
|
|
|
27867
27882
|
var TW = 20;
|
|
27868
27883
|
var EMU = 12700;
|
|
27869
27884
|
var CONTENT_TYPES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
27870
|
-
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="svg" ContentType="image/svg+xml"/><Override Part
|
|
27871
|
-
Name="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`;
|
|
27885
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="svg" ContentType="image/svg+xml"/><Override Part${
|
|
27886
|
+
""}Name="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`;
|
|
27872
27887
|
var RELS = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
27873
27888
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`;
|
|
27874
27889
|
var XML_CHUNK = 4 * 1024 * 1024;
|
|
@@ -27993,8 +28008,8 @@ function table(cells, indentPt, pics) {
|
|
|
27993
28008
|
}
|
|
27994
28009
|
return `<w:tr>${r.kind === "header" ? "<w:trPr><w:tblHeader/></w:trPr>" : ""}${tcs.join("")}</w:tr>`;
|
|
27995
28010
|
}).join("");
|
|
27996
|
-
return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${indentPt > 0 ? `<w:tblInd w:w="${Math.round(indentPt * TW)}" w:type="dxa"/>` : ""}<w:tblBorders>${tblB}</w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="60" w:type="dxa"/><w:right w:w="60" w:type="dxa"/></w:tblCellMar></w:tblPr><w:tblGrid>${grid}</w:tblGrid>${out}</w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="0"
|
|
27997
|
-
></w:pPr></w:p>`;
|
|
28011
|
+
return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${indentPt > 0 ? `<w:tblInd w:w="${Math.round(indentPt * TW)}" w:type="dxa"/>` : ""}<w:tblBorders>${tblB}</w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="60" w:type="dxa"/><w:right w:w="60" w:type="dxa"/></w:tblCellMar></w:tblPr><w:tblGrid>${grid}</w:tblGrid>${out}</w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="0"/${
|
|
28012
|
+
""}></w:pPr></w:p>`;
|
|
27998
28013
|
}
|
|
27999
28014
|
function layoutRow(row, margin) {
|
|
28000
28015
|
const cols = [], cells = [];
|
|
@@ -28012,8 +28027,8 @@ function layoutRow(row, margin) {
|
|
|
28012
28027
|
x = c.x + c.w;
|
|
28013
28028
|
}
|
|
28014
28029
|
const ind = row[0].it.clip.x - margin;
|
|
28015
|
-
return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${Math.abs(ind) > 0.5 ? `<w:tblInd w:w="${Math.round(ind * TW)}" w:type="dxa"/>` : ""}<w:tblBorders><w:top w:val="nil"/><w:left w:val="nil"/><w:bottom w:val="nil"/><w:right w:val="nil"/><w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="0" w:type="dxa"/><w:right w:w="0" w:ty
|
|
28016
|
-
pe="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>${cols.map((w) => `<w:gridCol w:w="${Math.round(w * TW)}"/>`).join("")}</w:tblGrid><w:tr>${cells.join("")}</w:tr></w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="40"/><w:rPr><w:sz w:val="4"/></w:rPr></w:pPr></w:p>`;
|
|
28030
|
+
return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${Math.abs(ind) > 0.5 ? `<w:tblInd w:w="${Math.round(ind * TW)}" w:type="dxa"/>` : ""}<w:tblBorders><w:top w:val="nil"/><w:left w:val="nil"/><w:bottom w:val="nil"/><w:right w:val="nil"/><w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="0" w:type="dxa"/><w:right w:w="0" w:ty${
|
|
28031
|
+
""}pe="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>${cols.map((w) => `<w:gridCol w:w="${Math.round(w * TW)}"/>`).join("")}</w:tblGrid><w:tr>${cells.join("")}</w:tr></w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="40"/><w:rPr><w:sz w:val="4"/></w:rPr></w:pPr></w:p>`;
|
|
28017
28032
|
}
|
|
28018
28033
|
function exportDocx(model, opt = {}) {
|
|
28019
28034
|
return withDeadline(
|
|
@@ -28052,8 +28067,8 @@ async function writeDocx(pages, model, opt, put) {
|
|
|
28052
28067
|
const id = ++docPr, cx = Math.max(1, Math.round(pic.w * EMU)), cy = Math.max(1, Math.round(pic.h * EMU));
|
|
28053
28068
|
const name = `Picture ${id}`, descr = alt ? ` descr="${esc5(alt)}"` : "";
|
|
28054
28069
|
const ext = svg ? `<a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="${svg}"/></a:ext></a:extLst>` : "";
|
|
28055
|
-
return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${name}"${descr}/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descr}
|
|
28056
|
-
><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
|
|
28070
|
+
return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${name}"${descr}/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descr}/${
|
|
28071
|
+
""}><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
|
|
28057
28072
|
};
|
|
28058
28073
|
const picOpt = { fontStore: opt.fontStore, fetchImage: opt.fetchImage, rasterize: opt.rasterize };
|
|
28059
28074
|
const pageXml = async (pg) => {
|
|
@@ -28196,12 +28211,12 @@ async function writeDocx(pages, model, opt, put) {
|
|
|
28196
28211
|
const lang = `<w:lang w:val="${esc5(opt.lang || model.locale || "en-US")}"/>`;
|
|
28197
28212
|
const headings = [28, 24, 22, 20, 18, 18].map((sz, i) => `<w:style w:type="paragraph" w:styleId="Heading${i + 1}"><w:name w:val="heading ${i + 1}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:qFormat/><w:pPr><w:keepNext/><w:outlineLvl w:val="${i}"/></w:pPr><w:rPr><w:b/><w:sz w:val="${sz}"/></w:rPr></w:style>`).join("");
|
|
28198
28213
|
const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
28199
|
-
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Inter" w:hAnsi="Inter" w:cs="Inter"/><w:sz w:val="18"/>${lang}</w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w
|
|
28200
|
-
name w:val="Normal"/></w:style>${headings}</w:styles>`;
|
|
28214
|
+
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Inter" w:hAnsi="Inter" w:cs="Inter"/><w:sz w:val="18"/>${lang}</w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:${
|
|
28215
|
+
""}name w:val="Normal"/></w:style>${headings}</w:styles>`;
|
|
28201
28216
|
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
28202
28217
|
const core = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
28203
|
-
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc5(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc5(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type
|
|
28204
|
-
"dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
|
|
28218
|
+
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc5(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc5(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=${
|
|
28219
|
+
""}"dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
|
|
28205
28220
|
await file("word/_rels/document.xml.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
28206
28221
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>${media.map((m) => `<Relationship Id="${m.rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/${m.name}"/>`).join("")}</Relationships>`));
|
|
28207
28222
|
await file("word/styles.xml", strToU83(styles));
|
|
@@ -28290,8 +28305,8 @@ async function pptxOf(model, opt) {
|
|
|
28290
28305
|
const svg = pic.png && pic.svg ? media(strToU84(pic.svg), "svg") : null;
|
|
28291
28306
|
const n5 = ++id;
|
|
28292
28307
|
const ext = svg ? `<a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="${svg}"/></a:ext></a:extLst>` : "";
|
|
28293
|
-
return `<p:pic><p:nvPicPr><p:cNvPr id="${n5}" name="Picture ${n5}" descr="${esc6(alt)}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${e(pic.x)}" y="${e(pic.y)}"/><a:ext cx="${Math.max(1, e(pic.w))}" cy="${Math.max(1, e(pic.h))}"
|
|
28294
|
-
/a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
|
|
28308
|
+
return `<p:pic><p:nvPicPr><p:cNvPr id="${n5}" name="Picture ${n5}" descr="${esc6(alt)}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${e(pic.x)}" y="${e(pic.y)}"/><a:ext cx="${Math.max(1, e(pic.w))}" cy="${Math.max(1, e(pic.h))}"/><${
|
|
28309
|
+
""}/a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
|
|
28295
28310
|
};
|
|
28296
28311
|
const sp = (name, x, y, w, h, geom, body, extra = "") => {
|
|
28297
28312
|
const n5 = ++id;
|
|
@@ -28374,34 +28389,34 @@ async function pptxOf(model, opt) {
|
|
|
28374
28389
|
slides.push(pi + 1);
|
|
28375
28390
|
}
|
|
28376
28391
|
const cx = Math.min(51206400, Math.max(914400, e(W2))), cy = Math.min(51206400, Math.max(914400, e(H)));
|
|
28377
|
-
files["ppt/presentation.xml"] = strToU84(`${XML2}<p:presentation ${NS2} saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${slides.map((n5, i) => `<p:sldId id="${256 + i}" r:id="rId${n5 + 2}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${cx}" cy="${cy}"/><p:notesSz cx="${cy}" cy="${cx}"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="${lang}
|
|
28378
|
-
"/></a:defPPr></p:defaultTextStyle></p:presentation>`);
|
|
28379
|
-
files["ppt/_rels/presentation.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme
|
|
28380
|
-
" Target="theme/theme1.xml"/>${slides.map((n5) => `<Relationship Id="rId${n5 + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${n5}.xml"/>`).join("")}</Relationships>`);
|
|
28392
|
+
files["ppt/presentation.xml"] = strToU84(`${XML2}<p:presentation ${NS2} saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${slides.map((n5, i) => `<p:sldId id="${256 + i}" r:id="rId${n5 + 2}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${cx}" cy="${cy}"/><p:notesSz cx="${cy}" cy="${cx}"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="${lang}${
|
|
28393
|
+
""}"/></a:defPPr></p:defaultTextStyle></p:presentation>`);
|
|
28394
|
+
files["ppt/_rels/presentation.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme${
|
|
28395
|
+
""}" Target="theme/theme1.xml"/>${slides.map((n5) => `<Relationship Id="rId${n5 + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${n5}.xml"/>`).join("")}</Relationships>`);
|
|
28381
28396
|
const emptyTree = '<p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/></p:spTree>';
|
|
28382
|
-
files["ppt/slideMasters/slideMaster1.xml"] = strToU84(`${XML2}<p:sldMaster ${NS2}><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>${emptyTree}</p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLay
|
|
28383
|
-
outId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="2400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:bodyStyle><p:otherStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:otherStyle></p:txStyles></p:sldMaster>`);
|
|
28384
|
-
files["ppt/slideMasters/_rels/slideMaster1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/rel
|
|
28385
|
-
ationships/theme" Target="../theme/theme1.xml"/></Relationships>`);
|
|
28397
|
+
files["ppt/slideMasters/slideMaster1.xml"] = strToU84(`${XML2}<p:sldMaster ${NS2}><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>${emptyTree}</p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLay${
|
|
28398
|
+
""}outId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="2400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:bodyStyle><p:otherStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:otherStyle></p:txStyles></p:sldMaster>`);
|
|
28399
|
+
files["ppt/slideMasters/_rels/slideMaster1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/rel${
|
|
28400
|
+
""}ationships/theme" Target="../theme/theme1.xml"/></Relationships>`);
|
|
28386
28401
|
files["ppt/slideLayouts/slideLayout1.xml"] = strToU84(`${XML2}<p:sldLayout ${NS2} type="blank" preserve="1"><p:cSld name="Blank">${emptyTree}</p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr></p:sldLayout>`);
|
|
28387
28402
|
files["ppt/slideLayouts/_rels/slideLayout1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster1.xml"/></Relationships>`);
|
|
28388
28403
|
files["ppt/theme/theme1.xml"] = strToU84(THEME);
|
|
28389
28404
|
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
28390
|
-
files["docProps/core.xml"] = strToU84(`${XML2}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc6(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc6(opt.author)}
|
|
28391
|
-
</dc:creator>` : ""}<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`);
|
|
28392
|
-
files["_rels/.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docP
|
|
28393
|
-
rops/core.xml"/></Relationships>`);
|
|
28394
|
-
files["[Content_Types].xml"] = strToU84(`${XML2}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension
|
|
28395
|
-
="svg" ContentType="image/svg+xml"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="applic
|
|
28396
|
-
ation/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>${slides.map((n5) => `<Override PartName="/ppt/slides/slide${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>`).join("")}<Override PartName="/docProps/core.xml" Conte
|
|
28397
|
-
ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
|
|
28405
|
+
files["docProps/core.xml"] = strToU84(`${XML2}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc6(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc6(opt.author)}${
|
|
28406
|
+
""}</dc:creator>` : ""}<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`);
|
|
28407
|
+
files["_rels/.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docP${
|
|
28408
|
+
""}rops/core.xml"/></Relationships>`);
|
|
28409
|
+
files["[Content_Types].xml"] = strToU84(`${XML2}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension${
|
|
28410
|
+
""}="svg" ContentType="image/svg+xml"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="applic${
|
|
28411
|
+
""}ation/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>${slides.map((n5) => `<Override PartName="/ppt/slides/slide${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>`).join("")}<Override PartName="/docProps/core.xml" Conte${
|
|
28412
|
+
""}ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
|
|
28398
28413
|
return zipSync3(files, { level: 6 });
|
|
28399
28414
|
}
|
|
28400
|
-
var THEME = `${XML2}<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="ReportWright"><a:themeElements><a:clrScheme name="ReportWright"><a:dk1><a:srgbClr val="000000"/></a:dk1><a:lt1><a:srgbClr val="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F2328"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="2563EB"/></a:accent1><a:accent2><a:srgbClr val="F5
|
|
28401
|
-
9E0B"/></a:accent2><a:accent3><a:srgbClr val="16A34A"/></a:accent3><a:accent4><a:srgbClr val="DC2626"/></a:accent4><a:accent5><a:srgbClr val="7C3AED"/></a:accent5><a:accent6><a:srgbClr val="0891B2"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="ReportWright"><a:majorFont><a:latin typeface="Inter"/><a:ea t
|
|
28402
|
-
ypeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Inter"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="ReportWright"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="
|
|
28403
|
-
6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyl
|
|
28404
|
-
eLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
|
|
28415
|
+
var THEME = `${XML2}<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="ReportWright"><a:themeElements><a:clrScheme name="ReportWright"><a:dk1><a:srgbClr val="000000"/></a:dk1><a:lt1><a:srgbClr val="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F2328"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="2563EB"/></a:accent1><a:accent2><a:srgbClr val="F5${
|
|
28416
|
+
""}9E0B"/></a:accent2><a:accent3><a:srgbClr val="16A34A"/></a:accent3><a:accent4><a:srgbClr val="DC2626"/></a:accent4><a:accent5><a:srgbClr val="7C3AED"/></a:accent5><a:accent6><a:srgbClr val="0891B2"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="ReportWright"><a:majorFont><a:latin typeface="Inter"/><a:ea t${
|
|
28417
|
+
""}ypeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Inter"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="ReportWright"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="${
|
|
28418
|
+
""}6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyl${
|
|
28419
|
+
""}eLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
|
|
28405
28420
|
|
|
28406
28421
|
// src/exporters/spill.js
|
|
28407
28422
|
var node2 = (m) => (
|
|
@@ -29188,6 +29203,19 @@ function defaultStore() {
|
|
|
29188
29203
|
return sharedStore;
|
|
29189
29204
|
}
|
|
29190
29205
|
var defaultSubset;
|
|
29206
|
+
var subsetMissing = "";
|
|
29207
|
+
var defaultSubsetter = () => defaultSubset ||= createSubsetter(async () => {
|
|
29208
|
+
const url = fontsUrl("harfbuzz-subset.wasm");
|
|
29209
|
+
try {
|
|
29210
|
+
if (!url) throw new Error("@reportwright/fonts is not installed");
|
|
29211
|
+
return await readUrl(url);
|
|
29212
|
+
} catch (e2) {
|
|
29213
|
+
subsetMissing = `harfbuzz-subset.wasm did not load from ${url?.href || "@reportwright/fonts/public/harfbuzz-subset.wasm"} (${/** @type {any} */
|
|
29214
|
+
e2?.message || e2}), so fonts are embedded in full and PDFs are many times larger. Install @reportwright/fonts next to the engine, or pass subset: createSubsetter(() => wasmBytes) with the file's bytes (subset: false embeds fonts in full on purpose).`;
|
|
29215
|
+
console.warn(`ReportWright: ${subsetMissing}`);
|
|
29216
|
+
throw e2;
|
|
29217
|
+
}
|
|
29218
|
+
});
|
|
29191
29219
|
var warned = /* @__PURE__ */ new Set();
|
|
29192
29220
|
async function render2(def, opts) {
|
|
29193
29221
|
const warn = checkOptions(opts);
|
|
@@ -29246,23 +29274,21 @@ var modelFonts = async (model, o) => {
|
|
|
29246
29274
|
async function exportPdf2(model, options) {
|
|
29247
29275
|
const opt = optionsOf("exportPdf", [...arguments], "fonts");
|
|
29248
29276
|
for (const w of checkOptions(opt)) (opt.onWarning || console.warn)(w);
|
|
29249
|
-
const subset = opt.subset === false ? void 0 : opt.subset || (
|
|
29250
|
-
const url = fontsUrl("harfbuzz-subset.wasm");
|
|
29251
|
-
if (!url) throw new Error("@reportwright/fonts is not installed");
|
|
29252
|
-
return readUrl(url);
|
|
29253
|
-
}));
|
|
29277
|
+
const subset = opt.subset === false ? void 0 : opt.subset || defaultSubsetter();
|
|
29254
29278
|
const { fonts, fontStore, ...rest } = opt;
|
|
29255
29279
|
if (rest.pdfa && !(typeof rest.pdfa === "object" && rest.pdfa.icc)) {
|
|
29256
29280
|
const url = fontsUrl("icc/sRGB-v2-magic.icc");
|
|
29257
29281
|
if (!url) throw new Error("PDF/A needs an sRGB colour profile: install @reportwright/fonts, or pass pdfa: { icc: bytes }");
|
|
29258
29282
|
rest.pdfa = { ...typeof rest.pdfa === "object" ? rest.pdfa : {}, icc: new Uint8Array(await readUrl(url)) };
|
|
29259
29283
|
}
|
|
29260
|
-
|
|
29284
|
+
const pdf = await exportPdf(
|
|
29261
29285
|
model,
|
|
29262
29286
|
fontsOf(opt),
|
|
29263
29287
|
/** @type {any} */
|
|
29264
29288
|
{ ...rest, subset }
|
|
29265
29289
|
);
|
|
29290
|
+
if (subsetMissing && subset === defaultSubset && model?.warnings && !model.warnings.includes(subsetMissing)) model.warnings.push(subsetMissing);
|
|
29291
|
+
return pdf;
|
|
29266
29292
|
}
|
|
29267
29293
|
function exportXlsx2(model, options) {
|
|
29268
29294
|
const opt = optionsOf("exportXlsx", [...arguments], "excel");
|
|
@@ -29285,11 +29311,7 @@ async function exportPdfStream2(def, options, sink) {
|
|
|
29285
29311
|
options || {}
|
|
29286
29312
|
);
|
|
29287
29313
|
const store = fonts || fontStore || defaultStore();
|
|
29288
|
-
const subset = sub === false ? void 0 : sub || (
|
|
29289
|
-
const url = fontsUrl("harfbuzz-subset.wasm");
|
|
29290
|
-
if (!url) throw new Error("@reportwright/fonts is not installed");
|
|
29291
|
-
return readUrl(url);
|
|
29292
|
-
}));
|
|
29314
|
+
const subset = sub === false ? void 0 : sub || defaultSubsetter();
|
|
29293
29315
|
let pdfaOpt = pdfa;
|
|
29294
29316
|
if (pdfa && !(typeof pdfa === "object" && pdfa.icc)) {
|
|
29295
29317
|
const url = fontsUrl("icc/sRGB-v2-magic.icc");
|
|
@@ -29299,6 +29321,7 @@ async function exportPdfStream2(def, options, sink) {
|
|
|
29299
29321
|
const sorter = rest.sorter || (spill !== false && canSpill() ? spillSorter(spillOptions(spill)) : void 0);
|
|
29300
29322
|
const r = await exportPdfStream(def, { ...rest, sorter, fontStore: store, subset, pdfa: pdfaOpt, exportData: !!rest.tagged }, sink);
|
|
29301
29323
|
if (unknown.length) r.warnings = [...unknown, ...r.warnings];
|
|
29324
|
+
if (subsetMissing && subset === defaultSubset) r.warnings = [...r.warnings, subsetMissing];
|
|
29302
29325
|
return r;
|
|
29303
29326
|
}
|
|
29304
29327
|
var officeOpts = (o = {}) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Render a report definition to a page model (pages, regions), the input of every exporter. Throws ReportError for a
|
|
3
3
|
* definition that cannot render at all; everything else is a warning in the model.
|
|
4
|
-
* @param {any} def0 the report definition (
|
|
4
|
+
* @param {any} def0 the report definition (reportwright/report@1), or a saved report's JSON
|
|
5
5
|
* @param {RenderOptions} [opts]
|
|
6
6
|
* @returns {Promise<any>} the page model
|
|
7
7
|
*/
|
|
@@ -19,5 +19,5 @@ export function validate(def: any): {
|
|
|
19
19
|
checkOnly: any[];
|
|
20
20
|
renderSays: string[];
|
|
21
21
|
};
|
|
22
|
-
export const SCHEMA_ID: "
|
|
23
|
-
export const SCHEMA_ALIAS: "
|
|
22
|
+
export const SCHEMA_ID: "reportwright/report@1";
|
|
23
|
+
export const SCHEMA_ALIAS: "pagewright/report@1";
|
|
@@ -25,10 +25,14 @@ export namespace XML_LIMITS {
|
|
|
25
25
|
let maxElements: number;
|
|
26
26
|
let maxAttributes: number;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* pos: where its start tag begins in the input (a character offset)
|
|
30
|
+
*/
|
|
28
31
|
export type XmlElement = {
|
|
29
32
|
name: string;
|
|
30
33
|
ns: string;
|
|
31
34
|
attrs: Record<string, string>;
|
|
32
35
|
children: XmlElement[];
|
|
33
36
|
text: string;
|
|
37
|
+
pos?: number;
|
|
34
38
|
};
|
package/examples/stream-1m.mjs
CHANGED
|
@@ -54,7 +54,7 @@ async function* rows() {
|
|
|
54
54
|
const grouped = flag('grouped');
|
|
55
55
|
const total = (label) => [{ height: 15, style: { fontWeight: 'bold' }, cells: [{ value: label }, { value: '=CountRows()' }, null, null, null, { value: '=Sum(Fields.amount)', style: { format: 'N2', textAlign: 'right' } }, null] }];
|
|
56
56
|
const def = {
|
|
57
|
-
$schema: '
|
|
57
|
+
$schema: 'reportwright/report@1', name: 'Ledger', locale: 'en-IN', page: { size: 'A4', margins: [36, 36, 36, 36] },
|
|
58
58
|
// the rows come from opts.sqlRows below (a cursor); the query text is not run
|
|
59
59
|
dataSources: [{ name: 'db', type: 'sql', connection: 'ledger', query: 'select * from transactions order by id' }],
|
|
60
60
|
dataSets: [{ name: 'Tx', source: 'db', fields: [{ name: 'id', type: 'number' }, { name: 'account', type: 'string' }, { name: 'region', type: 'string' }, { name: 'type', type: 'string' },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reportwright/engine",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2-rc.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"bidi-js": "1.0.3"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
|
-
"@reportwright/fonts": "0.13.
|
|
75
|
+
"@reportwright/fonts": "0.13.2-rc.2"
|
|
76
76
|
},
|
|
77
77
|
"peerDependenciesMeta": {
|
|
78
78
|
"@reportwright/fonts": {
|
package/report.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Types for a ReportWright report definition (
|
|
1
|
+
// Types for a ReportWright report definition (reportwright/report@1), the JSON that render() takes.
|
|
2
2
|
// GENERATED from src/engine/schema/report.schema.js by scripts/gen-report-types.mjs: do not edit by hand.
|
|
3
3
|
// The same schema is published as @reportwright/engine/schema.json, and validate() checks against it.
|
|
4
4
|
// Any value marked Expr may be a literal or an expression string starting with "=" (e.g. "=Fields.amount").
|
|
@@ -595,13 +595,13 @@ export interface DataSet {
|
|
|
595
595
|
sort?: SortSpec[];
|
|
596
596
|
[key: string]: unknown;
|
|
597
597
|
}
|
|
598
|
-
/** A ReportWright report definition (
|
|
598
|
+
/** A ReportWright report definition (reportwright/report@1).
|
|
599
599
|
* @example
|
|
600
|
-
* {"$schema":"
|
|
600
|
+
* {"$schema":"reportwright/report@1","name":"Invoice","page":{"size":"A4","margins":[36,36,36,36]},"dataSources":[{"name":"orders","type":"json","data":{"rows":[{"customer":"Asha Rao","amount":1200.5}]}}],"dataSets":[{"name":"Rows","source":"orders","path":"$.rows"}],"sections":{"body":{"items":[{"type":"textbox","name":"Title","x":0,"y":0,"w":300,"h":24,"value":"Invoice","style":{"fontSize":18,"fontWeight":"bold"}},{"type":"table","name":"Lines","x":0,"y":40,"w":400,"h":40,"dataSet":"Rows","columns":[{"width":250},{"width":150}],"header":[{"height":18,"cells":[{"value":"Customer","colSpan":1},{"value":"Amount"}]}],"detail":[{"height":18,"cells":[{"value":"=Fields.customer"},{"value":"=Fields.amount","style":{"format":"C2"}}]}],"footer":[{"height":18,"cells":[{"value":"Total","colSpan":2}]}]}]}}}
|
|
601
601
|
*/
|
|
602
602
|
export interface Report {
|
|
603
|
-
/**
|
|
604
|
-
$schema: '
|
|
603
|
+
/** reportwright/report@1; pagewright/report@1 (deprecated, the name before the rename) is the same format. */
|
|
604
|
+
$schema: 'reportwright/report@1' | 'pagewright/report@1';
|
|
605
605
|
name?: string;
|
|
606
606
|
description?: string;
|
|
607
607
|
locale?: string;
|
package/schema.json
CHANGED
|
@@ -2279,14 +2279,14 @@
|
|
|
2279
2279
|
"additionalProperties": true
|
|
2280
2280
|
},
|
|
2281
2281
|
"Report": {
|
|
2282
|
-
"description": "A ReportWright report definition (
|
|
2282
|
+
"description": "A ReportWright report definition (reportwright/report@1).",
|
|
2283
2283
|
"type": "object",
|
|
2284
2284
|
"properties": {
|
|
2285
2285
|
"$schema": {
|
|
2286
|
-
"description": "
|
|
2286
|
+
"description": "reportwright/report@1; pagewright/report@1 (deprecated, the name before the rename) is the same format.",
|
|
2287
2287
|
"enum": [
|
|
2288
|
-
"
|
|
2289
|
-
"
|
|
2288
|
+
"reportwright/report@1",
|
|
2289
|
+
"pagewright/report@1"
|
|
2290
2290
|
]
|
|
2291
2291
|
},
|
|
2292
2292
|
"name": {
|
|
@@ -2404,7 +2404,7 @@
|
|
|
2404
2404
|
],
|
|
2405
2405
|
"examples": [
|
|
2406
2406
|
{
|
|
2407
|
-
"$schema": "
|
|
2407
|
+
"$schema": "reportwright/report@1",
|
|
2408
2408
|
"name": "Invoice",
|
|
2409
2409
|
"page": {
|
|
2410
2410
|
"size": "A4",
|