postext-pdf 1.20.2 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/__tests__/comic.test.js +33 -1
- package/dist/__tests__/comic.test.js.map +1 -1
- package/dist/__tests__/printOutput.test.d.ts +2 -0
- package/dist/__tests__/printOutput.test.d.ts.map +1 -0
- package/dist/__tests__/printOutput.test.js +225 -0
- package/dist/__tests__/printOutput.test.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pdf-backend/blockRender.d.ts +9 -0
- package/dist/pdf-backend/blockRender.d.ts.map +1 -1
- package/dist/pdf-backend/blockRender.js +27 -1
- package/dist/pdf-backend/blockRender.js.map +1 -1
- package/dist/pdf-backend/comic.d.ts +3 -0
- package/dist/pdf-backend/comic.d.ts.map +1 -1
- package/dist/pdf-backend/comic.js +14 -7
- package/dist/pdf-backend/comic.js.map +1 -1
- package/dist/pdf-backend/fontHelpers.js +1 -1
- package/dist/pdf-backend/fontHelpers.js.map +1 -1
- package/dist/pdf-backend/index.d.ts +25 -2
- package/dist/pdf-backend/index.d.ts.map +1 -1
- package/dist/pdf-backend/index.js +104 -12
- package/dist/pdf-backend/index.js.map +1 -1
- package/dist/pdf-backend/primitives.d.ts +6 -4
- package/dist/pdf-backend/primitives.d.ts.map +1 -1
- package/dist/pdf-backend/primitives.js +34 -2
- package/dist/pdf-backend/primitives.js.map +1 -1
- package/dist/pdf-backend/renderResourceBlock.d.ts +5 -1
- package/dist/pdf-backend/renderResourceBlock.d.ts.map +1 -1
- package/dist/pdf-backend/renderResourceBlock.js +12 -6
- package/dist/pdf-backend/renderResourceBlock.js.map +1 -1
- package/dist/pdf-backend/svgVector.d.ts.map +1 -1
- package/dist/pdf-backend/svgVector.js +38 -8
- package/dist/pdf-backend/svgVector.js.map +1 -1
- package/dist/print/colorMode.d.ts +41 -0
- package/dist/print/colorMode.d.ts.map +1 -0
- package/dist/print/colorMode.js +49 -0
- package/dist/print/colorMode.js.map +1 -0
- package/dist/print/images.d.ts +38 -0
- package/dist/print/images.d.ts.map +1 -0
- package/dist/print/images.js +198 -0
- package/dist/print/images.js.map +1 -0
- package/dist/print/inspectMaster.d.ts +17 -0
- package/dist/print/inspectMaster.d.ts.map +1 -0
- package/dist/print/inspectMaster.js +139 -0
- package/dist/print/inspectMaster.js.map +1 -0
- package/dist/print/pdfx.d.ts +35 -0
- package/dist/print/pdfx.d.ts.map +1 -0
- package/dist/print/pdfx.js +144 -0
- package/dist/print/pdfx.js.map +1 -0
- package/dist/print/printPass.d.ts +51 -0
- package/dist/print/printPass.d.ts.map +1 -0
- package/dist/print/printPass.js +253 -0
- package/dist/print/printPass.js.map +1 -0
- package/dist/worker/client.d.ts.map +1 -1
- package/dist/worker/client.js +12 -2
- package/dist/worker/client.js.map +1 -1
- package/dist/worker/protocol.d.ts +1 -1
- package/dist/worker/protocol.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pictures in a colour-managed print render (#603): RGB bitmaps are
|
|
3
|
+
* separated through the output profile into DeviceCMYK image XObjects.
|
|
4
|
+
* PDF/X-1a, which has no transparency, gets each picture composed over the
|
|
5
|
+
* paper; PDF/X-4 keeps its alpha as a DeviceGray soft mask. CMYK and
|
|
6
|
+
* grayscale JPEGs pass through untouched (they are already print data).
|
|
7
|
+
*/
|
|
8
|
+
import { PDFImage, PDFName } from 'pdf-lib';
|
|
9
|
+
import UPNG from '@pdf-lib/upng';
|
|
10
|
+
import { buildRgbLut, outputTransform, sampleRgbLut } from 'postext';
|
|
11
|
+
/** Channels of a JPEG from its SOF marker (1 gray, 3 YCbCr/RGB, 4 CMYK). */
|
|
12
|
+
export function jpegComponents(bytes) {
|
|
13
|
+
let i = 2;
|
|
14
|
+
while (i + 9 < bytes.length) {
|
|
15
|
+
if (bytes[i] !== 0xff)
|
|
16
|
+
return null;
|
|
17
|
+
const marker = bytes[i + 1];
|
|
18
|
+
const len = (bytes[i + 2] << 8) | bytes[i + 3];
|
|
19
|
+
// SOF0–SOF15 except DHT (C4), JPG (C8) and DAC (CC).
|
|
20
|
+
if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) {
|
|
21
|
+
return bytes[i + 9];
|
|
22
|
+
}
|
|
23
|
+
i += 2 + len;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
async function decodeWithCanvas(bytes, type) {
|
|
28
|
+
const g = globalThis;
|
|
29
|
+
if (!g.createImageBitmap || !g.OffscreenCanvas)
|
|
30
|
+
return null;
|
|
31
|
+
try {
|
|
32
|
+
const bitmap = await g.createImageBitmap(new Blob([bytes], { type }));
|
|
33
|
+
const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);
|
|
34
|
+
const ctx = canvas.getContext('2d');
|
|
35
|
+
if (!ctx)
|
|
36
|
+
return null;
|
|
37
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
38
|
+
const { data } = ctx.getImageData(0, 0, bitmap.width, bitmap.height);
|
|
39
|
+
return { width: bitmap.width, height: bitmap.height, data };
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Decode a PNG or JPEG to RGBA. */
|
|
46
|
+
export async function decodeRgba(bytes, format) {
|
|
47
|
+
if (format === 'png') {
|
|
48
|
+
try {
|
|
49
|
+
const img = UPNG.decode(bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
|
|
50
|
+
const frames = UPNG.toRGBA8(img);
|
|
51
|
+
const first = frames[0];
|
|
52
|
+
if (!first)
|
|
53
|
+
return null;
|
|
54
|
+
return { width: img.width, height: img.height, data: new Uint8Array(first) };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return decodeWithCanvas(bytes, 'image/png');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const viaCanvas = await decodeWithCanvas(bytes, 'image/jpeg');
|
|
61
|
+
if (viaCanvas)
|
|
62
|
+
return viaCanvas;
|
|
63
|
+
try {
|
|
64
|
+
const jpeg = (await import('jpeg-js'));
|
|
65
|
+
const decode = jpeg.decode ?? jpeg.default?.decode;
|
|
66
|
+
if (!decode)
|
|
67
|
+
return null;
|
|
68
|
+
const out = decode(bytes, { useTArray: true, formatAsRGBA: true });
|
|
69
|
+
return { width: out.width, height: out.height, data: out.data };
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const lutCache = new WeakMap();
|
|
76
|
+
/** The sRGB → CMYK pixel LUT of a mode: the profile's own black
|
|
77
|
+
* generation (no K-only neutrals, which suit flat colours, not tones). */
|
|
78
|
+
function pixelLut(mode) {
|
|
79
|
+
let lut = lutCache.get(mode);
|
|
80
|
+
if (!lut) {
|
|
81
|
+
const t = outputTransform(mode.profile, {
|
|
82
|
+
intent: mode.config.renderingIntent,
|
|
83
|
+
blackPointCompensation: mode.config.blackPointCompensation,
|
|
84
|
+
preserveNeutrals: false,
|
|
85
|
+
});
|
|
86
|
+
lut = buildRgbLut(33, 4, (r, g, b) => {
|
|
87
|
+
const k = t.fromRgb(r, g, b);
|
|
88
|
+
return [k.c, k.m, k.y, k.k];
|
|
89
|
+
});
|
|
90
|
+
lutCache.set(mode, lut);
|
|
91
|
+
}
|
|
92
|
+
return lut;
|
|
93
|
+
}
|
|
94
|
+
/** Separate RGBA pixels into CMYK bytes (and an alpha plane when any pixel
|
|
95
|
+
* is translucent and the mode keeps transparency). */
|
|
96
|
+
export function separatePixels(px, mode) {
|
|
97
|
+
const lut = pixelLut(mode);
|
|
98
|
+
const n = px.width * px.height;
|
|
99
|
+
const cmyk = new Uint8Array(n * 4);
|
|
100
|
+
const keepAlpha = !mode.flattenTransparency;
|
|
101
|
+
let alpha;
|
|
102
|
+
const out = new Float32Array(4);
|
|
103
|
+
// Flat areas repeat colours: remember the last few conversions.
|
|
104
|
+
const memo = new Map();
|
|
105
|
+
for (let i = 0; i < n; i++) {
|
|
106
|
+
let r = px.data[i * 4];
|
|
107
|
+
let g = px.data[i * 4 + 1];
|
|
108
|
+
let b = px.data[i * 4 + 2];
|
|
109
|
+
const a = px.data[i * 4 + 3];
|
|
110
|
+
if (a < 255) {
|
|
111
|
+
if (keepAlpha) {
|
|
112
|
+
alpha ??= new Uint8Array(n).fill(255);
|
|
113
|
+
alpha[i] = a;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Over the paper.
|
|
117
|
+
const f = a / 255;
|
|
118
|
+
r = Math.round(r * f + 255 * (1 - f));
|
|
119
|
+
g = Math.round(g * f + 255 * (1 - f));
|
|
120
|
+
b = Math.round(b * f + 255 * (1 - f));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const key = (r << 16) | (g << 8) | b;
|
|
124
|
+
const hit = memo.get(key);
|
|
125
|
+
if (hit !== undefined) {
|
|
126
|
+
cmyk[i * 4] = hit >>> 24;
|
|
127
|
+
cmyk[i * 4 + 1] = (hit >>> 16) & 255;
|
|
128
|
+
cmyk[i * 4 + 2] = (hit >>> 8) & 255;
|
|
129
|
+
cmyk[i * 4 + 3] = hit & 255;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
sampleRgbLut(lut, r, g, b, out);
|
|
133
|
+
const c = Math.round(out[0] * 255);
|
|
134
|
+
const m = Math.round(out[1] * 255);
|
|
135
|
+
const y = Math.round(out[2] * 255);
|
|
136
|
+
const k = Math.round(out[3] * 255);
|
|
137
|
+
cmyk[i * 4] = c;
|
|
138
|
+
cmyk[i * 4 + 1] = m;
|
|
139
|
+
cmyk[i * 4 + 2] = y;
|
|
140
|
+
cmyk[i * 4 + 3] = k;
|
|
141
|
+
if (memo.size > 4096)
|
|
142
|
+
memo.clear();
|
|
143
|
+
memo.set(key, ((c << 24) | (m << 16) | (y << 8) | k) >>> 0);
|
|
144
|
+
}
|
|
145
|
+
return alpha ? { cmyk, alpha } : { cmyk };
|
|
146
|
+
}
|
|
147
|
+
/** A pdf-lib PDFImage over an image XObject already written to `ref`. */
|
|
148
|
+
function imageOf(pdfDoc, ref, width, height) {
|
|
149
|
+
const embedder = {
|
|
150
|
+
width,
|
|
151
|
+
height,
|
|
152
|
+
bitsPerComponent: 8,
|
|
153
|
+
embedIntoContext: async (_context, r) => r ?? ref,
|
|
154
|
+
};
|
|
155
|
+
return PDFImage.of(ref, pdfDoc, embedder);
|
|
156
|
+
}
|
|
157
|
+
/** Write separated pixels as a DeviceCMYK image XObject. */
|
|
158
|
+
export function embedCmykPixels(pdfDoc, width, height, sep) {
|
|
159
|
+
const context = pdfDoc.context;
|
|
160
|
+
let smask;
|
|
161
|
+
if (sep.alpha) {
|
|
162
|
+
smask = context.register(context.flateStream(sep.alpha, { Type: 'XObject', Subtype: 'Image', Width: width, Height: height, ColorSpace: 'DeviceGray', BitsPerComponent: 8 }));
|
|
163
|
+
}
|
|
164
|
+
const dict = {
|
|
165
|
+
Type: 'XObject',
|
|
166
|
+
Subtype: 'Image',
|
|
167
|
+
Width: width,
|
|
168
|
+
Height: height,
|
|
169
|
+
ColorSpace: 'DeviceCMYK',
|
|
170
|
+
BitsPerComponent: 8,
|
|
171
|
+
};
|
|
172
|
+
const stream = context.flateStream(sep.cmyk, dict);
|
|
173
|
+
if (smask)
|
|
174
|
+
stream.dict.set(PDFName.of('SMask'), smask);
|
|
175
|
+
const ref = context.register(stream);
|
|
176
|
+
return imageOf(pdfDoc, ref, width, height);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Embed a raster picture for a print render: separated into CMYK when the
|
|
180
|
+
* mode converts pictures and the bitmap is RGB, else as pdf-lib embeds it.
|
|
181
|
+
* PDF/X-1a always flattens a PNG's alpha (over paper) even when it keeps
|
|
182
|
+
* a picture's colours.
|
|
183
|
+
*/
|
|
184
|
+
export async function embedPrintRaster(pdfDoc, bytes, format, mode) {
|
|
185
|
+
if (format === 'jpeg') {
|
|
186
|
+
const channels = jpegComponents(bytes);
|
|
187
|
+
if (channels !== 3 || !mode.convertImages)
|
|
188
|
+
return pdfDoc.embedJpg(bytes);
|
|
189
|
+
}
|
|
190
|
+
if (!mode.convertImages && !mode.flattenTransparency) {
|
|
191
|
+
return format === 'png' ? pdfDoc.embedPng(bytes) : pdfDoc.embedJpg(bytes);
|
|
192
|
+
}
|
|
193
|
+
const px = await decodeRgba(bytes, format);
|
|
194
|
+
if (!px)
|
|
195
|
+
return format === 'png' ? pdfDoc.embedPng(bytes) : pdfDoc.embedJpg(bytes);
|
|
196
|
+
return embedCmykPixels(pdfDoc, px.width, px.height, separatePixels(px, mode));
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.js","sourceRoot":"","sources":["../../src/print/images.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a placed PDF (a print master, `Resource.svg.pdfFileId`) brings into
|
|
3
|
+
* a print file that postext does not control (#605): fonts it does not
|
|
4
|
+
* embed, RGB colour, and transparency (which PDF/X-1a forbids).
|
|
5
|
+
*/
|
|
6
|
+
export interface PrintMasterReport {
|
|
7
|
+
/** Base names of fonts used without an embedded font program. */
|
|
8
|
+
nonEmbeddedFonts: string[];
|
|
9
|
+
/** The page paints in an RGB colour space (device or ICC-based). */
|
|
10
|
+
rgb: boolean;
|
|
11
|
+
/** The page uses transparency: alpha, soft masks, blend modes or
|
|
12
|
+
* transparency groups. */
|
|
13
|
+
transparency: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Inspect the first page of a PDF's bytes (the page postext embeds). */
|
|
16
|
+
export declare function inspectPrintMaster(bytes: Uint8Array): Promise<PrintMasterReport>;
|
|
17
|
+
//# sourceMappingURL=inspectMaster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspectMaster.d.ts","sourceRoot":"","sources":["../../src/print/inspectMaster.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oEAAoE;IACpE,GAAG,EAAE,OAAO,CAAC;IACb;+BAC2B;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB;AAID,yEAAyE;AACzE,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8GtF"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a placed PDF (a print master, `Resource.svg.pdfFileId`) brings into
|
|
3
|
+
* a print file that postext does not control (#605): fonts it does not
|
|
4
|
+
* embed, RGB colour, and transparency (which PDF/X-1a forbids).
|
|
5
|
+
*/
|
|
6
|
+
import { PDFArray, PDFDict, PDFDocument, PDFName, PDFNumber, PDFRawStream, PDFRef, PDFStream, decodePDFRawStream } from 'pdf-lib';
|
|
7
|
+
const name = (o) => (o instanceof PDFName ? o.asString().slice(1) : undefined);
|
|
8
|
+
/** Inspect the first page of a PDF's bytes (the page postext embeds). */
|
|
9
|
+
export async function inspectPrintMaster(bytes) {
|
|
10
|
+
const pdf = await PDFDocument.load(bytes, { ignoreEncryption: true, updateMetadata: false });
|
|
11
|
+
const ctx = pdf.context;
|
|
12
|
+
const lookup = (o) => (o instanceof PDFRef ? ctx.lookup(o) : o);
|
|
13
|
+
const fonts = new Set();
|
|
14
|
+
let rgb = false;
|
|
15
|
+
let transparency = false;
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
const checkSpace = (cs) => {
|
|
18
|
+
const v = lookup(cs);
|
|
19
|
+
const n = name(v);
|
|
20
|
+
if (n === 'DeviceRGB' || n === 'CalRGB' || n === 'RGB')
|
|
21
|
+
rgb = true;
|
|
22
|
+
if (v instanceof PDFArray) {
|
|
23
|
+
const kind = name(lookup(v.get(0)));
|
|
24
|
+
if (kind === 'CalRGB')
|
|
25
|
+
rgb = true;
|
|
26
|
+
if (kind === 'ICCBased') {
|
|
27
|
+
const s = lookup(v.get(1));
|
|
28
|
+
const comps = s instanceof PDFStream ? lookup(s.dict.get(PDFName.of('N'))) : undefined;
|
|
29
|
+
if (comps instanceof PDFNumber && comps.asNumber() === 3)
|
|
30
|
+
rgb = true;
|
|
31
|
+
}
|
|
32
|
+
// Indexed / Separation / DeviceN: their base or alternate space.
|
|
33
|
+
if (kind === 'Indexed')
|
|
34
|
+
checkSpace(v.get(1));
|
|
35
|
+
if (kind === 'Separation' || kind === 'DeviceN')
|
|
36
|
+
checkSpace(v.get(kind === 'Separation' ? 2 : 2));
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const fontEmbedded = (font) => {
|
|
40
|
+
const sub = name(lookup(font.get(PDFName.of('Subtype'))));
|
|
41
|
+
if (sub === 'Type3')
|
|
42
|
+
return true;
|
|
43
|
+
if (sub === 'Type0') {
|
|
44
|
+
const kids = lookup(font.get(PDFName.of('DescendantFonts')));
|
|
45
|
+
const kid = kids instanceof PDFArray ? lookup(kids.get(0)) : undefined;
|
|
46
|
+
return kid instanceof PDFDict ? fontEmbedded(kid) : false;
|
|
47
|
+
}
|
|
48
|
+
const fd = lookup(font.get(PDFName.of('FontDescriptor')));
|
|
49
|
+
if (!(fd instanceof PDFDict))
|
|
50
|
+
return false;
|
|
51
|
+
return ['FontFile', 'FontFile2', 'FontFile3'].some((k) => fd.get(PDFName.of(k)) !== undefined);
|
|
52
|
+
};
|
|
53
|
+
/** Device RGB set straight in a content stream (`rg` / `RG`). */
|
|
54
|
+
const scanContent = (stream) => {
|
|
55
|
+
const s = lookup(stream);
|
|
56
|
+
if (s instanceof PDFArray) {
|
|
57
|
+
for (let i = 0; i < s.size(); i++)
|
|
58
|
+
scanContent(s.get(i));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!(s instanceof PDFRawStream))
|
|
62
|
+
return;
|
|
63
|
+
try {
|
|
64
|
+
const text = new TextDecoder('latin1').decode(decodePDFRawStream(s).decode());
|
|
65
|
+
if (/(^|[\s\]])(rg|RG)(?=\s|$)/.test(text))
|
|
66
|
+
rgb = true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// An undecodable stream says nothing.
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const walkResources = (res) => {
|
|
73
|
+
const r = lookup(res);
|
|
74
|
+
if (!(r instanceof PDFDict) || seen.has(r))
|
|
75
|
+
return;
|
|
76
|
+
seen.add(r);
|
|
77
|
+
const fontDict = lookup(r.get(PDFName.of('Font')));
|
|
78
|
+
if (fontDict instanceof PDFDict) {
|
|
79
|
+
for (const [, f] of fontDict.entries()) {
|
|
80
|
+
const font = lookup(f);
|
|
81
|
+
if (font instanceof PDFDict && !fontEmbedded(font))
|
|
82
|
+
fonts.add(name(lookup(font.get(PDFName.of('BaseFont')))) ?? 'unnamed');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const spaces = lookup(r.get(PDFName.of('ColorSpace')));
|
|
86
|
+
if (spaces instanceof PDFDict)
|
|
87
|
+
for (const [, cs] of spaces.entries())
|
|
88
|
+
checkSpace(cs);
|
|
89
|
+
const states = lookup(r.get(PDFName.of('ExtGState')));
|
|
90
|
+
if (states instanceof PDFDict) {
|
|
91
|
+
for (const [, g] of states.entries()) {
|
|
92
|
+
const gs = lookup(g);
|
|
93
|
+
if (!(gs instanceof PDFDict))
|
|
94
|
+
continue;
|
|
95
|
+
for (const k of ['ca', 'CA']) {
|
|
96
|
+
const v = lookup(gs.get(PDFName.of(k)));
|
|
97
|
+
if (v instanceof PDFNumber && v.asNumber() < 1)
|
|
98
|
+
transparency = true;
|
|
99
|
+
}
|
|
100
|
+
const smask = lookup(gs.get(PDFName.of('SMask')));
|
|
101
|
+
if (smask && name(smask) !== 'None')
|
|
102
|
+
transparency = true;
|
|
103
|
+
const bm = lookup(gs.get(PDFName.of('BM')));
|
|
104
|
+
if (bm && name(bm) !== 'Normal' && name(bm) !== 'Compatible')
|
|
105
|
+
transparency = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const xobjects = lookup(r.get(PDFName.of('XObject')));
|
|
109
|
+
if (xobjects instanceof PDFDict) {
|
|
110
|
+
for (const [, x] of xobjects.entries()) {
|
|
111
|
+
const xo = lookup(x);
|
|
112
|
+
if (!(xo instanceof PDFStream))
|
|
113
|
+
continue;
|
|
114
|
+
const d = xo.dict;
|
|
115
|
+
const sub = name(lookup(d.get(PDFName.of('Subtype'))));
|
|
116
|
+
if (sub === 'Image') {
|
|
117
|
+
checkSpace(d.get(PDFName.of('ColorSpace')));
|
|
118
|
+
if (d.get(PDFName.of('SMask')) !== undefined)
|
|
119
|
+
transparency = true;
|
|
120
|
+
}
|
|
121
|
+
else if (sub === 'Form') {
|
|
122
|
+
scanContent(xo);
|
|
123
|
+
const group = lookup(d.get(PDFName.of('Group')));
|
|
124
|
+
if (group instanceof PDFDict && name(lookup(group.get(PDFName.of('S')))) === 'Transparency')
|
|
125
|
+
transparency = true;
|
|
126
|
+
walkResources(d.get(PDFName.of('Resources')));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const page = pdf.getPage(0);
|
|
132
|
+
walkResources(page.node.Resources());
|
|
133
|
+
scanContent(page.node.get(PDFName.of('Contents')));
|
|
134
|
+
const group = page.node.lookup(PDFName.of('Group'));
|
|
135
|
+
if (group instanceof PDFDict && name(lookup(group.get(PDFName.of('S')))) === 'Transparency')
|
|
136
|
+
transparency = true;
|
|
137
|
+
return { nonEmbeddedFonts: [...fonts].sort(), rgb, transparency };
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=inspectMaster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspectMaster.js","sourceRoot":"","sources":["../../src/print/inspectMaster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF/X identification and the output intent (#603): what turns a CMYK
|
|
3
|
+
* render into a PDF/X-1a:2003 or PDF/X-4 file.
|
|
4
|
+
*
|
|
5
|
+
* - The output intent `GTS_PDFX`, naming the printing condition (the ICC
|
|
6
|
+
* characterization registry name) and embedding the destination
|
|
7
|
+
* profile.
|
|
8
|
+
* - The Info dictionary's `GTS_PDFXVersion`, `/Trapped /False`, title and
|
|
9
|
+
* dates; an XMP packet with the same, `pdfxid:GTSPDFXVersion` and the
|
|
10
|
+
* document / version ids (PDF/X-4), merged with the PDF/UA one when the
|
|
11
|
+
* file is tagged; the trailer `/ID`.
|
|
12
|
+
* - A TrimBox and BleedBox on every page (the version header, 1.4 for
|
|
13
|
+
* X-1a and 1.6 for X-4, is set on the saved bytes), and for X-4 a transparency page group blending in
|
|
14
|
+
* CMYK plus `/DefaultRGB` (sRGB) where RGB pictures were kept.
|
|
15
|
+
*/
|
|
16
|
+
import { PDFDocument } from 'pdf-lib';
|
|
17
|
+
import type { PrintColorMode } from './colorMode';
|
|
18
|
+
export interface PdfXMeta {
|
|
19
|
+
title: string;
|
|
20
|
+
author?: string;
|
|
21
|
+
lang?: string;
|
|
22
|
+
producer: string;
|
|
23
|
+
creatorTool: string;
|
|
24
|
+
/** The file is also tagged PDF/UA-1. */
|
|
25
|
+
pdfua: boolean;
|
|
26
|
+
/** Set the dates (tests pin them). */
|
|
27
|
+
date?: Date;
|
|
28
|
+
}
|
|
29
|
+
export declare function pdfxVersionString(standard: 'pdfx1a' | 'pdfx4'): string;
|
|
30
|
+
/** The XMP packet of a PDF/X file (and PDF/UA when tagged). */
|
|
31
|
+
export declare function buildPdfXXmp(meta: PdfXMeta, standard: 'pdfx1a' | 'pdfx4', date: Date, documentId: string): string;
|
|
32
|
+
/** Write the PDF/X parts of a render. Call after every page and the
|
|
33
|
+
* structure tree are written, before saving. */
|
|
34
|
+
export declare function writePdfX(pdfDoc: PDFDocument, mode: PrintColorMode, meta: PdfXMeta, keptRgb: boolean): void;
|
|
35
|
+
//# sourceMappingURL=pdfx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfx.d.ts","sourceRoot":"","sources":["../../src/print/pdfx.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAW,WAAW,EAAkD,MAAM,SAAS,CAAC;AAE/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,sCAAsC;IACtC,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AA2BD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAEtE;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAiCjH;AAUD;iDACiD;AACjD,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CA2D3G"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF/X identification and the output intent (#603): what turns a CMYK
|
|
3
|
+
* render into a PDF/X-1a:2003 or PDF/X-4 file.
|
|
4
|
+
*
|
|
5
|
+
* - The output intent `GTS_PDFX`, naming the printing condition (the ICC
|
|
6
|
+
* characterization registry name) and embedding the destination
|
|
7
|
+
* profile.
|
|
8
|
+
* - The Info dictionary's `GTS_PDFXVersion`, `/Trapped /False`, title and
|
|
9
|
+
* dates; an XMP packet with the same, `pdfxid:GTSPDFXVersion` and the
|
|
10
|
+
* document / version ids (PDF/X-4), merged with the PDF/UA one when the
|
|
11
|
+
* file is tagged; the trailer `/ID`.
|
|
12
|
+
* - A TrimBox and BleedBox on every page (the version header, 1.4 for
|
|
13
|
+
* X-1a and 1.6 for X-4, is set on the saved bytes), and for X-4 a transparency page group blending in
|
|
14
|
+
* CMYK plus `/DefaultRGB` (sRGB) where RGB pictures were kept.
|
|
15
|
+
*/
|
|
16
|
+
import { PDFDict, PDFHexString, PDFName, PDFString } from 'pdf-lib';
|
|
17
|
+
import { srgbProfileBytes } from 'postext';
|
|
18
|
+
function xmlEscape(s) {
|
|
19
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
20
|
+
}
|
|
21
|
+
function isoDate(d) {
|
|
22
|
+
return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
23
|
+
}
|
|
24
|
+
function hex(bytes) {
|
|
25
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
26
|
+
}
|
|
27
|
+
function randomBytes(n) {
|
|
28
|
+
const out = new Uint8Array(n);
|
|
29
|
+
const c = globalThis.crypto;
|
|
30
|
+
if (c?.getRandomValues)
|
|
31
|
+
return c.getRandomValues(out);
|
|
32
|
+
for (let i = 0; i < n; i++)
|
|
33
|
+
out[i] = Math.floor(Math.random() * 256);
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function uuid(bytes) {
|
|
37
|
+
const h = hex(bytes.subarray(0, 16));
|
|
38
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
|
|
39
|
+
}
|
|
40
|
+
export function pdfxVersionString(standard) {
|
|
41
|
+
return standard === 'pdfx1a' ? 'PDF/X-1a:2003' : 'PDF/X-4';
|
|
42
|
+
}
|
|
43
|
+
/** The XMP packet of a PDF/X file (and PDF/UA when tagged). */
|
|
44
|
+
export function buildPdfXXmp(meta, standard, date, documentId) {
|
|
45
|
+
const title = xmlEscape(meta.title);
|
|
46
|
+
const creator = meta.author ? `<dc:creator><rdf:Seq><rdf:li>${xmlEscape(meta.author)}</rdf:li></rdf:Seq></dc:creator>\n` : '';
|
|
47
|
+
const language = meta.lang ? `<dc:language><rdf:Bag><rdf:li>${xmlEscape(meta.lang)}</rdf:li></rdf:Bag></dc:language>\n` : '';
|
|
48
|
+
const when = isoDate(date);
|
|
49
|
+
return ('<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>\n' +
|
|
50
|
+
'<x:xmpmeta xmlns:x="adobe:ns:meta/">\n' +
|
|
51
|
+
'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\n' +
|
|
52
|
+
'<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"' +
|
|
53
|
+
' xmlns:pdf="http://ns.adobe.com/pdf/1.3/" xmlns:xmp="http://ns.adobe.com/xap/1.0/"' +
|
|
54
|
+
' xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/"' +
|
|
55
|
+
(meta.pdfua ? ' xmlns:pdfuaid="http://www.aiim.org/pdfua/ns/id/"' : '') +
|
|
56
|
+
'>\n' +
|
|
57
|
+
`<dc:title><rdf:Alt><rdf:li xml:lang="x-default">${title}</rdf:li></rdf:Alt></dc:title>\n` +
|
|
58
|
+
creator +
|
|
59
|
+
language +
|
|
60
|
+
'<dc:format>application/pdf</dc:format>\n' +
|
|
61
|
+
`<pdf:Producer>${xmlEscape(meta.producer)}</pdf:Producer>\n` +
|
|
62
|
+
'<pdf:Trapped>False</pdf:Trapped>\n' +
|
|
63
|
+
`<xmp:CreatorTool>${xmlEscape(meta.creatorTool)}</xmp:CreatorTool>\n` +
|
|
64
|
+
`<xmp:CreateDate>${when}</xmp:CreateDate>\n` +
|
|
65
|
+
`<xmp:ModifyDate>${when}</xmp:ModifyDate>\n` +
|
|
66
|
+
`<xmp:MetadataDate>${when}</xmp:MetadataDate>\n` +
|
|
67
|
+
`<xmpMM:DocumentID>uuid:${documentId}</xmpMM:DocumentID>\n` +
|
|
68
|
+
`<xmpMM:InstanceID>uuid:${documentId}</xmpMM:InstanceID>\n` +
|
|
69
|
+
'<xmpMM:VersionID>1</xmpMM:VersionID>\n' +
|
|
70
|
+
'<xmpMM:RenditionClass>default</xmpMM:RenditionClass>\n' +
|
|
71
|
+
`<pdfxid:GTSPDFXVersion>${pdfxVersionString(standard)}</pdfxid:GTSPDFXVersion>\n` +
|
|
72
|
+
(meta.pdfua ? '<pdfuaid:part>1</pdfuaid:part>\n' : '') +
|
|
73
|
+
'</rdf:Description>\n</rdf:RDF>\n</x:xmpmeta>\n' +
|
|
74
|
+
'<?xpacket end="w"?>');
|
|
75
|
+
}
|
|
76
|
+
/** Give a page a TrimBox and BleedBox (its MediaBox) when it has none. */
|
|
77
|
+
function ensureBoxes(page) {
|
|
78
|
+
const has = (k) => page.node.get(PDFName.of(k)) !== undefined;
|
|
79
|
+
const { x, y, width, height } = page.getMediaBox();
|
|
80
|
+
if (!has('TrimBox'))
|
|
81
|
+
page.setTrimBox(x, y, width, height);
|
|
82
|
+
if (!has('BleedBox'))
|
|
83
|
+
page.setBleedBox(x, y, width, height);
|
|
84
|
+
}
|
|
85
|
+
/** Write the PDF/X parts of a render. Call after every page and the
|
|
86
|
+
* structure tree are written, before saving. */
|
|
87
|
+
export function writePdfX(pdfDoc, mode, meta, keptRgb) {
|
|
88
|
+
if (mode.standard === 'none')
|
|
89
|
+
return;
|
|
90
|
+
const standard = mode.standard;
|
|
91
|
+
const context = pdfDoc.context;
|
|
92
|
+
const date = meta.date ?? new Date();
|
|
93
|
+
const idBytes = randomBytes(16);
|
|
94
|
+
const documentId = uuid(idBytes);
|
|
95
|
+
// Output intent with the destination profile.
|
|
96
|
+
const profileRef = context.register(context.flateStream(mode.profile.bytes, { N: 4 }));
|
|
97
|
+
const intent = context.obj({
|
|
98
|
+
Type: 'OutputIntent',
|
|
99
|
+
S: 'GTS_PDFX',
|
|
100
|
+
OutputConditionIdentifier: PDFString.of(mode.condition.registryName),
|
|
101
|
+
...(mode.condition.registryName !== 'Custom' ? { RegistryName: PDFString.of('http://www.color.org') } : {}),
|
|
102
|
+
OutputCondition: PDFString.of(mode.condition.condition),
|
|
103
|
+
Info: PDFString.of(mode.condition.name),
|
|
104
|
+
DestOutputProfile: profileRef,
|
|
105
|
+
});
|
|
106
|
+
pdfDoc.catalog.set(PDFName.of('OutputIntents'), context.obj([context.register(intent)]));
|
|
107
|
+
// Info dictionary.
|
|
108
|
+
pdfDoc.setTitle(meta.title, { showInWindowTitleBar: true });
|
|
109
|
+
if (meta.author)
|
|
110
|
+
pdfDoc.setAuthor(meta.author);
|
|
111
|
+
pdfDoc.setCreator(meta.creatorTool);
|
|
112
|
+
pdfDoc.setProducer(meta.producer);
|
|
113
|
+
pdfDoc.setCreationDate(date);
|
|
114
|
+
pdfDoc.setModificationDate(date);
|
|
115
|
+
const info = pdfDoc.getInfoDict();
|
|
116
|
+
info.set(PDFName.of('Trapped'), PDFName.of('False'));
|
|
117
|
+
info.set(PDFName.of('GTS_PDFXVersion'), PDFString.of(pdfxVersionString(standard)));
|
|
118
|
+
// XMP (replacing the PDF/UA-only packet of a tagged render).
|
|
119
|
+
const xmp = buildPdfXXmp(meta, standard, date, documentId);
|
|
120
|
+
const metadata = context.stream(new TextEncoder().encode(xmp), { Type: 'Metadata', Subtype: 'XML' });
|
|
121
|
+
pdfDoc.catalog.set(PDFName.of('Metadata'), context.register(metadata));
|
|
122
|
+
// Trailer ID: the same bytes twice (a first version of the file).
|
|
123
|
+
const id = PDFHexString.of(hex(idBytes));
|
|
124
|
+
context.trailerInfo.ID = context.obj([id, id]);
|
|
125
|
+
const srgbRef = standard === 'pdfx4' && keptRgb
|
|
126
|
+
? context.register(context.flateStream(srgbProfileBytes(), { N: 3 }))
|
|
127
|
+
: undefined;
|
|
128
|
+
for (const page of pdfDoc.getPages()) {
|
|
129
|
+
ensureBoxes(page);
|
|
130
|
+
if (standard === 'pdfx4') {
|
|
131
|
+
page.node.set(PDFName.of('Group'), context.obj({ Type: 'Group', S: 'Transparency', CS: 'DeviceCMYK' }));
|
|
132
|
+
if (srgbRef) {
|
|
133
|
+
const resources = page.node.normalizedEntries().Resources;
|
|
134
|
+
let spaces = resources.lookup(PDFName.of('ColorSpace'));
|
|
135
|
+
if (!(spaces instanceof PDFDict)) {
|
|
136
|
+
spaces = context.obj({});
|
|
137
|
+
resources.set(PDFName.of('ColorSpace'), spaces);
|
|
138
|
+
}
|
|
139
|
+
spaces.set(PDFName.of('DefaultRGB'), context.obj([PDFName.of('ICCBased'), srgbRef]));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=pdfx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfx.js","sourceRoot":"","sources":["../../src/print/pdfx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The black-handling pass over a content stream (#604), run on every page
|
|
3
|
+
* and every vector form of a colour-managed (ICC) render once its
|
|
4
|
+
* operators are written:
|
|
5
|
+
*
|
|
6
|
+
* - **Overprint**: whatever paints in 100 % K only (black text, rules,
|
|
7
|
+
* strokes, small black shapes) overprints — `op`/`OP` true with `OPM 1`
|
|
8
|
+
* — so a plate shifting on press never opens a white halo round it.
|
|
9
|
+
* Everything else knocks out, as before; pictures and shadings never
|
|
10
|
+
* overprint.
|
|
11
|
+
* - **Rich black**: a K-only fill whose smaller side reaches
|
|
12
|
+
* `richBlackMinSize` (a background, a band, a box) is set in the
|
|
13
|
+
* rich-black recipe instead, and knocks out. Text never turns rich.
|
|
14
|
+
*
|
|
15
|
+
* Working on the operators rather than at each painter catches every way
|
|
16
|
+
* the backend paints (pdf-lib's `drawRectangle`/`drawSvgPath`, raw
|
|
17
|
+
* operator runs, text objects) with one rule.
|
|
18
|
+
*/
|
|
19
|
+
import { PDFName, PDFOperator, type PDFPage } from 'pdf-lib';
|
|
20
|
+
import type { PrintColorMode } from './colorMode';
|
|
21
|
+
/** Overprint flags of a graphics state: fill (`op`) and stroke (`OP`). */
|
|
22
|
+
export interface OverprintFlags {
|
|
23
|
+
fill: boolean;
|
|
24
|
+
stroke: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Registers (or reuses) the ExtGState for a pair of flags in the
|
|
27
|
+
* resources the operators run against, returning its name. */
|
|
28
|
+
export type OverprintStateFactory = (flags: OverprintFlags) => PDFName;
|
|
29
|
+
export interface PrintPassOptions {
|
|
30
|
+
/** Apply rich black to large K-only fills. Off for forms, whose size on
|
|
31
|
+
* the page is not known when they are written. */
|
|
32
|
+
richBlack: boolean;
|
|
33
|
+
/** User-space units per point at the identity CTM (1 for a page). */
|
|
34
|
+
unitsPerPoint?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Run the black-handling pass over `ops`, returning the new operator
|
|
37
|
+
* list. `stateFor` names the overprint ExtGStates in the stream's
|
|
38
|
+
* resources. */
|
|
39
|
+
export declare function applyPrintPass(ops: readonly PDFOperator[], mode: PrintColorMode, stateFor: OverprintStateFactory, options?: PrintPassOptions): PDFOperator[];
|
|
40
|
+
/** The ExtGState dictionary of a pair of overprint flags. */
|
|
41
|
+
export declare function overprintStateDict(flags: OverprintFlags): {
|
|
42
|
+
Type: string;
|
|
43
|
+
op: boolean;
|
|
44
|
+
OP: boolean;
|
|
45
|
+
OPM: number;
|
|
46
|
+
};
|
|
47
|
+
/** Run the pass over a page's content stream, registering the overprint
|
|
48
|
+
* states in the page's resources. Rich black applies (a page's user space
|
|
49
|
+
* is in points). */
|
|
50
|
+
export declare function runPagePrintPass(page: PDFPage, mode: PrintColorMode): void;
|
|
51
|
+
//# sourceMappingURL=printPass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"printPass.d.ts","sourceRoot":"","sources":["../../src/print/printPass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAa,WAAW,EAAoB,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAE1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;+DAC+D;AAC/D,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;AA4DvE,MAAM,WAAW,gBAAgB;IAC/B;uDACmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;iBAEiB;AACjB,wBAAgB,cAAc,CAC5B,GAAG,EAAE,SAAS,WAAW,EAAE,EAC3B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,GAAE,gBAAuC,GAC/C,WAAW,EAAE,CAgKf;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAEjH;AAED;;qBAEqB;AACrB,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAa1E"}
|