@reportwright/viewer 0.11.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/README.md +27 -5
- package/dist/{chunk-KJTRZJHN.js → chunk-2BPBQMH2.js} +4 -3
- package/dist/chunk-2BPBQMH2.js.map +6 -0
- package/dist/{chunk-ODREGGKA.js → chunk-3D2KFKG2.js} +5 -4
- package/dist/chunk-3D2KFKG2.js.map +6 -0
- package/dist/chunk-6TPZ7G74.js +494 -0
- package/dist/chunk-6TPZ7G74.js.map +6 -0
- package/dist/chunk-BRB34AJ2.js +16 -0
- package/dist/{chunk-APRPSQOD.js → chunk-DPVJEFKP.js} +28 -9
- package/dist/chunk-DPVJEFKP.js.map +6 -0
- package/dist/{chunk-RYHJUQSV.js → chunk-DXHLIJEY.js} +2 -2
- package/dist/{chunk-SR2TQ2ZK.js → chunk-F6RMRXIN.js} +2 -2
- package/dist/chunk-F6RMRXIN.js.map +6 -0
- package/dist/{chunk-3D43XGIN.js → chunk-M6AYND5G.js} +8 -638
- package/dist/chunk-M6AYND5G.js.map +6 -0
- package/dist/{chunk-HAMBWF6C.js → chunk-NR2G4TMG.js} +39 -31
- package/dist/chunk-NR2G4TMG.js.map +6 -0
- package/dist/{chunk-66QZ3RDV.js → chunk-PGP3QA6L.js} +526 -508
- package/dist/chunk-PGP3QA6L.js.map +6 -0
- package/dist/{chunk-N5WHQ4DM.js → chunk-Q6MMPKQA.js} +14 -9
- package/dist/chunk-Q6MMPKQA.js.map +6 -0
- package/dist/{chunk-SBD55ZES.js → chunk-S2IUUI6N.js} +76 -32
- package/dist/chunk-S2IUUI6N.js.map +6 -0
- package/dist/chunk-ULKEEARQ.js +553 -0
- package/dist/chunk-ULKEEARQ.js.map +6 -0
- package/dist/{chunk-WQOBRZAL.js → chunk-VNOWPSE6.js} +579 -1484
- package/dist/chunk-VNOWPSE6.js.map +6 -0
- package/dist/chunk-Z7MKH66Z.js +642 -0
- package/dist/chunk-Z7MKH66Z.js.map +6 -0
- package/dist/designer.d.ts +10 -3
- package/dist/designer.js +28 -18
- package/dist/designer.js.map +1 -1
- package/dist/engine.worker.js +71 -0
- package/dist/engine.worker.js.map +6 -0
- package/dist/peer/chunk-2FZTYEDE.js +15 -0
- package/dist/peer/{chunk-776OR56A.js → chunk-6I2EAAVN.js} +39 -31
- package/dist/peer/chunk-6I2EAAVN.js.map +6 -0
- package/dist/peer/{chunk-IPU2YRL2.js → chunk-BMAXIBP2.js} +28 -9
- package/dist/peer/chunk-BMAXIBP2.js.map +6 -0
- package/dist/peer/chunk-BQFI3DHK.js +494 -0
- package/dist/peer/chunk-BQFI3DHK.js.map +6 -0
- package/dist/peer/{chunk-76ZABVTI.js → chunk-R4VX5UC7.js} +4 -3
- package/dist/peer/{chunk-5X4ZSSJT.js → chunk-TSC4RAH3.js} +526 -508
- package/dist/peer/chunk-TSC4RAH3.js.map +6 -0
- package/dist/peer/{chunk-M4AGFUWE.js → chunk-V42KN7HD.js} +2 -2
- package/dist/peer/{chunk-Y5CAHLXS.js → chunk-WQGENQZO.js} +5 -4
- package/dist/peer/{chunk-EKWTFHVE.js → chunk-WSNRD2AQ.js} +14 -9
- package/dist/peer/chunk-WSNRD2AQ.js.map +6 -0
- package/dist/peer/designer.js +28 -18
- package/dist/peer/designer.js.map +1 -1
- package/dist/peer/engine.worker.js +70 -0
- package/dist/peer/engine.worker.js.map +6 -0
- package/dist/peer/viewer.js +12 -5
- package/dist/peer/viewer.js.map +1 -1
- package/dist/viewer.d.ts +9 -1
- package/dist/viewer.js +12 -5
- package/dist/viewer.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-3D43XGIN.js.map +0 -6
- package/dist/chunk-66QZ3RDV.js.map +0 -6
- package/dist/chunk-AH47FS6Y.js +0 -13
- package/dist/chunk-APRPSQOD.js.map +0 -6
- package/dist/chunk-HAMBWF6C.js.map +0 -6
- package/dist/chunk-N5WHQ4DM.js.map +0 -6
- package/dist/chunk-SBD55ZES.js.map +0 -6
- package/dist/chunk-SR2TQ2ZK.js.map +0 -6
- package/dist/chunk-WQOBRZAL.js.map +0 -6
- package/dist/peer/chunk-5X4ZSSJT.js.map +0 -6
- package/dist/peer/chunk-6YO42ALN.js +0 -14777
- package/dist/peer/chunk-6YO42ALN.js.map +0 -6
- package/dist/peer/chunk-76ZABVTI.js.map +0 -6
- package/dist/peer/chunk-776OR56A.js.map +0 -6
- package/dist/peer/chunk-EKWTFHVE.js.map +0 -6
- package/dist/peer/chunk-IMQRHDR4.js +0 -12
- package/dist/peer/chunk-IPU2YRL2.js.map +0 -6
- package/dist/peer/chunk-Y5CAHLXS.js.map +0 -6
- /package/dist/{chunk-AH47FS6Y.js.map → chunk-BRB34AJ2.js.map} +0 -0
- /package/dist/{chunk-RYHJUQSV.js.map → chunk-DXHLIJEY.js.map} +0 -0
- /package/dist/peer/{chunk-IMQRHDR4.js.map → chunk-2FZTYEDE.js.map} +0 -0
- /package/dist/{chunk-KJTRZJHN.js.map → peer/chunk-R4VX5UC7.js.map} +0 -0
- /package/dist/peer/{chunk-M4AGFUWE.js.map → chunk-V42KN7HD.js.map} +0 -0
- /package/dist/{chunk-ODREGGKA.js.map → peer/chunk-WQGENQZO.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/exporters/regions.js
|
|
2
2
|
function needsTableData(model, what) {
|
|
3
|
-
if (model && model.regions === null) throw Object.assign(new Error(`${what} needs the report's table data: render it with { exportData: true }`), { code: "NO_EXPORT_DATA" });
|
|
3
|
+
if (model && model.regions === null && model.hasTables !== false) throw Object.assign(new Error(`${what} needs the report's table data: render it with { exportData: true }`), { code: "NO_EXPORT_DATA" });
|
|
4
4
|
}
|
|
5
5
|
var needsExportData = (fmt, o = {}) => ["xlsx", "csv", "docx", "pptx", "html", "json"].includes(fmt) || fmt === "pdf" && !!(o.pdfua || o.ua || o.tagged);
|
|
6
6
|
function mergedRegions(model) {
|
|
@@ -67,4 +67,4 @@ export {
|
|
|
67
67
|
isJustified,
|
|
68
68
|
textRows
|
|
69
69
|
};
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
70
|
+
//# sourceMappingURL=chunk-F6RMRXIN.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/exporters/regions.js"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -1,611 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
async function createShaper(wasm) {
|
|
9
|
-
let memory;
|
|
10
|
-
const { instance } = await WebAssembly.instantiate(wasm, {
|
|
11
|
-
env: {
|
|
12
|
-
_emscripten_runtime_keepalive_clear() {
|
|
13
|
-
},
|
|
14
|
-
_abort_js() {
|
|
15
|
-
throw new Error("HarfBuzz stopped");
|
|
16
|
-
},
|
|
17
|
-
_setitimer_js() {
|
|
18
|
-
return 0;
|
|
19
|
-
},
|
|
20
|
-
emscripten_resize_heap(size) {
|
|
21
|
-
const need = (size >>> 0) - memory.buffer.byteLength;
|
|
22
|
-
try {
|
|
23
|
-
memory.grow(Math.ceil(need / 65536));
|
|
24
|
-
return 1;
|
|
25
|
-
} catch {
|
|
26
|
-
return 0;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
wasi_snapshot_preview1: { proc_exit(code) {
|
|
31
|
-
throw new Error(`HarfBuzz exited (${code})`);
|
|
32
|
-
} }
|
|
33
|
-
});
|
|
34
|
-
const x = (
|
|
35
|
-
/** @type {any} */
|
|
36
|
-
instance.exports
|
|
37
|
-
);
|
|
38
|
-
memory = x.memory;
|
|
39
|
-
x.__wasm_call_ctors();
|
|
40
|
-
const featPtr = x.malloc(16 * PLAIN.length);
|
|
41
|
-
PLAIN.forEach((f, i) => {
|
|
42
|
-
const s = x.malloc(f.length + 1);
|
|
43
|
-
new Uint8Array(memory.buffer).set([...f].map((c) => c.charCodeAt(0)).concat(0), s);
|
|
44
|
-
x.hb_feature_from_string(s, -1, featPtr + 16 * i);
|
|
45
|
-
x.free(s);
|
|
46
|
-
});
|
|
47
|
-
return {
|
|
48
|
-
/**
|
|
49
|
-
* A HarfBuzz font for these bytes. It lives as long as the shaper: fonts are few and reused.
|
|
50
|
-
* @param {Uint8Array} bytes @returns {{ ptr: number, upem: number }}
|
|
51
|
-
*/
|
|
52
|
-
font(bytes) {
|
|
53
|
-
const buf = x.malloc(bytes.byteLength);
|
|
54
|
-
new Uint8Array(memory.buffer).set(bytes, buf);
|
|
55
|
-
const blob = x.hb_blob_create(buf, bytes.byteLength, 1, 0, 0);
|
|
56
|
-
const face = x.hb_face_create(blob, 0);
|
|
57
|
-
const ptr = x.hb_font_create(face);
|
|
58
|
-
const upem = x.hb_face_get_upem(face);
|
|
59
|
-
x.hb_face_destroy(face);
|
|
60
|
-
x.hb_blob_destroy(blob);
|
|
61
|
-
return { ptr, upem };
|
|
62
|
-
},
|
|
63
|
-
/**
|
|
64
|
-
* Shape one run (one font, one script, one direction).
|
|
65
|
-
* @param {{ ptr: number }} font @param {string} text @param {boolean} rtl
|
|
66
|
-
* @param {boolean} [plain] kerning and ligatures off (a simple-script run in a right-to-left context)
|
|
67
|
-
* @returns {number[]} [glyph id, x advance, x offset, y offset, cluster (UTF-16 index)] per glyph, in visual order
|
|
68
|
-
*/
|
|
69
|
-
shape(font, text, rtl, plain = false) {
|
|
70
|
-
const n2 = text.length;
|
|
71
|
-
const p = x.malloc(n2 * 2 + 2);
|
|
72
|
-
const u16 = new Uint16Array(memory.buffer, p, n2);
|
|
73
|
-
for (let i = 0; i < n2; i++) u16[i] = text.charCodeAt(i);
|
|
74
|
-
const b = x.hb_buffer_create();
|
|
75
|
-
x.hb_buffer_add_utf16(b, p, n2, 0, n2);
|
|
76
|
-
x.hb_buffer_set_direction(b, rtl ? RTL : LTR);
|
|
77
|
-
x.hb_buffer_guess_segment_properties(b);
|
|
78
|
-
x.hb_shape(font.ptr, b, plain ? featPtr : 0, plain ? PLAIN.length : 0);
|
|
79
|
-
const len = x.hb_buffer_get_length(b);
|
|
80
|
-
const info = new Uint32Array(memory.buffer, x.hb_buffer_get_glyph_infos(b, 0), len * 5);
|
|
81
|
-
const pos = new Int32Array(memory.buffer, x.hb_buffer_get_glyph_positions(b, 0), len * 5);
|
|
82
|
-
const out = new Array(len * 5);
|
|
83
|
-
for (let i = 0; i < len; i++) {
|
|
84
|
-
out[i * 5] = info[i * 5];
|
|
85
|
-
out[i * 5 + 1] = pos[i * 5];
|
|
86
|
-
out[i * 5 + 2] = pos[i * 5 + 2];
|
|
87
|
-
out[i * 5 + 3] = pos[i * 5 + 3];
|
|
88
|
-
out[i * 5 + 4] = info[i * 5 + 2];
|
|
89
|
-
}
|
|
90
|
-
x.hb_buffer_destroy(b);
|
|
91
|
-
x.free(p);
|
|
92
|
-
return out;
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// src/engine/text/fonts.js
|
|
98
|
-
var fontkit = (
|
|
99
|
-
/** @type {any} */
|
|
100
|
-
fontkitModule.default || fontkitModule
|
|
101
|
-
);
|
|
102
|
-
var BUNDLED = [
|
|
103
|
-
["Inter", "Inter-Regular", 400],
|
|
104
|
-
["Inter", "Inter-Italic", 400, "italic"],
|
|
105
|
-
["Inter", "Inter-SemiBold", 600],
|
|
106
|
-
["Inter", "Inter-Bold", 700],
|
|
107
|
-
["Inter", "Inter-BoldItalic", 700, "italic"],
|
|
108
|
-
["JetBrains Mono", "JetBrainsMono-Regular", 400],
|
|
109
|
-
["JetBrains Mono", "JetBrainsMono-Bold", 700],
|
|
110
|
-
["Noto Sans Devanagari", "NotoSansDevanagari-Regular", 400],
|
|
111
|
-
["Noto Sans Devanagari", "NotoSansDevanagari-Bold", 700],
|
|
112
|
-
["Noto Sans Arabic", "NotoSansArabic-Regular", 400],
|
|
113
|
-
["Noto Sans Arabic", "NotoSansArabic-Bold", 700],
|
|
114
|
-
["Noto Sans Hebrew", "NotoSansHebrew-Regular", 400],
|
|
115
|
-
["Noto Sans Hebrew", "NotoSansHebrew-Bold", 700],
|
|
116
|
-
// fallbacks loaded only when text uses the script (docs/TEXT.md has the sizes)
|
|
117
|
-
...["Thai", "Lao", "Khmer", "Myanmar", "Tamil", "Bengali", "Telugu", "Kannada", "Gujarati"].flatMap((s) => [
|
|
118
|
-
[`Noto Sans ${s}`, `NotoSans${s}-Regular`, 400],
|
|
119
|
-
[`Noto Sans ${s}`, `NotoSans${s}-Bold`, 700]
|
|
120
|
-
]),
|
|
121
|
-
// optional, about 40 MB (npm run fonts:cjk fetches them into /fonts/cjk): variable fonts drawn at their default
|
|
122
|
-
// (regular) weight. Without them the text shows as boxes, and the warning says how to add them.
|
|
123
|
-
["Noto Sans JP", "NotoSansJP", 400, "normal", "cjk/NotoSansJP.ttf"],
|
|
124
|
-
["Noto Sans KR", "NotoSansKR", 400, "normal", "cjk/NotoSansKR.ttf"],
|
|
125
|
-
["Noto Sans SC", "NotoSansSC", 400, "normal", "cjk/NotoSansSC.ttf"],
|
|
126
|
-
["Noto Emoji", "NotoEmoji", 400, "normal", "cjk/NotoEmoji.ttf"]
|
|
127
|
-
];
|
|
128
|
-
var OPTIONAL_KEYS = ["NotoSansJP", "NotoSansKR", "NotoSansSC", "NotoEmoji"];
|
|
129
|
-
var FONT_FAMILIES = {};
|
|
130
|
-
var FACES = /* @__PURE__ */ new Map();
|
|
131
|
-
var addFace = (f) => {
|
|
132
|
-
var _a;
|
|
133
|
-
(FONT_FAMILIES[_a = f.family] || (FONT_FAMILIES[_a] = [])).push(f);
|
|
134
|
-
FACES.set(f.key, f);
|
|
135
|
-
};
|
|
136
|
-
for (const [family, key, weight, style = "normal", file] of BUNDLED) {
|
|
137
|
-
addFace({ family: String(family), key: String(key), weight: Number(weight), style: style === "italic" ? "italic" : "normal", file: String(file || `${key}.ttf`) });
|
|
138
|
-
}
|
|
139
|
-
var BUNDLED_FAMILIES = Object.keys(FONT_FAMILIES);
|
|
140
|
-
var DEFAULT_FAMILY = "Inter";
|
|
141
|
-
var ALL_FONT_KEYS = [...FONT_FAMILIES.Inter, ...FONT_FAMILIES["JetBrains Mono"]].map((f) => f.key);
|
|
142
|
-
var CORE_FONT_KEY = "Inter-Regular";
|
|
143
|
-
var PRELOAD_KEYS = [...ALL_FONT_KEYS];
|
|
144
|
-
var SHAPER = "harfbuzz";
|
|
145
|
-
function fontFile(key) {
|
|
146
|
-
if (key === SHAPER) return "harfbuzz.wasm";
|
|
147
|
-
return FACES.get(key)?.file || `${key}.ttf`;
|
|
148
|
-
}
|
|
149
|
-
function setCustomFonts(list) {
|
|
150
|
-
for (const [k, f] of FACES) if (k.startsWith("u-")) {
|
|
151
|
-
FACES.delete(k);
|
|
152
|
-
const left = FONT_FAMILIES[f.family].filter((x) => x.key !== k);
|
|
153
|
-
if (left.length) FONT_FAMILIES[f.family] = left;
|
|
154
|
-
else delete FONT_FAMILIES[f.family];
|
|
155
|
-
}
|
|
156
|
-
for (const f of list || []) {
|
|
157
|
-
if (BUNDLED_FAMILIES.includes(f.family) || !/^[a-f0-9]{8,64}$/.test(String(f.id))) continue;
|
|
158
|
-
addFace({ key: `u-${f.id}`, family: String(f.family), weight: Number(f.weight) || 400, style: f.style === "italic" ? "italic" : "normal", file: `custom/${f.id}` });
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function resolveFontKey(family, weight, style) {
|
|
162
|
-
const faces = FONT_FAMILIES[family || DEFAULT_FAMILY] || FONT_FAMILIES[DEFAULT_FAMILY];
|
|
163
|
-
const w = weight === "bold" ? 700 : weight === "normal" || weight == null ? 400 : Number(weight) || 400;
|
|
164
|
-
const italic = faces.filter((f) => f.style === "italic");
|
|
165
|
-
const list = style === "italic" && italic.length ? italic : faces.filter((f) => f.style !== "italic").length ? faces.filter((f) => f.style !== "italic") : faces;
|
|
166
|
-
const rank = (f) => {
|
|
167
|
-
const fw = f.weight;
|
|
168
|
-
if (w >= 400 && w <= 500) return fw >= w && fw <= 500 ? fw - w : fw < w ? 1e3 + w - fw : 2e3 + fw - w;
|
|
169
|
-
if (w < 400) return fw <= w ? w - fw : 1e3 + fw - w;
|
|
170
|
-
return fw >= w ? fw - w : 1e3 + w - fw;
|
|
171
|
-
};
|
|
172
|
-
return list.reduce((best, f) => rank(f) < rank(best) ? f : best).key;
|
|
173
|
-
}
|
|
174
|
-
function fontCss(key) {
|
|
175
|
-
const f = FACES.get(key);
|
|
176
|
-
return f ? { family: f.family, weight: f.weight, style: f.style } : { family: DEFAULT_FAMILY, weight: 400, style: "normal" };
|
|
177
|
-
}
|
|
178
|
-
var FALLBACK = [
|
|
179
|
-
[1424, 1535, "Noto Sans Hebrew"],
|
|
180
|
-
[64285, 64335, "Noto Sans Hebrew"],
|
|
181
|
-
[1536, 2303, "Noto Sans Arabic"],
|
|
182
|
-
[64336, 65023, "Noto Sans Arabic"],
|
|
183
|
-
[65136, 65278, "Noto Sans Arabic"],
|
|
184
|
-
[2304, 2431, "Noto Sans Devanagari"],
|
|
185
|
-
[43232, 43263, "Noto Sans Devanagari"],
|
|
186
|
-
[7376, 7423, "Noto Sans Devanagari"],
|
|
187
|
-
[2432, 2559, "Noto Sans Bengali"],
|
|
188
|
-
[2688, 2815, "Noto Sans Gujarati"],
|
|
189
|
-
[2944, 3071, "Noto Sans Tamil"],
|
|
190
|
-
[73664, 73727, "Noto Sans Tamil"],
|
|
191
|
-
[3072, 3199, "Noto Sans Telugu"],
|
|
192
|
-
[3200, 3327, "Noto Sans Kannada"],
|
|
193
|
-
[3584, 3711, "Noto Sans Thai"],
|
|
194
|
-
[3712, 3839, "Noto Sans Lao"],
|
|
195
|
-
[4096, 4255, "Noto Sans Myanmar"],
|
|
196
|
-
[43488, 43519, "Noto Sans Myanmar"],
|
|
197
|
-
[43616, 43647, "Noto Sans Myanmar"],
|
|
198
|
-
[6016, 6143, "Noto Sans Khmer"],
|
|
199
|
-
[6624, 6655, "Noto Sans Khmer"],
|
|
200
|
-
// CJK (optional fonts): kana and Han in the Japanese face (Han shapes differ a little from Chinese; a report can
|
|
201
|
-
// set fontFamily "Noto Sans SC"), Hangul in the Korean one; emoji in Noto Emoji (monochrome)
|
|
202
|
-
[12352, 12543, "Noto Sans JP"],
|
|
203
|
-
[12784, 12799, "Noto Sans JP"],
|
|
204
|
-
[12288, 12351, "Noto Sans JP"],
|
|
205
|
-
[13312, 19903, "Noto Sans JP"],
|
|
206
|
-
[19968, 40959, "Noto Sans JP"],
|
|
207
|
-
[63744, 64255, "Noto Sans JP"],
|
|
208
|
-
[65280, 65519, "Noto Sans JP"],
|
|
209
|
-
[4352, 4607, "Noto Sans KR"],
|
|
210
|
-
[12592, 12687, "Noto Sans KR"],
|
|
211
|
-
[44032, 55215, "Noto Sans KR"],
|
|
212
|
-
[126976, 129791, "Noto Emoji"],
|
|
213
|
-
[9728, 10175, "Noto Emoji"],
|
|
214
|
-
[11008, 11263, "Noto Emoji"]
|
|
215
|
-
];
|
|
216
|
-
var allFontKeys = () => [...FACES.keys()];
|
|
217
|
-
function fallbackKeys(key) {
|
|
218
|
-
const c = fontCss(key);
|
|
219
|
-
return [...new Set(FALLBACK.map((f) => String(f[2])))].map((family) => resolveFontKey(family, c.weight, c.style));
|
|
220
|
-
}
|
|
221
|
-
function unicodeRange(key) {
|
|
222
|
-
const family = FACES.get(key)?.family;
|
|
223
|
-
const r = FALLBACK.filter((f) => f[2] === family).map(([a, b]) => `U+${Number(a).toString(16)}-${Number(b).toString(16)}`);
|
|
224
|
-
return r.length ? [...r, "U+300-36F", "U+2000-206F", "U+25CC", "U+FE00-FE0F"].join(",") : null;
|
|
225
|
-
}
|
|
226
|
-
function fallbackKey(cp, key) {
|
|
227
|
-
for (const [a, b, family] of FALLBACK) {
|
|
228
|
-
if (cp >= /** @type {number} */
|
|
229
|
-
a && cp <= /** @type {number} */
|
|
230
|
-
b) {
|
|
231
|
-
const c = fontCss(key);
|
|
232
|
-
return resolveFontKey(String(family), c.weight, c.style);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return null;
|
|
236
|
-
}
|
|
237
|
-
var SIMPLE_FALLBACK = /* @__PURE__ */ new Set(["Noto Sans JP", "Noto Sans KR", "Noto Emoji"]);
|
|
238
|
-
var BEYOND_LATIN = /[^\u0000-\u024f\u1e00-\u1eff\u2000-\u20cf\u2100-\u218f]/;
|
|
239
|
-
function fontsForDef(def) {
|
|
240
|
-
const keys = /* @__PURE__ */ new Set();
|
|
241
|
-
const seen = /* @__PURE__ */ new Set();
|
|
242
|
-
const walk = (o) => {
|
|
243
|
-
if (!o || typeof o !== "object" || seen.has(o)) return;
|
|
244
|
-
seen.add(o);
|
|
245
|
-
if (Array.isArray(o)) {
|
|
246
|
-
for (const x of o) walk(x);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
if (o.fontFamily != null || o.fontWeight != null || o.fontStyle != null) keys.add(resolveFontKey(o.fontFamily, o.fontWeight, o.fontStyle));
|
|
250
|
-
if (o.type === "chart") keys.add(resolveFontKey(o.fontFamily, "bold", "normal"));
|
|
251
|
-
for (const [k, v] of Object.entries(o)) if (v && typeof v === "object" && k !== "dataSources" && k !== "data") walk(v);
|
|
252
|
-
};
|
|
253
|
-
walk(def);
|
|
254
|
-
return [...keys];
|
|
255
|
-
}
|
|
256
|
-
function fontsFor(texts) {
|
|
257
|
-
const keys = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set();
|
|
258
|
-
let shaper = false;
|
|
259
|
-
for (const t of texts) {
|
|
260
|
-
if (typeof t !== "string" || !BEYOND_LATIN.test(t)) continue;
|
|
261
|
-
for (const ch of t) {
|
|
262
|
-
const cp = (
|
|
263
|
-
/** @type {number} */
|
|
264
|
-
ch.codePointAt(0)
|
|
265
|
-
);
|
|
266
|
-
if (cp < 592 || seen.has(cp)) continue;
|
|
267
|
-
seen.add(cp);
|
|
268
|
-
for (const [a, b, family] of FALLBACK) {
|
|
269
|
-
if (cp < /** @type {number} */
|
|
270
|
-
a || cp > /** @type {number} */
|
|
271
|
-
b) continue;
|
|
272
|
-
keys.add(resolveFontKey(String(family), 400, "normal")).add(resolveFontKey(String(family), 700, "normal"));
|
|
273
|
-
if (!SIMPLE_FALLBACK.has(String(family))) shaper = true;
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (shaper) keys.add(SHAPER);
|
|
279
|
-
return [...keys];
|
|
280
|
-
}
|
|
281
|
-
var FontStore = class {
|
|
282
|
-
/** @param {(key: string) => Promise<ArrayBuffer|Uint8Array>} loader */
|
|
283
|
-
constructor(loader) {
|
|
284
|
-
this.loader = loader;
|
|
285
|
-
this.fonts = /* @__PURE__ */ new Map();
|
|
286
|
-
this.bytes = /* @__PURE__ */ new Map();
|
|
287
|
-
this.pending = /* @__PURE__ */ new Map();
|
|
288
|
-
this.failed = /* @__PURE__ */ new Set();
|
|
289
|
-
this.shaper = null;
|
|
290
|
-
this.hb = /* @__PURE__ */ new Map();
|
|
291
|
-
}
|
|
292
|
-
/** @param {string[]} keys */
|
|
293
|
-
async load(keys = ALL_FONT_KEYS) {
|
|
294
|
-
await Promise.all(keys.map((k) => {
|
|
295
|
-
if (this.fonts.has(k) || this.failed.has(k) || k === SHAPER && this.shaper) return null;
|
|
296
|
-
if (!this.pending.has(k)) {
|
|
297
|
-
this.pending.set(k, (async () => {
|
|
298
|
-
try {
|
|
299
|
-
const b = await this.loader(k);
|
|
300
|
-
const u8 = b instanceof Uint8Array ? b : new Uint8Array(b);
|
|
301
|
-
if (k === SHAPER) {
|
|
302
|
-
this.shaper = await createShaper(u8);
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
this.fonts.set(k, fontkit.create(u8));
|
|
306
|
-
this.bytes.set(k, u8);
|
|
307
|
-
} catch (e) {
|
|
308
|
-
this.pending.delete(k);
|
|
309
|
-
if (k === CORE_FONT_KEY) throw e;
|
|
310
|
-
this.failed.add(k);
|
|
311
|
-
}
|
|
312
|
-
})());
|
|
313
|
-
}
|
|
314
|
-
return this.pending.get(k);
|
|
315
|
-
}));
|
|
316
|
-
}
|
|
317
|
-
/** @param {string} key */
|
|
318
|
-
has(key) {
|
|
319
|
-
return this.fonts.has(key);
|
|
320
|
-
}
|
|
321
|
-
/** The HarfBuzz font for a loaded key (the shaper must be loaded). @param {string} key */
|
|
322
|
-
hbFont(key) {
|
|
323
|
-
let f = this.hb.get(key);
|
|
324
|
-
if (!f) {
|
|
325
|
-
f = this.shaper.font(this.bytes.get(key));
|
|
326
|
-
this.hb.set(key, f);
|
|
327
|
-
}
|
|
328
|
-
return f;
|
|
329
|
-
}
|
|
330
|
-
/** @param {string} key */
|
|
331
|
-
get(key) {
|
|
332
|
-
const f = this.fonts.get(key);
|
|
333
|
-
if (!f) throw new Error(`Font "${key}" is not loaded`);
|
|
334
|
-
return f;
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
// src/engine/image.js
|
|
339
|
-
var IMAGE_LIMITS = {
|
|
340
|
-
bytes: 10 * 1024 * 1024,
|
|
341
|
-
// one image
|
|
342
|
-
total: 50 * 1024 * 1024,
|
|
343
|
-
// all images of one render (each distinct image counted once)
|
|
344
|
-
pixels: 4e7,
|
|
345
|
-
// a PNG larger than this is not decoded (a small file can inflate to gigabytes)
|
|
346
|
-
svgBytes: 2 * 1024 * 1024,
|
|
347
|
-
// an SVG drawn as vector paths in the PDF
|
|
348
|
-
svgShapes: 1e4
|
|
349
|
-
};
|
|
350
|
-
var PX = 0.75;
|
|
351
|
-
var MIME = { png: "image/png", jpeg: "image/jpeg", gif: "image/gif", webp: "image/webp", svg: "image/svg+xml" };
|
|
352
|
-
function sniff(b) {
|
|
353
|
-
if (b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) return "png";
|
|
354
|
-
if (b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255) return "jpeg";
|
|
355
|
-
if (b.length >= 6 && b[0] === 71 && b[1] === 73 && b[2] === 70 && b[3] === 56) return "gif";
|
|
356
|
-
if (b.length >= 12 && b[0] === 82 && b[1] === 73 && b[2] === 70 && b[3] === 70 && b[8] === 87 && b[9] === 69 && b[10] === 66 && b[11] === 80) return "webp";
|
|
357
|
-
const head = String.fromCharCode(...b.subarray(0, 512)).replace(/^|^\xEF\xBB\xBF/, "").trimStart();
|
|
358
|
-
if (/^<(\?xml|svg|!--|!DOCTYPE svg)/i.test(head) && /<svg[\s>]/i.test(head + (b.length > 512 ? "<svg " : ""))) return "svg";
|
|
359
|
-
return null;
|
|
360
|
-
}
|
|
361
|
-
function toBase64(b) {
|
|
362
|
-
let s = "";
|
|
363
|
-
for (let i = 0; i < b.length; i += 32768) s += String.fromCharCode(...b.subarray(i, i + 32768));
|
|
364
|
-
return btoa(s);
|
|
365
|
-
}
|
|
366
|
-
function fromBase64(s) {
|
|
367
|
-
const bin = atob(s);
|
|
368
|
-
const out = new Uint8Array(bin.length);
|
|
369
|
-
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
370
|
-
return out;
|
|
371
|
-
}
|
|
372
|
-
var B64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
373
|
-
function toDataUri(v) {
|
|
374
|
-
if (v instanceof ArrayBuffer) v = new Uint8Array(v);
|
|
375
|
-
if (v instanceof Uint8Array) {
|
|
376
|
-
if (v.length > IMAGE_LIMITS.bytes) return null;
|
|
377
|
-
const type2 = sniff(v);
|
|
378
|
-
return type2 ? `data:${MIME[type2]};base64,${toBase64(v)}` : null;
|
|
379
|
-
}
|
|
380
|
-
if (typeof v !== "string" || v.length < 16 || v.startsWith("data:")) return v;
|
|
381
|
-
if (/[^A-Za-z0-9+/=\r\n]/.test(v)) return v;
|
|
382
|
-
const s = v.replace(/[\r\n]/g, "");
|
|
383
|
-
if (!B64.test(s) || s.length % 4) return v;
|
|
384
|
-
let type;
|
|
385
|
-
try {
|
|
386
|
-
type = sniff(fromBase64(s.slice(0, 700)));
|
|
387
|
-
} catch {
|
|
388
|
-
return v;
|
|
389
|
-
}
|
|
390
|
-
return type ? `data:${MIME[type]};base64,${s}` : v;
|
|
391
|
-
}
|
|
392
|
-
function splitDataUri(uri) {
|
|
393
|
-
if (typeof uri !== "string" || !/^data:/i.test(uri)) return null;
|
|
394
|
-
const c = uri.indexOf(",");
|
|
395
|
-
if (c < 0) return null;
|
|
396
|
-
const meta = uri.slice(5, c);
|
|
397
|
-
return { meta, b64: meta.slice(meta.lastIndexOf(";") + 1).trim().toLowerCase() === "base64" && meta.includes(";"), body: uri.slice(c + 1) };
|
|
398
|
-
}
|
|
399
|
-
function dataUriBytes(uri) {
|
|
400
|
-
const d = splitDataUri(uri);
|
|
401
|
-
if (!d) return 0;
|
|
402
|
-
return d.b64 ? Math.floor(d.body.length * 3 / 4) : d.body.length;
|
|
403
|
-
}
|
|
404
|
-
function dataUriHead(uri, max = 262144) {
|
|
405
|
-
const d = splitDataUri(uri);
|
|
406
|
-
if (!d) return null;
|
|
407
|
-
try {
|
|
408
|
-
if (d.b64) return fromBase64(d.body.slice(0, Number.isFinite(max) ? Math.ceil(max / 3) * 4 : void 0).replace(/\s/g, ""));
|
|
409
|
-
return new TextEncoder().encode(decodeURIComponent(d.body.slice(0, max)));
|
|
410
|
-
} catch {
|
|
411
|
-
return null;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
function dataUriBytesOf(uri) {
|
|
415
|
-
return dataUriHead(uri, Infinity);
|
|
416
|
-
}
|
|
417
|
-
var UNIT = { px: 1, pt: 4 / 3, pc: 16, mm: 96 / 25.4, cm: 96 / 2.54, in: 96, "": 1 };
|
|
418
|
-
function svgLength(v) {
|
|
419
|
-
const t = String(v ?? "").trim();
|
|
420
|
-
if (t.length > 64) return null;
|
|
421
|
-
const m = /^([\d.]+(?:e[-+]?\d+)?)(px|pt|pc|mm|cm|in)?$/i.exec(t);
|
|
422
|
-
if (!m) return null;
|
|
423
|
-
const n2 = Number(m[1]) * UNIT[(m[2] || "").toLowerCase()];
|
|
424
|
-
return Number.isFinite(n2) && n2 > 0 ? n2 : null;
|
|
425
|
-
}
|
|
426
|
-
var isName = (c) => c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "_" || c === ":" || c === "-" || c === ".";
|
|
427
|
-
var isSpace = (c) => c === " " || c === " " || c === "\n" || c === "\r";
|
|
428
|
-
function* xmlTags(text) {
|
|
429
|
-
const n2 = text.length;
|
|
430
|
-
let i = 0;
|
|
431
|
-
while (i < n2) {
|
|
432
|
-
const lt = text.indexOf("<", i);
|
|
433
|
-
if (lt < 0) return;
|
|
434
|
-
if (text.startsWith("<!--", lt)) {
|
|
435
|
-
const e = text.indexOf("-->", lt + 4);
|
|
436
|
-
if (e < 0) return;
|
|
437
|
-
i = e + 3;
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
if (text.startsWith("<![CDATA[", lt)) {
|
|
441
|
-
const e = text.indexOf("]]>", lt + 9);
|
|
442
|
-
if (e < 0) return;
|
|
443
|
-
i = e + 3;
|
|
444
|
-
continue;
|
|
445
|
-
}
|
|
446
|
-
if (text[lt + 1] === "?" || text[lt + 1] === "!") {
|
|
447
|
-
const e = text.indexOf(">", lt + 2);
|
|
448
|
-
if (e < 0) return;
|
|
449
|
-
i = e + 1;
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
452
|
-
let j = lt + 1, q = "";
|
|
453
|
-
for (; j < n2; j++) {
|
|
454
|
-
const c = text[j];
|
|
455
|
-
if (q) {
|
|
456
|
-
if (c === q) q = "";
|
|
457
|
-
} else if (c === '"' || c === "'") q = c;
|
|
458
|
-
else if (c === ">") break;
|
|
459
|
-
}
|
|
460
|
-
if (j >= n2) return;
|
|
461
|
-
i = j + 1;
|
|
462
|
-
let body = text.slice(lt + 1, j);
|
|
463
|
-
const close = body[0] === "/";
|
|
464
|
-
if (close) body = body.slice(1);
|
|
465
|
-
const self = body.endsWith("/");
|
|
466
|
-
if (self) body = body.slice(0, -1);
|
|
467
|
-
let k = 0;
|
|
468
|
-
while (k < body.length && isName(body[k])) k++;
|
|
469
|
-
const name = body.slice(0, k);
|
|
470
|
-
if (!/^[a-zA-Z]/.test(name)) continue;
|
|
471
|
-
yield { close, name, attrs: body.slice(k), self };
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
function xmlAttrs(s) {
|
|
475
|
-
const a = /* @__PURE__ */ Object.create(null);
|
|
476
|
-
const n2 = s.length;
|
|
477
|
-
let i = 0;
|
|
478
|
-
while (i < n2) {
|
|
479
|
-
while (i < n2 && !isName(s[i])) i++;
|
|
480
|
-
const st = i;
|
|
481
|
-
while (i < n2 && isName(s[i])) i++;
|
|
482
|
-
const name = s.slice(st, i);
|
|
483
|
-
while (i < n2 && isSpace(s[i])) i++;
|
|
484
|
-
if (s[i] !== "=") continue;
|
|
485
|
-
i++;
|
|
486
|
-
while (i < n2 && isSpace(s[i])) i++;
|
|
487
|
-
const q = s[i];
|
|
488
|
-
if (q !== '"' && q !== "'") continue;
|
|
489
|
-
const e = s.indexOf(q, i + 1);
|
|
490
|
-
if (e < 0) break;
|
|
491
|
-
if (name) a[name] = s.slice(i + 1, e);
|
|
492
|
-
i = e + 1;
|
|
493
|
-
}
|
|
494
|
-
return a;
|
|
495
|
-
}
|
|
496
|
-
function svgRootAttrs(text) {
|
|
497
|
-
for (const t of xmlTags(String(text))) if (!t.close && t.name.toLowerCase() === "svg") return xmlAttrs(t.attrs);
|
|
498
|
-
return null;
|
|
499
|
-
}
|
|
500
|
-
function svgSize(text) {
|
|
501
|
-
const a = svgRootAttrs(text);
|
|
502
|
-
if (!a) return null;
|
|
503
|
-
const vb = String(a.viewBox || "").trim().split(/[\s,]+/).map(Number);
|
|
504
|
-
const hasVb = vb.length === 4 && vb.every(Number.isFinite) && vb[2] > 0 && vb[3] > 0;
|
|
505
|
-
let w = svgLength(a.width), h = svgLength(a.height);
|
|
506
|
-
if (w && !h) h = hasVb ? w * vb[3] / vb[2] : null;
|
|
507
|
-
if (h && !w) w = hasVb ? h * vb[2] / vb[3] : null;
|
|
508
|
-
if (!w && hasVb) {
|
|
509
|
-
w = vb[2];
|
|
510
|
-
h = vb[3];
|
|
511
|
-
}
|
|
512
|
-
return w && h ? { w, h } : null;
|
|
513
|
-
}
|
|
514
|
-
function imageInfoOf(b) {
|
|
515
|
-
const type = sniff(b);
|
|
516
|
-
if (!type) return null;
|
|
517
|
-
const u32 = (i) => (b[i] << 24 | b[i + 1] << 16 | b[i + 2] << 8 | b[i + 3]) >>> 0;
|
|
518
|
-
if (type === "png") return pngInfo(b);
|
|
519
|
-
if (type === "gif" && b.length >= 10) return { type, w: b[6] | b[7] << 8, h: b[8] | b[9] << 8 };
|
|
520
|
-
if (type === "jpeg") {
|
|
521
|
-
for (let i = 2; i + 9 < b.length; ) {
|
|
522
|
-
if (b[i] !== 255) {
|
|
523
|
-
i++;
|
|
524
|
-
continue;
|
|
525
|
-
}
|
|
526
|
-
const mk = b[i + 1];
|
|
527
|
-
if (mk === 255) {
|
|
528
|
-
i++;
|
|
529
|
-
continue;
|
|
530
|
-
}
|
|
531
|
-
if (mk === 216 || mk === 1 || mk >= 208 && mk <= 215) {
|
|
532
|
-
i += 2;
|
|
533
|
-
continue;
|
|
534
|
-
}
|
|
535
|
-
if (mk >= 192 && mk <= 207 && mk !== 196 && mk !== 200 && mk !== 204) return { type, w: b[i + 7] << 8 | b[i + 8], h: b[i + 5] << 8 | b[i + 6] };
|
|
536
|
-
i += 2 + (b[i + 2] << 8 | b[i + 3]);
|
|
537
|
-
}
|
|
538
|
-
return { type };
|
|
539
|
-
}
|
|
540
|
-
if (type === "svg") {
|
|
541
|
-
const s = svgSize(new TextDecoder().decode(b));
|
|
542
|
-
return s ? { type, ...s } : { type };
|
|
543
|
-
}
|
|
544
|
-
return { type };
|
|
545
|
-
}
|
|
546
|
-
function pngInfo(b) {
|
|
547
|
-
const u32 = (i) => (b[i] << 24 | b[i + 1] << 16 | b[i + 2] << 8 | b[i + 3]) >>> 0;
|
|
548
|
-
let w = 0, h = 0, ihdrs = 0, animated = false;
|
|
549
|
-
for (let off = 8; off + 8 <= b.length; ) {
|
|
550
|
-
const len = u32(off);
|
|
551
|
-
const t = String.fromCharCode(b[off + 4], b[off + 5], b[off + 6], b[off + 7]);
|
|
552
|
-
const d = off + 8;
|
|
553
|
-
if (t === "IHDR" && d + 8 <= b.length) {
|
|
554
|
-
w = u32(d);
|
|
555
|
-
h = u32(d + 4);
|
|
556
|
-
ihdrs++;
|
|
557
|
-
} else if (t === "acTL" || t === "fcTL" || t === "fdAT") animated = true;
|
|
558
|
-
else if (t === "IEND") break;
|
|
559
|
-
off = d + len + 4;
|
|
560
|
-
}
|
|
561
|
-
if (!ihdrs) return { type: "png" };
|
|
562
|
-
return { type: "png", w, h, ...animated || ihdrs > 1 ? { suspect: true } : {} };
|
|
563
|
-
}
|
|
564
|
-
function imageInfo(uri) {
|
|
565
|
-
const b = typeof uri === "string" && uri.startsWith("data:") ? dataUriHead(uri) : null;
|
|
566
|
-
return b ? imageInfoOf(b) : null;
|
|
567
|
-
}
|
|
568
|
-
function resolveImageSrc(v, who, c) {
|
|
569
|
-
var _a;
|
|
570
|
-
if (v == null || v === "" || v === "#Error") return null;
|
|
571
|
-
if (typeof v === "string" && v.startsWith("embedded:")) {
|
|
572
|
-
const name = v.slice(9);
|
|
573
|
-
const img = c.images && Object.prototype.hasOwnProperty.call(c.images, name) ? c.images[name] : void 0;
|
|
574
|
-
if (typeof img !== "string" || !/^data:image\/[\w.+-]+[;,]/i.test(img)) {
|
|
575
|
-
c.warn(`${who}: there is no embedded image named "${name}" (add it to the report's images as a data:image/… URI)`);
|
|
576
|
-
return null;
|
|
577
|
-
}
|
|
578
|
-
v = img;
|
|
579
|
-
}
|
|
580
|
-
const memo = c.budget ? (_a = c.budget).memo || (_a.memo = /* @__PURE__ */ new Map()) : null;
|
|
581
|
-
let u = memo?.get(v);
|
|
582
|
-
if (u === void 0) {
|
|
583
|
-
u = toDataUri(v);
|
|
584
|
-
memo?.set(v, u);
|
|
585
|
-
}
|
|
586
|
-
if (u == null) {
|
|
587
|
-
c.warn(`${who}: the image data is not a PNG, JPEG, GIF, WebP or SVG image, or is larger than 10 MB`);
|
|
588
|
-
return null;
|
|
589
|
-
}
|
|
590
|
-
const s = String(u);
|
|
591
|
-
if (s.startsWith("data:")) {
|
|
592
|
-
const n2 = dataUriBytes(s);
|
|
593
|
-
if (n2 > IMAGE_LIMITS.bytes) {
|
|
594
|
-
c.warn(`${who}: the image is ${(n2 / 1048576).toFixed(1)} MB; images are limited to 10 MB each, so it is left out`);
|
|
595
|
-
return null;
|
|
596
|
-
}
|
|
597
|
-
const b = c.budget;
|
|
598
|
-
if (b && !b.seen.has(s)) {
|
|
599
|
-
if (b.bytes + n2 > IMAGE_LIMITS.total) {
|
|
600
|
-
c.warn(`${who}: the report's images pass 50 MB in all, so this one is left out`);
|
|
601
|
-
return null;
|
|
602
|
-
}
|
|
603
|
-
b.seen.add(s);
|
|
604
|
-
b.bytes += n2;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
return s;
|
|
608
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
IMAGE_LIMITS,
|
|
3
|
+
dataUriBytesOf,
|
|
4
|
+
fontFile,
|
|
5
|
+
imageInfoOf,
|
|
6
|
+
unicodeRange
|
|
7
|
+
} from "./chunk-Z7MKH66Z.js";
|
|
609
8
|
|
|
610
9
|
// src/exporters/color.js
|
|
611
10
|
var NAMED = { black: "#000000", white: "#ffffff", red: "#ff0000", green: "#008000", blue: "#0000ff", gray: "#808080", grey: "#808080", orange: "#ffa500", yellow: "#ffff00" };
|
|
@@ -1119,35 +518,6 @@ function cellVisuals(items, used, tables) {
|
|
|
1119
518
|
}
|
|
1120
519
|
|
|
1121
520
|
export {
|
|
1122
|
-
OPTIONAL_KEYS,
|
|
1123
|
-
FONT_FAMILIES,
|
|
1124
|
-
BUNDLED_FAMILIES,
|
|
1125
|
-
DEFAULT_FAMILY,
|
|
1126
|
-
ALL_FONT_KEYS,
|
|
1127
|
-
CORE_FONT_KEY,
|
|
1128
|
-
PRELOAD_KEYS,
|
|
1129
|
-
SHAPER,
|
|
1130
|
-
fontFile,
|
|
1131
|
-
setCustomFonts,
|
|
1132
|
-
resolveFontKey,
|
|
1133
|
-
fontCss,
|
|
1134
|
-
allFontKeys,
|
|
1135
|
-
fallbackKeys,
|
|
1136
|
-
fallbackKey,
|
|
1137
|
-
fontsForDef,
|
|
1138
|
-
fontsFor,
|
|
1139
|
-
FontStore,
|
|
1140
|
-
IMAGE_LIMITS,
|
|
1141
|
-
PX,
|
|
1142
|
-
dataUriBytes,
|
|
1143
|
-
dataUriBytesOf,
|
|
1144
|
-
svgLength,
|
|
1145
|
-
xmlTags,
|
|
1146
|
-
xmlAttrs,
|
|
1147
|
-
svgRootAttrs,
|
|
1148
|
-
imageInfoOf,
|
|
1149
|
-
imageInfo,
|
|
1150
|
-
resolveImageSrc,
|
|
1151
521
|
parseColor,
|
|
1152
522
|
figures,
|
|
1153
523
|
boxOf,
|
|
@@ -1164,4 +534,4 @@ export {
|
|
|
1164
534
|
fontFaceCss,
|
|
1165
535
|
fontKeysOf
|
|
1166
536
|
};
|
|
1167
|
-
//# sourceMappingURL=chunk-
|
|
537
|
+
//# sourceMappingURL=chunk-M6AYND5G.js.map
|