@reportwright/cli 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/pw.mjs +571 -533
- package/dist/pw.mjs.map +3 -3
- package/package.json +2 -2
package/dist/pw.mjs
CHANGED
|
@@ -13348,8 +13348,8 @@ function rgbOf(c) {
|
|
|
13348
13348
|
if (h.length === 3) h = h.replace(/./g, (x) => x + x);
|
|
13349
13349
|
return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16) / 255);
|
|
13350
13350
|
}
|
|
13351
|
-
var lum = (
|
|
13352
|
-
const [r, g, b] =
|
|
13351
|
+
var lum = (rgb4) => {
|
|
13352
|
+
const [r, g, b] = rgb4.map((v) => v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4);
|
|
13353
13353
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
13354
13354
|
};
|
|
13355
13355
|
function contrast(a, b) {
|
|
@@ -17884,7 +17884,7 @@ register("table", {
|
|
|
17884
17884
|
(item.groups || []).forEach((g, i) => {
|
|
17885
17885
|
if (g.name) groupChains[g.name] = { rows, keys: item.groups.slice(0, i + 1).map((x) => x.expr) };
|
|
17886
17886
|
});
|
|
17887
|
-
const base = { ...tctx, aggRows: rows, aggIndex: void 0, fields: rows[0] || null, scopes, region: tableScope, group: void 0, groupChains: { ...tctx.groupChains || {}, ...groupChains } };
|
|
17887
|
+
const base = { ...tctx, aggRows: rows, aggIndex: void 0, fields: lc.win?.first || rows[0] || null, scopes, region: tableScope, group: void 0, groupChains: { ...tctx.groupChains || {}, ...groupChains } };
|
|
17888
17888
|
const units = [];
|
|
17889
17889
|
let y = 0;
|
|
17890
17890
|
let repeatH = 0;
|
|
@@ -18122,7 +18122,8 @@ register("table", {
|
|
|
18122
18122
|
openSpans = [];
|
|
18123
18123
|
};
|
|
18124
18124
|
const fl = base.bandRows === "first-last";
|
|
18125
|
-
const
|
|
18125
|
+
const first0 = lc.win?.first || rows[0];
|
|
18126
|
+
const headerUnits = (item.header || []).map((r) => layRow(r, fl && rows.length ? { ...base, pendingRows: [first0] } : base, "header")).filter(Boolean);
|
|
18126
18127
|
endBand();
|
|
18127
18128
|
const headerHeight = headerUnits.reduce((s, u) => s + u.height, 0);
|
|
18128
18129
|
if (item.repeatHeader !== false) repeatH = headerHeight;
|
|
@@ -18136,7 +18137,7 @@ register("table", {
|
|
|
18136
18137
|
y += tl.needed;
|
|
18137
18138
|
}
|
|
18138
18139
|
const groups = item.groups || [];
|
|
18139
|
-
let rowNo = 0;
|
|
18140
|
+
let rowNo = lc.win?.rowOffset || 0;
|
|
18140
18141
|
const groupTables = [];
|
|
18141
18142
|
const tableKey = `${item.name}#${lc.nextId()}`;
|
|
18142
18143
|
const emit2 = (level, grows, ctx, chain, keyPath) => {
|
|
@@ -18156,9 +18157,16 @@ register("table", {
|
|
|
18156
18157
|
const dctx = { ...ctx, fields: grows[i], aggRows: grows, aggIndex: i, rowNumber: rowNo };
|
|
18157
18158
|
const u0 = units.length;
|
|
18158
18159
|
for (const r of item.detail || []) layRow(r, dctx, "detail", { level: groups.length });
|
|
18159
|
-
if (
|
|
18160
|
+
if (lc.win && units[u0]) {
|
|
18161
|
+
units[u0].rowHead = true;
|
|
18162
|
+
for (let k = u0; k < units.length; k++) units[k].dataRow = rowNo;
|
|
18163
|
+
}
|
|
18164
|
+
if (groups.length && item.widowControl !== false) for (let k = u0; k < units.length; k++) {
|
|
18165
|
+
units[k].grp = tableKey + keyPath;
|
|
18166
|
+
if (ctx.__before) units[k].grpBefore = ctx.__before;
|
|
18167
|
+
}
|
|
18160
18168
|
const every = Math.trunc(Number(item.pageBreakEvery)) || 0;
|
|
18161
|
-
if (every > 0 && rowNo > 1 && (rowNo - 1) % every === 0 && units[u0]) units[u0].breakBefore = true;
|
|
18169
|
+
if (every > 0 && rowNo > (lc.win?.rowOffset || 0) + 1 && (rowNo - 1) % every === 0 && units[u0]) units[u0].breakBefore = true;
|
|
18162
18170
|
endBand();
|
|
18163
18171
|
}
|
|
18164
18172
|
return;
|
|
@@ -18218,7 +18226,8 @@ register("table", {
|
|
|
18218
18226
|
if (lc.rowBudget?.cut || shown2.has(bk)) return;
|
|
18219
18227
|
shown2.add(bk);
|
|
18220
18228
|
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) } : {} };
|
|
18221
|
-
const
|
|
18229
|
+
const cont = bi === 0 && (level === 0 || ctx.__cont) ? lc.win?.cont?.[level] : null;
|
|
18230
|
+
const gctx = { ...ctx, fields: cont ? cont.first : bk.rows[0], aggRows: bk.rows, aggIndex: void 0, scopes: { ...ctx.scopes, [gname]: sc }, groupKey: bk.key, group: sc, __cont: !!cont, __before: cont && level === groups.length - 1 ? cont.before : 0 };
|
|
18222
18231
|
if (kids) {
|
|
18223
18232
|
gctx.level = depth;
|
|
18224
18233
|
if (g.indent) gctx.indent = (ctx.indent || 0) + depth * Number(g.indent);
|
|
@@ -18228,10 +18237,15 @@ register("table", {
|
|
|
18228
18237
|
const dflt = kids && g.expandLevels != null ? depth < Number(g.expandLevels) : !g.initiallyCollapsed;
|
|
18229
18238
|
const open = !g.collapsible ? true : lc.state?.toggles?.[tkey] ?? dflt;
|
|
18230
18239
|
const start = units.length;
|
|
18231
|
-
const hctx = g.header?.length ? { ...gctx, pendingRows: fl ? [bk.rows[0]] : recOf.get(bk) || bk.rows } : gctx;
|
|
18232
|
-
const hu = (g.header || []).map((r, ri) => layRow(r, hctx, "groupHeader", { level, ...ri === 0 && g.collapsible ? { toggle: { key: tkey, open } } : {} })).filter(Boolean);
|
|
18240
|
+
const hctx = g.header?.length ? { ...gctx, pendingRows: fl ? [cont ? cont.first : bk.rows[0]] : recOf.get(bk) || bk.rows } : gctx;
|
|
18241
|
+
const hu = (cont && !g.repeatHeader ? [] : g.header || []).map((r, ri) => layRow(r, hctx, "groupHeader", { level, ...ri === 0 && g.collapsible ? { toggle: { key: tkey, open } } : {} })).filter(Boolean);
|
|
18233
18242
|
endBand();
|
|
18234
18243
|
const before = units.length;
|
|
18244
|
+
if (lc.win && !cont && before > start) {
|
|
18245
|
+
for (let k = start; k < before; k++) units[k].dataRow = rowNo + 1;
|
|
18246
|
+
units[start].rowHead = true;
|
|
18247
|
+
units[start].headLevel = level;
|
|
18248
|
+
}
|
|
18235
18249
|
const rep = g.repeatHeader && before > start && !lc.fixed ? [...ctx.__rep || [], (() => {
|
|
18236
18250
|
const hdr = units.slice(start, before), h0 = hdr[0].top, its = [];
|
|
18237
18251
|
for (const u of hdr) for (const it of shiftLocal(u.items.filter((i) => i.t !== "link" && i.t !== "bookmark"), u.top - h0)) its.push(it);
|
|
@@ -18271,7 +18285,10 @@ register("table", {
|
|
|
18271
18285
|
if (g.pageBreak === "after" && bi < sibs.length - 1) units[units.length - 1].breakAfter = true;
|
|
18272
18286
|
if (g.keepTogether) {
|
|
18273
18287
|
const id = `${item.name}:g${level}:${path2}:${lc.nextId()}`;
|
|
18274
|
-
for (let k = start; k < units.length; k++) units[k].block
|
|
18288
|
+
for (let k = start; k < units.length; k++) if (!units[k].block) {
|
|
18289
|
+
units[k].block = id;
|
|
18290
|
+
if (cont) units[k].blockOpen = true;
|
|
18291
|
+
}
|
|
18275
18292
|
}
|
|
18276
18293
|
}
|
|
18277
18294
|
};
|
|
@@ -19161,7 +19178,8 @@ function paginate(units, tables, pageH, warn, stats) {
|
|
|
19161
19178
|
if (b) {
|
|
19162
19179
|
b.top = Math.min(b.top, u.top);
|
|
19163
19180
|
b.bottom = Math.max(b.bottom, u.top + u.height);
|
|
19164
|
-
|
|
19181
|
+
if (u.blockOpen) b.open = true;
|
|
19182
|
+
} else blockMap.set(u.block, { top: u.top, bottom: u.top + u.height, open: !!u.blockOpen });
|
|
19165
19183
|
}
|
|
19166
19184
|
const blockUnits = /* @__PURE__ */ new Map();
|
|
19167
19185
|
for (const u of units) if (u.block) {
|
|
@@ -19169,18 +19187,18 @@ function paginate(units, tables, pageH, warn, stats) {
|
|
|
19169
19187
|
if (!l) blockUnits.set(u.block, l = []);
|
|
19170
19188
|
l.push(u);
|
|
19171
19189
|
}
|
|
19172
|
-
const blocks = [...blockMap.values()].filter((b) => b.bottom - b.top <= pageH + EPS2);
|
|
19190
|
+
const blocks = [...blockMap.values()].filter((b) => !b.open && b.bottom - b.top <= pageH + EPS2);
|
|
19173
19191
|
for (const b of blocks) cand.push(b.top, b.bottom);
|
|
19174
19192
|
cand.sort((a, b) => a - b);
|
|
19175
19193
|
const grpRows = /* @__PURE__ */ new Map();
|
|
19176
19194
|
for (const u of units) if (u.grp) {
|
|
19177
19195
|
let g = grpRows.get(u.grp);
|
|
19178
|
-
if (!g) grpRows.set(u.grp, g = { tops: /* @__PURE__ */ new Set(), first: u.top, last: 0, block: u.block || null });
|
|
19196
|
+
if (!g) grpRows.set(u.grp, g = { tops: /* @__PURE__ */ new Set(), first: u.top, last: 0, block: u.block || null, before: u.grpBefore || 0 });
|
|
19179
19197
|
g.tops.add(u.top);
|
|
19180
19198
|
g.last = Math.max(g.last, u.top + u.height);
|
|
19181
19199
|
if (g.block !== (u.block || null)) g.block = void 0;
|
|
19182
19200
|
}
|
|
19183
|
-
const widowGroups = [...grpRows.values()].map((g) => ({ first: g.first, last: g.last, tops: [...g.tops].sort((a, b) => a - b), block: g.block })).filter((g) => g.
|
|
19201
|
+
const widowGroups = [...grpRows.values()].map((g) => ({ first: g.first, last: g.last, tops: [...g.tops].sort((a, b) => a - b), block: g.block, before: g.before, n: g.tops.size + g.before })).filter((g) => g.n >= 4 || !g.before && g.n >= 2 && g.last - g.first <= pageH + EPS2).sort((a, b) => a.first - b.first);
|
|
19184
19202
|
const wFirst = widowGroups.map((g) => g.first);
|
|
19185
19203
|
const wMaxLast = [];
|
|
19186
19204
|
widowGroups.forEach((g, i) => wMaxLast.push(Math.max(i ? wMaxLast[i - 1] : -Infinity, g.last)));
|
|
@@ -19207,9 +19225,9 @@ function paginate(units, tables, pageH, warn, stats) {
|
|
|
19207
19225
|
tick(1);
|
|
19208
19226
|
const g = widowGroups[i];
|
|
19209
19227
|
if (g.last <= y + EPS2 || g.block && !withBlocks) continue;
|
|
19210
|
-
if (g.
|
|
19211
|
-
const above = rowsAbove(g.tops, y);
|
|
19212
|
-
if (above < 2 || g.
|
|
19228
|
+
if (g.n < 4) return false;
|
|
19229
|
+
const above = g.before + rowsAbove(g.tops, y);
|
|
19230
|
+
if (above < 2 || g.n - above < 2) return false;
|
|
19213
19231
|
}
|
|
19214
19232
|
return true;
|
|
19215
19233
|
};
|
|
@@ -19264,7 +19282,7 @@ function paginate(units, tables, pageH, warn, stats) {
|
|
|
19264
19282
|
if (u.block) {
|
|
19265
19283
|
const bl = blockMap.get(u.block);
|
|
19266
19284
|
if (movedBlocks.has(bl)) continue;
|
|
19267
|
-
if (!bl || bl.bottom - bl.top > room + EPS2 || bl.top <= top2 + EPS2) return null;
|
|
19285
|
+
if (!bl || bl.open || bl.bottom - bl.top > room + EPS2 || bl.top <= top2 + EPS2) return null;
|
|
19268
19286
|
movedBlocks.add(bl);
|
|
19269
19287
|
for (const m of blockUnits.get(u.block)) if (!placed.has(m)) moved.push(m);
|
|
19270
19288
|
continue;
|
|
@@ -22775,14 +22793,16 @@ async function render(def0, opts = {}) {
|
|
|
22775
22793
|
ctxFor: (item) => {
|
|
22776
22794
|
const ds = item.dataSet || defaultDs;
|
|
22777
22795
|
const rows = ds && dataSets[ds] || [];
|
|
22778
|
-
return { ...baseCtx, globals, fields: rows[0] || null, aggRows: rows };
|
|
22796
|
+
return { ...baseCtx, globals, fields: (opts.pageWindow?.first && ds === defaultDs ? opts.pageWindow.first : rows[0]) || null, aggRows: rows };
|
|
22779
22797
|
},
|
|
22780
22798
|
subreports: null,
|
|
22781
22799
|
bodyWidth: opts.bodyWidth ?? page.bodyWidth,
|
|
22782
22800
|
images: def.images || {},
|
|
22783
22801
|
imageBudget,
|
|
22784
|
-
cellItems: { left: 1e5 }
|
|
22802
|
+
cellItems: { left: 1e5 },
|
|
22785
22803
|
// rows of items inside table cells, for the whole render (items/index.js)
|
|
22804
|
+
win: opts.pageWindow || null
|
|
22805
|
+
// paged.js: units carry their row number (dataRow, rowHead), rows and groups continue
|
|
22786
22806
|
};
|
|
22787
22807
|
return lc;
|
|
22788
22808
|
};
|
|
@@ -22920,12 +22940,14 @@ async function render(def0, opts = {}) {
|
|
|
22920
22940
|
const bodyTop = mt + g.hH;
|
|
22921
22941
|
const items = [];
|
|
22922
22942
|
const cut = lc.rowBudget?.cut;
|
|
22923
|
-
const
|
|
22943
|
+
const win = opts.pageWindow, off = win ? win.offset : 0, all = win ? win.total ?? "…" : null;
|
|
22944
|
+
const globals = { ...baseCtx.globals, PageNumber: n5 - secStart[n5] + 1 + (secStart[n5] ? 0 : off), TotalPages: cut ? "…" : all ?? secLen.get(secStart[n5]), OverallPageNumber: n5 + 1 + off, OverallTotalPages: cut ? "…" : all ?? total };
|
|
22945
|
+
const isFirst = n5 + off === 0, isLast = n5 === total - 1 && (!win || win.final);
|
|
22924
22946
|
const plc = makeLc(globals, true);
|
|
22925
|
-
const band = (section, y0,
|
|
22947
|
+
const band = (section, y0, isFirst2, isLast2) => {
|
|
22926
22948
|
if (!section) return;
|
|
22927
|
-
if (
|
|
22928
|
-
if (
|
|
22949
|
+
if (isFirst2 && section.printOnFirstPage === false) return;
|
|
22950
|
+
if (isLast2 && section.printOnLastPage === false) return;
|
|
22929
22951
|
const capped2 = () => warn(`The page headers and footers would draw more than ${BAND_ITEMS.toLocaleString("en-US")} items in this report; they are left out of the later pages. Make them lighter, or the report shorter.`);
|
|
22930
22952
|
if (bandWork.left <= 0) {
|
|
22931
22953
|
capped2();
|
|
@@ -22946,7 +22968,7 @@ async function render(def0, opts = {}) {
|
|
|
22946
22968
|
for (const u of r.units) if (c.paged) placeItems(u.items, ml, y0 + u.top, items);
|
|
22947
22969
|
else for (const it of shiftItems(u.items, ml, y0 + u.top)) items.push(it);
|
|
22948
22970
|
};
|
|
22949
|
-
band(g.hdr, mt, g.own.h ? k === 0 :
|
|
22971
|
+
band(g.hdr, mt, g.own.h ? k === 0 : isFirst, g.own.h ? last : isLast);
|
|
22950
22972
|
const frozen = [];
|
|
22951
22973
|
for (let c = 0; c < colCount; c++) {
|
|
22952
22974
|
const p = slices[k * colCount + c];
|
|
@@ -22956,30 +22978,38 @@ async function render(def0, opts = {}) {
|
|
|
22956
22978
|
for (const t of body.tables) {
|
|
22957
22979
|
if (!(t.top < p.bottom - EPS4 && t.bottom > p.top + EPS4)) continue;
|
|
22958
22980
|
const cont = p.repeat.includes(t);
|
|
22959
|
-
let
|
|
22981
|
+
let off2 = 0;
|
|
22960
22982
|
if (!cont) {
|
|
22961
|
-
for (const r of p.repeat) if (t.x0 < r.x1 - EPS4 && r.x0 < t.x1 - EPS4)
|
|
22983
|
+
for (const r of p.repeat) if (t.x0 < r.x1 - EPS4 && r.x0 < t.x1 - EPS4) off2 = Math.max(off2, r.headerHeight);
|
|
22962
22984
|
}
|
|
22963
|
-
const y = cont ? bodyTop : bodyTop +
|
|
22964
|
-
frozen.push({ x: cx + t.x0, y, w: t.x1 - t.x0, h: t.headerHeight, end: bodyTop + (cont ? t.headerHeight :
|
|
22985
|
+
const y = cont ? bodyTop : bodyTop + off2 + t.top - p.top;
|
|
22986
|
+
frozen.push({ x: cx + t.x0, y, w: t.x1 - t.x0, h: t.headerHeight, end: bodyTop + (cont ? t.headerHeight : off2) + Math.min(t.bottom, p.bottom) - p.top });
|
|
22965
22987
|
}
|
|
22966
22988
|
for (const u of p.units) {
|
|
22967
|
-
let
|
|
22968
|
-
for (const t of p.repeat) if (u.x0 < t.x1 - EPS4 && t.x0 < u.x1 - EPS4)
|
|
22969
|
-
if (u.atBottom)
|
|
22970
|
-
if (u.cont && u.top <= p.top + EPS4) placeItems(u.cont, cx, bodyTop +
|
|
22971
|
-
placeItems(u.items, cx, bodyTop +
|
|
22989
|
+
let off2 = 0;
|
|
22990
|
+
for (const t of p.repeat) if (u.x0 < t.x1 - EPS4 && t.x0 < u.x1 - EPS4) off2 = Math.max(off2, t.headerHeight);
|
|
22991
|
+
if (u.atBottom) off2 += Math.max(0, cH - off2 - (p.bottom - p.top));
|
|
22992
|
+
if (u.cont && u.top <= p.top + EPS4) placeItems(u.cont, cx, bodyTop + off2, items);
|
|
22993
|
+
placeItems(u.items, cx, bodyTop + off2 + (u.top - p.top), items);
|
|
22972
22994
|
}
|
|
22973
22995
|
}
|
|
22974
|
-
band(g.ftr, ph - pg.margins.bottom - g.fH, g.own.f ? k === 0 :
|
|
22996
|
+
band(g.ftr, ph - pg.margins.bottom - g.fH, g.own.f ? k === 0 : isFirst, g.own.f ? last : isLast);
|
|
22975
22997
|
let j = 0;
|
|
22976
22998
|
for (let i = 0; i < items.length; i++) {
|
|
22977
22999
|
const it = items[i];
|
|
22978
|
-
if (it.t === "bookmark") (it.heading ? headings : bookmarks2).push({ label: it.label, page: n5 + 1, y: it.y, level: it.level || 0, ...secStart[n5] ? { shown: n5 - secStart[n5] + 1 } : {} });
|
|
23000
|
+
if (it.t === "bookmark") (it.heading ? headings : bookmarks2).push({ label: it.label, page: n5 + 1 + off, y: it.y, level: it.level || 0, ...secStart[n5] ? { shown: n5 - secStart[n5] + 1 } : {} });
|
|
22979
23001
|
else items[j++] = it;
|
|
22980
23002
|
}
|
|
22981
23003
|
items.length = j;
|
|
22982
23004
|
const out = frozen.length ? { items, frozen } : { items };
|
|
23005
|
+
if (win) {
|
|
23006
|
+
const u = slices[k * colCount]?.units[0];
|
|
23007
|
+
if (u?.dataRow != null) {
|
|
23008
|
+
out.firstRow = u.dataRow;
|
|
23009
|
+
out.rowHead = !!u.rowHead;
|
|
23010
|
+
if (u.headLevel != null) out.headLevel = u.headLevel;
|
|
23011
|
+
}
|
|
23012
|
+
}
|
|
22983
23013
|
if (pg.width !== first.width || ph !== pageH) {
|
|
22984
23014
|
out.width = pg.width;
|
|
22985
23015
|
out.height = ph;
|
|
@@ -23378,36 +23408,9 @@ function pdfEncryptOptions(pdf) {
|
|
|
23378
23408
|
}
|
|
23379
23409
|
|
|
23380
23410
|
// src/exporters/pdf.js
|
|
23381
|
-
import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as
|
|
23411
|
+
import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as PDFHexString5, PDFRawStream as PDFRawStream2, rgb as rgb3 } from "pdf-lib";
|
|
23382
23412
|
import fontkitModule2 from "@pdf-lib/fontkit";
|
|
23383
23413
|
|
|
23384
|
-
// src/exporters/color.js
|
|
23385
|
-
var NAMED2 = { black: "#000000", white: "#ffffff", red: "#ff0000", green: "#008000", blue: "#0000ff", gray: "#808080", grey: "#808080", orange: "#ffa500", yellow: "#ffff00" };
|
|
23386
|
-
function parseColor(c) {
|
|
23387
|
-
if (!c || c === "none" || c === "transparent") return null;
|
|
23388
|
-
let s = String(c).trim().toLowerCase();
|
|
23389
|
-
if (NAMED2[s]) s = NAMED2[s];
|
|
23390
|
-
let m = /^#([0-9a-f]{3,8})$/.exec(s);
|
|
23391
|
-
if (m) {
|
|
23392
|
-
let h = m[1];
|
|
23393
|
-
if (h.length === 3 || h.length === 4) h = [...h].map((x) => x + x).join("");
|
|
23394
|
-
const n5 = parseInt(h.slice(0, 6), 16);
|
|
23395
|
-
const a = h.length === 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1;
|
|
23396
|
-
return { r: (n5 >> 16 & 255) / 255, g: (n5 >> 8 & 255) / 255, b: (n5 & 255) / 255, a };
|
|
23397
|
-
}
|
|
23398
|
-
m = /^rgba?\(([^)]+)\)$/.exec(s);
|
|
23399
|
-
if (m) {
|
|
23400
|
-
const [r, g, b, a = 1] = m[1].split(/[\s,/]+/).map(Number);
|
|
23401
|
-
return { r: r / 255, g: g / 255, b: b / 255, a };
|
|
23402
|
-
}
|
|
23403
|
-
return null;
|
|
23404
|
-
}
|
|
23405
|
-
function cssColor(c) {
|
|
23406
|
-
const p = parseColor(c);
|
|
23407
|
-
if (!p) return "none";
|
|
23408
|
-
return `rgba(${Math.round(p.r * 255)},${Math.round(p.g * 255)},${Math.round(p.b * 255)},${p.a})`;
|
|
23409
|
-
}
|
|
23410
|
-
|
|
23411
23414
|
// src/exporters/pdfa.js
|
|
23412
23415
|
import { PDFName, PDFNumber as PDFNumber2, PDFString as PDFString2, PDFHexString as PDFHexString2, PDFArray as PDFArray2, PDFDict as PDFDict2 } from "pdf-lib";
|
|
23413
23416
|
var xml = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -23481,6 +23484,35 @@ function setUaMetadata(doc, { title: title2 = "Report", author = void 0, created
|
|
|
23481
23484
|
|
|
23482
23485
|
// src/exporters/svgimage.js
|
|
23483
23486
|
import { pushGraphicsState, popGraphicsState, concatTransformationMatrix, rgb } from "pdf-lib";
|
|
23487
|
+
|
|
23488
|
+
// src/exporters/color.js
|
|
23489
|
+
var NAMED2 = { black: "#000000", white: "#ffffff", red: "#ff0000", green: "#008000", blue: "#0000ff", gray: "#808080", grey: "#808080", orange: "#ffa500", yellow: "#ffff00" };
|
|
23490
|
+
function parseColor(c) {
|
|
23491
|
+
if (!c || c === "none" || c === "transparent") return null;
|
|
23492
|
+
let s = String(c).trim().toLowerCase();
|
|
23493
|
+
if (NAMED2[s]) s = NAMED2[s];
|
|
23494
|
+
let m = /^#([0-9a-f]{3,8})$/.exec(s);
|
|
23495
|
+
if (m) {
|
|
23496
|
+
let h = m[1];
|
|
23497
|
+
if (h.length === 3 || h.length === 4) h = [...h].map((x) => x + x).join("");
|
|
23498
|
+
const n5 = parseInt(h.slice(0, 6), 16);
|
|
23499
|
+
const a = h.length === 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1;
|
|
23500
|
+
return { r: (n5 >> 16 & 255) / 255, g: (n5 >> 8 & 255) / 255, b: (n5 & 255) / 255, a };
|
|
23501
|
+
}
|
|
23502
|
+
m = /^rgba?\(([^)]+)\)$/.exec(s);
|
|
23503
|
+
if (m) {
|
|
23504
|
+
const [r, g, b, a = 1] = m[1].split(/[\s,/]+/).map(Number);
|
|
23505
|
+
return { r: r / 255, g: g / 255, b: b / 255, a };
|
|
23506
|
+
}
|
|
23507
|
+
return null;
|
|
23508
|
+
}
|
|
23509
|
+
function cssColor(c) {
|
|
23510
|
+
const p = parseColor(c);
|
|
23511
|
+
if (!p) return "none";
|
|
23512
|
+
return `rgba(${Math.round(p.r * 255)},${Math.round(p.g * 255)},${Math.round(p.b * 255)},${p.a})`;
|
|
23513
|
+
}
|
|
23514
|
+
|
|
23515
|
+
// src/exporters/svgimage.js
|
|
23484
23516
|
var mul = (a, b) => [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], a[0] * b[4] + a[2] * b[5] + a[4], a[1] * b[4] + a[3] * b[5] + a[5]];
|
|
23485
23517
|
var I = [1, 0, 0, 1, 0, 0];
|
|
23486
23518
|
var TRANSFORMS = /* @__PURE__ */ new Set(["matrix", "translate", "scale", "rotate", "skewX", "skewY"]);
|
|
@@ -24547,11 +24579,8 @@ function pngProblem(b) {
|
|
|
24547
24579
|
return null;
|
|
24548
24580
|
}
|
|
24549
24581
|
|
|
24550
|
-
// src/exporters/
|
|
24551
|
-
|
|
24552
|
-
/** @type {any} */
|
|
24553
|
-
fontkitModule2.default || fontkitModule2
|
|
24554
|
-
);
|
|
24582
|
+
// src/exporters/pdfpaint.js
|
|
24583
|
+
import { PDFHexString as PDFHexString4, rgb as rgb2 } from "pdf-lib";
|
|
24555
24584
|
var colors = /* @__PURE__ */ new Map();
|
|
24556
24585
|
var col = (c) => {
|
|
24557
24586
|
if (colors.has(c)) return colors.get(c);
|
|
@@ -24566,148 +24595,463 @@ var n4 = (v) => Math.round(v * 1e4) / 1e4;
|
|
|
24566
24595
|
var hex4 = (id) => id.toString(16).padStart(4, "0");
|
|
24567
24596
|
var KAPPA = 4 * ((Math.SQRT2 - 1) / 3);
|
|
24568
24597
|
var cleanText = (t) => t.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
|
|
24569
|
-
function
|
|
24570
|
-
|
|
24571
|
-
|
|
24572
|
-
|
|
24573
|
-
|
|
24574
|
-
);
|
|
24575
|
-
|
|
24576
|
-
|
|
24577
|
-
|
|
24578
|
-
|
|
24579
|
-
|
|
24580
|
-
|
|
24581
|
-
|
|
24582
|
-
|
|
24583
|
-
|
|
24584
|
-
|
|
24585
|
-
|
|
24586
|
-
setInfoDates(doc, when);
|
|
24587
|
-
if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString4.of(fileId), PDFHexString4.of(fileId)]);
|
|
24588
|
-
const used = /* @__PURE__ */ new Map();
|
|
24589
|
-
const shaped = /* @__PURE__ */ new Map();
|
|
24590
|
-
const spans2 = /* @__PURE__ */ new WeakMap();
|
|
24591
|
-
const chars = (key) => {
|
|
24592
|
-
let c = used.get(key);
|
|
24593
|
-
if (!c) {
|
|
24594
|
-
c = /* @__PURE__ */ new Set([32]);
|
|
24595
|
-
used.set(key, c);
|
|
24596
|
-
}
|
|
24597
|
-
return c;
|
|
24598
|
+
function drawRun(c, run, x, y, size, pf, color2, spans2, texts) {
|
|
24599
|
+
const f4 = pf.embedder.font;
|
|
24600
|
+
const per = 1e3 / size;
|
|
24601
|
+
const span = (text2) => `/Span <</ActualText ${PDFHexString4.fromText(text2).toString()}>> BDC
|
|
24602
|
+
`;
|
|
24603
|
+
c.et();
|
|
24604
|
+
c.paint(color2, null);
|
|
24605
|
+
c.font(pf, size);
|
|
24606
|
+
if (!run.rtl) c.s += span(run.text);
|
|
24607
|
+
c.s += `BT ${n2(x)} ${n2(y)} Td
|
|
24608
|
+
`;
|
|
24609
|
+
let arr = "";
|
|
24610
|
+
let pen = 0, rise = 0;
|
|
24611
|
+
const flush = () => {
|
|
24612
|
+
if (arr) c.s += `[${arr}] TJ
|
|
24613
|
+
`;
|
|
24614
|
+
arr = "";
|
|
24598
24615
|
};
|
|
24599
|
-
|
|
24600
|
-
|
|
24601
|
-
|
|
24602
|
-
|
|
24603
|
-
|
|
24604
|
-
|
|
24605
|
-
|
|
24606
|
-
|
|
24607
|
-
|
|
24608
|
-
|
|
24609
|
-
for (
|
|
24610
|
-
const c = chars(r.font);
|
|
24611
|
-
for (const ch of r.text) c.add(
|
|
24612
|
-
/** @type {number} */
|
|
24613
|
-
ch.codePointAt(0)
|
|
24614
|
-
);
|
|
24615
|
-
let g = shaped.get(r.font);
|
|
24616
|
-
if (!g) {
|
|
24617
|
-
g = /* @__PURE__ */ new Map();
|
|
24618
|
-
shaped.set(r.font, g);
|
|
24619
|
-
}
|
|
24620
|
-
glyphText(r, fontStore2.get(r.font), g, spans2);
|
|
24621
|
-
}
|
|
24616
|
+
const all = run.glyphs;
|
|
24617
|
+
const adv = (id) => f4.getGlyph(id).advanceWidth;
|
|
24618
|
+
let g = all, quietAt = -1;
|
|
24619
|
+
if (run.rtl) {
|
|
24620
|
+
const hasBase = /* @__PURE__ */ new Set();
|
|
24621
|
+
for (let i = 0; i < all.length; i += 4) if (adv(all[i]) > 0) hasBase.add(all[i + 3]);
|
|
24622
|
+
const quiet = (i) => spans2?.has(all[i + 3]) ? adv(all[i]) === 0 && hasBase.has(all[i + 3]) : texts?.get(all[i]) === "";
|
|
24623
|
+
g = [];
|
|
24624
|
+
for (const late of [false, true]) {
|
|
24625
|
+
if (late) quietAt = g.length;
|
|
24626
|
+
for (let i = 0; i < all.length; i += 4) if (quiet(i) === late) g.push(all[i], all[i + 1], all[i + 2], all[i + 3]);
|
|
24622
24627
|
}
|
|
24628
|
+
if (quietAt === g.length) quietAt = -1;
|
|
24623
24629
|
}
|
|
24624
|
-
const
|
|
24625
|
-
|
|
24626
|
-
|
|
24627
|
-
|
|
24628
|
-
if (
|
|
24629
|
-
|
|
24630
|
-
|
|
24631
|
-
|
|
24632
|
-
|
|
24633
|
-
|
|
24634
|
-
|
|
24635
|
-
|
|
24636
|
-
const sub = withPadding(await opt.subset(bytes, cps, glyphs ? { glyphs: glyphs.keys() } : void 0));
|
|
24637
|
-
const f4 = fontkit2.create(sub);
|
|
24638
|
-
for (const cp of cps) void f4.glyphForCodePoint(cp).advanceWidth;
|
|
24639
|
-
for (const id of glyphs?.keys() || []) void f4.getGlyph(id).advanceWidth;
|
|
24640
|
-
bytes = sub;
|
|
24641
|
-
} catch {
|
|
24642
|
-
}
|
|
24643
|
-
}
|
|
24644
|
-
const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag(bytes)}+${fontStore2.get(key).postscriptName || "Font"}` });
|
|
24645
|
-
plainEncoding(pf);
|
|
24646
|
-
if (glyphs) addGlyphs(pf, glyphs, !!opt.tagged);
|
|
24647
|
-
const file = bytes, e2 = (
|
|
24648
|
-
/** @type {any} */
|
|
24649
|
-
pf.embedder
|
|
24650
|
-
);
|
|
24651
|
-
if (!e2.isCFF()) e2.embedFontStream = async (c) => c.register(PDFRawStream2.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
|
|
24652
|
-
fonts.set(key, pf);
|
|
24630
|
+
const starts = run.rtl ? [...new Set(all.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b) : [];
|
|
24631
|
+
let inSpan = false;
|
|
24632
|
+
for (let i = 0; i < g.length; i += 4) {
|
|
24633
|
+
const id = g[i], gx = g[i + 1], gy = g[i + 2], cl = g[i + 3];
|
|
24634
|
+
if (i === quietAt) {
|
|
24635
|
+
flush();
|
|
24636
|
+
c.s += span("");
|
|
24637
|
+
inSpan = true;
|
|
24638
|
+
} else if (run.rtl && spans2?.has(cl) && (quietAt < 0 || i < quietAt) && (i === 0 || g[i - 1] !== cl)) {
|
|
24639
|
+
flush();
|
|
24640
|
+
c.s += span(run.text.slice(cl, starts[starts.indexOf(cl) + 1] ?? run.text.length));
|
|
24641
|
+
inSpan = true;
|
|
24653
24642
|
}
|
|
24654
|
-
|
|
24655
|
-
|
|
24656
|
-
|
|
24657
|
-
|
|
24658
|
-
|
|
24659
|
-
const out = await loadImage(src).catch((e2) => ({ img: null, why: `it could not be embedded (${e2?.message || e2})` }));
|
|
24660
|
-
images.set(src, out);
|
|
24661
|
-
return out;
|
|
24662
|
-
};
|
|
24663
|
-
async function loadImage(src) {
|
|
24664
|
-
const local = /^data:/i.test(src);
|
|
24665
|
-
if (local && dataUriBytes(src) > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
24666
|
-
if (!local && !opt.fetchImage) return { img: null, why: "it is a URL, and no fetchImage was given to load it" };
|
|
24667
|
-
const bytes = local ? dataUriBytesOf(src) : await opt.fetchImage(src);
|
|
24668
|
-
if (!bytes?.length) return { img: null, why: "it could not be loaded" };
|
|
24669
|
-
if (bytes.length > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
24670
|
-
const info = imageInfoOf(bytes);
|
|
24671
|
-
if (info?.type === "svg") {
|
|
24672
|
-
const svg = parseSvg(new TextDecoder().decode(bytes));
|
|
24673
|
-
return svg ? { img: { svg, width: svg.w, height: svg.h } } : { img: null, why: "the SVG could not be read" };
|
|
24643
|
+
if (gy !== rise) {
|
|
24644
|
+
flush();
|
|
24645
|
+
c.s += `${n4(gy)} Ts
|
|
24646
|
+
`;
|
|
24647
|
+
rise = gy;
|
|
24674
24648
|
}
|
|
24675
|
-
|
|
24676
|
-
|
|
24677
|
-
|
|
24678
|
-
|
|
24649
|
+
const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
|
|
24650
|
+
if (id === 0 && c.tagged) pen = gx;
|
|
24651
|
+
else {
|
|
24652
|
+
arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
|
|
24653
|
+
pen = gx + adv(id) * size / f4.unitsPerEm;
|
|
24679
24654
|
}
|
|
24680
|
-
if (
|
|
24681
|
-
|
|
24682
|
-
|
|
24683
|
-
|
|
24684
|
-
const res = ctx.obj({ Font: {}, ExtGState: {}, XObject: {} });
|
|
24685
|
-
const resRef = ctx.register(res);
|
|
24686
|
-
const names = /* @__PURE__ */ new Map();
|
|
24687
|
-
const nameOf = (kind, key, value) => {
|
|
24688
|
-
let n5 = names.get(key);
|
|
24689
|
-
if (!n5) {
|
|
24690
|
-
n5 = `${kind[0]}${names.size + 1}`;
|
|
24691
|
-
names.set(key, n5);
|
|
24692
|
-
res.get(PDFName3.of(kind)).set(PDFName3.of(n5), value());
|
|
24655
|
+
if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
|
|
24656
|
+
flush();
|
|
24657
|
+
c.s += "EMC\n";
|
|
24658
|
+
inSpan = false;
|
|
24693
24659
|
}
|
|
24694
|
-
|
|
24695
|
-
|
|
24696
|
-
|
|
24697
|
-
|
|
24698
|
-
|
|
24699
|
-
|
|
24700
|
-
|
|
24701
|
-
const
|
|
24702
|
-
const
|
|
24703
|
-
|
|
24704
|
-
|
|
24705
|
-
|
|
24706
|
-
|
|
24707
|
-
|
|
24708
|
-
|
|
24709
|
-
|
|
24710
|
-
|
|
24660
|
+
}
|
|
24661
|
+
flush();
|
|
24662
|
+
if (rise) c.s += "0 Ts\n";
|
|
24663
|
+
c.s += "ET\n";
|
|
24664
|
+
if (!run.rtl) c.s += "EMC\n";
|
|
24665
|
+
}
|
|
24666
|
+
function glyphText(run, font, out, spans2) {
|
|
24667
|
+
const g = run.glyphs;
|
|
24668
|
+
const starts = [...new Set(g.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b);
|
|
24669
|
+
for (let k = 0; k < starts.length; k++) {
|
|
24670
|
+
const chars = [...run.text.slice(starts[k], starts[k + 1] ?? run.text.length)];
|
|
24671
|
+
const ids = [];
|
|
24672
|
+
for (let i = 0; i < g.length; i += 4) if (g[i + 3] === starts[k]) ids.push(g[i]);
|
|
24673
|
+
const own = new Map(chars.map((ch) => [font.glyphForCodePoint(ch.codePointAt(0)).id, ch]));
|
|
24674
|
+
const rest2 = chars.filter((ch) => !ids.includes(font.glyphForCodePoint(ch.codePointAt(0)).id)).join("");
|
|
24675
|
+
const carrier = rest2 ? ids.find((id) => !own.has(id) && font.getGlyph(id).advanceWidth > 0) ?? ids.find((id) => !own.has(id)) : void 0;
|
|
24676
|
+
let ok = !rest2 || carrier !== void 0;
|
|
24677
|
+
const want = /* @__PURE__ */ new Map();
|
|
24678
|
+
for (const id of ids) {
|
|
24679
|
+
const t = own.get(id) ?? (id === carrier ? rest2 : "");
|
|
24680
|
+
if (want.has(id) && want.get(id) !== t) ok = false;
|
|
24681
|
+
want.set(id, t);
|
|
24682
|
+
}
|
|
24683
|
+
for (const [id, t] of want) {
|
|
24684
|
+
if (!out.has(id)) out.set(id, t);
|
|
24685
|
+
else if (out.get(id) !== t) ok = false;
|
|
24686
|
+
}
|
|
24687
|
+
if (!ok && run.rtl && spans2) {
|
|
24688
|
+
let s = spans2.get(run);
|
|
24689
|
+
if (!s) spans2.set(run, s = /* @__PURE__ */ new Set());
|
|
24690
|
+
s.add(starts[k]);
|
|
24691
|
+
}
|
|
24692
|
+
}
|
|
24693
|
+
}
|
|
24694
|
+
function insideClip(it, m) {
|
|
24695
|
+
const k = it.clip, asc = m.asc * it.size, desc = m.desc * it.size;
|
|
24696
|
+
return it.lines.every((l) => l.w != null && !l.runs && l.x >= k.x && l.x + l.w <= k.x + k.w && l.y - asc >= k.y && l.y + desc <= k.y + k.h);
|
|
24697
|
+
}
|
|
24698
|
+
var Content = class {
|
|
24699
|
+
constructor(shared) {
|
|
24700
|
+
this.shared = shared;
|
|
24701
|
+
this._s = "";
|
|
24702
|
+
this.bt = false;
|
|
24703
|
+
this.tx = 0;
|
|
24704
|
+
this.ty = 0;
|
|
24705
|
+
this.st = { fill: "0 0 0", stroke: "0 0 0", lw: 1, dash: "[] 0", ca: 1, CA: 1, font: "", size: 0 };
|
|
24706
|
+
this.saved = [];
|
|
24707
|
+
this.lines = null;
|
|
24708
|
+
this.tagged = false;
|
|
24709
|
+
}
|
|
24710
|
+
/**
|
|
24711
|
+
* The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
|
|
24712
|
+
* of a table's cells stays in one text object (relative moves, which compress to little) instead of one per cell.
|
|
24713
|
+
*/
|
|
24714
|
+
get s() {
|
|
24715
|
+
this.flushLines();
|
|
24716
|
+
return this._s;
|
|
24717
|
+
}
|
|
24718
|
+
set s(v) {
|
|
24719
|
+
this._s = v;
|
|
24720
|
+
}
|
|
24721
|
+
/**
|
|
24722
|
+
* A straight line. Untagged, it waits until something other than text is drawn (table borders between cell
|
|
24723
|
+
* texts); collinear segments that touch, in the same stroke, become one (a row's border is one line).
|
|
24724
|
+
* ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
|
|
24725
|
+
*/
|
|
24726
|
+
line(stroke, w, dash, x1, y1, x2, y2) {
|
|
24727
|
+
if (this.tagged) {
|
|
24728
|
+
this.paint(null, stroke, w, dash);
|
|
24729
|
+
this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
|
|
24730
|
+
`;
|
|
24731
|
+
return;
|
|
24732
|
+
}
|
|
24733
|
+
const key = `${stroke.rgb}|${stroke.opacity}|${w}|${(dash || []).join(" ")}`;
|
|
24734
|
+
if (this.lines && this.lines.key !== key) this.flushLines();
|
|
24735
|
+
this.lines ||= { key, stroke, w, dash, segs: [] };
|
|
24736
|
+
const segs = this.lines.segs, last = segs[segs.length - 1];
|
|
24737
|
+
const eq = (a, b) => Math.abs(a - b) < 5e-3;
|
|
24738
|
+
if (last && eq(last[1], y1) && eq(last[3], y2) && eq(y1, y2) && eq(last[2], x1)) last[2] = x2;
|
|
24739
|
+
else if (last && eq(last[0], x1) && eq(last[2], x2) && eq(x1, x2) && eq(last[3], y1)) last[3] = y2;
|
|
24740
|
+
else segs.push([x1, y1, x2, y2]);
|
|
24741
|
+
}
|
|
24742
|
+
flushLines() {
|
|
24743
|
+
const L = this.lines;
|
|
24744
|
+
if (!L) return;
|
|
24745
|
+
this.lines = null;
|
|
24746
|
+
this.et();
|
|
24747
|
+
this.paint(null, L.stroke, L.w, L.dash);
|
|
24748
|
+
const g = L.segs;
|
|
24749
|
+
const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
|
|
24750
|
+
if (dy && g.every((q3, i) => q3[1] === q3[3] && n2(q3[0]) === n2(g[0][0]) && n2(q3[2]) === n2(g[0][2]) && Math.abs(q3[1] - (g[0][1] + i * dy / 100)) < 0.01)) {
|
|
24751
|
+
const one = `${n2(g[0][0])} ${n2(g[0][1])} m ${n2(g[0][2])} ${n2(g[0][1])} l S
|
|
24752
|
+
`;
|
|
24753
|
+
this._s += `q
|
|
24754
|
+
${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
|
|
24755
|
+
`;
|
|
24756
|
+
return;
|
|
24757
|
+
}
|
|
24758
|
+
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
|
|
24759
|
+
}
|
|
24760
|
+
q() {
|
|
24761
|
+
this.et();
|
|
24762
|
+
this._s += "q\n";
|
|
24763
|
+
this.saved.push({ ...this.st });
|
|
24764
|
+
}
|
|
24765
|
+
Q() {
|
|
24766
|
+
this.et();
|
|
24767
|
+
this._s += "Q\n";
|
|
24768
|
+
this.st = this.saved.pop();
|
|
24769
|
+
}
|
|
24770
|
+
/**
|
|
24771
|
+
* A line of plain text at (x, y). Lines follow one another in one text object, each placed relative to the
|
|
24772
|
+
* last (in whole hundredths, so nothing drifts): most of a table page is these.
|
|
24773
|
+
* @param {string} str the glyphs, as a literal string's escaped body (array: a TJ array's body)
|
|
24774
|
+
*/
|
|
24775
|
+
text(pf, size, color2, x, y, str, array = false) {
|
|
24776
|
+
this.setPaint(color2, null);
|
|
24777
|
+
this.setFont(pf, size);
|
|
24778
|
+
const X = Math.round(x * 10) * 10, Y = Math.round(y * 10) * 10;
|
|
24779
|
+
if (!this.bt) {
|
|
24780
|
+
this._s += "BT\n";
|
|
24781
|
+
this.bt = true;
|
|
24782
|
+
this.tx = 0;
|
|
24783
|
+
this.ty = 0;
|
|
24784
|
+
}
|
|
24785
|
+
this._s += array ? `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td [${str}] TJ
|
|
24786
|
+
` : `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td (${str}) Tj
|
|
24787
|
+
`;
|
|
24788
|
+
this.tx = X;
|
|
24789
|
+
this.ty = Y;
|
|
24790
|
+
}
|
|
24791
|
+
/** end the open text object, if any: anything but text needs that (and draws the lines waiting) */
|
|
24792
|
+
et() {
|
|
24793
|
+
if (this.bt) {
|
|
24794
|
+
this._s += "ET\n";
|
|
24795
|
+
this.bt = false;
|
|
24796
|
+
}
|
|
24797
|
+
if (this.lines) this.flushLines();
|
|
24798
|
+
}
|
|
24799
|
+
lineWidth(w) {
|
|
24800
|
+
if (this.lines) this.flushLines();
|
|
24801
|
+
this.setLineWidth(w);
|
|
24802
|
+
}
|
|
24803
|
+
setLineWidth(w) {
|
|
24804
|
+
if (this.st.lw !== w) {
|
|
24805
|
+
this._s += `${n3(w)} w
|
|
24806
|
+
`;
|
|
24807
|
+
this.st.lw = w;
|
|
24808
|
+
}
|
|
24809
|
+
}
|
|
24810
|
+
/** the graphics state that sets these opacities, or undefined when they are set already */
|
|
24811
|
+
gsFor(ca, CA) {
|
|
24812
|
+
return ca === this.st.ca && CA === this.st.CA ? void 0 : this.shared.gs(ca, CA);
|
|
24813
|
+
}
|
|
24814
|
+
alpha(ca, CA) {
|
|
24815
|
+
if (this.lines) this.flushLines();
|
|
24816
|
+
this.setAlpha(ca, CA);
|
|
24817
|
+
}
|
|
24818
|
+
setAlpha(ca, CA) {
|
|
24819
|
+
const g = this.gsFor(ca, CA);
|
|
24820
|
+
if (g) {
|
|
24821
|
+
this._s += `/${g} gs
|
|
24822
|
+
`;
|
|
24823
|
+
this.st.ca = ca;
|
|
24824
|
+
this.st.CA = CA;
|
|
24825
|
+
}
|
|
24826
|
+
}
|
|
24827
|
+
/** set up to fill with fill and/or stroke with stroke (width w, dash); the lines waiting are drawn first */
|
|
24828
|
+
paint(fill3, stroke, w = 1, dash = null) {
|
|
24829
|
+
if (this.lines) this.flushLines();
|
|
24830
|
+
this.setPaint(fill3, stroke, w, dash);
|
|
24831
|
+
}
|
|
24832
|
+
setPaint(fill3, stroke, w = 1, dash = null) {
|
|
24833
|
+
const st = this.st;
|
|
24834
|
+
if (fill3 && fill3.rgb !== st.fill) {
|
|
24835
|
+
this._s += `${fill3.rgb} rg
|
|
24836
|
+
`;
|
|
24837
|
+
st.fill = fill3.rgb;
|
|
24838
|
+
}
|
|
24839
|
+
if (stroke) {
|
|
24840
|
+
if (stroke.rgb !== st.stroke) {
|
|
24841
|
+
this._s += `${stroke.rgb} RG
|
|
24842
|
+
`;
|
|
24843
|
+
st.stroke = stroke.rgb;
|
|
24844
|
+
}
|
|
24845
|
+
this.setLineWidth(w);
|
|
24846
|
+
const d = `[${(dash || []).map(n3).join(" ")}] 0`;
|
|
24847
|
+
if (d !== st.dash) {
|
|
24848
|
+
this._s += `${d} d
|
|
24849
|
+
`;
|
|
24850
|
+
st.dash = d;
|
|
24851
|
+
}
|
|
24852
|
+
}
|
|
24853
|
+
this.setAlpha(fill3 ? fill3.opacity : st.ca, stroke ? stroke.opacity : st.CA);
|
|
24854
|
+
}
|
|
24855
|
+
font(pf, size) {
|
|
24856
|
+
if (this.lines) this.flushLines();
|
|
24857
|
+
this.setFont(pf, size);
|
|
24858
|
+
}
|
|
24859
|
+
setFont(pf, size) {
|
|
24860
|
+
const name = this.shared.font(pf);
|
|
24861
|
+
if (name !== this.st.font || size !== this.st.size) {
|
|
24862
|
+
this._s += `/${name} ${n3(size)} Tf
|
|
24863
|
+
`;
|
|
24864
|
+
this.st.font = name;
|
|
24865
|
+
this.st.size = size;
|
|
24866
|
+
}
|
|
24867
|
+
}
|
|
24868
|
+
};
|
|
24869
|
+
function latin1(s) {
|
|
24870
|
+
const B = (
|
|
24871
|
+
/** @type {any} */
|
|
24872
|
+
globalThis.Buffer
|
|
24873
|
+
);
|
|
24874
|
+
if (B) return B.from(s, "latin1");
|
|
24875
|
+
const out = new Uint8Array(s.length);
|
|
24876
|
+
for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
|
|
24877
|
+
return out;
|
|
24878
|
+
}
|
|
24879
|
+
async function deflate(bytes) {
|
|
24880
|
+
if (zslots.free > 0) zslots.free--;
|
|
24881
|
+
else await new Promise((ok) => zslots.wait.push(
|
|
24882
|
+
/** @type {() => void} */
|
|
24883
|
+
ok
|
|
24884
|
+
));
|
|
24885
|
+
try {
|
|
24886
|
+
return await deflateNow(bytes);
|
|
24887
|
+
} finally {
|
|
24888
|
+
const next = zslots.wait.shift();
|
|
24889
|
+
if (next) next();
|
|
24890
|
+
else zslots.free++;
|
|
24891
|
+
}
|
|
24892
|
+
}
|
|
24893
|
+
var zslots = { free: 4, wait: (
|
|
24894
|
+
/** @type {(() => void)[]} */
|
|
24895
|
+
[]
|
|
24896
|
+
) };
|
|
24897
|
+
var NODE_ZLIB = (
|
|
24898
|
+
/** @type {any} */
|
|
24899
|
+
globalThis.process?.getBuiltinModule?.("node:zlib")
|
|
24900
|
+
);
|
|
24901
|
+
async function deflateNow(bytes) {
|
|
24902
|
+
const zlib = NODE_ZLIB;
|
|
24903
|
+
if (zlib) return new Promise((ok, fail2) => zlib.deflate(bytes, { level: 9 }, (e2, z) => e2 ? fail2(e2) : ok(z)));
|
|
24904
|
+
if (typeof CompressionStream === "undefined") return (await import("fflate")).zlibSync(bytes);
|
|
24905
|
+
return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
|
|
24906
|
+
}
|
|
24907
|
+
|
|
24908
|
+
// src/exporters/pdf.js
|
|
24909
|
+
var fontkit2 = (
|
|
24910
|
+
/** @type {any} */
|
|
24911
|
+
fontkitModule2.default || fontkitModule2
|
|
24912
|
+
);
|
|
24913
|
+
function exportPdf(model, fontStore2, opt = {}) {
|
|
24914
|
+
return withDeadline(
|
|
24915
|
+
pdfOf(model, fontStore2, opt),
|
|
24916
|
+
/** @type {any} */
|
|
24917
|
+
opt.timeoutMs
|
|
24918
|
+
);
|
|
24919
|
+
}
|
|
24920
|
+
async function pdfOf(model, fontStore2, opt) {
|
|
24921
|
+
const fixed2 = fixedDate(opt);
|
|
24922
|
+
const when = fixed2 ?? /* @__PURE__ */ new Date();
|
|
24923
|
+
const fileId = fixed2 ? await contentId(model, opt, when) : void 0;
|
|
24924
|
+
const doc = await PDFDocument.create({ updateMetadata: false });
|
|
24925
|
+
doc.registerFontkit(fontkit2);
|
|
24926
|
+
doc.setTitle(opt.title || "Report");
|
|
24927
|
+
doc.setProducer("ReportWright");
|
|
24928
|
+
doc.setCreator("ReportWright");
|
|
24929
|
+
if (opt.author) doc.setAuthor(opt.author);
|
|
24930
|
+
setInfoDates(doc, when);
|
|
24931
|
+
if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString5.of(fileId), PDFHexString5.of(fileId)]);
|
|
24932
|
+
const used = /* @__PURE__ */ new Map();
|
|
24933
|
+
const shaped = /* @__PURE__ */ new Map();
|
|
24934
|
+
const spans2 = /* @__PURE__ */ new WeakMap();
|
|
24935
|
+
const chars = (key) => {
|
|
24936
|
+
let c = used.get(key);
|
|
24937
|
+
if (!c) {
|
|
24938
|
+
c = /* @__PURE__ */ new Set([32]);
|
|
24939
|
+
used.set(key, c);
|
|
24940
|
+
}
|
|
24941
|
+
return c;
|
|
24942
|
+
};
|
|
24943
|
+
for (const pg of model.pages) for (const it of pg.items.flatMap((i) => i.t === "field" ? i.draw.filter((d) => d.t === "text") : i.t === "text" ? [i] : [])) {
|
|
24944
|
+
for (const l of it.lines) {
|
|
24945
|
+
if (!l.runs) {
|
|
24946
|
+
const c = chars(it.font);
|
|
24947
|
+
for (const ch of l.text) c.add(
|
|
24948
|
+
/** @type {number} */
|
|
24949
|
+
ch.codePointAt(0)
|
|
24950
|
+
);
|
|
24951
|
+
continue;
|
|
24952
|
+
}
|
|
24953
|
+
for (const r of l.runs) {
|
|
24954
|
+
const c = chars(r.font);
|
|
24955
|
+
for (const ch of r.text) c.add(
|
|
24956
|
+
/** @type {number} */
|
|
24957
|
+
ch.codePointAt(0)
|
|
24958
|
+
);
|
|
24959
|
+
let g = shaped.get(r.font);
|
|
24960
|
+
if (!g) {
|
|
24961
|
+
g = /* @__PURE__ */ new Map();
|
|
24962
|
+
shaped.set(r.font, g);
|
|
24963
|
+
}
|
|
24964
|
+
glyphText(r, fontStore2.get(r.font), g, spans2);
|
|
24965
|
+
}
|
|
24966
|
+
}
|
|
24967
|
+
}
|
|
24968
|
+
const fieldFonts = /* @__PURE__ */ new Set();
|
|
24969
|
+
for (const pg of model.pages) for (const it of pg.items) if (it.t === "field") fieldFonts.add(fieldFont(it));
|
|
24970
|
+
const fonts = /* @__PURE__ */ new Map();
|
|
24971
|
+
const font = async (key) => {
|
|
24972
|
+
if (!fonts.has(key)) {
|
|
24973
|
+
const full = fontStore2.bytes.get(key);
|
|
24974
|
+
let bytes = full;
|
|
24975
|
+
if (!bytes) throw new Error(`Font "${key}" is not loaded`);
|
|
24976
|
+
const glyphs = shaped.get(key);
|
|
24977
|
+
if (opt.subset && !fieldFonts.has(key) && !fontStore2.get(key)["OS/2"]?.fsType?.noSubsetting) {
|
|
24978
|
+
const cps = used.get(key) || /* @__PURE__ */ new Set([32]);
|
|
24979
|
+
try {
|
|
24980
|
+
const sub = withPadding(await opt.subset(bytes, cps, glyphs ? { glyphs: glyphs.keys() } : void 0));
|
|
24981
|
+
const f4 = fontkit2.create(sub);
|
|
24982
|
+
for (const cp of cps) void f4.glyphForCodePoint(cp).advanceWidth;
|
|
24983
|
+
for (const id of glyphs?.keys() || []) void f4.getGlyph(id).advanceWidth;
|
|
24984
|
+
bytes = sub;
|
|
24985
|
+
} catch {
|
|
24986
|
+
}
|
|
24987
|
+
}
|
|
24988
|
+
const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag(bytes)}+${fontStore2.get(key).postscriptName || "Font"}` });
|
|
24989
|
+
plainEncoding(pf);
|
|
24990
|
+
if (glyphs) addGlyphs(pf, glyphs, !!opt.tagged);
|
|
24991
|
+
const file = bytes, e2 = (
|
|
24992
|
+
/** @type {any} */
|
|
24993
|
+
pf.embedder
|
|
24994
|
+
);
|
|
24995
|
+
if (!e2.isCFF()) e2.embedFontStream = async (c) => c.register(PDFRawStream2.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
|
|
24996
|
+
fonts.set(key, pf);
|
|
24997
|
+
}
|
|
24998
|
+
return fonts.get(key);
|
|
24999
|
+
};
|
|
25000
|
+
const images = /* @__PURE__ */ new Map();
|
|
25001
|
+
const image2 = async (src) => {
|
|
25002
|
+
if (images.has(src)) return images.get(src);
|
|
25003
|
+
const out = await loadImage(src).catch((e2) => ({ img: null, why: `it could not be embedded (${e2?.message || e2})` }));
|
|
25004
|
+
images.set(src, out);
|
|
25005
|
+
return out;
|
|
25006
|
+
};
|
|
25007
|
+
async function loadImage(src) {
|
|
25008
|
+
const local = /^data:/i.test(src);
|
|
25009
|
+
if (local && dataUriBytes(src) > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
25010
|
+
if (!local && !opt.fetchImage) return { img: null, why: "it is a URL, and no fetchImage was given to load it" };
|
|
25011
|
+
const bytes = local ? dataUriBytesOf(src) : await opt.fetchImage(src);
|
|
25012
|
+
if (!bytes?.length) return { img: null, why: "it could not be loaded" };
|
|
25013
|
+
if (bytes.length > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
25014
|
+
const info = imageInfoOf(bytes);
|
|
25015
|
+
if (info?.type === "svg") {
|
|
25016
|
+
const svg = parseSvg(new TextDecoder().decode(bytes));
|
|
25017
|
+
return svg ? { img: { svg, width: svg.w, height: svg.h } } : { img: null, why: "the SVG could not be read" };
|
|
25018
|
+
}
|
|
25019
|
+
if (info?.type === "png") {
|
|
25020
|
+
const why = "w" in info && !/** @type {any} */
|
|
25021
|
+
info.suspect && info.w * info.h <= IMAGE_LIMITS.pixels ? pngProblem(bytes) : "too large or animated";
|
|
25022
|
+
return why ? { img: null, why: `the PNG is not usable (${why})` } : { img: await doc.embedPng(bytes) };
|
|
25023
|
+
}
|
|
25024
|
+
if (info?.type === "jpeg") return { img: await doc.embedJpg(bytes) };
|
|
25025
|
+
return { img: null, why: info ? `${info.type.toUpperCase()} is not embedded (PNG, JPEG and SVG are)` : "it is not a PNG, JPEG or SVG" };
|
|
25026
|
+
}
|
|
25027
|
+
const ctx = doc.context;
|
|
25028
|
+
const res = ctx.obj({ Font: {}, ExtGState: {}, XObject: {} });
|
|
25029
|
+
const resRef = ctx.register(res);
|
|
25030
|
+
const names = /* @__PURE__ */ new Map();
|
|
25031
|
+
const nameOf = (kind, key, value) => {
|
|
25032
|
+
let n5 = names.get(key);
|
|
25033
|
+
if (!n5) {
|
|
25034
|
+
n5 = `${kind[0]}${names.size + 1}`;
|
|
25035
|
+
names.set(key, n5);
|
|
25036
|
+
res.get(PDFName3.of(kind)).set(PDFName3.of(n5), value());
|
|
25037
|
+
}
|
|
25038
|
+
return n5;
|
|
25039
|
+
};
|
|
25040
|
+
const shared = {
|
|
25041
|
+
font: (pf) => nameOf("Font", pf, () => pf.ref),
|
|
25042
|
+
gs: (ca, CA) => nameOf("ExtGState", `gs ${ca} ${CA}`, () => ctx.obj({ Type: "ExtGState", ca, CA })),
|
|
25043
|
+
image: (img) => nameOf("XObject", img, () => img.ref)
|
|
25044
|
+
};
|
|
25045
|
+
const links = [];
|
|
25046
|
+
const taken = /* @__PURE__ */ new Set();
|
|
25047
|
+
const uniqueName = (n5) => {
|
|
25048
|
+
let name = n5, i = 1;
|
|
25049
|
+
while (taken.has(name)) name = `${n5}_${++i}`;
|
|
25050
|
+
taken.add(name);
|
|
25051
|
+
return name;
|
|
25052
|
+
};
|
|
25053
|
+
const contents = [];
|
|
25054
|
+
if (opt.tagged) needsTableData(model, "An accessible PDF");
|
|
24711
25055
|
const tags = opt.tagged ? createTagger(model, doc) : null;
|
|
24712
25056
|
let pi = -1;
|
|
24713
25057
|
const vm = /* @__PURE__ */ new Map();
|
|
@@ -24831,7 +25175,7 @@ async function pdfOf(model, fontStore2, opt) {
|
|
|
24831
25175
|
const form = doc.getForm();
|
|
24832
25176
|
const f4 = await font(fieldFont(it));
|
|
24833
25177
|
const name = uniqueName(it.name);
|
|
24834
|
-
const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor:
|
|
25178
|
+
const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb3(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb3(1, 1, 1) };
|
|
24835
25179
|
let field;
|
|
24836
25180
|
if (it.kind === "checkbox") {
|
|
24837
25181
|
field = form.createCheckBox(name);
|
|
@@ -24888,7 +25232,7 @@ async function pdfOf(model, fontStore2, opt) {
|
|
|
24888
25232
|
if (it.required) field.enableRequired();
|
|
24889
25233
|
if (it.readOnly) field.enableReadOnly();
|
|
24890
25234
|
if (tags) {
|
|
24891
|
-
field.acroField.dict.set(PDFName3.of("TU"),
|
|
25235
|
+
field.acroField.dict.set(PDFName3.of("TU"), PDFHexString5.fromText(it.label || it.name || name));
|
|
24892
25236
|
const w = field.acroField.getWidgets()[0];
|
|
24893
25237
|
const ref3 = w && doc.context.getObjectRef(w.dict);
|
|
24894
25238
|
if (ref3) tags.annot(pi, ii, ref3, "field");
|
|
@@ -24962,7 +25306,7 @@ async function pdfOf(model, fontStore2, opt) {
|
|
|
24962
25306
|
const to = l.href ? { A: { Type: "Action", S: "URI", URI: pdfLiteral(asciiUrl(l.href)) } } : { Dest: dest(l.to) };
|
|
24963
25307
|
if (!l.href && !to.Dest) continue;
|
|
24964
25308
|
const annot = doc.context.obj({ Type: "Annot", Subtype: "Link", F: 4, Rect: l.rect, Border: [0, 0, 0], ...to });
|
|
24965
|
-
if (tags) annot.set(PDFName3.of("Contents"),
|
|
25309
|
+
if (tags) annot.set(PDFName3.of("Contents"), PDFHexString5.fromText(String(l.text || l.tip || l.href || "Link")));
|
|
24966
25310
|
const ref2 = doc.context.register(annot);
|
|
24967
25311
|
if (tags) tags.annot(l.pi, l.ii, ref2, "link");
|
|
24968
25312
|
const annots = l.page.node.lookup(PDFName3.of("Annots"));
|
|
@@ -24989,122 +25333,26 @@ function coveredText(items, box) {
|
|
|
24989
25333
|
for (const t of items) if (t.t === "text" && t.lines) {
|
|
24990
25334
|
for (const l of t.lines) if (l.text?.trim() && l.x >= box.x && l.x <= box.x + box.w && l.y >= box.y && l.y <= box.y + box.h) lines.push(l);
|
|
24991
25335
|
}
|
|
24992
|
-
return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
|
|
24993
|
-
}
|
|
24994
|
-
function fixedDate(opt) {
|
|
24995
|
-
if (opt.creationDate !== void 0) {
|
|
24996
|
-
if (!(opt.creationDate instanceof Date) || Number.isNaN(opt.creationDate.getTime())) throw Object.assign(new Error("creationDate must be a valid Date"), { status: 400 });
|
|
24997
|
-
return opt.creationDate;
|
|
24998
|
-
}
|
|
24999
|
-
const epoch = globalThis.process?.env?.SOURCE_DATE_EPOCH;
|
|
25000
|
-
return epoch && /^\d+$/.test(epoch) ? new Date(Number(epoch) * 1e3) : null;
|
|
25001
|
-
}
|
|
25002
|
-
async function contentId(model, opt, when) {
|
|
25003
|
-
const bytes = new TextEncoder().encode(JSON.stringify([{ ...model, stats: void 0 }, opt.title || "Report", opt.author || "", when.toISOString()]));
|
|
25004
|
-
const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
|
|
25005
|
-
return Array.from(digest.subarray(0, 16), (b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
25006
|
-
}
|
|
25007
|
-
function fieldFont(it) {
|
|
25008
|
-
for (const d of it.draw) if (d.t === "text") {
|
|
25009
|
-
for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
|
|
25010
|
-
}
|
|
25011
|
-
return it.font;
|
|
25012
|
-
}
|
|
25013
|
-
function drawRun(c, run, x, y, size, pf, color2, spans2, texts) {
|
|
25014
|
-
const f4 = pf.embedder.font;
|
|
25015
|
-
const per = 1e3 / size;
|
|
25016
|
-
const span = (text2) => `/Span <</ActualText ${PDFHexString4.fromText(text2).toString()}>> BDC
|
|
25017
|
-
`;
|
|
25018
|
-
c.et();
|
|
25019
|
-
c.paint(color2, null);
|
|
25020
|
-
c.font(pf, size);
|
|
25021
|
-
if (!run.rtl) c.s += span(run.text);
|
|
25022
|
-
c.s += `BT ${n2(x)} ${n2(y)} Td
|
|
25023
|
-
`;
|
|
25024
|
-
let arr = "";
|
|
25025
|
-
let pen = 0, rise = 0;
|
|
25026
|
-
const flush = () => {
|
|
25027
|
-
if (arr) c.s += `[${arr}] TJ
|
|
25028
|
-
`;
|
|
25029
|
-
arr = "";
|
|
25030
|
-
};
|
|
25031
|
-
const all = run.glyphs;
|
|
25032
|
-
const adv = (id) => f4.getGlyph(id).advanceWidth;
|
|
25033
|
-
let g = all, quietAt = -1;
|
|
25034
|
-
if (run.rtl) {
|
|
25035
|
-
const hasBase = /* @__PURE__ */ new Set();
|
|
25036
|
-
for (let i = 0; i < all.length; i += 4) if (adv(all[i]) > 0) hasBase.add(all[i + 3]);
|
|
25037
|
-
const quiet = (i) => spans2?.has(all[i + 3]) ? adv(all[i]) === 0 && hasBase.has(all[i + 3]) : texts?.get(all[i]) === "";
|
|
25038
|
-
g = [];
|
|
25039
|
-
for (const late of [false, true]) {
|
|
25040
|
-
if (late) quietAt = g.length;
|
|
25041
|
-
for (let i = 0; i < all.length; i += 4) if (quiet(i) === late) g.push(all[i], all[i + 1], all[i + 2], all[i + 3]);
|
|
25042
|
-
}
|
|
25043
|
-
if (quietAt === g.length) quietAt = -1;
|
|
25044
|
-
}
|
|
25045
|
-
const starts = run.rtl ? [...new Set(all.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b) : [];
|
|
25046
|
-
let inSpan = false;
|
|
25047
|
-
for (let i = 0; i < g.length; i += 4) {
|
|
25048
|
-
const id = g[i], gx = g[i + 1], gy = g[i + 2], cl = g[i + 3];
|
|
25049
|
-
if (i === quietAt) {
|
|
25050
|
-
flush();
|
|
25051
|
-
c.s += span("");
|
|
25052
|
-
inSpan = true;
|
|
25053
|
-
} else if (run.rtl && spans2?.has(cl) && (quietAt < 0 || i < quietAt) && (i === 0 || g[i - 1] !== cl)) {
|
|
25054
|
-
flush();
|
|
25055
|
-
c.s += span(run.text.slice(cl, starts[starts.indexOf(cl) + 1] ?? run.text.length));
|
|
25056
|
-
inSpan = true;
|
|
25057
|
-
}
|
|
25058
|
-
if (gy !== rise) {
|
|
25059
|
-
flush();
|
|
25060
|
-
c.s += `${n4(gy)} Ts
|
|
25061
|
-
`;
|
|
25062
|
-
rise = gy;
|
|
25063
|
-
}
|
|
25064
|
-
const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
|
|
25065
|
-
if (id === 0 && c.tagged) pen = gx;
|
|
25066
|
-
else {
|
|
25067
|
-
arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
|
|
25068
|
-
pen = gx + adv(id) * size / f4.unitsPerEm;
|
|
25069
|
-
}
|
|
25070
|
-
if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
|
|
25071
|
-
flush();
|
|
25072
|
-
c.s += "EMC\n";
|
|
25073
|
-
inSpan = false;
|
|
25074
|
-
}
|
|
25336
|
+
return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
|
|
25337
|
+
}
|
|
25338
|
+
function fixedDate(opt) {
|
|
25339
|
+
if (opt.creationDate !== void 0) {
|
|
25340
|
+
if (!(opt.creationDate instanceof Date) || Number.isNaN(opt.creationDate.getTime())) throw Object.assign(new Error("creationDate must be a valid Date"), { status: 400 });
|
|
25341
|
+
return opt.creationDate;
|
|
25075
25342
|
}
|
|
25076
|
-
|
|
25077
|
-
|
|
25078
|
-
c.s += "ET\n";
|
|
25079
|
-
if (!run.rtl) c.s += "EMC\n";
|
|
25343
|
+
const epoch = globalThis.process?.env?.SOURCE_DATE_EPOCH;
|
|
25344
|
+
return epoch && /^\d+$/.test(epoch) ? new Date(Number(epoch) * 1e3) : null;
|
|
25080
25345
|
}
|
|
25081
|
-
function
|
|
25082
|
-
const
|
|
25083
|
-
const
|
|
25084
|
-
|
|
25085
|
-
|
|
25086
|
-
|
|
25087
|
-
|
|
25088
|
-
const
|
|
25089
|
-
const rest2 = chars.filter((ch) => !ids.includes(font.glyphForCodePoint(ch.codePointAt(0)).id)).join("");
|
|
25090
|
-
const carrier = rest2 ? ids.find((id) => !own.has(id) && font.getGlyph(id).advanceWidth > 0) ?? ids.find((id) => !own.has(id)) : void 0;
|
|
25091
|
-
let ok = !rest2 || carrier !== void 0;
|
|
25092
|
-
const want = /* @__PURE__ */ new Map();
|
|
25093
|
-
for (const id of ids) {
|
|
25094
|
-
const t = own.get(id) ?? (id === carrier ? rest2 : "");
|
|
25095
|
-
if (want.has(id) && want.get(id) !== t) ok = false;
|
|
25096
|
-
want.set(id, t);
|
|
25097
|
-
}
|
|
25098
|
-
for (const [id, t] of want) {
|
|
25099
|
-
if (!out.has(id)) out.set(id, t);
|
|
25100
|
-
else if (out.get(id) !== t) ok = false;
|
|
25101
|
-
}
|
|
25102
|
-
if (!ok && run.rtl && spans2) {
|
|
25103
|
-
let s = spans2.get(run);
|
|
25104
|
-
if (!s) spans2.set(run, s = /* @__PURE__ */ new Set());
|
|
25105
|
-
s.add(starts[k]);
|
|
25106
|
-
}
|
|
25346
|
+
async function contentId(model, opt, when) {
|
|
25347
|
+
const bytes = new TextEncoder().encode(JSON.stringify([{ ...model, stats: void 0 }, opt.title || "Report", opt.author || "", when.toISOString()]));
|
|
25348
|
+
const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
|
|
25349
|
+
return Array.from(digest.subarray(0, 16), (b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
25350
|
+
}
|
|
25351
|
+
function fieldFont(it) {
|
|
25352
|
+
for (const d of it.draw) if (d.t === "text") {
|
|
25353
|
+
for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
|
|
25107
25354
|
}
|
|
25355
|
+
return it.font;
|
|
25108
25356
|
}
|
|
25109
25357
|
var pdfLiteral = (s) => PDFString4.of(String(s).replace(/[\\()]/g, "\\$&"));
|
|
25110
25358
|
function plainEncoding(pf) {
|
|
@@ -25122,7 +25370,7 @@ function plainEncoding(pf) {
|
|
|
25122
25370
|
}
|
|
25123
25371
|
return hex6;
|
|
25124
25372
|
};
|
|
25125
|
-
e2.encodeText = (text2) =>
|
|
25373
|
+
e2.encodeText = (text2) => PDFHexString5.of(e2.hexOf(text2));
|
|
25126
25374
|
e2.widthOfTextAtSize = (text2, size) => {
|
|
25127
25375
|
let w = 0;
|
|
25128
25376
|
for (const ch of text2) w += f4.glyphForCodePoint(
|
|
@@ -25213,7 +25461,7 @@ function addOutline(doc, bookmarks, dest) {
|
|
|
25213
25461
|
if (!Dest) continue;
|
|
25214
25462
|
const level = Math.max(0, Math.min(9, Number(b.level) || 0));
|
|
25215
25463
|
while (stack2[stack2.length - 1].level >= level) stack2.pop();
|
|
25216
|
-
const node2 = { ref: ctx.nextRef(), level, kids: [], Title:
|
|
25464
|
+
const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString5.fromText(b.label), Dest };
|
|
25217
25465
|
stack2[stack2.length - 1].kids.push(node2);
|
|
25218
25466
|
stack2.push(node2);
|
|
25219
25467
|
}
|
|
@@ -25244,216 +25492,6 @@ function subsetTag(bytes) {
|
|
|
25244
25492
|
}
|
|
25245
25493
|
return tag4;
|
|
25246
25494
|
}
|
|
25247
|
-
function insideClip(it, m) {
|
|
25248
|
-
const k = it.clip, asc = m.asc * it.size, desc = m.desc * it.size;
|
|
25249
|
-
return it.lines.every((l) => l.w != null && !l.runs && l.x >= k.x && l.x + l.w <= k.x + k.w && l.y - asc >= k.y && l.y + desc <= k.y + k.h);
|
|
25250
|
-
}
|
|
25251
|
-
var Content = class {
|
|
25252
|
-
constructor(shared) {
|
|
25253
|
-
this.shared = shared;
|
|
25254
|
-
this._s = "";
|
|
25255
|
-
this.bt = false;
|
|
25256
|
-
this.tx = 0;
|
|
25257
|
-
this.ty = 0;
|
|
25258
|
-
this.st = { fill: "0 0 0", stroke: "0 0 0", lw: 1, dash: "[] 0", ca: 1, CA: 1, font: "", size: 0 };
|
|
25259
|
-
this.saved = [];
|
|
25260
|
-
this.lines = null;
|
|
25261
|
-
this.tagged = false;
|
|
25262
|
-
}
|
|
25263
|
-
/**
|
|
25264
|
-
* The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
|
|
25265
|
-
* of a table's cells stays in one text object (relative moves, which compress to little) instead of one per cell.
|
|
25266
|
-
*/
|
|
25267
|
-
get s() {
|
|
25268
|
-
this.flushLines();
|
|
25269
|
-
return this._s;
|
|
25270
|
-
}
|
|
25271
|
-
set s(v) {
|
|
25272
|
-
this._s = v;
|
|
25273
|
-
}
|
|
25274
|
-
/**
|
|
25275
|
-
* A straight line. Untagged, it waits until something other than text is drawn (table borders between cell
|
|
25276
|
-
* texts); collinear segments that touch, in the same stroke, become one (a row's border is one line).
|
|
25277
|
-
* ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
|
|
25278
|
-
*/
|
|
25279
|
-
line(stroke, w, dash, x1, y1, x2, y2) {
|
|
25280
|
-
if (this.tagged) {
|
|
25281
|
-
this.paint(null, stroke, w, dash);
|
|
25282
|
-
this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
|
|
25283
|
-
`;
|
|
25284
|
-
return;
|
|
25285
|
-
}
|
|
25286
|
-
const key = `${stroke.rgb}|${stroke.opacity}|${w}|${(dash || []).join(" ")}`;
|
|
25287
|
-
if (this.lines && this.lines.key !== key) this.flushLines();
|
|
25288
|
-
this.lines ||= { key, stroke, w, dash, segs: [] };
|
|
25289
|
-
const segs = this.lines.segs, last = segs[segs.length - 1];
|
|
25290
|
-
const eq = (a, b) => Math.abs(a - b) < 5e-3;
|
|
25291
|
-
if (last && eq(last[1], y1) && eq(last[3], y2) && eq(y1, y2) && eq(last[2], x1)) last[2] = x2;
|
|
25292
|
-
else if (last && eq(last[0], x1) && eq(last[2], x2) && eq(x1, x2) && eq(last[3], y1)) last[3] = y2;
|
|
25293
|
-
else segs.push([x1, y1, x2, y2]);
|
|
25294
|
-
}
|
|
25295
|
-
flushLines() {
|
|
25296
|
-
const L = this.lines;
|
|
25297
|
-
if (!L) return;
|
|
25298
|
-
this.lines = null;
|
|
25299
|
-
this.et();
|
|
25300
|
-
this.paint(null, L.stroke, L.w, L.dash);
|
|
25301
|
-
const g = L.segs;
|
|
25302
|
-
const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
|
|
25303
|
-
if (dy && g.every((q3, i) => q3[1] === q3[3] && n2(q3[0]) === n2(g[0][0]) && n2(q3[2]) === n2(g[0][2]) && Math.abs(q3[1] - (g[0][1] + i * dy / 100)) < 0.01)) {
|
|
25304
|
-
const one = `${n2(g[0][0])} ${n2(g[0][1])} m ${n2(g[0][2])} ${n2(g[0][1])} l S
|
|
25305
|
-
`;
|
|
25306
|
-
this._s += `q
|
|
25307
|
-
${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
|
|
25308
|
-
`;
|
|
25309
|
-
return;
|
|
25310
|
-
}
|
|
25311
|
-
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
|
|
25312
|
-
}
|
|
25313
|
-
q() {
|
|
25314
|
-
this.et();
|
|
25315
|
-
this._s += "q\n";
|
|
25316
|
-
this.saved.push({ ...this.st });
|
|
25317
|
-
}
|
|
25318
|
-
Q() {
|
|
25319
|
-
this.et();
|
|
25320
|
-
this._s += "Q\n";
|
|
25321
|
-
this.st = this.saved.pop();
|
|
25322
|
-
}
|
|
25323
|
-
/**
|
|
25324
|
-
* A line of plain text at (x, y). Lines follow one another in one text object, each placed relative to the
|
|
25325
|
-
* last (in whole hundredths, so nothing drifts): most of a table page is these.
|
|
25326
|
-
* @param {string} str the glyphs, as a literal string's escaped body (array: a TJ array's body)
|
|
25327
|
-
*/
|
|
25328
|
-
text(pf, size, color2, x, y, str, array = false) {
|
|
25329
|
-
this.setPaint(color2, null);
|
|
25330
|
-
this.setFont(pf, size);
|
|
25331
|
-
const X = Math.round(x * 10) * 10, Y = Math.round(y * 10) * 10;
|
|
25332
|
-
if (!this.bt) {
|
|
25333
|
-
this._s += "BT\n";
|
|
25334
|
-
this.bt = true;
|
|
25335
|
-
this.tx = 0;
|
|
25336
|
-
this.ty = 0;
|
|
25337
|
-
}
|
|
25338
|
-
this._s += array ? `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td [${str}] TJ
|
|
25339
|
-
` : `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td (${str}) Tj
|
|
25340
|
-
`;
|
|
25341
|
-
this.tx = X;
|
|
25342
|
-
this.ty = Y;
|
|
25343
|
-
}
|
|
25344
|
-
/** end the open text object, if any: anything but text needs that (and draws the lines waiting) */
|
|
25345
|
-
et() {
|
|
25346
|
-
if (this.bt) {
|
|
25347
|
-
this._s += "ET\n";
|
|
25348
|
-
this.bt = false;
|
|
25349
|
-
}
|
|
25350
|
-
if (this.lines) this.flushLines();
|
|
25351
|
-
}
|
|
25352
|
-
lineWidth(w) {
|
|
25353
|
-
if (this.lines) this.flushLines();
|
|
25354
|
-
this.setLineWidth(w);
|
|
25355
|
-
}
|
|
25356
|
-
setLineWidth(w) {
|
|
25357
|
-
if (this.st.lw !== w) {
|
|
25358
|
-
this._s += `${n3(w)} w
|
|
25359
|
-
`;
|
|
25360
|
-
this.st.lw = w;
|
|
25361
|
-
}
|
|
25362
|
-
}
|
|
25363
|
-
/** the graphics state that sets these opacities, or undefined when they are set already */
|
|
25364
|
-
gsFor(ca, CA) {
|
|
25365
|
-
return ca === this.st.ca && CA === this.st.CA ? void 0 : this.shared.gs(ca, CA);
|
|
25366
|
-
}
|
|
25367
|
-
alpha(ca, CA) {
|
|
25368
|
-
if (this.lines) this.flushLines();
|
|
25369
|
-
this.setAlpha(ca, CA);
|
|
25370
|
-
}
|
|
25371
|
-
setAlpha(ca, CA) {
|
|
25372
|
-
const g = this.gsFor(ca, CA);
|
|
25373
|
-
if (g) {
|
|
25374
|
-
this._s += `/${g} gs
|
|
25375
|
-
`;
|
|
25376
|
-
this.st.ca = ca;
|
|
25377
|
-
this.st.CA = CA;
|
|
25378
|
-
}
|
|
25379
|
-
}
|
|
25380
|
-
/** set up to fill with fill and/or stroke with stroke (width w, dash); the lines waiting are drawn first */
|
|
25381
|
-
paint(fill3, stroke, w = 1, dash = null) {
|
|
25382
|
-
if (this.lines) this.flushLines();
|
|
25383
|
-
this.setPaint(fill3, stroke, w, dash);
|
|
25384
|
-
}
|
|
25385
|
-
setPaint(fill3, stroke, w = 1, dash = null) {
|
|
25386
|
-
const st = this.st;
|
|
25387
|
-
if (fill3 && fill3.rgb !== st.fill) {
|
|
25388
|
-
this._s += `${fill3.rgb} rg
|
|
25389
|
-
`;
|
|
25390
|
-
st.fill = fill3.rgb;
|
|
25391
|
-
}
|
|
25392
|
-
if (stroke) {
|
|
25393
|
-
if (stroke.rgb !== st.stroke) {
|
|
25394
|
-
this._s += `${stroke.rgb} RG
|
|
25395
|
-
`;
|
|
25396
|
-
st.stroke = stroke.rgb;
|
|
25397
|
-
}
|
|
25398
|
-
this.setLineWidth(w);
|
|
25399
|
-
const d = `[${(dash || []).map(n3).join(" ")}] 0`;
|
|
25400
|
-
if (d !== st.dash) {
|
|
25401
|
-
this._s += `${d} d
|
|
25402
|
-
`;
|
|
25403
|
-
st.dash = d;
|
|
25404
|
-
}
|
|
25405
|
-
}
|
|
25406
|
-
this.setAlpha(fill3 ? fill3.opacity : st.ca, stroke ? stroke.opacity : st.CA);
|
|
25407
|
-
}
|
|
25408
|
-
font(pf, size) {
|
|
25409
|
-
if (this.lines) this.flushLines();
|
|
25410
|
-
this.setFont(pf, size);
|
|
25411
|
-
}
|
|
25412
|
-
setFont(pf, size) {
|
|
25413
|
-
const name = this.shared.font(pf);
|
|
25414
|
-
if (name !== this.st.font || size !== this.st.size) {
|
|
25415
|
-
this._s += `/${name} ${n3(size)} Tf
|
|
25416
|
-
`;
|
|
25417
|
-
this.st.font = name;
|
|
25418
|
-
this.st.size = size;
|
|
25419
|
-
}
|
|
25420
|
-
}
|
|
25421
|
-
};
|
|
25422
|
-
function latin1(s) {
|
|
25423
|
-
const B = (
|
|
25424
|
-
/** @type {any} */
|
|
25425
|
-
globalThis.Buffer
|
|
25426
|
-
);
|
|
25427
|
-
if (B) return B.from(s, "latin1");
|
|
25428
|
-
const out = new Uint8Array(s.length);
|
|
25429
|
-
for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
|
|
25430
|
-
return out;
|
|
25431
|
-
}
|
|
25432
|
-
async function deflate(bytes) {
|
|
25433
|
-
if (zslots.free > 0) zslots.free--;
|
|
25434
|
-
else await new Promise((ok) => zslots.wait.push(ok));
|
|
25435
|
-
try {
|
|
25436
|
-
return await deflateNow(bytes);
|
|
25437
|
-
} finally {
|
|
25438
|
-
const next = zslots.wait.shift();
|
|
25439
|
-
if (next) next();
|
|
25440
|
-
else zslots.free++;
|
|
25441
|
-
}
|
|
25442
|
-
}
|
|
25443
|
-
var zslots = { free: 4, wait: (
|
|
25444
|
-
/** @type {(() => void)[]} */
|
|
25445
|
-
[]
|
|
25446
|
-
) };
|
|
25447
|
-
var NODE_ZLIB = (
|
|
25448
|
-
/** @type {any} */
|
|
25449
|
-
globalThis.process?.getBuiltinModule?.("node:zlib")
|
|
25450
|
-
);
|
|
25451
|
-
async function deflateNow(bytes) {
|
|
25452
|
-
const zlib = NODE_ZLIB;
|
|
25453
|
-
if (zlib) return new Promise((ok, fail2) => zlib.deflate(bytes, { level: 9 }, (e2, z) => e2 ? fail2(e2) : ok(z)));
|
|
25454
|
-
if (typeof CompressionStream === "undefined") return (await import("fflate")).zlibSync(bytes);
|
|
25455
|
-
return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
|
|
25456
|
-
}
|
|
25457
25495
|
function roundRect(x, y, w, h, r) {
|
|
25458
25496
|
r = Math.min(r, w / 2, h / 2);
|
|
25459
25497
|
return `M ${x + r} ${y} H ${x + w - r} A ${r} ${r} 0 0 1 ${x + w} ${y + r} V ${y + h - r} A ${r} ${r} 0 0 1 ${x + w - r} ${y + h} H ${x + r} A ${r} ${r} 0 0 1 ${x} ${y + h - r} V ${y + r} A ${r} ${r} 0 0 1 ${x + r} ${y} Z`;
|