@reportwright/engine 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -1
- package/README.md +54 -12
- package/dist/index.js +589 -180
- package/dist/types/packages/engine/entry.d.ts +18 -4
- package/dist/types/src/engine/data/guard.d.ts +4 -1
- package/dist/types/src/engine/index.d.ts +1 -1
- package/dist/types/src/engine/items/chart-kit.d.ts +6 -0
- package/dist/types/src/engine/stream.d.ts +5 -3
- package/dist/types/src/engine/text/measure.d.ts +2 -0
- package/dist/types/src/exporters/docx.d.ts +5 -1
- package/dist/types/src/exporters/html.d.ts +9 -5
- package/dist/types/src/exporters/pdfpaint.d.ts +3 -11
- package/dist/types/src/exporters/pdfstream.d.ts +3 -2
- package/dist/types/src/exporters/pdfstreamtags.d.ts +8 -1
- package/dist/types/src/exporters/spill.d.ts +20 -0
- package/dist/types/src/exporters/subset.d.ts +1 -0
- package/examples/stream-1m.mjs +21 -8
- package/package.json +2 -2
- package/pool/worker.js +1 -1
package/dist/index.js
CHANGED
|
@@ -395,6 +395,7 @@ function special(cp) {
|
|
|
395
395
|
if (cp >= 8192 && cp <= 8303) return cp >= 8203 && cp <= 8207 || cp >= 8234 && cp <= 8238 || cp >= 8288;
|
|
396
396
|
return cp >= 11904 && cp <= 42191 || cp >= 43056 && cp <= 44031 || cp >= 44032 && cp <= 55215 || cp >= 63744 && cp <= 64255 || cp >= 64285 && cp <= 65023 || cp >= 65024 && cp <= 65039 || cp >= 65072 && cp <= 65103 || cp >= 65136 && cp <= 65278 || cp >= 65280 && cp <= 65519 || cp >= 65536;
|
|
397
397
|
}
|
|
398
|
+
var FORMAT_CHAR = /^\p{Cf}$/u;
|
|
398
399
|
var cjk = (cp) => cp >= 11904 && cp <= 40959 || cp >= 44032 && cp <= 55215 || cp >= 63744 && cp <= 64255 || cp >= 65280 && cp <= 65519 || cp >= 131072 && cp <= 262143;
|
|
399
400
|
var NO_START = new Set("、。,.・:;?!ー)」』】〕〉》〗〙〟’”}⦆ぁぃぅぇぉっゃゅょゎゕゖァィゥェォッャュョヮヵヶ々〻‐゠–〜~…‥,.!?:;)]}%ゝゞヽヾ゛゜ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ。」、・ー%]⦆");
|
|
400
401
|
var NO_END = new Set("(「『【〔〈《〖〘〝‘“{⦅([{[「$¥£");
|
|
@@ -790,7 +791,7 @@ var TextMeasurer = class {
|
|
|
790
791
|
}
|
|
791
792
|
/** The font for one character: the chosen one, else the bundled fallback for its script, else the one before. */
|
|
792
793
|
pick(cp, key, prev) {
|
|
793
|
-
if (cp < 32 || this.has(key, cp)) return key;
|
|
794
|
+
if (cp < 32 || this.has(key, cp) || FORMAT_CHAR.test(String.fromCodePoint(cp))) return key;
|
|
794
795
|
const fb = fallbackKey(cp, key);
|
|
795
796
|
if (fb && !this.store.failed.has(fb)) {
|
|
796
797
|
if (!this.store.has(fb)) {
|
|
@@ -4422,9 +4423,23 @@ function nodeRequest(url, init, trusted) {
|
|
|
4422
4423
|
for (let i = 0; i < res.rawHeaders.length; i += 2) pairs2.push([res.rawHeaders[i], res.rawHeaders[i + 1]]);
|
|
4423
4424
|
const none = [101, 204, 205, 304].includes(res.statusCode) || (init.method || "GET").toUpperCase() === "HEAD";
|
|
4424
4425
|
if (none) res.resume();
|
|
4425
|
-
|
|
4426
|
+
const enc = String(res.headers["content-encoding"] || "").trim().toLowerCase();
|
|
4427
|
+
let body = res, decoded = false;
|
|
4428
|
+
if (!none && enc && enc !== "identity") {
|
|
4429
|
+
const zlib = nodeMod("node:zlib");
|
|
4430
|
+
const dec2 = enc === "gzip" || enc === "x-gzip" ? zlib.createGunzip() : enc === "deflate" ? zlib.createInflate() : enc === "br" ? zlib.createBrotliDecompress() : null;
|
|
4431
|
+
if (!dec2) {
|
|
4432
|
+
res.resume();
|
|
4433
|
+
return reject(Object.assign(new Error(`the response is encoded as "${enc}", which the data fetch cannot decode`), { status: 415 }));
|
|
4434
|
+
}
|
|
4435
|
+
body = stream.pipeline(res, dec2, () => {
|
|
4436
|
+
});
|
|
4437
|
+
decoded = true;
|
|
4438
|
+
}
|
|
4439
|
+
const kept = decoded ? pairs2.filter(([k]) => !/^(content-encoding|content-length)$/i.test(k)) : pairs2;
|
|
4440
|
+
resolve(new Response(none ? null : stream.Readable.toWeb(body), { status: res.statusCode, statusText: res.statusMessage, headers: (
|
|
4426
4441
|
/** @type {any} */
|
|
4427
|
-
|
|
4442
|
+
kept
|
|
4428
4443
|
) }));
|
|
4429
4444
|
});
|
|
4430
4445
|
req.on("error", reject);
|
|
@@ -4443,7 +4458,7 @@ function redirectRequest(from, to, req, status) {
|
|
|
4443
4458
|
}
|
|
4444
4459
|
function guardedFetch(opt, base) {
|
|
4445
4460
|
const allow = (opt.allowHosts || []).map((h) => String(h).toLowerCase().replace(/^\[|\]$/g, ""));
|
|
4446
|
-
const
|
|
4461
|
+
const node3 = !opt.viaBase && inNode();
|
|
4447
4462
|
return (
|
|
4448
4463
|
/** @type {any} */
|
|
4449
4464
|
(async (input, init = {}) => {
|
|
@@ -4451,7 +4466,7 @@ function guardedFetch(opt, base) {
|
|
|
4451
4466
|
let req = { ...init };
|
|
4452
4467
|
for (let hop = 0; ; hop++) {
|
|
4453
4468
|
const trusted = allow.includes(url.hostname.replace(/^\[|\]$/g, "").toLowerCase());
|
|
4454
|
-
const res =
|
|
4469
|
+
const res = node3 ? await nodeRequest(url, req, trusted) : await base(url.href, { ...req, redirect: "manual" });
|
|
4455
4470
|
if (res.type === "opaqueredirect") throw new Error(`${url.host} redirects; a redirect cannot be checked here (pass your own fetch to render)`);
|
|
4456
4471
|
const loc = res.status >= 300 && res.status < 400 ? res.headers.get("location") : null;
|
|
4457
4472
|
if (!loc) return res;
|
|
@@ -5335,7 +5350,10 @@ function fetcherFor(opt) {
|
|
|
5335
5350
|
return boundedFetch(f4, opt);
|
|
5336
5351
|
}
|
|
5337
5352
|
function checkHostSource(src, url, opt) {
|
|
5338
|
-
|
|
5353
|
+
const rule = opt.fetch ? opt.fetch.hostRule : opt.unsafeFetch ? null : opt;
|
|
5354
|
+
if (!rule) return;
|
|
5355
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(String(url).trim());
|
|
5356
|
+
if (scheme && !/^https?$/i.test(scheme[1])) throw Object.assign(new Error(`Only http and https URLs can be fetched, not ${scheme[1].toLowerCase()}:`), { status: 400 });
|
|
5339
5357
|
const t = String(src.url ?? "").trim();
|
|
5340
5358
|
if (/^\/(?![/\\])/.test(t)) return;
|
|
5341
5359
|
const m = /^https?:\/\/([^/?#\\]*)/i.exec(t);
|
|
@@ -5346,7 +5364,7 @@ function checkHostSource(src, url, opt) {
|
|
|
5346
5364
|
host = new URL(url).hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
5347
5365
|
} catch {
|
|
5348
5366
|
}
|
|
5349
|
-
if (whole && host && (
|
|
5367
|
+
if (whole && host && (rule.allowHosts || []).map((h) => String(h).toLowerCase()).includes(host)) return;
|
|
5350
5368
|
throw Object.assign(new Error("its host is made by a parameter or an expression: write the scheme and host out (parameters may fill the path and query), or make the whole URL a parameter and list its host in allowHosts"), { status: 403 });
|
|
5351
5369
|
}
|
|
5352
5370
|
async function loadSources(def, opt) {
|
|
@@ -5841,7 +5859,7 @@ var BASE_STYLE = {
|
|
|
5841
5859
|
radius: 0
|
|
5842
5860
|
};
|
|
5843
5861
|
function resolveStyle(layers, ctx) {
|
|
5844
|
-
let
|
|
5862
|
+
let node3 = null, allStatic = true;
|
|
5845
5863
|
for (const l of layers) {
|
|
5846
5864
|
if (!l || typeof l !== "object") continue;
|
|
5847
5865
|
if (hasDynamic(l)) {
|
|
@@ -5858,10 +5876,10 @@ function resolveStyle(layers, ctx) {
|
|
|
5858
5876
|
next = { map: /* @__PURE__ */ new WeakMap(), value: null };
|
|
5859
5877
|
map.set(l, next);
|
|
5860
5878
|
}
|
|
5861
|
-
|
|
5879
|
+
node3 = next;
|
|
5862
5880
|
map = next.map;
|
|
5863
5881
|
}
|
|
5864
|
-
if (
|
|
5882
|
+
if (node3?.value) return node3.value;
|
|
5865
5883
|
}
|
|
5866
5884
|
const out = {};
|
|
5867
5885
|
for (const l of layers) {
|
|
@@ -5872,7 +5890,7 @@ function resolveStyle(layers, ctx) {
|
|
|
5872
5890
|
out[k] = isDynamic(v) ? safe(v, ctx) : v;
|
|
5873
5891
|
}
|
|
5874
5892
|
}
|
|
5875
|
-
if (allStatic &&
|
|
5893
|
+
if (allStatic && node3) node3.value = Object.freeze(out);
|
|
5876
5894
|
return out;
|
|
5877
5895
|
}
|
|
5878
5896
|
var CACHE = /* @__PURE__ */ new WeakMap();
|
|
@@ -6504,6 +6522,11 @@ function niceScale(min, max, ticks = 5) {
|
|
|
6504
6522
|
const step3 = niceNum(range / Math.max(1, ticks - 1), true);
|
|
6505
6523
|
return { lo: Math.floor(min / step3) * step3, hi: Math.ceil(max / step3) * step3, step: step3 };
|
|
6506
6524
|
}
|
|
6525
|
+
function niceScaleSpan(min, max, ticks = 5) {
|
|
6526
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || !(max > min)) return niceScale(min, max, ticks);
|
|
6527
|
+
const step3 = niceNum((max - min) / Math.max(1, ticks - 1), true);
|
|
6528
|
+
return { lo: Math.floor(min / step3) * step3, hi: Math.ceil(max / step3) * step3, step: step3 };
|
|
6529
|
+
}
|
|
6507
6530
|
function niceNum(x, round) {
|
|
6508
6531
|
const e2 = Math.floor(Math.log10(x));
|
|
6509
6532
|
const f4 = x / 10 ** e2;
|
|
@@ -6826,10 +6849,10 @@ function paintGauge(g) {
|
|
|
6826
6849
|
if (!(hi > lo)) hi = lo + 1;
|
|
6827
6850
|
const shape = Object.hasOwn(GAUGE_SHAPES, item.gaugeShape) ? item.gaugeShape : "half";
|
|
6828
6851
|
const indicator = GAUGE_INDICATORS.includes(item.gaugeIndicator) ? item.gaugeIndicator : "needle";
|
|
6829
|
-
const [start,
|
|
6852
|
+
const [start, sweep2] = GAUGE_SHAPES[shape];
|
|
6830
6853
|
const frac = (x) => Math.max(0, Math.min(1, (x - lo) / (hi - lo)));
|
|
6831
|
-
const ang = (x) => start + frac(x) *
|
|
6832
|
-
const end = start +
|
|
6854
|
+
const ang = (x) => start + frac(x) * sweep2;
|
|
6855
|
+
const end = start + sweep2 - (shape === "full" ? 1e-4 : 0);
|
|
6833
6856
|
const cx = X + W2 / 2, H = bottom - top;
|
|
6834
6857
|
let R2, cy;
|
|
6835
6858
|
if (shape === "full") {
|
|
@@ -6886,7 +6909,7 @@ function paintGauge(g) {
|
|
|
6886
6909
|
text2(fmtV(t), p.x, p.y + fs * 0.3, { align: "center", size: fs * 0.8, color: "#6b7280" });
|
|
6887
6910
|
});
|
|
6888
6911
|
} else if (shape !== "full") {
|
|
6889
|
-
const e0 = at(start, R2 - th / 2), e1 = at(start +
|
|
6912
|
+
const e0 = at(start, R2 - th / 2), e1 = at(start + sweep2, R2 - th / 2);
|
|
6890
6913
|
text2(fmtV(lo), e0.x, e0.y + fs * 1.3, { align: "center", color: "#6b7280" });
|
|
6891
6914
|
text2(fmtV(hi), e1.x, e1.y + fs * 1.3, { align: "center", color: "#6b7280" });
|
|
6892
6915
|
}
|
|
@@ -7460,7 +7483,7 @@ var byName = (lc, pal) => (name) => {
|
|
|
7460
7483
|
};
|
|
7461
7484
|
function chartData(item, ctx, lc, pal = paletteOf(item.palette)) {
|
|
7462
7485
|
let rows = item.dataSet ? related(lc.dataSets[item.dataSet] || [], ctx) : ctx.aggRows || [];
|
|
7463
|
-
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name}: the data set "${item.dataSet}" does not exist`);
|
|
7486
|
+
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name || item.type}: the data set "${item.dataSet}" does not exist`);
|
|
7464
7487
|
if (item.filters?.length) rows = applyFilters(rows, item.filters, ctx);
|
|
7465
7488
|
if (item.sort?.length) rows = applySort(rows, item.sort, ctx);
|
|
7466
7489
|
const who = item.name || "Chart";
|
|
@@ -7748,13 +7771,15 @@ function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs = 7
|
|
|
7748
7771
|
lo = lo < 0 ? -1 : 0;
|
|
7749
7772
|
hi = 1;
|
|
7750
7773
|
}
|
|
7774
|
+
let padded = false;
|
|
7751
7775
|
if (pad2 > 0 && hi > lo) {
|
|
7752
7776
|
const d = (hi - lo) * pad2;
|
|
7753
|
-
if (smin == null) lo
|
|
7754
|
-
if (smax == null) hi
|
|
7777
|
+
if (smin == null) lo = lo >= 0 && lo - d < 0 ? 0 : lo - d;
|
|
7778
|
+
if (smax == null) hi = hi <= 0 && hi + d > 0 ? 0 : hi + d;
|
|
7779
|
+
padded = true;
|
|
7755
7780
|
}
|
|
7756
7781
|
const want = len < fs * 6 ? 3 : 5;
|
|
7757
|
-
const sc = niceScale(smin ?? lo, smax ?? hi, want);
|
|
7782
|
+
const sc = padded && smin == null && smax == null && (lo >= 0 || hi <= 0) ? niceScaleSpan(lo, hi, want) : niceScale(smin ?? lo, smax ?? hi, want);
|
|
7758
7783
|
let a = sc.lo, b = sc.hi, ticks;
|
|
7759
7784
|
if (smin != null || smax != null) {
|
|
7760
7785
|
a = smin ?? sc.lo;
|
|
@@ -8182,31 +8207,27 @@ function rowPoints(type, g) {
|
|
|
8182
8207
|
rows = rows.slice(0, cap);
|
|
8183
8208
|
}
|
|
8184
8209
|
const blank2 = (v) => v == null || v === "";
|
|
8185
|
-
const
|
|
8210
|
+
const drawn = /* @__PURE__ */ new Set();
|
|
8186
8211
|
const sets = data.series.map((s, si) => {
|
|
8187
8212
|
const pts2 = [];
|
|
8188
8213
|
rows.forEach((r, ri) => {
|
|
8189
8214
|
c.fields = r;
|
|
8190
8215
|
const rx = safe2(item.xValue, c, lc, who), ry = safe2(s.def.value || "=0", { ...c, aggRows: [r] }, lc, who);
|
|
8191
|
-
if (blank2(rx) || blank2(ry))
|
|
8192
|
-
missing.add(ri);
|
|
8193
|
-
return;
|
|
8194
|
-
}
|
|
8216
|
+
if (blank2(rx) || blank2(ry)) return;
|
|
8195
8217
|
const x = Number(rx), y = Number(ry);
|
|
8196
|
-
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
8197
|
-
missing.add(ri);
|
|
8198
|
-
return;
|
|
8199
|
-
}
|
|
8218
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return;
|
|
8200
8219
|
let size = 1;
|
|
8201
8220
|
if (type === "bubble") {
|
|
8202
8221
|
size = Number(safe2(s.def.size || "=1", { ...c, aggRows: [r] }, lc, who));
|
|
8203
8222
|
if (!Number.isFinite(size) || size <= 0) return;
|
|
8204
8223
|
}
|
|
8205
8224
|
pts2.push({ x, y, size });
|
|
8225
|
+
drawn.add(ri);
|
|
8206
8226
|
});
|
|
8207
8227
|
return { s, pts: pts2, i: si };
|
|
8208
8228
|
});
|
|
8209
|
-
|
|
8229
|
+
const missing = rows.length - drawn.size;
|
|
8230
|
+
if (missing > 0) lc.warn(`${who}: ${missing} of ${rows.length} rows have no x or y value and are not drawn`);
|
|
8210
8231
|
return sets;
|
|
8211
8232
|
}
|
|
8212
8233
|
function paintXY(type, g) {
|
|
@@ -10096,7 +10117,7 @@ function buildTree(groups, rows, ctx, lc, who, axis, state) {
|
|
|
10096
10117
|
for (const n5 of frontier) {
|
|
10097
10118
|
const bs = sortBuckets(groupRows(n5.rows, g.expr || "=''", ctx, lc, who), g, ctx, lc, who);
|
|
10098
10119
|
n5.children = bs.map((b) => {
|
|
10099
|
-
const
|
|
10120
|
+
const node3 = { key: b.key, text: b.text, label: "", rows: b.rows, level: l, parent: n5, children: null, path: `${n5.path}/${b.text}`, open: true, lo: 0, hi: 0, toggle: null };
|
|
10100
10121
|
if (g.label) {
|
|
10101
10122
|
let v;
|
|
10102
10123
|
try {
|
|
@@ -10105,14 +10126,14 @@ function buildTree(groups, rows, ctx, lc, who, axis, state) {
|
|
|
10105
10126
|
lc.warn(`${who}: ${e2.message}`);
|
|
10106
10127
|
v = "#Error";
|
|
10107
10128
|
}
|
|
10108
|
-
|
|
10109
|
-
} else
|
|
10129
|
+
node3.label = toText(v, g.format || null, ctx);
|
|
10130
|
+
} else node3.label = toText(b.key, g.format || null, ctx);
|
|
10110
10131
|
if (g.collapsible && l < groups.length - 1) {
|
|
10111
|
-
const key = `${who}|${axis}${l}|${
|
|
10112
|
-
|
|
10113
|
-
|
|
10132
|
+
const key = `${who}|${axis}${l}|${node3.path}`;
|
|
10133
|
+
node3.open = state?.toggles?.[key] ?? !g.initiallyCollapsed;
|
|
10134
|
+
node3.toggle = { key, open: node3.open };
|
|
10114
10135
|
}
|
|
10115
|
-
return
|
|
10136
|
+
return node3;
|
|
10116
10137
|
});
|
|
10117
10138
|
if (g.parent && axis === "r") {
|
|
10118
10139
|
if (l === groups.length - 1) recurse(n5, g, l);
|
|
@@ -10264,14 +10285,14 @@ function buildPivot(item, rows, ctx, lc) {
|
|
|
10264
10285
|
const withClick = (cell, click, n5, chain, groups, axis) => click ? Object.assign(cell, click, { ctx: headCtx(n5, chain, groups, axis) }) : cell;
|
|
10265
10286
|
const isPct = (v) => v.show === "percentOfTotal" || v.show === "percentOfRow" || v.show === "percentOfColumn";
|
|
10266
10287
|
const denCache = /* @__PURE__ */ new Map();
|
|
10267
|
-
const den = (vi, kind,
|
|
10268
|
-
let m = denCache.get(
|
|
10288
|
+
const den = (vi, kind, node3, scopes) => {
|
|
10289
|
+
let m = denCache.get(node3);
|
|
10269
10290
|
if (!m) {
|
|
10270
10291
|
m = /* @__PURE__ */ new Map();
|
|
10271
|
-
denCache.set(
|
|
10292
|
+
denCache.set(node3, m);
|
|
10272
10293
|
}
|
|
10273
10294
|
const k = `${vi}|${kind}`;
|
|
10274
|
-
if (!m.has(k)) m.set(k, evalAgg(vals[vi].value || "=Count(Fields)",
|
|
10295
|
+
if (!m.has(k)) m.set(k, evalAgg(vals[vi].value || "=Count(Fields)", node3.rows, scopes));
|
|
10275
10296
|
return m.get(k);
|
|
10276
10297
|
};
|
|
10277
10298
|
const cols = [];
|
|
@@ -10626,7 +10647,7 @@ function hidden(item, ctx, lc) {
|
|
|
10626
10647
|
const r = evalSafe(item.hidden, ctx, lc, item.name || item.type);
|
|
10627
10648
|
h = !r.err && truthy(r.v);
|
|
10628
10649
|
}
|
|
10629
|
-
return item.name && lc.state?.toggles?.[`item:${item.name}`] ? !h : h;
|
|
10650
|
+
return item.name && lc.state?.toggles?.[`item:${item.name || item.type}`] ? !h : h;
|
|
10630
10651
|
}
|
|
10631
10652
|
var SHRINK_DEFAULTS = { minFontSize: 4, step: 0.5 };
|
|
10632
10653
|
function rotationOf(item) {
|
|
@@ -10962,7 +10983,7 @@ register("table", {
|
|
|
10962
10983
|
else {
|
|
10963
10984
|
rows = item.dataSet && lc.dataSets[item.dataSet] || [];
|
|
10964
10985
|
rows = related(rows, tctx);
|
|
10965
|
-
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name ||
|
|
10986
|
+
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name || item.type}: the data set "${item.dataSet}" does not exist`);
|
|
10966
10987
|
if (item.filters?.length) rows = applyFilters(rows, item.filters, tctx);
|
|
10967
10988
|
const sort = lc.state?.sort?.[item.name] || item.sort;
|
|
10968
10989
|
if (sort?.length) rows = applySort(rows, sort, tctx);
|
|
@@ -10978,11 +10999,11 @@ register("table", {
|
|
|
10978
10999
|
if (overflow === "shrink" && room > 0) {
|
|
10979
11000
|
const k = room / designedW;
|
|
10980
11001
|
cols = cols.map((c) => ({ ...c, width: (Number(c.width) || 0) * k }));
|
|
10981
|
-
lc.warn(`${item.name ||
|
|
11002
|
+
lc.warn(`${item.name || item.type}: its columns are ${Math.round(designedW)}pt wide, wider than the page (${Math.round(room)}pt), so they are narrowed to fit`);
|
|
10982
11003
|
} else if (overflow === "clip" || overflow === "paginate" && lc.fixed) {
|
|
10983
|
-
lc.warn(`${item.name ||
|
|
11004
|
+
lc.warn(`${item.name || item.type}: its columns are ${Math.round(designedW)}pt wide, wider than the page (${Math.round(room)}pt), so the columns past the page edge are cut`, true);
|
|
10984
11005
|
} else if (overflow === "paginate" && item.overflow !== "paginate") {
|
|
10985
|
-
lc.warn(`${item.name ||
|
|
11006
|
+
lc.warn(`${item.name || item.type}: its columns are ${Math.round(designedW)}pt wide, wider than the page (${Math.round(room)}pt), so they continue on the next pages`);
|
|
10986
11007
|
}
|
|
10987
11008
|
const colX = [];
|
|
10988
11009
|
let acc = item.x;
|
|
@@ -10992,6 +11013,7 @@ register("table", {
|
|
|
10992
11013
|
}
|
|
10993
11014
|
const width = acc - item.x;
|
|
10994
11015
|
const region = { name: item.name, columns: cols.map((c) => c.width), rows: [] };
|
|
11016
|
+
if (lc.tablesSeen) lc.tablesSeen.n++;
|
|
10995
11017
|
const tableScope = { rows, index: -1, run: [] };
|
|
10996
11018
|
const scopes = { ...tctx.scopes || {}, [item.name]: tableScope };
|
|
10997
11019
|
const groupChains = {};
|
|
@@ -11015,7 +11037,7 @@ register("table", {
|
|
|
11015
11037
|
const covered = (ci) => cover[ci] !== null;
|
|
11016
11038
|
const cellsAt = /* @__PURE__ */ new WeakMap();
|
|
11017
11039
|
const layRow = (row, ctx, kind, extra) => {
|
|
11018
|
-
if (row.hidden != null && row.hidden !== false && row.hidden !== "" && hidden({ hidden: row.hidden, name: `${item.name ||
|
|
11040
|
+
if (row.hidden != null && row.hidden !== false && row.hidden !== "" && hidden({ hidden: row.hidden, name: `${item.name || item.type} row` }, ctx, lc)) {
|
|
11019
11041
|
if (openSpans.length) {
|
|
11020
11042
|
for (const s of openSpans) s.left--;
|
|
11021
11043
|
for (const s of openSpans) if (s.left <= 0) closeSpan(s);
|
|
@@ -11049,7 +11071,7 @@ register("table", {
|
|
|
11049
11071
|
else try {
|
|
11050
11072
|
v = evalValue(cell.value ?? "", cctx);
|
|
11051
11073
|
} catch (e2) {
|
|
11052
|
-
lc.warn(`${item.name ||
|
|
11074
|
+
lc.warn(`${item.name || item.type} cell: ${e2.message}`);
|
|
11053
11075
|
v = "#Error";
|
|
11054
11076
|
}
|
|
11055
11077
|
let text2 = textOf(v, st, cctx, lc);
|
|
@@ -11092,7 +11114,7 @@ register("table", {
|
|
|
11092
11114
|
cells.forEach((c, k) => {
|
|
11093
11115
|
if (c.cell.visual?.type) {
|
|
11094
11116
|
items.push(...paintBox({ x: c.x, y: 0, w: c.w, h, st: c.st, tl: null, m: lc.m }));
|
|
11095
|
-
if (first) items.push(...paintVisual(c.cell.visual, { x: c.x, y: 0, w: c.w, h }, c.ctx, lc, c.st, `${item.name} cell`, { cell: true }));
|
|
11117
|
+
if (first) items.push(...paintVisual(c.cell.visual, { x: c.x, y: 0, w: c.w, h }, c.ctx, lc, c.st, `${item.name || item.type} cell`, { cell: true }));
|
|
11096
11118
|
return;
|
|
11097
11119
|
}
|
|
11098
11120
|
if (c.nested) {
|
|
@@ -11147,7 +11169,7 @@ register("table", {
|
|
|
11147
11169
|
};
|
|
11148
11170
|
const layoutInCell = (inner, x, cw, st, cctx, row) => {
|
|
11149
11171
|
const pd = padding(st);
|
|
11150
|
-
const it = { ...inner, name: inner.name || `${item.name}_cell`, x: x + pd[3], y: 0, w: Math.max(1, cw - pd[1] - pd[3]), h: Number(inner.h) || Math.max(1, (row.height || 18) - pd[0] - pd[2]) };
|
|
11172
|
+
const it = { ...inner, name: inner.name || `${item.name || item.type}_cell`, x: x + pd[3], y: 0, w: Math.max(1, cw - pd[1] - pd[3]), h: Number(inner.h) || Math.max(1, (row.height || 18) - pd[0] - pd[2]) };
|
|
11151
11173
|
const scopeRows2 = cctx.aggIndex != null ? [cctx.fields] : cctx.aggRows || [];
|
|
11152
11174
|
const current = item.dataSet ? { ...cctx.current || {}, [item.dataSet]: scopeRows2 } : cctx.current;
|
|
11153
11175
|
const child = {
|
|
@@ -11167,7 +11189,7 @@ register("table", {
|
|
|
11167
11189
|
const reads = (it.dataSet && it.dataSet !== item.dataSet ? child.ctxFor(it).aggRows?.length : scopeRows2.length) || 1;
|
|
11168
11190
|
if (budget.left < reads) {
|
|
11169
11191
|
budget.left = 0;
|
|
11170
|
-
lc.warn(`${item.name}: more than ${CELL_ITEM_UNITS} rows of items inside cells; the rest are left empty`);
|
|
11192
|
+
lc.warn(`${item.name || item.type}: more than ${CELL_ITEM_UNITS} rows of items inside cells; the rest are left empty`);
|
|
11171
11193
|
return { items: [], height: 0 };
|
|
11172
11194
|
}
|
|
11173
11195
|
budget.left -= reads;
|
|
@@ -11211,7 +11233,7 @@ register("table", {
|
|
|
11211
11233
|
u.items.splice(at < 0 ? u.items.length : at, 0, ...add2);
|
|
11212
11234
|
});
|
|
11213
11235
|
if (s.tl.needed > s.units[0].height + GROW_TOLERANCE || s.st.verticalAlign && s.st.verticalAlign !== "top") {
|
|
11214
|
-
const id = `${item.name}:span:${lc.nextId()}`;
|
|
11236
|
+
const id = `${item.name || item.type}:span:${lc.nextId()}`;
|
|
11215
11237
|
for (const u of s.units) u.block ||= id;
|
|
11216
11238
|
} else {
|
|
11217
11239
|
let above = s.units[0].height;
|
|
@@ -11253,7 +11275,7 @@ register("table", {
|
|
|
11253
11275
|
const groups = item.groups || [];
|
|
11254
11276
|
let rowNo = lc.win?.rowOffset || 0;
|
|
11255
11277
|
const groupTables = [];
|
|
11256
|
-
const tableKey = `${item.name}#${lc.nextId()}`;
|
|
11278
|
+
const tableKey = `${item.name || item.type}#${lc.nextId()}`;
|
|
11257
11279
|
const emit = (level, grows, ctx, chain, keyPath) => {
|
|
11258
11280
|
if (level === groups.length) {
|
|
11259
11281
|
for (let i = 0; i < grows.length; i++) {
|
|
@@ -11315,7 +11337,7 @@ register("table", {
|
|
|
11315
11337
|
kids = /* @__PURE__ */ new Map();
|
|
11316
11338
|
roots = [];
|
|
11317
11339
|
for (const b of buckets) {
|
|
11318
|
-
const pk = evalSafe(g.parent, { ...ctx, fields: b.rows[0], aggRows: b.rows, aggIndex: void 0 }, lc, `${item.name} group parent`).v;
|
|
11340
|
+
const pk = evalSafe(g.parent, { ...ctx, fields: b.rows[0], aggRows: b.rows, aggIndex: void 0 }, lc, `${item.name || item.type} group parent`).v;
|
|
11319
11341
|
const pr = pk == null || pk === "" ? null : byText.get(pk instanceof Date ? String(pk.getTime()) : String(pk));
|
|
11320
11342
|
if (!pr || pr === b) roots.push(b);
|
|
11321
11343
|
else {
|
|
@@ -11336,7 +11358,7 @@ register("table", {
|
|
|
11336
11358
|
for (const b of buckets) if (!recOf.has(b)) rec(b, 0);
|
|
11337
11359
|
}
|
|
11338
11360
|
const shown2 = /* @__PURE__ */ new Set();
|
|
11339
|
-
const
|
|
11361
|
+
const node3 = (bk, bi, sibs, depth, parentPath) => {
|
|
11340
11362
|
if (lc.rowBudget?.cut || shown2.has(bk)) return;
|
|
11341
11363
|
shown2.add(bk);
|
|
11342
11364
|
const sc = { rows: bk.rows, index: -1, run: [], number: bi + 1, prevRows: bi > 0 ? sibs[bi - 1].rows : null, siblings: sibRows(sibs), ...kids ? { level: depth, recRows: recOf.get(bk) } : {} };
|
|
@@ -11347,7 +11369,7 @@ register("table", {
|
|
|
11347
11369
|
if (g.indent) gctx.indent = (ctx.indent || 0) + depth * Number(g.indent);
|
|
11348
11370
|
}
|
|
11349
11371
|
const path = `${parentPath}/${bk.text}`;
|
|
11350
|
-
const tkey = `${item.name}|${level}|${path}`;
|
|
11372
|
+
const tkey = `${item.name || item.type}|${level}|${path}`;
|
|
11351
11373
|
const dflt = kids && g.expandLevels != null ? depth < Number(g.expandLevels) : !g.initiallyCollapsed;
|
|
11352
11374
|
const open = !g.collapsible ? true : lc.state?.toggles?.[tkey] ?? dflt;
|
|
11353
11375
|
const start = units.length;
|
|
@@ -11369,8 +11391,8 @@ register("table", {
|
|
|
11369
11391
|
const ch = kids?.get(bk) || [];
|
|
11370
11392
|
if (open) {
|
|
11371
11393
|
emit(level + 1, bk.rows, gctx, [...chain, sc], path);
|
|
11372
|
-
if (ch.length && depth + 1 >= MAX_TREE_DEPTH) lc.warn(`${item.name}: the group "${gname}" is more than ${MAX_TREE_DEPTH} levels deep; deeper rows are listed at the top level`);
|
|
11373
|
-
else ch.forEach((c, ci) =>
|
|
11394
|
+
if (ch.length && depth + 1 >= MAX_TREE_DEPTH) lc.warn(`${item.name || item.type}: the group "${gname}" is more than ${MAX_TREE_DEPTH} levels deep; deeper rows are listed at the top level`);
|
|
11395
|
+
else ch.forEach((c, ci) => node3(c, ci, ch, depth + 1, path));
|
|
11374
11396
|
} else {
|
|
11375
11397
|
const rs = recOf.get(bk) || bk.rows;
|
|
11376
11398
|
for (const s of [...chain, sc]) {
|
|
@@ -11398,7 +11420,7 @@ register("table", {
|
|
|
11398
11420
|
if (g.newSection) units[start].sectionStart = true;
|
|
11399
11421
|
if (g.pageBreak === "after" && bi < sibs.length - 1) units[units.length - 1].breakAfter = true;
|
|
11400
11422
|
if (g.keepTogether) {
|
|
11401
|
-
const id = `${item.name}:g${level}:${path}:${lc.nextId()}`;
|
|
11423
|
+
const id = `${item.name || item.type}:g${level}:${path}:${lc.nextId()}`;
|
|
11402
11424
|
for (let k = start; k < units.length; k++) if (!units[k].block) {
|
|
11403
11425
|
units[k].block = id;
|
|
11404
11426
|
if (cont) units[k].blockOpen = true;
|
|
@@ -11415,12 +11437,12 @@ register("table", {
|
|
|
11415
11437
|
for (const c of kids?.get(x) || []) st.push(c);
|
|
11416
11438
|
}
|
|
11417
11439
|
};
|
|
11418
|
-
roots.forEach((bk, bi) =>
|
|
11440
|
+
roots.forEach((bk, bi) => node3(bk, bi, roots, 0, keyPath));
|
|
11419
11441
|
if (kids) {
|
|
11420
11442
|
const rest = buckets.filter((b) => !shown2.has(b));
|
|
11421
11443
|
if (rest.length) {
|
|
11422
|
-
lc.warn(`${item.name}: ${rest.length} rows of the group "${gname}" have no root (a cycle or too deep); they are listed at the top level`);
|
|
11423
|
-
rest.forEach((bk, bi) =>
|
|
11444
|
+
lc.warn(`${item.name || item.type}: ${rest.length} rows of the group "${gname}" have no root (a cycle or too deep); they are listed at the top level`);
|
|
11445
|
+
rest.forEach((bk, bi) => node3(bk, bi, rest, 0, keyPath));
|
|
11424
11446
|
}
|
|
11425
11447
|
}
|
|
11426
11448
|
};
|
|
@@ -11447,7 +11469,7 @@ register("table", {
|
|
|
11447
11469
|
units[units.length - 1].breakAfter = true;
|
|
11448
11470
|
}
|
|
11449
11471
|
if (item.bookmark && units.length) {
|
|
11450
|
-
const b = evalSafe(item.bookmark, base, lc, `${item.name ||
|
|
11472
|
+
const b = evalSafe(item.bookmark, base, lc, `${item.name || item.type} bookmark`).v;
|
|
11451
11473
|
if (b != null && b !== "" && b !== "#Error") units[0].items.unshift({ t: "bookmark", label: String(b), x: item.x, y: 0, level: item.bookmarkLevel ?? 0 });
|
|
11452
11474
|
}
|
|
11453
11475
|
if (!lc.fixed) lc.regions?.push(region);
|
|
@@ -11542,7 +11564,7 @@ register("container", {
|
|
|
11542
11564
|
const ctx = lc.ctxFor(item);
|
|
11543
11565
|
if (hidden(item, ctx, lc)) return { height: 0, units: [] };
|
|
11544
11566
|
const res = lc.layoutItems(item.items, lc, { dx: item.x });
|
|
11545
|
-
return frame2(item, lc, ctx, res, item.keepTogether !== false ? `c:${item.name}:${lc.nextId()}` : null);
|
|
11567
|
+
return frame2(item, lc, ctx, res, item.keepTogether !== false ? `c:${item.name || item.type}:${lc.nextId()}` : null);
|
|
11546
11568
|
}
|
|
11547
11569
|
});
|
|
11548
11570
|
function frame2(item, lc, ctx, res, blockId0) {
|
|
@@ -11599,7 +11621,7 @@ register("list", {
|
|
|
11599
11621
|
let rows = item.dataSet && lc.dataSets[item.dataSet] || [];
|
|
11600
11622
|
if (item.inheritRows && item.dataSet && ctx.current?.[item.dataSet]) rows = ctx.current[item.dataSet];
|
|
11601
11623
|
else rows = related(rows, ctx);
|
|
11602
|
-
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name}: the data set "${item.dataSet}" does not exist`);
|
|
11624
|
+
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name || item.type}: the data set "${item.dataSet}" does not exist`);
|
|
11603
11625
|
if (item.filters?.length) rows = applyFilters(rows, item.filters, ctx);
|
|
11604
11626
|
if (item.sort?.length) rows = applySort(rows, item.sort, ctx);
|
|
11605
11627
|
const reps = item.groupBy ? groupRows(rows, item.groupBy, ctx, lc, item.name, item.groupAdjacent === true).map((b) => b.rows) : rows.map((r) => [r]);
|
|
@@ -11628,7 +11650,7 @@ register("list", {
|
|
|
11628
11650
|
} };
|
|
11629
11651
|
const k = i % ncol;
|
|
11630
11652
|
const res = lc.layoutItems(item.items, child, { dx: item.x + k * (item.w + gap) });
|
|
11631
|
-
const fr = frame2({ ...item, x: item.x + k * (item.w + gap), name: `${item.name}[${i + 1}]` }, child, rctx, res, item.keepTogether !== false ? `l:${item.name}:${i}:${lc.nextId()}` : null);
|
|
11653
|
+
const fr = frame2({ ...item, x: item.x + k * (item.w + gap), name: `${item.name || item.type}[${i + 1}]` }, child, rctx, res, item.keepTogether !== false ? `l:${item.name || item.type}:${i}:${lc.nextId()}` : null);
|
|
11632
11654
|
if (ncol > 1) {
|
|
11633
11655
|
if (k === 0) {
|
|
11634
11656
|
cells = { top: y, height: 0, items: [], x0: item.x, x1: item.x + ncol * item.w + (ncol - 1) * gap, block: void 0 };
|
|
@@ -12099,7 +12121,7 @@ register("subreport", {
|
|
|
12099
12121
|
if (hidden(item, ctx, lc)) return { height: 0, units: [] };
|
|
12100
12122
|
const params = {};
|
|
12101
12123
|
for (const [k, v] of Object.entries(item.params || {})) {
|
|
12102
|
-
const r = evalSafe(v, ctx, lc, `${item.name} parameter ${k}`);
|
|
12124
|
+
const r = evalSafe(v, ctx, lc, `${item.name || item.type} parameter ${k}`);
|
|
12103
12125
|
params[k] = r.v instanceof Date ? isoDate(r.v, ctx.timeZone) : r.v;
|
|
12104
12126
|
}
|
|
12105
12127
|
const key = `${item.report}|${JSON.stringify(params)}`;
|
|
@@ -12118,10 +12140,10 @@ register("subreport", {
|
|
|
12118
12140
|
const res = sub.results.get(key);
|
|
12119
12141
|
if (!res) return placeholder(`Subreport "${item.report}" did not load`);
|
|
12120
12142
|
if (res.error) {
|
|
12121
|
-
lc.warn(`${item.name}: ${res.error}`);
|
|
12143
|
+
lc.warn(`${item.name || item.type}: ${res.error}`);
|
|
12122
12144
|
return placeholder(`Subreport "${item.report}": ${res.error}`);
|
|
12123
12145
|
}
|
|
12124
|
-
const block = item.keepTogether ? `s:${item.name}:${lc.nextId()}` : void 0;
|
|
12146
|
+
const block = item.keepTogether ? `s:${item.name || item.type}:${lc.nextId()}` : void 0;
|
|
12125
12147
|
const units = res.units.map((u) => ({ ...u, items: shiftItems(u.items, item.x, 0), ...u.cont ? { cont: shiftItems(u.cont, item.x, 0) } : {}, x0: (u.x0 ?? 0) + item.x, x1: (u.x1 ?? item.w) + item.x, block: u.block || block, tableId: void 0 }));
|
|
12126
12148
|
const tables = res.tables.map((t) => ({ ...t, x0: t.x0 + item.x, x1: t.x1 + item.x, headerItems: shiftItems(t.headerItems, item.x, 0), id: `sub${lc.nextId()}` }));
|
|
12127
12149
|
for (const r of res.regions || []) lc.regions?.push(r);
|
|
@@ -15136,6 +15158,7 @@ var SCHEMA_ALIAS = "reportwright/report@1";
|
|
|
15136
15158
|
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\
|
|
15137
15159
|
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\
|
|
15138
15160
|
ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description".split(" "));
|
|
15161
|
+
var NO_SERIES_CHARTS = /* @__PURE__ */ new Set(["gantt"]);
|
|
15139
15162
|
function looksLikeLink(it) {
|
|
15140
15163
|
if (it.type !== "textbox" || it.action && it.action.type && it.action.type !== "none") return false;
|
|
15141
15164
|
const st = it.style && typeof it.style === "object" ? it.style : {};
|
|
@@ -15264,6 +15287,9 @@ function validate(def) {
|
|
|
15264
15287
|
if (p?.hidden && p.required && (p.default == null || p.default === "") && !p.nullable) {
|
|
15265
15288
|
warnings.push(`Parameter "${p.name}" is hidden and required but has no default: only a URL, the API or a drill-through can set it`);
|
|
15266
15289
|
}
|
|
15290
|
+
if (p?.required && p.nullable && !p.multi && (p.default == null || p.default === "")) {
|
|
15291
|
+
warnings.push(`Parameter "${p.name}" is required and nullable with no default: when no value is given it is null and the report can draw blank; give it a default, or drop "nullable" to require a value`);
|
|
15292
|
+
}
|
|
15267
15293
|
if (p?.type === "date" && typeof p.default === "string" && p.default.trim() && !p.default.startsWith("=") && !toDate(p.default)) {
|
|
15268
15294
|
warnings.push(`Parameter "${p.name}": its default "${p.default}" is not a date; write it as 2026-12-31 (year-month-day)`);
|
|
15269
15295
|
}
|
|
@@ -15344,7 +15370,7 @@ function validate(def) {
|
|
|
15344
15370
|
warnings.push(`${label}: there is no named style "${it.styleName}"${g ? ` (did you mean "${g}"?)` : ""}; it is ignored`);
|
|
15345
15371
|
}
|
|
15346
15372
|
if (Array.isArray(it.sort)) sortIssues(it.sort, label, warnings);
|
|
15347
|
-
if (it.type === "chart" && Array.isArray(it.series) &&
|
|
15373
|
+
if (it.type === "chart" && !NO_SERIES_CHARTS.has(it.chartType) && !(Array.isArray(it.series) && it.series.length)) warnings.push(`${label}: the chart has no series, so it plots a count of its rows; add one, e.g. series: [{ "name": "Value", "value": "=Sum(Fields.Amount)" }]`);
|
|
15348
15374
|
if (it.type === "image" && typeof it.src === "string" && !it.src.startsWith("=") && LOCAL_IMAGE.test(it.src.trim())) warnings.push(`${label}: "${it.src}" is a local file path, which a browser cannot load; embed the image (images: { name: "data:image/png;base64,..." } and src: "embedded:name") or use an https:// address`);
|
|
15349
15375
|
if (it.style != null && (typeof it.style !== "object" || Array.isArray(it.style))) warnings.push(`${label}: "style" must be an object of style properties, such as { "fontWeight": "bold" }; ${JSON.stringify(it.style).slice(0, 40)} is ignored`);
|
|
15350
15376
|
const own = ownKeys(it.type);
|
|
@@ -15387,6 +15413,9 @@ function validate(def) {
|
|
|
15387
15413
|
const n5 = Array.isArray(it.columns) ? it.columns.length : 0;
|
|
15388
15414
|
const rowsOf = [["header", it.header], ["detail", it.detail], ["footer", it.footer], ...(it.groups || []).flatMap((g, gi) => [[`group ${gi + 1} header`, g?.header], [`group ${gi + 1} footer`, g?.footer]])];
|
|
15389
15415
|
for (const [part2, rows] of rowsOf) (Array.isArray(rows) ? rows : []).forEach((row, ri) => {
|
|
15416
|
+
const cells = Array.isArray(row?.cells) ? row.cells : [];
|
|
15417
|
+
const placed = cells.length < n5 && cells.some((c) => Number(c?.colSpan) > 1) ? cells.reduce((s, c) => s + Math.max(1, Math.floor(Number(c?.colSpan)) || 1), 0) : cells.length;
|
|
15418
|
+
if (placed < n5) warnings.push(`${label} ${part2} row ${ri + 1}: the row has ${placed} of ${n5} cells and no colSpan covers the other ${n5 - placed}; add the cells or a colSpan`);
|
|
15390
15419
|
for (const [k, j] of rowCells(row?.cells, n5).covered) warnings.push(`${label} ${part2} row ${ri + 1}: cell ${k} is covered by colSpan of cell ${j}, so it is not drawn (leave it null, or omit the spanned cells: a row with fewer cells than columns places each cell after the previous one's span)`);
|
|
15391
15420
|
});
|
|
15392
15421
|
}
|
|
@@ -15801,7 +15830,7 @@ function* textsOf(def, dataSets) {
|
|
|
15801
15830
|
}
|
|
15802
15831
|
}
|
|
15803
15832
|
}
|
|
15804
|
-
var NO_CJK_FONTS = "Text in Japanese/Chinese/Korean needs the optional CJK fonts: npm run fonts:cjk";
|
|
15833
|
+
var NO_CJK_FONTS = "Text in Japanese/Chinese/Korean needs the optional CJK fonts: npm i @reportwright/fonts-cjk, then npx reportwright-fonts-cjk (npm); in the app, npm run fonts:cjk";
|
|
15805
15834
|
async function render(def0, opts = {}) {
|
|
15806
15835
|
const t0 = Date.now();
|
|
15807
15836
|
const reuseWarnings = [];
|
|
@@ -15872,6 +15901,7 @@ async function render(def0, opts = {}) {
|
|
|
15872
15901
|
const base = { ...BASE_STYLE, ...def.styles?.base || {} };
|
|
15873
15902
|
let idSeq = 0;
|
|
15874
15903
|
const regions = [];
|
|
15904
|
+
const tablesSeen = { n: 0 };
|
|
15875
15905
|
const imageBudget = opts.imageBudget || { seen: /* @__PURE__ */ new Set(), bytes: 0 };
|
|
15876
15906
|
const makeLc = (globals, fixed2) => {
|
|
15877
15907
|
const lc = {
|
|
@@ -15882,6 +15912,7 @@ async function render(def0, opts = {}) {
|
|
|
15882
15912
|
fixed: fixed2,
|
|
15883
15913
|
maxUnitHeight: contentH,
|
|
15884
15914
|
state: opts.state || {},
|
|
15915
|
+
tablesSeen,
|
|
15885
15916
|
regions: opts.exportData || opts.dataOnly ? regions : null,
|
|
15886
15917
|
dataOnly: !!opts.dataOnly,
|
|
15887
15918
|
// exportData: true: table data and cell tags (Excel, CSV, Word, HTML, accessible PDF)
|
|
@@ -15999,8 +16030,8 @@ async function render(def0, opts = {}) {
|
|
|
15999
16030
|
u.breakBefore = false;
|
|
16000
16031
|
u.breakAfter = false;
|
|
16001
16032
|
}
|
|
16002
|
-
const
|
|
16003
|
-
parts2.push({ body, slices, g });
|
|
16033
|
+
const slices2 = paginate(body.units, body.tables, g.cH, warn);
|
|
16034
|
+
parts2.push({ body, slices: slices2, g });
|
|
16004
16035
|
if (lc.rowBudget?.cut) break sections;
|
|
16005
16036
|
if (!overflow.more) break;
|
|
16006
16037
|
if (rep + 1 >= REUSE_LIMITS.repeats) {
|
|
@@ -16041,7 +16072,7 @@ async function render(def0, opts = {}) {
|
|
|
16041
16072
|
const headings = [];
|
|
16042
16073
|
const pages2 = [];
|
|
16043
16074
|
list.forEach(({ part: part2, k, last }, n5) => {
|
|
16044
|
-
const { body, slices, g } = part2;
|
|
16075
|
+
const { body, slices: slices2, g } = part2;
|
|
16045
16076
|
const { pg, colCount, colW, colGap, cH } = g;
|
|
16046
16077
|
const ph = parts2.length === 1 ? pageH : pg.height;
|
|
16047
16078
|
const ml = pg.margins.left, mt = pg.margins.top;
|
|
@@ -16079,7 +16110,7 @@ async function render(def0, opts = {}) {
|
|
|
16079
16110
|
band(g.hdr, mt, g.own.h ? k === 0 : isFirst, g.own.h ? last : isLast);
|
|
16080
16111
|
const frozen = [];
|
|
16081
16112
|
for (let c = 0; c < colCount; c++) {
|
|
16082
|
-
const p =
|
|
16113
|
+
const p = slices2[k * colCount + c];
|
|
16083
16114
|
if (!p) break;
|
|
16084
16115
|
const cx = ml + c * (colW + colGap);
|
|
16085
16116
|
for (const t of p.repeat) placeItems(t.headerItems, cx, bodyTop, items);
|
|
@@ -16111,7 +16142,7 @@ async function render(def0, opts = {}) {
|
|
|
16111
16142
|
items.length = j;
|
|
16112
16143
|
const out = frozen.length ? { items, frozen } : { items };
|
|
16113
16144
|
if (win) {
|
|
16114
|
-
const u =
|
|
16145
|
+
const u = slices2[k * colCount]?.units[0];
|
|
16115
16146
|
if (u?.dataRow != null) {
|
|
16116
16147
|
out.firstRow = u.dataRow;
|
|
16117
16148
|
out.rowHead = !!u.rowHead;
|
|
@@ -16185,7 +16216,7 @@ async function render(def0, opts = {}) {
|
|
|
16185
16216
|
if (m.noGlyph.size) {
|
|
16186
16217
|
const cjk2 = [...m.noGlyph].some((c) => /[\u1100-\u11ff\u2600-\u27bf\u2b00-\u2bff\u3000-\u9fff\uac00-\ud7af\uf900-\ufaff\uff00-\uffef]|[\u{1f000}-\u{1faff}]/u.test(c));
|
|
16187
16218
|
const list = [...m.noGlyph].slice(0, 20).join(" ");
|
|
16188
|
-
warn(cjk2 ? `${NO_CJK_FONTS}
|
|
16219
|
+
warn(cjk2 ? `${NO_CJK_FONTS}. Until then these characters show as boxes: ${list}.` : `No font has these characters, so they show as boxes: ${list}. Upload a font that has them and use it for this text.`);
|
|
16189
16220
|
}
|
|
16190
16221
|
if (opts.bodyOnly) return { units: result.body.units, tables: result.body.tables, height: result.body.height, regions, warnings, clipped: clipped() };
|
|
16191
16222
|
if (opts.dataOnly) return {
|
|
@@ -16225,6 +16256,7 @@ async function render(def0, opts = {}) {
|
|
|
16225
16256
|
headings: result.headings || [],
|
|
16226
16257
|
pageStarts: result.pageStarts || [],
|
|
16227
16258
|
regions: opts.exportData ? regions : null,
|
|
16259
|
+
hasTables: tablesSeen.n > 0,
|
|
16228
16260
|
name: def.name || "",
|
|
16229
16261
|
partial: cutRows(),
|
|
16230
16262
|
timeZone: timeZone || null,
|
|
@@ -16361,7 +16393,8 @@ async function parameterOptions(def, given = {}, opts = {}) {
|
|
|
16361
16393
|
seen.add(k);
|
|
16362
16394
|
list.push({ value: v instanceof Date ? isoDate(v) : v, label: String(p.optionsFrom.label ? evalValue(p.optionsFrom.label, c) : v) });
|
|
16363
16395
|
}
|
|
16364
|
-
out[p.name] =
|
|
16396
|
+
const fixed2 = out[p.name] || [], have = new Set(fixed2.map((o) => o.value));
|
|
16397
|
+
out[p.name] = [...fixed2, ...list.filter((o) => !have.has(o.value))];
|
|
16365
16398
|
}
|
|
16366
16399
|
return out;
|
|
16367
16400
|
}
|
|
@@ -17079,7 +17112,7 @@ function pathBox(d) {
|
|
|
17079
17112
|
}
|
|
17080
17113
|
return x0 === Infinity ? null : { x0, y0, x1, y1 };
|
|
17081
17114
|
}
|
|
17082
|
-
function arcExtremes(x1, y1, rx, ry, phi, large,
|
|
17115
|
+
function arcExtremes(x1, y1, rx, ry, phi, large, sweep2, x2, y2) {
|
|
17083
17116
|
rx = Math.abs(rx);
|
|
17084
17117
|
ry = Math.abs(ry);
|
|
17085
17118
|
if (!rx || !ry || x1 === x2 && y1 === y2) return [];
|
|
@@ -17092,7 +17125,7 @@ function arcExtremes(x1, y1, rx, ry, phi, large, sweep, x2, y2) {
|
|
|
17092
17125
|
ry *= Math.sqrt(lam);
|
|
17093
17126
|
}
|
|
17094
17127
|
const num6 = rx * rx * ry * ry - rx * rx * y1p * y1p - ry * ry * x1p * x1p;
|
|
17095
|
-
const k = (large !==
|
|
17128
|
+
const k = (large !== sweep2 ? 1 : -1) * Math.sqrt(Math.max(0, num6 / (rx * rx * y1p * y1p + ry * ry * x1p * x1p)));
|
|
17096
17129
|
const cxp = k * rx * y1p / ry, cyp = -k * ry * x1p / rx;
|
|
17097
17130
|
const cx = cf * cxp - sf * cyp + (x1 + x2) / 2, cy = sf * cxp + cf * cyp + (y1 + y2) / 2;
|
|
17098
17131
|
if (Math.abs(sf) > 1e-9) {
|
|
@@ -17102,8 +17135,8 @@ function arcExtremes(x1, y1, rx, ry, phi, large, sweep, x2, y2) {
|
|
|
17102
17135
|
const ang = (ux, uy) => Math.atan2(uy, ux);
|
|
17103
17136
|
const t1 = ang((x1p - cxp) / rx, (y1p - cyp) / ry);
|
|
17104
17137
|
let dt2 = ang((-x1p - cxp) / rx, (-y1p - cyp) / ry) - t1;
|
|
17105
|
-
if (
|
|
17106
|
-
else if (!
|
|
17138
|
+
if (sweep2 && dt2 < 0) dt2 += 2 * Math.PI;
|
|
17139
|
+
else if (!sweep2 && dt2 > 0) dt2 -= 2 * Math.PI;
|
|
17107
17140
|
const out = [];
|
|
17108
17141
|
for (let q2 = -4; q2 <= 4; q2++) {
|
|
17109
17142
|
const t = q2 * Math.PI / 2, rel2 = dt2 >= 0 ? t - t1 : t1 - t;
|
|
@@ -17318,7 +17351,7 @@ function cellVisuals(items, used, tables) {
|
|
|
17318
17351
|
|
|
17319
17352
|
// src/exporters/regions.js
|
|
17320
17353
|
function needsTableData(model, what) {
|
|
17321
|
-
if (model && model.regions === null) throw Object.assign(new Error(`${what} needs the report's table data: render it with { exportData: true }`), { code: "NO_EXPORT_DATA" });
|
|
17354
|
+
if (model && model.regions === null && model.hasTables !== false) throw Object.assign(new Error(`${what} needs the report's table data: render it with { exportData: true }`), { code: "NO_EXPORT_DATA" });
|
|
17322
17355
|
}
|
|
17323
17356
|
var needsExportData = (fmt2, o = {}) => ["xlsx", "csv", "docx", "pptx", "html", "json"].includes(fmt2) || fmt2 === "pdf" && !!(o.pdfua || o.ua || o.tagged);
|
|
17324
17357
|
function mergedRegions(model) {
|
|
@@ -17770,6 +17803,10 @@ var n4 = (v) => Math.round(v * 1e4) / 1e4;
|
|
|
17770
17803
|
var hex4 = (id) => id.toString(16).padStart(4, "0");
|
|
17771
17804
|
var KAPPA = 4 * ((Math.SQRT2 - 1) / 3);
|
|
17772
17805
|
var cleanText = (t) => t.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
|
|
17806
|
+
var formatAt = (run, cl) => {
|
|
17807
|
+
const cp = run.text.codePointAt(cl);
|
|
17808
|
+
return cp !== void 0 && FORMAT_CHAR.test(String.fromCodePoint(cp));
|
|
17809
|
+
};
|
|
17773
17810
|
function drawRun(c, run, x, y, size, pf, color2, spans2, texts) {
|
|
17774
17811
|
const f4 = pf.embedder.font;
|
|
17775
17812
|
const per = 1e3 / size;
|
|
@@ -17822,7 +17859,7 @@ function drawRun(c, run, x, y, size, pf, color2, spans2, texts) {
|
|
|
17822
17859
|
rise = gy;
|
|
17823
17860
|
}
|
|
17824
17861
|
const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
|
|
17825
|
-
if (id === 0 && c.tagged) pen = gx;
|
|
17862
|
+
if (id === 0 && (c.tagged || formatAt(run, cl))) pen = gx;
|
|
17826
17863
|
else {
|
|
17827
17864
|
arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
|
|
17828
17865
|
pen = gx + adv(id) * size / f4.unitsPerEm;
|
|
@@ -17881,6 +17918,7 @@ var Content = class {
|
|
|
17881
17918
|
this.saved = [];
|
|
17882
17919
|
this.lines = null;
|
|
17883
17920
|
this.tagged = false;
|
|
17921
|
+
this.artLines = false;
|
|
17884
17922
|
}
|
|
17885
17923
|
/**
|
|
17886
17924
|
* The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
|
|
@@ -17899,7 +17937,7 @@ var Content = class {
|
|
|
17899
17937
|
* ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
|
|
17900
17938
|
*/
|
|
17901
17939
|
line(stroke, w, dash, x1, y1, x2, y2) {
|
|
17902
|
-
if (this.tagged) {
|
|
17940
|
+
if (this.tagged && !this.artLines) {
|
|
17903
17941
|
this.paint(null, stroke, w, dash);
|
|
17904
17942
|
this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
|
|
17905
17943
|
`;
|
|
@@ -17919,6 +17957,8 @@ var Content = class {
|
|
|
17919
17957
|
if (!L) return;
|
|
17920
17958
|
this.lines = null;
|
|
17921
17959
|
this.et();
|
|
17960
|
+
const end = this.artLines ? "EMC\n" : "";
|
|
17961
|
+
if (end) this._s += "/Artifact BMC\n";
|
|
17922
17962
|
this.paint(null, L.stroke, L.w, L.dash);
|
|
17923
17963
|
const g = L.segs;
|
|
17924
17964
|
const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
|
|
@@ -17927,10 +17967,10 @@ var Content = class {
|
|
|
17927
17967
|
`;
|
|
17928
17968
|
this._s += `q
|
|
17929
17969
|
${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
|
|
17930
|
-
`;
|
|
17970
|
+
${end}`;
|
|
17931
17971
|
return;
|
|
17932
17972
|
}
|
|
17933
|
-
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
|
|
17973
|
+
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n" + end;
|
|
17934
17974
|
}
|
|
17935
17975
|
q() {
|
|
17936
17976
|
this.et();
|
|
@@ -18636,9 +18676,9 @@ function addOutline(doc, bookmarks, dest) {
|
|
|
18636
18676
|
if (!Dest) continue;
|
|
18637
18677
|
const level = Math.max(0, Math.min(9, Number(b.level) || 0));
|
|
18638
18678
|
while (stack2[stack2.length - 1].level >= level) stack2.pop();
|
|
18639
|
-
const
|
|
18640
|
-
stack2[stack2.length - 1].kids.push(
|
|
18641
|
-
stack2.push(
|
|
18679
|
+
const node3 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString5.fromText(b.label), Dest };
|
|
18680
|
+
stack2[stack2.length - 1].kids.push(node3);
|
|
18681
|
+
stack2.push(node3);
|
|
18642
18682
|
}
|
|
18643
18683
|
if (!root.kids.length) return;
|
|
18644
18684
|
const count = (n5) => n5.kids.reduce((s, k) => s + 1 + count(k), 0);
|
|
@@ -18716,6 +18756,7 @@ function createSubsetter(loadWasm) {
|
|
|
18716
18756
|
for (const g of opt.glyphs) x.hb_set_add(gs, g);
|
|
18717
18757
|
}
|
|
18718
18758
|
x.hb_subset_input_pin_all_axes_to_default(input, face);
|
|
18759
|
+
x.hb_subset_input_pin_axis_location(input, face, tag3("wght"), opt.weight ?? 400);
|
|
18719
18760
|
const sub = x.hb_subset_or_fail(face, input);
|
|
18720
18761
|
if (!sub) throw new Error("HarfBuzz: subsetting failed");
|
|
18721
18762
|
const res = x.hb_face_reference_blob(sub);
|
|
@@ -18735,6 +18776,7 @@ function createSubsetter(loadWasm) {
|
|
|
18735
18776
|
}
|
|
18736
18777
|
|
|
18737
18778
|
// src/exporters/htmldata.js
|
|
18779
|
+
var dateKey = (d, tz) => tz ? toWall(d, tz) : Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
|
|
18738
18780
|
var MAX_DATA_ROWS = 2e4;
|
|
18739
18781
|
var DATA_STRINGS = { pages: "Pages", tables: "Tables", all: "All", filter: "Filter", toggle: "Show or hide the rows of this group", sortAsc: "Sort ascending", sortDesc: "Sort descending" };
|
|
18740
18782
|
function tablesData(model, o = {}) {
|
|
@@ -18757,7 +18799,7 @@ function tablesData(model, o = {}) {
|
|
|
18757
18799
|
rows: r.rows.map((row) => ({
|
|
18758
18800
|
k: row.kind,
|
|
18759
18801
|
l: row.level || 0,
|
|
18760
|
-
c: row.cells.filter((c) => c.colIndex >= 0).map((c) => [c.colIndex, String(show(c) ?? ""), c.value instanceof Date ? c.value.
|
|
18802
|
+
c: row.cells.filter((c) => c.colIndex >= 0).map((c) => [c.colIndex, String(show(c) ?? ""), c.value instanceof Date ? dateKey(c.value, model.timeZone || void 0) : typeof c.value === "number" ? c.value : String(c.value ?? "").toLowerCase(), c.span || 1])
|
|
18761
18803
|
}))
|
|
18762
18804
|
}));
|
|
18763
18805
|
}
|
|
@@ -18889,13 +18931,29 @@ async function cspHash(text2) {
|
|
|
18889
18931
|
}
|
|
18890
18932
|
|
|
18891
18933
|
// src/exporters/html.js
|
|
18892
|
-
function exportHtml(model,
|
|
18934
|
+
function exportHtml(model, options, legacyOpt) {
|
|
18935
|
+
const isStore = (x) => !!x && typeof x.load === "function" && typeof x.get === "function" && x.bytes instanceof Map;
|
|
18936
|
+
let fontStore, opt;
|
|
18937
|
+
if (isStore(options)) {
|
|
18938
|
+
if (!warnedLegacy) {
|
|
18939
|
+
warnedLegacy = true;
|
|
18940
|
+
console.warn("[reportwright] DEPRECATED: exportHtml(model, fontStore, options) is replaced by exportHtml(model, { fonts: fontStore, ...options }); the old form is removed in 0.9");
|
|
18941
|
+
}
|
|
18942
|
+
fontStore = options;
|
|
18943
|
+
opt = legacyOpt || {};
|
|
18944
|
+
} else {
|
|
18945
|
+
opt = /** @type {any} */
|
|
18946
|
+
options || {};
|
|
18947
|
+
fontStore = opt.fonts || opt.fontStore;
|
|
18948
|
+
if (!isStore(fontStore)) throw new TypeError("exportHtml(model, { fonts }): fonts must be a FontStore (defaultFontStore() or new FontStore(loader)), got " + (fontStore === void 0 ? "nothing" : typeof fontStore));
|
|
18949
|
+
}
|
|
18893
18950
|
return withDeadline(
|
|
18894
18951
|
htmlOf(model, fontStore, opt),
|
|
18895
18952
|
/** @type {any} */
|
|
18896
18953
|
opt.timeoutMs
|
|
18897
18954
|
);
|
|
18898
18955
|
}
|
|
18956
|
+
var warnedLegacy = false;
|
|
18899
18957
|
async function htmlOf(model, fontStore, opt) {
|
|
18900
18958
|
const used = /* @__PURE__ */ new Map();
|
|
18901
18959
|
const layout = /* @__PURE__ */ new Set();
|
|
@@ -19643,9 +19701,22 @@ async function xlsxOf(model, opt) {
|
|
|
19643
19701
|
}
|
|
19644
19702
|
|
|
19645
19703
|
// src/exporters/docx.js
|
|
19646
|
-
import {
|
|
19704
|
+
import { Zip, ZipDeflate, strToU8 as strToU83 } from "fflate";
|
|
19647
19705
|
var TW = 20;
|
|
19648
19706
|
var EMU = 12700;
|
|
19707
|
+
var XML_CHUNK = 4 * 1024 * 1024;
|
|
19708
|
+
function slices(s, max) {
|
|
19709
|
+
const out = [];
|
|
19710
|
+
let i = 0;
|
|
19711
|
+
while (s.length - i > max) {
|
|
19712
|
+
const j = s.indexOf(">", i + max);
|
|
19713
|
+
if (j < 0) break;
|
|
19714
|
+
out.push(s.slice(i, j + 1));
|
|
19715
|
+
i = j + 1;
|
|
19716
|
+
}
|
|
19717
|
+
out.push(s.slice(i));
|
|
19718
|
+
return out;
|
|
19719
|
+
}
|
|
19649
19720
|
var esc3 = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
19650
19721
|
var hex5 = (c) => {
|
|
19651
19722
|
const m = /^#?([0-9a-f]{6})$/i.exec(String(c || "").trim());
|
|
@@ -19789,9 +19860,9 @@ async function docxOf(model, opt) {
|
|
|
19789
19860
|
const margin = 18;
|
|
19790
19861
|
const media = [];
|
|
19791
19862
|
let docPr = 0;
|
|
19792
|
-
const addMedia = (
|
|
19863
|
+
const addMedia = (bytes2, ext) => {
|
|
19793
19864
|
const rid = `rIdm${media.length + 1}`;
|
|
19794
|
-
media.push({ name: `image${media.length + 1}.${ext}`, bytes, rid });
|
|
19865
|
+
media.push({ name: `image${media.length + 1}.${ext}`, bytes: bytes2, rid });
|
|
19795
19866
|
return rid;
|
|
19796
19867
|
};
|
|
19797
19868
|
const pictureRun = (pic, alt) => {
|
|
@@ -19855,7 +19926,7 @@ async function docxOf(model, opt) {
|
|
|
19855
19926
|
}
|
|
19856
19927
|
for (const f4 of figs) if (!f4.used) blocks.push({ kind: "fig", y: f4.box.y, x: f4.box.x, fig: f4 });
|
|
19857
19928
|
blocks.sort((a, b) => a.y - b.y || a.x - b.x);
|
|
19858
|
-
let
|
|
19929
|
+
let xml2 = "";
|
|
19859
19930
|
for (let bi = 0; bi < blocks.length; bi++) {
|
|
19860
19931
|
const b = blocks[bi];
|
|
19861
19932
|
if (b.kind === "fig") {
|
|
@@ -19870,7 +19941,7 @@ async function docxOf(model, opt) {
|
|
|
19870
19941
|
right = pic.x + pic.w;
|
|
19871
19942
|
}
|
|
19872
19943
|
const first = row[0];
|
|
19873
|
-
|
|
19944
|
+
xml2 += `<w:p><w:pPr><w:spacing w:before="0" w:after="80"/>${Math.abs(first.x - margin) > 0.5 ? `<w:ind w:left="${Math.round(Math.max(-margin, first.x - margin) * TW)}"/>` : ""}</w:pPr>${runs}</w:p>`;
|
|
19874
19945
|
} else if (b.kind === "table") {
|
|
19875
19946
|
const pics = /* @__PURE__ */ new Map();
|
|
19876
19947
|
for (const [k, v] of visuals.get(b.key) || []) {
|
|
@@ -19878,19 +19949,19 @@ async function docxOf(model, opt) {
|
|
|
19878
19949
|
const svg = figureSvg({ items: v.items, box: v.box }, opt.fontStore);
|
|
19879
19950
|
pics.set(k, pictureRun({ svg, png: await rasterize(svg, v.box.w, v.box.h, picOpt), w: v.box.w, h: v.box.h }, "Chart in a table cell"));
|
|
19880
19951
|
}
|
|
19881
|
-
|
|
19882
|
-
} else if (b.kind === "rich")
|
|
19952
|
+
xml2 += table(b.cells, b.x - margin, pics);
|
|
19953
|
+
} else if (b.kind === "rich") xml2 += richPara(b.items, b.x - margin);
|
|
19883
19954
|
else {
|
|
19884
19955
|
const row = [b];
|
|
19885
19956
|
const top = (t) => t.it.clip?.y ?? t.y - t.it.size;
|
|
19886
19957
|
while (blocks[bi + 1]?.kind === "text" && Math.abs(top(blocks[bi + 1]) - top(b)) < 3 && blocks[bi + 1].it.clip && b.it.clip) row.push(blocks[++bi]);
|
|
19887
19958
|
row.sort((p, q2) => p.it.clip.x - q2.it.clip.x);
|
|
19888
19959
|
const apart = row.every((r, k) => k === 0 || r.it.clip.x >= row[k - 1].it.clip.x + row[k - 1].it.clip.w - 0.5);
|
|
19889
|
-
if (row.length > 1 && apart)
|
|
19890
|
-
else for (const r of row)
|
|
19960
|
+
if (row.length > 1 && apart) xml2 += layoutRow(row, margin);
|
|
19961
|
+
else for (const r of row) xml2 += para(r.it, (r.it.clip?.x ?? r.x) - margin, r.decor);
|
|
19891
19962
|
}
|
|
19892
19963
|
}
|
|
19893
|
-
body.push(
|
|
19964
|
+
body.push(xml2);
|
|
19894
19965
|
}
|
|
19895
19966
|
const M = margin * TW, V = 36 * TW;
|
|
19896
19967
|
const sectPr = (pg) => {
|
|
@@ -19898,17 +19969,39 @@ async function docxOf(model, opt) {
|
|
|
19898
19969
|
return `<w:sectPr><w:pgSz w:w="${W2}" w:h="${H}"${W2 > H ? ' w:orient="landscape"' : ""}/><w:pgMar w:top="${V}" w:right="${M}" w:bottom="${V}" w:left="${M}" w:header="0" w:footer="0" w:gutter="0"/></w:sectPr>`;
|
|
19899
19970
|
};
|
|
19900
19971
|
const sizeOf = (pg) => `${pg.width ?? model.width}x${pg.height ?? model.height}`;
|
|
19901
|
-
|
|
19972
|
+
const zipOut = [];
|
|
19973
|
+
const zip = new Zip((err, data) => {
|
|
19974
|
+
if (err) throw err;
|
|
19975
|
+
zipOut.push(data);
|
|
19976
|
+
});
|
|
19977
|
+
const put = (name, bytes2) => {
|
|
19978
|
+
const e2 = new ZipDeflate(name, { level: 6 });
|
|
19979
|
+
zip.add(e2);
|
|
19980
|
+
e2.push(bytes2, true);
|
|
19981
|
+
};
|
|
19982
|
+
const parts = [];
|
|
19983
|
+
const max = opt.xmlChunk || XML_CHUNK;
|
|
19984
|
+
let buf = "";
|
|
19985
|
+
const write = (str) => {
|
|
19986
|
+
for (const p of slices(str, max)) {
|
|
19987
|
+
if (buf.length + p.length > max) {
|
|
19988
|
+
parts.push(buf);
|
|
19989
|
+
buf = "";
|
|
19990
|
+
}
|
|
19991
|
+
buf += p;
|
|
19992
|
+
}
|
|
19993
|
+
};
|
|
19994
|
+
write(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
19995
|
+
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><w:body>`);
|
|
19902
19996
|
model.pages.forEach((pg, i) => {
|
|
19903
|
-
|
|
19997
|
+
write(body[i]);
|
|
19904
19998
|
const next = model.pages[i + 1];
|
|
19905
19999
|
if (!next) return;
|
|
19906
|
-
|
|
20000
|
+
write(sizeOf(next) !== sizeOf(pg) ? `<w:p><w:pPr>${sectPr(pg)}</w:pPr></w:p>` : '<w:p><w:pPr><w:pageBreakBefore/><w:spacing w:before="0" w:after="0" w:line="20" w:lineRule="exact"/><w:rPr><w:sz w:val="2"/></w:rPr></w:pPr></w:p>');
|
|
19907
20001
|
});
|
|
19908
20002
|
const last = model.pages[model.pages.length - 1] || {};
|
|
19909
|
-
|
|
19910
|
-
|
|
19911
|
-
last)}</w:body></w:document>`;
|
|
20003
|
+
write(`${sectPr(last)}</w:body></w:document>`);
|
|
20004
|
+
parts.push(buf);
|
|
19912
20005
|
const lang = `<w:lang w:val="${esc3(opt.lang || model.locale || "en-US")}"/>`;
|
|
19913
20006
|
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("");
|
|
19914
20007
|
const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
@@ -19918,24 +20011,32 @@ name w:val="Normal"/></w:style>${headings}</w:styles>`;
|
|
|
19918
20011
|
const core = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
19919
20012
|
<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>${esc3(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc3(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=\
|
|
19920
20013
|
"dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
|
|
19921
|
-
|
|
19922
|
-
"[Content_Types].xml": strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
20014
|
+
put("[Content_Types].xml", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
19923
20015
|
<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\
|
|
19924
|
-
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>`)
|
|
19925
|
-
|
|
19926
|
-
<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>`)
|
|
19927
|
-
|
|
19928
|
-
<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>`)
|
|
19929
|
-
|
|
19930
|
-
|
|
19931
|
-
|
|
19932
|
-
|
|
19933
|
-
|
|
19934
|
-
|
|
20016
|
+
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>`));
|
|
20017
|
+
put("_rels/.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
20018
|
+
<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>`));
|
|
20019
|
+
put("word/_rels/document.xml.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
20020
|
+
<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>`));
|
|
20021
|
+
const doc = new ZipDeflate("word/document.xml", { level: 6 });
|
|
20022
|
+
zip.add(doc);
|
|
20023
|
+
for (const p of parts) doc.push(strToU83(p), false);
|
|
20024
|
+
doc.push(new Uint8Array(0), true);
|
|
20025
|
+
put("word/styles.xml", strToU83(styles));
|
|
20026
|
+
put("docProps/core.xml", strToU83(core));
|
|
20027
|
+
for (const m of media) put(`word/media/${m.name}`, m.bytes);
|
|
20028
|
+
zip.end();
|
|
20029
|
+
const total = zipOut.reduce((n5, c) => n5 + c.length, 0), bytes = new Uint8Array(total);
|
|
20030
|
+
let at = 0;
|
|
20031
|
+
for (const c of zipOut) {
|
|
20032
|
+
bytes.set(c, at);
|
|
20033
|
+
at += c.length;
|
|
20034
|
+
}
|
|
20035
|
+
return bytes;
|
|
19935
20036
|
}
|
|
19936
20037
|
|
|
19937
20038
|
// src/exporters/pptx.js
|
|
19938
|
-
import { zipSync as
|
|
20039
|
+
import { zipSync as zipSync3, strToU8 as strToU84 } from "fflate";
|
|
19939
20040
|
var EMU2 = 12700;
|
|
19940
20041
|
var e = (v) => Math.round(v * EMU2);
|
|
19941
20042
|
var esc4 = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f]/g, "");
|
|
@@ -20118,7 +20219,7 @@ rops/core.xml"/></Relationships>`);
|
|
|
20118
20219
|
="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\
|
|
20119
20220
|
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\
|
|
20120
20221
|
ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
|
|
20121
|
-
return
|
|
20222
|
+
return zipSync3(files, { level: 6 });
|
|
20122
20223
|
}
|
|
20123
20224
|
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\
|
|
20124
20225
|
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\
|
|
@@ -20573,7 +20674,7 @@ async function planStream(def0, opts) {
|
|
|
20573
20674
|
const f4 = fold && fold(row, ci);
|
|
20574
20675
|
v2 = f4 ? f4.v : evalValue(cell.value ?? "", ctx);
|
|
20575
20676
|
} catch (e2) {
|
|
20576
|
-
warn(`${item.name ||
|
|
20677
|
+
warn(`${item.name || item.type} cell: ${e2.message}`);
|
|
20577
20678
|
v2 = "#Error";
|
|
20578
20679
|
}
|
|
20579
20680
|
const plain2 = textOf(v2, st, ctx, lc);
|
|
@@ -20590,7 +20691,8 @@ async function planStream(def0, opts) {
|
|
|
20590
20691
|
return;
|
|
20591
20692
|
}
|
|
20592
20693
|
try {
|
|
20593
|
-
if (src.type === "json"
|
|
20694
|
+
if (src.type === "json" && typeof src.data === "string") yield* jsonRows(src.data, ds.path, { maxElementBytes: opts.maxJsonRowBytes ?? 8 * 1048576, maxWholeBytes: Infinity });
|
|
20695
|
+
else if (src.type === "json") yield* inBatches(listAt(src.data, ds.path));
|
|
20594
20696
|
else if (src.type === "csv" && src.data) yield* inBatches(parseCsv(src.data, src));
|
|
20595
20697
|
else if (src.type === "csv") {
|
|
20596
20698
|
const res = await sourceResponse(src, { params, globals: {}, dataSets: {}, fields: null, functions: functionTable(def) }, opts);
|
|
@@ -20611,6 +20713,21 @@ async function planStream(def0, opts) {
|
|
|
20611
20713
|
}
|
|
20612
20714
|
}
|
|
20613
20715
|
const plainOf = (fields) => fields.filter((fd) => !fd.expr);
|
|
20716
|
+
let seen = (
|
|
20717
|
+
/** @type {any[]|null} */
|
|
20718
|
+
null
|
|
20719
|
+
);
|
|
20720
|
+
const fieldList = async () => {
|
|
20721
|
+
if (ds.fields?.length) return ds.fields;
|
|
20722
|
+
const it = typed();
|
|
20723
|
+
try {
|
|
20724
|
+
await it.next();
|
|
20725
|
+
} finally {
|
|
20726
|
+
await it.return(void 0);
|
|
20727
|
+
stats.rows = 0;
|
|
20728
|
+
}
|
|
20729
|
+
return seen || [];
|
|
20730
|
+
};
|
|
20614
20731
|
async function* typed() {
|
|
20615
20732
|
let fields = ds.fields && ds.fields.length ? ds.fields : null;
|
|
20616
20733
|
let head = fields ? null : [];
|
|
@@ -20656,7 +20773,7 @@ async function planStream(def0, opts) {
|
|
|
20656
20773
|
return out;
|
|
20657
20774
|
};
|
|
20658
20775
|
const ready = (fs) => {
|
|
20659
|
-
fields = fs;
|
|
20776
|
+
fields = seen = fs;
|
|
20660
20777
|
plain2 = plainOf(fs);
|
|
20661
20778
|
calc = fs.filter((fd) => fd.expr);
|
|
20662
20779
|
fopts = new Map(fs.map((fd) => [fd, optFor(fd)]));
|
|
@@ -20684,23 +20801,44 @@ async function planStream(def0, opts) {
|
|
|
20684
20801
|
const tSort = item.sort || [], dSort = ds.sort || [];
|
|
20685
20802
|
const sorted = tSort.length || dSort.length;
|
|
20686
20803
|
const sorter = opts.sorter || memorySorter;
|
|
20687
|
-
|
|
20688
|
-
|
|
20804
|
+
const checked = (cmp) => {
|
|
20805
|
+
let prev = (
|
|
20806
|
+
/** @type {any} */
|
|
20807
|
+
null
|
|
20808
|
+
), n5 = 0;
|
|
20809
|
+
return (x) => {
|
|
20810
|
+
n5++;
|
|
20811
|
+
if (prev && cmp(prev, x) > 0) throw Object.assign(new Error(`The rows are not in the report's order (row ${n5} comes before the one above it, by the table's sort or its groups), so they cannot be read as presorted. Sort them at the source, or leave presorted off.`), { status: 400 });
|
|
20812
|
+
prev = x;
|
|
20813
|
+
};
|
|
20814
|
+
};
|
|
20815
|
+
const kc = { ...tctx }, dkc = { ...setCtx };
|
|
20816
|
+
const keyed = (r, s) => {
|
|
20817
|
+
kc.fields = r;
|
|
20818
|
+
dkc.fields = r;
|
|
20819
|
+
return { t: tSort.length ? sortKeys(tSort, kc) : null, d: dSort.length ? sortKeys(dSort, dkc) : null, s, r };
|
|
20820
|
+
};
|
|
20821
|
+
const keyCmp = (a, b) => tSort.length && compareKeys(a.t, b.t, tSort, tctx) || dSort.length && compareKeys(a.d, b.d, dSort, setCtx);
|
|
20822
|
+
async function* inOrder(grouped = false) {
|
|
20823
|
+
if (!sorted || grouped && opts.presorted) {
|
|
20689
20824
|
for await (const b of typed()) for (const r of b) yield r;
|
|
20690
20825
|
return;
|
|
20691
20826
|
}
|
|
20692
|
-
const
|
|
20693
|
-
const
|
|
20827
|
+
const cmp = (a, b) => keyCmp(a, b) || a.s - b.s;
|
|
20828
|
+
const check = opts.presorted ? checked(cmp) : null;
|
|
20829
|
+
const s = check ? null : sorter(cmp);
|
|
20694
20830
|
try {
|
|
20695
20831
|
let seq = 0;
|
|
20696
20832
|
for await (const b of typed()) for (const r of b) {
|
|
20697
|
-
|
|
20698
|
-
|
|
20699
|
-
|
|
20833
|
+
const x = keyed(r, seq++);
|
|
20834
|
+
if (check) {
|
|
20835
|
+
check(x);
|
|
20836
|
+
yield r;
|
|
20837
|
+
} else await s.push(x);
|
|
20700
20838
|
}
|
|
20701
|
-
for await (const x of s.drain()) yield x.r;
|
|
20839
|
+
if (s) for await (const x of s.drain()) yield x.r;
|
|
20702
20840
|
} finally {
|
|
20703
|
-
await s
|
|
20841
|
+
await s?.close();
|
|
20704
20842
|
}
|
|
20705
20843
|
}
|
|
20706
20844
|
async function* displayOrder() {
|
|
@@ -20711,7 +20849,7 @@ async function planStream(def0, opts) {
|
|
|
20711
20849
|
const gc = { ...tctx }, fc = { ...tctx };
|
|
20712
20850
|
const paths = groups.map(() => /* @__PURE__ */ new Map());
|
|
20713
20851
|
let ord = 0, keyText = 0;
|
|
20714
|
-
const
|
|
20852
|
+
const byGroup = (a, b) => {
|
|
20715
20853
|
for (let l = 0; l < groups.length; l++) {
|
|
20716
20854
|
const x = a.g[l], y = b.g[l];
|
|
20717
20855
|
if (x[0] === y[0]) continue;
|
|
@@ -20722,11 +20860,14 @@ async function planStream(def0, opts) {
|
|
|
20722
20860
|
}
|
|
20723
20861
|
return x[0] - y[0];
|
|
20724
20862
|
}
|
|
20725
|
-
return
|
|
20726
|
-
}
|
|
20863
|
+
return 0;
|
|
20864
|
+
};
|
|
20865
|
+
const cmp = (a, b) => byGroup(a, b) || a.s - b.s;
|
|
20866
|
+
const check = opts.presorted ? checked((a, b) => byGroup(a, b) || (sorted ? keyCmp(a.k, b.k) : 0)) : null;
|
|
20867
|
+
const s = check ? null : sorter(cmp);
|
|
20727
20868
|
try {
|
|
20728
20869
|
let seq = 0;
|
|
20729
|
-
for await (const r of inOrder()) {
|
|
20870
|
+
for await (const r of inOrder(true)) {
|
|
20730
20871
|
gc.fields = r;
|
|
20731
20872
|
let path = "";
|
|
20732
20873
|
const g = [];
|
|
@@ -20735,7 +20876,7 @@ async function planStream(def0, opts) {
|
|
|
20735
20876
|
try {
|
|
20736
20877
|
key = evalValue(groups[l].expr, gc);
|
|
20737
20878
|
} catch (e2) {
|
|
20738
|
-
warn(`${item.name} group: ${e2.message}`);
|
|
20879
|
+
warn(`${item.name || item.type} group: ${e2.message}`);
|
|
20739
20880
|
key = "#Error";
|
|
20740
20881
|
}
|
|
20741
20882
|
path += `\0${groupKeyText(key, tctx)}`;
|
|
@@ -20756,12 +20897,16 @@ async function planStream(def0, opts) {
|
|
|
20756
20897
|
foldRow(sc, fc);
|
|
20757
20898
|
}
|
|
20758
20899
|
}
|
|
20759
|
-
|
|
20900
|
+
const x = { g, s: seq++, r };
|
|
20901
|
+
if (check) {
|
|
20902
|
+
check({ g, k: sorted ? keyed(r, 0) : null });
|
|
20903
|
+
yield x;
|
|
20904
|
+
} else await s.push(x);
|
|
20760
20905
|
}
|
|
20761
20906
|
for (const m of paths) m.clear();
|
|
20762
|
-
for await (const x of s.drain()) yield x;
|
|
20907
|
+
if (s) for await (const x of s.drain()) yield x;
|
|
20763
20908
|
} finally {
|
|
20764
|
-
await s
|
|
20909
|
+
await s?.close();
|
|
20765
20910
|
}
|
|
20766
20911
|
}
|
|
20767
20912
|
const foldCells = (rows2) => {
|
|
@@ -20812,7 +20957,7 @@ async function planStream(def0, opts) {
|
|
|
20812
20957
|
const L = groups.length;
|
|
20813
20958
|
const tableScope = openScope(L);
|
|
20814
20959
|
folds.table = tableScope;
|
|
20815
|
-
folds.groups = bands && L ? groups.map(() => /* @__PURE__ */ new Map()) : null;
|
|
20960
|
+
folds.groups = bands && L && !opts.presorted ? groups.map(() => /* @__PURE__ */ new Map()) : null;
|
|
20816
20961
|
const scopes = new Array(L).fill(null);
|
|
20817
20962
|
const dctx = { ...tctx, rowNumber: 0 };
|
|
20818
20963
|
let headerDone = false, rowNo = 0, first = null, last = null;
|
|
@@ -20867,7 +21012,10 @@ async function planStream(def0, opts) {
|
|
|
20867
21012
|
if ((rowNo & 255) === 0) overTime();
|
|
20868
21013
|
dctx.fields = r;
|
|
20869
21014
|
dctx.rowNumber = rowNo;
|
|
20870
|
-
if (bands && !
|
|
21015
|
+
if (bands && !folds.groups) {
|
|
21016
|
+
foldRow(tableScope, dctx);
|
|
21017
|
+
for (const s of scopes) foldRow(s.folds, dctx);
|
|
21018
|
+
}
|
|
20871
21019
|
for (const dr of item.detail || []) {
|
|
20872
21020
|
const x = regionRow(dr, dctx, "detail", L);
|
|
20873
21021
|
if (x) yield x;
|
|
@@ -20884,7 +21032,7 @@ async function planStream(def0, opts) {
|
|
|
20884
21032
|
}
|
|
20885
21033
|
overTime();
|
|
20886
21034
|
}
|
|
20887
|
-
return { name: item.name, columns: cols.map((c) => c.width), title: def.name || "", timeZone: timeZone || null, locale: def.locale || null, currency: def.currency || null, warnings, rows, records: inOrder, grouped: displayOrder, stats };
|
|
21035
|
+
return { name: item.name, columns: cols.map((c) => c.width), title: def.name || "", timeZone: timeZone || null, locale: def.locale || null, currency: def.currency || null, warnings, rows, records: inOrder, grouped: displayOrder, fieldList, stats };
|
|
20888
21036
|
}
|
|
20889
21037
|
function listAt(raw, path) {
|
|
20890
21038
|
let { rows } = jsonPathRows(raw, path || "$");
|
|
@@ -20907,8 +21055,7 @@ async function planPaged(def0, opts = {}) {
|
|
|
20907
21055
|
const plan2 = await planStream(def, { ...opts, format: "xlsx" });
|
|
20908
21056
|
if (plan2.why !== void 0) return no(plan2.why);
|
|
20909
21057
|
if ((def.dataSets || []).length !== 1) return no("more than one data set");
|
|
20910
|
-
|
|
20911
|
-
if (!ds.fields?.length) return no("undeclared fields");
|
|
21058
|
+
let ds = def.dataSets[0];
|
|
20912
21059
|
if (opts.firstPages || opts.dataOnly) return no("first pages or table data");
|
|
20913
21060
|
const sec = def.sections || {};
|
|
20914
21061
|
const body = Array.isArray(sec.body) ? sec.body[0] : sec.body;
|
|
@@ -20966,6 +21113,12 @@ async function planPaged(def0, opts = {}) {
|
|
|
20966
21113
|
}) })) })) };
|
|
20967
21114
|
const gfields = gfolds.flat().map((f4) => ({ name: f4.name }));
|
|
20968
21115
|
const size = Math.max(50, Number(opts.window) || WINDOW);
|
|
21116
|
+
if (!ds.fields?.length) {
|
|
21117
|
+
const fields = await /** @type {any} */
|
|
21118
|
+
plan2.fieldList();
|
|
21119
|
+
if (!fields.length) return no("undeclared fields (no rows to detect them from)");
|
|
21120
|
+
ds = { ...ds, fields };
|
|
21121
|
+
}
|
|
20969
21122
|
const strip = (fields) => fields.map(({ expr, path, ...f4 }) => f4);
|
|
20970
21123
|
const windowDef = (first, last, done) => {
|
|
20971
21124
|
const t = { ...gtable, sort: void 0, filters: void 0 };
|
|
@@ -21151,7 +21304,8 @@ async function planPaged(def0, opts = {}) {
|
|
|
21151
21304
|
for (let k = off + per + 1; k < bounds.length && end < 0; k++) if (bounds[k] >= 0) end = k;
|
|
21152
21305
|
let e2 = -1;
|
|
21153
21306
|
for (let k = end + 1; end >= 0 && k < bounds.length && e2 < 0; k++) if (bounds[k] >= 0 && bounds[k] - bounds[end] >= reach) e2 = k;
|
|
21154
|
-
|
|
21307
|
+
if (e2 < 0) end = -1;
|
|
21308
|
+
await read(end < 0 ? Infinity : bounds[e2] - base);
|
|
21155
21309
|
if (!ended) {
|
|
21156
21310
|
const r = await next();
|
|
21157
21311
|
if (r.done) {
|
|
@@ -21294,7 +21448,11 @@ async function planPaged(def0, opts = {}) {
|
|
|
21294
21448
|
}
|
|
21295
21449
|
|
|
21296
21450
|
// src/exporters/pdfstreamtags.js
|
|
21297
|
-
function createStreamTagger(w) {
|
|
21451
|
+
function createStreamTagger(w, { maxElements = Infinity } = {}) {
|
|
21452
|
+
let count = 0;
|
|
21453
|
+
const made = () => {
|
|
21454
|
+
if (++count > maxElements) throw Object.assign(new Error(`The tagged PDF has more than ${maxElements.toLocaleString("en-US")} structure elements (tagged.maxElements). Filter the data, or export it untagged.`), { status: 413 });
|
|
21455
|
+
};
|
|
21298
21456
|
const rootRef = w.reserve(), docRef = w.reserve();
|
|
21299
21457
|
const docKids = [];
|
|
21300
21458
|
let table2 = (
|
|
@@ -21339,6 +21497,7 @@ function createStreamTagger(w) {
|
|
|
21339
21497
|
);
|
|
21340
21498
|
let links = false, win = 0;
|
|
21341
21499
|
const el = (S3, parent, attrs2) => {
|
|
21500
|
+
made();
|
|
21342
21501
|
const e2 = { ref: w.reserve(), S: S3, parent, mcid: (
|
|
21343
21502
|
/** @type {number[]} */
|
|
21344
21503
|
[]
|
|
@@ -21357,6 +21516,10 @@ function createStreamTagger(w) {
|
|
|
21357
21516
|
`;
|
|
21358
21517
|
};
|
|
21359
21518
|
return {
|
|
21519
|
+
/** structure elements so far */
|
|
21520
|
+
get count() {
|
|
21521
|
+
return count;
|
|
21522
|
+
},
|
|
21360
21523
|
/** a new page (window: the paged window it came from; row ids are its own) @param {number} window */
|
|
21361
21524
|
page(window) {
|
|
21362
21525
|
mcids = [];
|
|
@@ -21390,13 +21553,14 @@ function createStreamTagger(w) {
|
|
|
21390
21553
|
const rk = `${win}:${c.row}`;
|
|
21391
21554
|
let r = rows.get(rk);
|
|
21392
21555
|
if (!r) {
|
|
21556
|
+
made();
|
|
21393
21557
|
r = { ref: w.reserve(), kind: c.kind, cells: /* @__PURE__ */ new Map() };
|
|
21394
21558
|
rows.set(rk, r);
|
|
21395
21559
|
addRow(r.ref);
|
|
21396
21560
|
}
|
|
21397
21561
|
let cell = r.cells.get(c.col);
|
|
21398
21562
|
if (!cell) {
|
|
21399
|
-
const attrs2 = { O: "/Table", ...c.kind === "header" ? { Scope: "/Column" } : {}, ...c.span > 1 ? { ColSpan: c.span } : {} };
|
|
21563
|
+
const attrs2 = c.kind === "header" || c.span > 1 ? { O: "/Table", ...c.kind === "header" ? { Scope: "/Column" } : {}, ...c.span > 1 ? { ColSpan: c.span } : {} } : null;
|
|
21400
21564
|
cell = el(c.kind === "header" ? "TH" : "TD", r.ref, attrs2);
|
|
21401
21565
|
r.cells.set(c.col, cell);
|
|
21402
21566
|
}
|
|
@@ -21428,7 +21592,7 @@ function createStreamTagger(w) {
|
|
|
21428
21592
|
table2.cols; ) {
|
|
21429
21593
|
let cell = r.cells.get(col3);
|
|
21430
21594
|
if (!cell) {
|
|
21431
|
-
cell = el(r.kind === "header" ? "TH" : "TD", r.ref, r.kind === "header" ? { O: "/Table", Scope: "/Column" } :
|
|
21595
|
+
cell = el(r.kind === "header" ? "TH" : "TD", r.ref, r.kind === "header" ? { O: "/Table", Scope: "/Column" } : null);
|
|
21432
21596
|
}
|
|
21433
21597
|
kids.push(cell.ref);
|
|
21434
21598
|
col3 += Math.max(1, cell.attrs?.ColSpan || 1);
|
|
@@ -21437,7 +21601,7 @@ function createStreamTagger(w) {
|
|
|
21437
21601
|
void col3;
|
|
21438
21602
|
kids.push(cell.ref);
|
|
21439
21603
|
}
|
|
21440
|
-
await w.objectAt(r.ref, `<< /
|
|
21604
|
+
await w.objectAt(r.ref, `<< /S /TR /P ${/** @type {any} */
|
|
21441
21605
|
table2.ref} 0 R /K [${kids.map((k) => `${k} 0 R`).join(" ")}] >>`);
|
|
21442
21606
|
}
|
|
21443
21607
|
if (rows.size && [...rows.values()].some((r) => r.kind === "header")) headerDone = true;
|
|
@@ -21445,7 +21609,7 @@ function createStreamTagger(w) {
|
|
|
21445
21609
|
const K = [...e2.mcid.map(String), ...e2.kids].join(" ");
|
|
21446
21610
|
const A = e2.attrs ? ` /A << ${Object.entries(e2.attrs).map(([k, v]) => `/${k} ${v}`).join(" ")} >>` : "";
|
|
21447
21611
|
const P = e2.parent === docRef ? docRef : e2.parent;
|
|
21448
|
-
await w.objectAt(e2.ref, `<< /
|
|
21612
|
+
await w.objectAt(e2.ref, `<< /S /${e2.S} /P ${P} 0 R${e2.mcid.length || e2.S === "Link" ? ` /Pg ${pageRef} 0 R` : ""} /K [${K}]${A} >>`);
|
|
21449
21613
|
}
|
|
21450
21614
|
let extra = "";
|
|
21451
21615
|
if (mcids.length) {
|
|
@@ -21498,6 +21662,7 @@ var fontkit3 = (
|
|
|
21498
21662
|
var CHUNK = 64 * 1024;
|
|
21499
21663
|
var LEAF = 64;
|
|
21500
21664
|
var OBJSTM = 100;
|
|
21665
|
+
var TAGGED_LARGE = 1e6;
|
|
21501
21666
|
var IN_FLIGHT = 8;
|
|
21502
21667
|
var hex42 = (id) => id.toString(16).padStart(4, "0");
|
|
21503
21668
|
var num5 = (v) => String(Math.round(v * 1e3) / 1e3);
|
|
@@ -21506,12 +21671,12 @@ var esc5 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(
|
|
|
21506
21671
|
function createPdfStream(sink, opt) {
|
|
21507
21672
|
const { fontStore } = opt;
|
|
21508
21673
|
let pos = 0, nextNum = 1;
|
|
21509
|
-
let kind = new Uint8Array(4096), loc = new Uint32Array(4096), idx = new
|
|
21674
|
+
let kind = new Uint8Array(4096), loc = new Uint32Array(4096), idx = new Uint16Array(4096);
|
|
21510
21675
|
const place = (n5, k, l, i = 0) => {
|
|
21511
21676
|
if (n5 >= kind.length) {
|
|
21512
21677
|
let L = kind.length;
|
|
21513
21678
|
while (L <= n5) L *= 2;
|
|
21514
|
-
const k2 = new Uint8Array(L), l2 = new Uint32Array(L), i2 = new
|
|
21679
|
+
const k2 = new Uint8Array(L), l2 = new Uint32Array(L), i2 = new Uint16Array(L);
|
|
21515
21680
|
k2.set(kind);
|
|
21516
21681
|
l2.set(loc);
|
|
21517
21682
|
i2.set(idx);
|
|
@@ -21790,7 +21955,7 @@ endobj
|
|
|
21790
21955
|
const kids = level.slice(k, k + LEAF);
|
|
21791
21956
|
up.push({ ref: reserve(), kids: kids.map((x) => x.ref), count: kids.reduce((s, x) => s + x.count, 0), below: kids });
|
|
21792
21957
|
}
|
|
21793
|
-
for (const
|
|
21958
|
+
for (const node3 of up) for (const kid of node3.below) kid.parent = node3.ref;
|
|
21794
21959
|
await writeNodes(level);
|
|
21795
21960
|
level = /** @type {any} */
|
|
21796
21961
|
up;
|
|
@@ -21813,21 +21978,32 @@ endobj
|
|
|
21813
21978
|
const zs = new Zlib({ level: 6 }, (d) => {
|
|
21814
21979
|
out.push(d);
|
|
21815
21980
|
});
|
|
21981
|
+
const prev = new Uint8Array(7), row = new Uint8Array(7);
|
|
21816
21982
|
for (let from = 0; from < size2; from += 65536) {
|
|
21817
|
-
const to = Math.min(size2, from + 65536), rows = new Uint8Array((to - from) *
|
|
21983
|
+
const to = Math.min(size2, from + 65536), rows = new Uint8Array((to - from) * 8);
|
|
21818
21984
|
for (let n5 = from; n5 < to; n5++) {
|
|
21819
|
-
|
|
21985
|
+
row.fill(0);
|
|
21986
|
+
const l = loc[n5];
|
|
21820
21987
|
if (n5 === 0) {
|
|
21821
|
-
|
|
21822
|
-
|
|
21823
|
-
|
|
21988
|
+
row[5] = 255;
|
|
21989
|
+
row[6] = 255;
|
|
21990
|
+
} else {
|
|
21991
|
+
row[0] = kind[n5];
|
|
21992
|
+
row[1] = l >>> 24 & 255;
|
|
21993
|
+
row[2] = l >>> 16 & 255;
|
|
21994
|
+
row[3] = l >>> 8 & 255;
|
|
21995
|
+
row[4] = l & 255;
|
|
21996
|
+
if (kind[n5] === 2) {
|
|
21997
|
+
row[5] = idx[n5] >> 8;
|
|
21998
|
+
row[6] = idx[n5] & 255;
|
|
21999
|
+
}
|
|
22000
|
+
}
|
|
22001
|
+
const at = (n5 - from) * 8;
|
|
22002
|
+
rows[at] = 2;
|
|
22003
|
+
for (let b = 0; b < 7; b++) {
|
|
22004
|
+
rows[at + 1 + b] = row[b] - prev[b] & 255;
|
|
22005
|
+
prev[b] = row[b];
|
|
21824
22006
|
}
|
|
21825
|
-
rows[at] = kind[n5];
|
|
21826
|
-
rows[at + 1] = l >>> 24 & 255;
|
|
21827
|
-
rows[at + 2] = l >>> 16 & 255;
|
|
21828
|
-
rows[at + 3] = l >>> 8 & 255;
|
|
21829
|
-
rows[at + 4] = l & 255;
|
|
21830
|
-
if (kind[n5] === 2) rows[at + 6] = idx[n5];
|
|
21831
22007
|
}
|
|
21832
22008
|
zs.push(rows, to === size2);
|
|
21833
22009
|
}
|
|
@@ -21841,7 +22017,7 @@ endobj
|
|
|
21841
22017
|
}
|
|
21842
22018
|
const id = opt.id || [...globalThis.crypto.getRandomValues(new Uint8Array(16))].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
21843
22019
|
await put(`${xn} 0 obj
|
|
21844
|
-
<< /Type /XRef /Size ${size2} /W [1 4 2] /Root ${catalog} 0 R /Info ${info} 0 R /ID [<${id}> <${id}>] /Filter /FlateDecode /Length ${z.length} >>
|
|
22020
|
+
<< /Type /XRef /Size ${size2} /W [1 4 2] /DecodeParms << /Columns 7 /Predictor 12 >> /Root ${catalog} 0 R /Info ${info} 0 R /ID [<${id}> <${id}>] /Filter /FlateDecode /Length ${z.length} >>
|
|
21845
22021
|
stream
|
|
21846
22022
|
`);
|
|
21847
22023
|
await put(z);
|
|
@@ -21914,9 +22090,9 @@ ${xref}
|
|
|
21914
22090
|
if (!(e2.page >= 1 && e2.page <= pages)) continue;
|
|
21915
22091
|
const level = Math.max(0, Math.min(9, Number(e2.level) || 0));
|
|
21916
22092
|
while (stack2[stack2.length - 1].level >= level) stack2.pop();
|
|
21917
|
-
const
|
|
21918
|
-
stack2[stack2.length - 1].kids.push(
|
|
21919
|
-
stack2.push(
|
|
22093
|
+
const node3 = { ref: reserve(), level, kids: [], title: e2.title, dest: `[${pageRefs[e2.page - 1]} 0 R ${e2.top == null ? "/Fit" : `/XYZ null ${num5(e2.top)} null`}]` };
|
|
22094
|
+
stack2[stack2.length - 1].kids.push(node3);
|
|
22095
|
+
stack2.push(node3);
|
|
21920
22096
|
}
|
|
21921
22097
|
if (!root.kids.length) return 0;
|
|
21922
22098
|
root.ref = reserve();
|
|
@@ -21999,7 +22175,8 @@ async function exportPdfStream(def, opts, sink) {
|
|
|
21999
22175
|
sink.once("drain", ok)
|
|
22000
22176
|
));
|
|
22001
22177
|
else await r3;
|
|
22002
|
-
|
|
22178
|
+
const warnings = [`The PDF was not streamed (${plan2.why}): the report was rendered whole, so its memory grows with its pages.`, ...model.warnings];
|
|
22179
|
+
return { streamed: false, pages: model.pages.length, warnings, why: plan2.why };
|
|
22003
22180
|
}
|
|
22004
22181
|
const r = await writePagedPdf(plan2, opts, sink);
|
|
22005
22182
|
return { streamed: true, ...r };
|
|
@@ -22011,7 +22188,7 @@ async function writePagedPdf(plan2, opts, sink) {
|
|
|
22011
22188
|
/** @type {any} */
|
|
22012
22189
|
plan2
|
|
22013
22190
|
);
|
|
22014
|
-
const tags = opts.tagged ? createStreamTagger(w) : null;
|
|
22191
|
+
const tags = opts.tagged ? createStreamTagger(w, { maxElements: Number(opts.tagged.maxElements) || Infinity }) : null;
|
|
22015
22192
|
const env = paintEnv(w, fontStore, { drillBase: opts.drillBase, tags });
|
|
22016
22193
|
const { shaped } = env;
|
|
22017
22194
|
const pool = !tags && Number(opts.parallel) > 1 ? paintPool(Number(opts.parallel), fontStore, opts, info) : null;
|
|
@@ -22057,6 +22234,7 @@ async function writePagedPdf(plan2, opts, sink) {
|
|
|
22057
22234
|
catalog += ` /OutputIntents [${await w.object(`<< /Type /OutputIntent /S /GTS_PDFA1 /OutputConditionIdentifier (sRGB) /Info (sRGB IEC61966-2.1) /DestOutputProfile ${icc} 0 R >>`)} 0 R]`;
|
|
22058
22235
|
}
|
|
22059
22236
|
const res = await w.finish({ outline: outline2, catalog, info: { title: title2, author: opts.author, creationDate: when } });
|
|
22237
|
+
if (tags && tags.count > TAGGED_LARGE) info.warnings.push(`The tagged PDF has ${tags.count.toLocaleString("en-US")} structure elements (${res.pages.toLocaleString("en-US")} pages): readers open it, but tools that load every object of a file (qpdf, pikepdf) may run out of memory on it. tagged.maxElements caps it.`);
|
|
22060
22238
|
return { pages: res.pages, warnings: info.warnings };
|
|
22061
22239
|
}
|
|
22062
22240
|
var lit = (v) => `(${String(v).replace(/[\\()]/g, "\\$&")})`;
|
|
@@ -22073,11 +22251,21 @@ function paintPage(pg, H, env) {
|
|
|
22073
22251
|
const { tags } = env;
|
|
22074
22252
|
if (tags) {
|
|
22075
22253
|
c.tagged = true;
|
|
22254
|
+
c.artLines = true;
|
|
22076
22255
|
tags.page(pg.win ?? 0);
|
|
22077
22256
|
}
|
|
22078
22257
|
for (const it of pg.items) {
|
|
22079
|
-
const mark = tags && tags.open(it);
|
|
22080
|
-
|
|
22258
|
+
const mark = tags && it.t !== "line" && tags.open(it);
|
|
22259
|
+
const inText = mark && it.t === "text" && !it.rotate && it.lines.every((l) => !l.runs) && !(it.clip && !insideClip(it, env.vmetrics(it.font)));
|
|
22260
|
+
if (inText) {
|
|
22261
|
+
if (!c.bt) {
|
|
22262
|
+
c._s += "BT\n";
|
|
22263
|
+
c.bt = true;
|
|
22264
|
+
c.tx = 0;
|
|
22265
|
+
c.ty = 0;
|
|
22266
|
+
}
|
|
22267
|
+
c._s += mark;
|
|
22268
|
+
} else if (mark) {
|
|
22081
22269
|
c.et();
|
|
22082
22270
|
c.s += mark;
|
|
22083
22271
|
}
|
|
@@ -22155,7 +22343,8 @@ function paintPage(pg, H, env) {
|
|
|
22155
22343
|
throw new Error(`A ${it.t} item does not stream yet`);
|
|
22156
22344
|
}
|
|
22157
22345
|
if (it.rotate) c.Q();
|
|
22158
|
-
if (
|
|
22346
|
+
if (inText) c._s += "EMC\n";
|
|
22347
|
+
else if (mark) {
|
|
22159
22348
|
c.et();
|
|
22160
22349
|
c.s += "EMC\n";
|
|
22161
22350
|
}
|
|
@@ -22265,6 +22454,225 @@ function paintPool(size, fontStore, opts, info) {
|
|
|
22265
22454
|
};
|
|
22266
22455
|
}
|
|
22267
22456
|
|
|
22457
|
+
// src/exporters/spill.js
|
|
22458
|
+
var node2 = (m) => (
|
|
22459
|
+
/** @type {any} */
|
|
22460
|
+
globalThis.process.getBuiltinModule(m)
|
|
22461
|
+
);
|
|
22462
|
+
var canSpill = () => typeof /** @type {any} */
|
|
22463
|
+
globalThis.process?.getBuiltinModule === "function";
|
|
22464
|
+
var CELLS = 64;
|
|
22465
|
+
var spillShared = () => (
|
|
22466
|
+
/** @type {any} */
|
|
22467
|
+
globalThis.__pwSpill ||= { cells: new Int32Array(new SharedArrayBuffer(4 * CELLS)), cell: 0 }
|
|
22468
|
+
);
|
|
22469
|
+
var usedKB = () => {
|
|
22470
|
+
const { cells } = spillShared();
|
|
22471
|
+
let n5 = 0;
|
|
22472
|
+
for (let i = 0; i < CELLS; i++) n5 += Number(Atomics.load(cells, i));
|
|
22473
|
+
return n5;
|
|
22474
|
+
};
|
|
22475
|
+
var live = /* @__PURE__ */ new Set();
|
|
22476
|
+
var hooked = false;
|
|
22477
|
+
var sweep = () => {
|
|
22478
|
+
const fs = node2("node:fs");
|
|
22479
|
+
for (const d of live) {
|
|
22480
|
+
try {
|
|
22481
|
+
fs.rmSync(d, { recursive: true, force: true });
|
|
22482
|
+
} catch {
|
|
22483
|
+
}
|
|
22484
|
+
}
|
|
22485
|
+
live.clear();
|
|
22486
|
+
};
|
|
22487
|
+
function sweepStale(root, staleMs) {
|
|
22488
|
+
const fs = node2("node:fs"), path = node2("node:path");
|
|
22489
|
+
try {
|
|
22490
|
+
for (const n5 of fs.readdirSync(root)) {
|
|
22491
|
+
if (!n5.startsWith("pw-spill-")) continue;
|
|
22492
|
+
const d = path.join(root, n5);
|
|
22493
|
+
if (live.has(d)) continue;
|
|
22494
|
+
try {
|
|
22495
|
+
if (Date.now() - fs.statSync(d).mtimeMs > staleMs) fs.rmSync(d, { recursive: true, force: true });
|
|
22496
|
+
} catch {
|
|
22497
|
+
}
|
|
22498
|
+
}
|
|
22499
|
+
} catch {
|
|
22500
|
+
}
|
|
22501
|
+
}
|
|
22502
|
+
function spillSorter({ run = 2e4, runBytes = 24 * 1048576, frame: frame3 = 1e3, maxMB = 2048, totalMB = 8192, dir: root = node2("node:os").tmpdir(), staleMs = 18e4 } = {}) {
|
|
22503
|
+
const fs = node2("node:fs"), path = node2("node:path"), v8 = node2("node:v8"), { threadId } = node2("node:worker_threads");
|
|
22504
|
+
sweepStale(root, staleMs);
|
|
22505
|
+
return (cmp) => {
|
|
22506
|
+
let buf = [], dir = null, written = 0, held = 0, takenKB = 0;
|
|
22507
|
+
const runs = [];
|
|
22508
|
+
const flush = async () => {
|
|
22509
|
+
if (!buf.length) return;
|
|
22510
|
+
buf.sort(cmp);
|
|
22511
|
+
if (!dir) {
|
|
22512
|
+
dir = fs.mkdtempSync(path.join(root, `pw-spill-${process.pid}-${threadId}-`));
|
|
22513
|
+
live.add(dir);
|
|
22514
|
+
if (!hooked) {
|
|
22515
|
+
hooked = true;
|
|
22516
|
+
process.once("exit", sweep);
|
|
22517
|
+
}
|
|
22518
|
+
}
|
|
22519
|
+
const file = path.join(dir, `run-${runs.length}`);
|
|
22520
|
+
const fh = await fs.promises.open(file, "wx", 384);
|
|
22521
|
+
try {
|
|
22522
|
+
for (let i = 0; i < buf.length; i += frame3) {
|
|
22523
|
+
const body = v8.serialize(buf.slice(i, i + frame3));
|
|
22524
|
+
written += body.length + 4;
|
|
22525
|
+
if (written > maxMB * 1048576) throw Object.assign(new Error(`The sort needs more than ${maxMB} MB of temporary disk (PW_SPILL_MAX_MB). Filter the data, or sort it at the source.`), { status: 413 });
|
|
22526
|
+
const kb = Math.ceil(written / 1024) - takenKB;
|
|
22527
|
+
if (kb > 0) {
|
|
22528
|
+
const { cells, cell } = spillShared();
|
|
22529
|
+
Atomics.add(cells, cell, kb);
|
|
22530
|
+
takenKB += kb;
|
|
22531
|
+
if (usedKB() > totalMB * 1024) throw Object.assign(new Error(`The server's temporary disk for sorting is in use (PW_SPILL_TOTAL_MB, ${totalMB} MB). Try again shortly, or filter the data.`), { status: 503 });
|
|
22532
|
+
}
|
|
22533
|
+
const head = Buffer.alloc(4);
|
|
22534
|
+
head.writeUInt32LE(body.length);
|
|
22535
|
+
await fh.write(head);
|
|
22536
|
+
await fh.write(body);
|
|
22537
|
+
}
|
|
22538
|
+
} finally {
|
|
22539
|
+
await fh.close();
|
|
22540
|
+
}
|
|
22541
|
+
runs.push(file);
|
|
22542
|
+
buf = [];
|
|
22543
|
+
held = 0;
|
|
22544
|
+
};
|
|
22545
|
+
return {
|
|
22546
|
+
/** @param {any} r */
|
|
22547
|
+
async push(r) {
|
|
22548
|
+
buf.push(r);
|
|
22549
|
+
held += approx(r);
|
|
22550
|
+
if (buf.length >= run || held >= runBytes) await flush();
|
|
22551
|
+
},
|
|
22552
|
+
async *drain() {
|
|
22553
|
+
if (!runs.length) {
|
|
22554
|
+
const all = buf;
|
|
22555
|
+
buf = [];
|
|
22556
|
+
all.sort(cmp);
|
|
22557
|
+
for (let i = 0; i < all.length; i++) {
|
|
22558
|
+
yield all[i];
|
|
22559
|
+
all[i] = null;
|
|
22560
|
+
}
|
|
22561
|
+
return;
|
|
22562
|
+
}
|
|
22563
|
+
await flush();
|
|
22564
|
+
const readers = await Promise.all(runs.map(openRun));
|
|
22565
|
+
try {
|
|
22566
|
+
const heap = [];
|
|
22567
|
+
const less = (i, j) => cmp(heap[i][0], heap[j][0]) < 0;
|
|
22568
|
+
const swap = (i, j) => {
|
|
22569
|
+
const t = heap[i];
|
|
22570
|
+
heap[i] = heap[j];
|
|
22571
|
+
heap[j] = t;
|
|
22572
|
+
};
|
|
22573
|
+
const up = (i) => {
|
|
22574
|
+
while (i > 0) {
|
|
22575
|
+
const p = i - 1 >> 1;
|
|
22576
|
+
if (!less(i, p)) break;
|
|
22577
|
+
swap(i, p);
|
|
22578
|
+
i = p;
|
|
22579
|
+
}
|
|
22580
|
+
};
|
|
22581
|
+
const down = (i) => {
|
|
22582
|
+
for (; ; ) {
|
|
22583
|
+
const l = 2 * i + 1, r = l + 1;
|
|
22584
|
+
let m = i;
|
|
22585
|
+
if (l < heap.length && less(l, m)) m = l;
|
|
22586
|
+
if (r < heap.length && less(r, m)) m = r;
|
|
22587
|
+
if (m === i) return;
|
|
22588
|
+
swap(i, m);
|
|
22589
|
+
i = m;
|
|
22590
|
+
}
|
|
22591
|
+
};
|
|
22592
|
+
for (const rd of readers) {
|
|
22593
|
+
const x = await rd.next();
|
|
22594
|
+
if (x !== void 0) {
|
|
22595
|
+
heap.push([x, rd]);
|
|
22596
|
+
up(heap.length - 1);
|
|
22597
|
+
}
|
|
22598
|
+
}
|
|
22599
|
+
while (heap.length) {
|
|
22600
|
+
const [x, rd] = heap[0];
|
|
22601
|
+
yield x;
|
|
22602
|
+
const n5 = await rd.next();
|
|
22603
|
+
if (n5 === void 0) {
|
|
22604
|
+
const last = (
|
|
22605
|
+
/** @type {[any, any]} */
|
|
22606
|
+
heap.pop()
|
|
22607
|
+
);
|
|
22608
|
+
if (heap.length) {
|
|
22609
|
+
heap[0] = last;
|
|
22610
|
+
down(0);
|
|
22611
|
+
}
|
|
22612
|
+
} else {
|
|
22613
|
+
heap[0] = [n5, rd];
|
|
22614
|
+
down(0);
|
|
22615
|
+
}
|
|
22616
|
+
}
|
|
22617
|
+
} finally {
|
|
22618
|
+
await Promise.all(readers.map((r) => r.close()));
|
|
22619
|
+
}
|
|
22620
|
+
},
|
|
22621
|
+
async close() {
|
|
22622
|
+
buf = [];
|
|
22623
|
+
if (takenKB) {
|
|
22624
|
+
const { cells, cell } = spillShared();
|
|
22625
|
+
Atomics.sub(cells, cell, takenKB);
|
|
22626
|
+
takenKB = 0;
|
|
22627
|
+
}
|
|
22628
|
+
if (dir) {
|
|
22629
|
+
const d = dir;
|
|
22630
|
+
dir = null;
|
|
22631
|
+
live.delete(d);
|
|
22632
|
+
await fs.promises.rm(d, { recursive: true, force: true }).catch(() => {
|
|
22633
|
+
});
|
|
22634
|
+
}
|
|
22635
|
+
},
|
|
22636
|
+
/** Tests: the runs written so far. */
|
|
22637
|
+
get runs() {
|
|
22638
|
+
return runs.length;
|
|
22639
|
+
}
|
|
22640
|
+
};
|
|
22641
|
+
};
|
|
22642
|
+
}
|
|
22643
|
+
function approx(x, d = 0) {
|
|
22644
|
+
if (typeof x === "string") return 2 * x.length + 16;
|
|
22645
|
+
if (!x || typeof x !== "object" || d > 2) return 8;
|
|
22646
|
+
let n5 = 32;
|
|
22647
|
+
for (const k in x) n5 += approx(x[k], d + 1) + 8;
|
|
22648
|
+
return n5;
|
|
22649
|
+
}
|
|
22650
|
+
async function openRun(file) {
|
|
22651
|
+
const fs = node2("node:fs"), v8 = node2("node:v8");
|
|
22652
|
+
const fh = await fs.promises.open(file, "r");
|
|
22653
|
+
let pos = 0, batch = [], i = 0;
|
|
22654
|
+
const head = Buffer.alloc(4);
|
|
22655
|
+
return {
|
|
22656
|
+
async next() {
|
|
22657
|
+
if (i < batch.length) {
|
|
22658
|
+
const x = batch[i];
|
|
22659
|
+
batch[i++] = null;
|
|
22660
|
+
return x;
|
|
22661
|
+
}
|
|
22662
|
+
const h = await fh.read(head, 0, 4, pos);
|
|
22663
|
+
if (h.bytesRead < 4) return void 0;
|
|
22664
|
+
const len = head.readUInt32LE(0);
|
|
22665
|
+
const body = Buffer.alloc(len);
|
|
22666
|
+
await fh.read(body, 0, len, pos + 4);
|
|
22667
|
+
pos += 4 + len;
|
|
22668
|
+
batch = v8.deserialize(body);
|
|
22669
|
+
i = 0;
|
|
22670
|
+
return this.next();
|
|
22671
|
+
},
|
|
22672
|
+
close: () => fh.close()
|
|
22673
|
+
};
|
|
22674
|
+
}
|
|
22675
|
+
|
|
22268
22676
|
// src/designer/tableGen.js
|
|
22269
22677
|
var HEAD = { fontWeight: "bold", backgroundColor: "#f1f5f9", borderBottom: "0.75 solid #94a3b8" };
|
|
22270
22678
|
var TOTAL = { fontWeight: "bold", borderTop: "0.75 solid #94a3b8" };
|
|
@@ -22455,11 +22863,11 @@ function optionsOf(fn, args, legacy) {
|
|
|
22455
22863
|
const [model, second, third] = args;
|
|
22456
22864
|
checkModel(fn, model);
|
|
22457
22865
|
if (legacy === "fonts" && isFontStore(second)) {
|
|
22458
|
-
deprecated(fn, `${fn}(model, fontStore, options) is replaced by ${fn}(model, { fonts: fontStore, ...options }); the old form
|
|
22866
|
+
deprecated(fn, `${fn}(model, fontStore, options) is replaced by ${fn}(model, { fonts: fontStore, ...options }); the old form will be removed in 1.0`);
|
|
22459
22867
|
return { ...third || {}, fonts: second };
|
|
22460
22868
|
}
|
|
22461
22869
|
if (legacy === "excel" && second && (typeof second === "function" || typeof second.Workbook === "function")) {
|
|
22462
|
-
deprecated(fn, `${fn}(model, ExcelJS, options) is replaced by ${fn}(model, options): ExcelJS is no longer used; the old form
|
|
22870
|
+
deprecated(fn, `${fn}(model, ExcelJS, options) is replaced by ${fn}(model, options): ExcelJS is no longer used; the old form will be removed in 1.0`);
|
|
22463
22871
|
return { ...third || {} };
|
|
22464
22872
|
}
|
|
22465
22873
|
if (second != null && (typeof second !== "object" || Array.isArray(second))) throw new TypeError(`${fn}(model, options): options must be an object such as { fonts }, got ${Array.isArray(second) ? "an array" : typeof second}`);
|
|
@@ -22502,7 +22910,7 @@ function exportPptx2(model, options) {
|
|
|
22502
22910
|
}
|
|
22503
22911
|
var __streamPaint = { createPdfStream, paintPage, paintEnv, latin1 };
|
|
22504
22912
|
async function exportPdfStream2(def, options, sink) {
|
|
22505
|
-
const { fonts, fontStore, subset: sub, pdfa, ...rest } = (
|
|
22913
|
+
const { fonts, fontStore, subset: sub, pdfa, spill, ...rest } = (
|
|
22506
22914
|
/** @type {any} */
|
|
22507
22915
|
options || {}
|
|
22508
22916
|
);
|
|
@@ -22518,7 +22926,8 @@ async function exportPdfStream2(def, options, sink) {
|
|
|
22518
22926
|
if (!url) throw new Error("PDF/A needs an sRGB colour profile: install @reportwright/fonts, or pass pdfa: { icc: bytes }");
|
|
22519
22927
|
pdfaOpt = { ...typeof pdfa === "object" ? pdfa : {}, icc: new Uint8Array(await readUrl(url)) };
|
|
22520
22928
|
}
|
|
22521
|
-
|
|
22929
|
+
const sorter = rest.sorter || (spill !== false && canSpill() ? spillSorter({ ...spill?.dir ? { dir: spill.dir } : {}, ...spill?.maxMB ? { maxMB: spill.maxMB } : {} }) : void 0);
|
|
22930
|
+
return exportPdfStream(def, { ...rest, sorter, fontStore: store, subset, pdfa: pdfaOpt, exportData: !!rest.tagged }, sink);
|
|
22522
22931
|
}
|
|
22523
22932
|
export {
|
|
22524
22933
|
FontStore,
|