@peculiar/pdf-font 1.17.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 ADDED
@@ -0,0 +1,66 @@
1
+ # `@peculiar/pdf-font`
2
+
3
+ A library for working with fonts in PDF documents, providing utilities for font loading, embedding, and text rendering.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @peculiar/pdf-font
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Font Operations
14
+
15
+ ```typescript
16
+ import { FontFactory, DefaultFonts } from "@peculiar/pdf-font";
17
+
18
+ // Use default font
19
+ const helvetica = FontFactory.createDefault(DefaultFonts.Helvetica);
20
+
21
+ // Load custom TrueType font
22
+ const fontBuffer = await loadFontFile("path/to/font.ttf");
23
+ const customFont = FontFactory.create(fontBuffer);
24
+ ```
25
+
26
+ ### Working with Font Metrics
27
+
28
+ ```typescript
29
+ // Get font metrics
30
+ const metrics = font.fontInfo;
31
+ console.log(metrics.ascent); // Font ascender
32
+ console.log(metrics.descent); // Font descender
33
+ console.log(metrics.unitsPerEm); // Font units per em
34
+
35
+ // Get glyph information
36
+ const glyph = font.findGlyph(unicodeCodePoint);
37
+ console.log(glyph.advanceWidth); // Glyph width
38
+ console.log(glyph.unicode); // Unicode values
39
+ ```
40
+
41
+ ### Font Information
42
+
43
+ ```typescript
44
+ // Access font name information
45
+ const fontName = font.fontInfo.name;
46
+ console.log(fontName.fontFamily); // Font family name
47
+ console.log(fontName.fullName); // Full font name
48
+ console.log(fontName.postScriptName); // PostScript name
49
+ ```
50
+
51
+ ## License
52
+
53
+ This project is dual-licensed under the AGPL-3.0 and a Commercial License:
54
+
55
+ ### AGPL-3.0
56
+
57
+ The library is open-source and freely available under the terms of the Affero General Public License (AGPL-3.0). This ensures that modifications and usage in network-based applications (e.g., SaaS) must be shared under the same license.
58
+
59
+ You can use the library under AGPL-3.0 if:
60
+
61
+ - Your project is open-source and distributed under a compatible license
62
+ - Your use complies with the AGPL-3.0 requirements
63
+
64
+ ### Commercial License
65
+
66
+ For use in proprietary, closed-source, or commercial projects where the AGPL is not suitable, a commercial license is available. This allows you to use the library without the AGPL's obligations.
@@ -0,0 +1,178 @@
1
+ import { BufferSource } from 'pvtsutils';
2
+
3
+ declare enum DefaultFonts {
4
+ Courier = "Courier",
5
+ CourierBold = "Courier-Bold",
6
+ CourierBoldOblique = "Courier-BoldOblique",
7
+ CourierOblique = "Courier-Oblique",
8
+ Helvetica = "Helvetica",
9
+ HelveticaBold = "Helvetica-Bold",
10
+ HelveticaBoldOblique = "Helvetica-BoldOblique",
11
+ HelveticaOblique = "Helvetica-Oblique",
12
+ Symbol = "Symbol",
13
+ TimesBold = "Times-Bold",
14
+ TimesBoldItalic = "Times-BoldItalic",
15
+ TimesItalic = "Times-Italic",
16
+ TimesRoman = "Times-Roman",
17
+ ZapfDingbats = "ZapfDingbats"
18
+ }
19
+ declare const DefaultFontsZip: Map<DefaultFonts, string>;
20
+
21
+ /**
22
+ * Interface representing a font glyph
23
+ * @remarks
24
+ * A font glyph is a specific graphical representation of a character in a font.
25
+ */
26
+ interface IFontGlyph {
27
+ /**
28
+ * Index of the glyph in the font
29
+ */
30
+ index: number;
31
+ /**
32
+ * The glyph's advance width, in font units.
33
+ */
34
+ advanceWidth: number;
35
+ /**
36
+ * Unicode scalar value(s) associated with the glyph
37
+ */
38
+ unicode: number[];
39
+ }
40
+
41
+ declare class FontGlyph implements IFontGlyph {
42
+ index: number;
43
+ advanceWidth: number;
44
+ unicode: number[];
45
+ constructor(params?: Partial<FontGlyph>);
46
+ }
47
+
48
+ declare class FontHead {
49
+ xMin: number;
50
+ xMax: number;
51
+ yMin: number;
52
+ yMax: number;
53
+ }
54
+
55
+ declare class FontName {
56
+ fontFamily: string;
57
+ fontSubfamily: string;
58
+ fullName: string;
59
+ postScriptName: string;
60
+ }
61
+
62
+ declare class FontOS2 {
63
+ sCapHeight: number;
64
+ sxHeight: number;
65
+ usWeightClass: number;
66
+ }
67
+
68
+ declare class FontPost {
69
+ italicAngle: number;
70
+ }
71
+
72
+ /**
73
+ * Information about a font.
74
+ */
75
+ interface IFontInfo {
76
+ /**
77
+ * The number of font units per em square.
78
+ */
79
+ unitsPerEm: number;
80
+ /**
81
+ * The font's ascent value, defined as the vertical distance from the baseline to the top of the font.
82
+ */
83
+ ascent: number;
84
+ /**
85
+ * The font's descent value, defined as the vertical distance from the baseline to the bottom of the font.
86
+ */
87
+ descent: number;
88
+ /**
89
+ * Looks for the GLYPH by the unicode
90
+ * @param code unicode
91
+ * @returns
92
+ */
93
+ findGlyph(code: number): IFontGlyph | null;
94
+ }
95
+
96
+ /**
97
+ * Implementation of IFontInfo interface that provides comprehensive information about a font.
98
+ * Contains font metrics, glyph data, and various font properties from different font tables
99
+ * (name, head, OS/2, post).
100
+ */
101
+ declare class FontInfo implements IFontInfo {
102
+ name: FontName;
103
+ head: FontHead;
104
+ os2: FontOS2;
105
+ post: FontPost;
106
+ glyphs: FontGlyph[];
107
+ unitsPerEm: number;
108
+ ascent: number;
109
+ descent: number;
110
+ /**
111
+ * Looks for the GLYPH by the unicode
112
+ * @param code unicode
113
+ * @returns
114
+ */
115
+ findGlyph(code: number): FontGlyph | null;
116
+ /**
117
+ * Returns a list of unique glyphs for all characters in the specified text.
118
+ * The glyphs are sorted by their index in ascending order.
119
+ * @param text - The input text to get glyphs for
120
+ * @returns Array of FontGlyph objects corresponding to unique characters in the text
121
+ */
122
+ getGlyphs(text: string): FontGlyph[];
123
+ /**
124
+ * Compares two FontGlyph objects by their index for sorting purposes.
125
+ * @param a - First FontGlyph to compare
126
+ * @param b - Second FontGlyph to compare
127
+ * @returns -1 if a < b, 1 if a > b, 0 if equal
128
+ * @private
129
+ */
130
+ private static sortByIndex;
131
+ }
132
+
133
+ /**
134
+ * Factory class for creating and managing font objects.
135
+ * Provides functionality to create fonts from different sources,
136
+ * manage default fonts, and create font subsets.
137
+ */
138
+ declare abstract class FontFactory {
139
+ private static readonly cache;
140
+ /**
141
+ * Creates a FontInfo object from either a default font or a buffer source.
142
+ * @param source - The font source, either a DefaultFonts enum value or a BufferSource
143
+ * @returns A FontInfo object representing the font
144
+ */
145
+ static create(source: DefaultFonts | BufferSource): FontInfo;
146
+ /**
147
+ * Creates a FontInfo object from a default font.
148
+ * Uses internal caching to improve performance for frequently used fonts.
149
+ * @param source - The default font to create
150
+ * @returns A FontInfo object representing the default font
151
+ * @throws Error if the specified default font doesn't exist
152
+ */
153
+ static createDefault(source: DefaultFonts): FontInfo;
154
+ /**
155
+ * Creates a FontInfo object from a font file buffer.
156
+ * @param source - The font file buffer
157
+ * @returns A FontInfo object containing the parsed font data
158
+ * @throws Error if required font tables are missing
159
+ */
160
+ static createFile(source: BufferSource): FontInfo;
161
+ /**
162
+ * Gets glyph indexes for the specified text from a font.
163
+ * @param fontjs - The font object
164
+ * @param text - The text to get indexes for
165
+ * @returns An array of glyph indexes
166
+ * @private
167
+ */
168
+ private static getIndexes;
169
+ /**
170
+ * Creates a subset of a font containing only the glyphs needed for the specified text.
171
+ * @param source - The original font buffer
172
+ * @param text - The text that determines which glyphs to include in the subset
173
+ * @returns A new ArrayBuffer containing the subsetted font
174
+ */
175
+ static subsetFont(source: BufferSource, text: string): ArrayBuffer;
176
+ }
177
+
178
+ export { DefaultFonts, DefaultFontsZip, FontFactory, FontGlyph, FontHead, FontInfo, FontName, FontOS2, type IFontGlyph, type IFontInfo };
@@ -0,0 +1,369 @@
1
+ import * as asn from '@peculiar/asn1-schema';
2
+ import { AsnConvert } from '@peculiar/asn1-schema';
3
+ import * as bs from 'bytestreamjs';
4
+ import * as fontjs from 'fontjs';
5
+ import * as pako from 'pako';
6
+ import { BufferSourceConverter, Convert } from 'pvtsutils';
7
+ import { __decorate } from 'tslib';
8
+
9
+ var DefaultFonts;
10
+ (function (DefaultFonts) {
11
+ DefaultFonts["Courier"] = "Courier";
12
+ DefaultFonts["CourierBold"] = "Courier-Bold";
13
+ DefaultFonts["CourierBoldOblique"] = "Courier-BoldOblique";
14
+ DefaultFonts["CourierOblique"] = "Courier-Oblique";
15
+ DefaultFonts["Helvetica"] = "Helvetica";
16
+ DefaultFonts["HelveticaBold"] = "Helvetica-Bold";
17
+ DefaultFonts["HelveticaBoldOblique"] = "Helvetica-BoldOblique";
18
+ DefaultFonts["HelveticaOblique"] = "Helvetica-Oblique";
19
+ DefaultFonts["Symbol"] = "Symbol";
20
+ DefaultFonts["TimesBold"] = "Times-Bold";
21
+ DefaultFonts["TimesBoldItalic"] = "Times-BoldItalic";
22
+ DefaultFonts["TimesItalic"] = "Times-Italic";
23
+ DefaultFonts["TimesRoman"] = "Times-Roman";
24
+ DefaultFonts["ZapfDingbats"] = "ZapfDingbats";
25
+ })(DefaultFonts || (DefaultFonts = {}));
26
+ const DefaultFontsZip = new Map();
27
+ DefaultFontsZip.set(DefaultFonts.Courier, "H4sIAAAAAAACA03WdXBXRxQF4PxeaBIgKVA3WiS4vRAkuAR3gjuUhBAIBALBpU3doS60xd0tELzUW+ru7u6llPadMz1nOrMze7+9e//ambs3LC6/NExNTswsKCrMyylMTszKyS3KH1f4v5P/grBiEJw8HgRJxUFwqjTaS8JyQSwOK4gtCeOjIK24fEZYKYjFEJdlMimIVQ4rBLEgCMqcSEsIYlFNSpgcxOJ5EFVVgcpIVaEzpGpQglQdSpRSoSSpBlRWqgmVk2pB5aXaULJUB0qR6kJnSvWgClJ9qKLUAKokNYTOkhpBZ0shdI6UBp0rNYbOk9Kh86Um0AVSU+hCqRl0kdQculjKgC6RWkCVpZbQpVIr6DKpNVRFagNVldpC1aR2UHWpPZQqdYBqSB2hmlImVEvqBNWWOkN1pC5QXakrVE/qBtWXukMNpB5QQ6kn1EjqBYVSbyhN6gM1lvpC6VI/qInUH2oqZUHNpAFQc2kglCENglpIg6GW0hColTQUai0Ng9pIw6G20gionTQSai+NgjpIo6GO0hgoUxoLdZLGQZ2ly6Eu0nioq5QNdZNyoO7SBKiHlAv1lCZCvaQ8qLc0CeojTYb6SvlQP2kK1F+aCmVJBdAAaRo0UJoODZIKocHSDGiINBMaKhVBw6RZ0HBpNjRCmgONlOZCo6R50GhpPjRGWgCNlRZC46RFYUr0GFTUKeOWg+PNFWC2uRLMMVeBE8zVYK65BpxorgXzzHXgJHM9ONncAOabG8Ep5iZwqrkZLDC3gNPMreB0cxtYGATx6eR2cEaUzSZ3gDN9eSdYZO4CZ5m7wdkRl5F7wDnO7gXnmiXgPHMfON/cDy4wS8GF5gFwkXkQXGweCqNvJe4K+zB9pX2ELraP0lfZx+ir7Ufoa+zj9LX2o/R19mP09fbj9A32E/SN9pP0TfZT9M320/Qt9jP0rfaz9G32CXqJ/Ry91H6evt1+gb7DfpG+036Jvst+mb7bfoW+x36Vvtd+jb7Pfp2+336DfsB+k15mv0U/aL9NP2S/Qz9sv0svt9+jV9jv0yvtD+hV9of0avsjeo39Mb3W/oReZ39Kr7c/ozfYn9Mb7S/oTfaX9Gb7K3qL/TW91f6G3mZ/S2+3v6N32N/TO+0f6F32j/Ru+yd6j/0zvdf+hS6xf6X32b/R+91TfqdLnf+DPmD/SR+0T9KH7L/ow/Yp+oj9N33UPk0fs/+JBupokE6IBtrTSf8Clfw2B5ULAAA=");
28
+ DefaultFontsZip.set(DefaultFonts.CourierBold, "H4sIAAAAAAACA1XWdXCVRxQF8LwvaQjkpUDdaINLCLwQJDgkuLtrSYBAIBAIDm1Td28ppS3u7hIkFarU3d2dKqW03znTc2Y6szO7v733/rUzd2+sJHlxLC1aLqewuCg/ryiakF1YkBuN/sfU/ykdilUKgpNlQZC0JAhOHQv3E7EKQSQOKwhKY/HhIaMkOStWOYhEcC7PYFIQqRKrGETCnITjGYlBJKxJiUWDSDwvwqpUKEGqCp0hVYMSpepQOakGlCTVhMpLtaAKUm0oWaoDRaW6UIpUDzpTSoMqSvWhSlI6VFlqAJ0lNYTOlmLQOVIGdK7UCDpPyoTOlxpDF0hNoAulptBFUjPoYikLukRqDlWRWkCXSi2hy6RWUKrUGqoqtYGqSW2h6lI7qIbUHqopZUO1pByottQBqiN1hOpKnaB6UmcoTeoC1Ze6QulSN6iB1B1qKPWAYlJPKEPqBTWSekOZUh+osdQXaiL1g5pK/aFm0gAoSxoINZcGQS2kwVBLaQjUShoKtZaGQW2k4VBbaQTUThoJtZdGQdnSaChHGgN1kMZCHaXLoU7SOKizlAt1kfKgrtJ4qJs0AeouTYR6SPlQT2kS1EuaDPWWCqA+0hSorzQV6icVQv2ladAAaTo0UCqCBkkzoMHSTGiIVAwNlWZBw6TZ0HBpDjRCmguNlOZBo6T50GhpATRGWgiNlRbFUsLHoMJOGbcMHGcuB3PNFWCeuRIcb64CJ5irwYnmGjDfXAtOMteBk831YIG5AZxibgSnmpvAQnMzOM3cAk43t4JFQRCfSW4DZ4TRXHI7ONPJO8Bicyc4y9wFzg65lNwNznF0DzjX3AvOM/eB88394ALzALjQPAguMkvBK8xDsfBbibvSPkxfZR+hS+yj9NV2GX2N/Sh9rf0YfZ39OH29/QR9g32MvtF+kr7Jfoq+2X6avsV+hr7Vfpa+zX6Ovt0+Tt9hP0/fab9A32W/SN9tv0TfY79M32u/Qt9nv0rfb79GL7Zfpx+w36CX2G/SD9pv0Uvtt+mH7Hfoh+136Ufs9+hl9vv0cvsDeoX9Ib3S/oheZX9Mr7Y/odfYn9Jr7c/odfbn9Hr7C3qD/SW90f6K3mR/TW+2v6G32N/SW+3v6G329/R2+wd6h/0jvdP+id5l/0zvtk/Qe+xf6L32r/Q++zd6v3vK7/QBx/+gD9p/0qX2SfqQ/Rd92D5FH7H/po/ap+ky+59woA4H6cRwoD2d9C9nsoPwnAsAAA==");
29
+ DefaultFontsZip.set(DefaultFonts.CourierBoldOblique, "H4sIAAAAAAACA1XWd3CVRRQF8Pc2kATyIiCIioKh18D3CCW0AAm9hd47CRAIhARCBzVWUIq9AErvPXRCR8CCvWDF3sECNqT4nTs5Z8aZndn5nXv3r53ZvV5eTL6XHIpKycrNyUjPCYWSszLT4lJHZmZk56aHyhTGcf9LSxem8UgLQ6+kc1eSnIs+59zVU/5+ySvuggEs5wq8KFc0cONyIBDOi0n0Srlg0C+Ei1lDtAuW90q4oN9X5Gw40gX9c7FeyAUjLIhwwTioCFURKkpVgiKpylAUVQWKpqpCxahqUHGqOhRD1YBCVE0olqoF3UTVhkpQdaCSVDxUiqoL3UzVg0pTHlSGCkO3UPWhslQCdCvVALqNagjdTjWCylGNoTuoROhOqglUnmoKVaCaQXdRzaE4qgVUkUqCKlEtocpUK6gK1RqqSiVD1agUqDrVBqpBtYVqUu2gWlR7qDbVAapDdYTiqU5QXaozVI/qAnlUVyhMdYPqU6lQAtUdakD1gBpSPaFGVC+oMdUbSqT6QE2ovlBTqh/UjOoPNacGQC2ogVASNQhqSQ2GWlFDoNbUUCiZGgalUMOhNtQIqC01EmpHjYLaU2lQByod6kiNhjpRY6DO1FioC5UBdaXGQd2o8VAqlQl1pyZAPaiJUE8qC+pFTYJ6U9lQHyoH6ktNhvpRU6D+VC40gJoKDaSmQYOo6dBgagY0hJoJDaVmQcOo2dBwag40gprrxfqXYfJfysBycJS4AkwTV4Lp4ipwtLgaHCOuAceKa8EMcR04TlwPjhc3gJniRnCCuAmcKG4Gs8Qt4CRxK5gtbgNznItIMG4HJ/vVNOMOcIqad4K5Yj44VdwFTvO51LgbnK7qHnCGuBecKe4DZ4n7wdniAXCOeBCcKxaAd4uHPP9bCdwjHzbfKx8x58lHzffJx8z3y8fND8gnzA/KJ80PyS+ZH5ZPmefJp83z5TPmR+SXzY/Kr5gXyK+aF8qvmRfJZ82L5dfNj8lvmB+X3zQ/Ib9lflJ+2/yU/I75afld8zPye+Zn5ffNz8kfmJ+Xz5mXyB+al8ofmZfJH5tfkD8xvyh/al4uf2ZeIZ83r5Q/N6+SvzCvlr80r5G/Mq+Vvzavk78xr5e/NW+QvzNvlL83b5J/MG+WfzRvkX8yb5V/Nm+TL5i3yxfNO+RfzDvlX8358m/mXfLv5t3yJfMe+bJ5r/yHeZ/8p3m/3pS/zAdU/9t8UP7HXCBfMR+S/zUflq+aj8jXzEfl6+Zj8g1/qPaH6Uh/oL0e/R+6DNOUtwsAAA==");
30
+ DefaultFontsZip.set(DefaultFonts.CourierOblique, "H4sIAAAAAAACA13WZXCWRxQF4O/dQBLIlwarlxJcA+9HAgSX4BYkuEMCBAIhgeDQkrpAqRsOwd0ChCB1o+7u7qWFUgp9zx3O+dGZndl5zt39tTN3r18YV+SnhGPScgvys7PywzHp43Oy8wqywgmXksT/B0mXAr+Cc+cynIstde58SbAX++WdF8Jy3nI/xpUNXTwdCkUK41L9is7zgkKknB2IdV5VP8F5zrkypyLRzgvuxfth50VZEOW8RKgMVR0qS9WAoqmaUAxVC4qlakPlqDpQeaouFEfVg8JUfSieagBdRjWEEqhGUAUqCapINYYqUU2gypQPVaEi0OVUU+gKKhm6kkqBrqKaQVdTzaFrqBbQtVQqdB3VEqpKtYKup1pD1ag2UCLVFqpOtYNqUO2hmlQHqBbVEapNdYLqUGlQXaozVI/qAtWnukINqG5QQ6o71IjqASVRPaHGVC+oCdUb8qk+UITqCzWl0qFkqh+UQvWHmlEDoObUQKgFlQGlUoOgltRgqBU1BGpNDYXaUMOgttRwqB01AmpPjYQ6UKOgjtRoqBM1BkqjxkKdqXFQF2o81JWaAHWjMqHuVBbUg5oI9aQmQb2oyVBvKhvqQ02B+lJToXQqB+pHTYP6U9OhAVQuNJCaAWVQedAgKh8aTM2EhlCzoKFUATSMmg0Np+ZAI6i50EhqHjSKmg+NphZAY6iF0FhqETSOWuzHB49hCjplaA04QVwLZorrwCxxPThR3ABOEovAyeJGMFvcBE4RN4NTxS1gjrgVnCZuA6eL28FccQc4Q9wJ5om7wHznopKNu8GZQTXTuAecpcN7wQJxHzhb3A/OCbjCeACcq+pBcJ5YDM4XD4ELxMPgQvEIuEgsAReLR8EbxFI/+FZCN8rHzEvk4+ZC+YT5Jvmk+Wb5CfMt8pPmW+WnzLfJT5tvl58x3yE/a75Tfs58l/y8+W75BfNS+UXzMvkl8z3yKfNy+WXzvfIr5vvkV833y6+ZH5BfNz8ov2F+SH7T/LD8lvkR+W3zo/I75sfkd82Py++ZV8jvm1fKH5hXyR+aV8sfmdfIH5vXyp+Y18mfmtfLn5k3yJ+bi+QvzBvlL82b5K/Mm+WvzVvkb8xb5W/N2+TvzNvl78075B/MO+Ufzbvkn8y75Z/Ne+RfzHvlX8375N/M++XfzQfkP8wH5dPmYvlP8yH5L/Nh9ZQz5iOqnzWXyH+bj8rnzKXyP+Zj8nnzcflf8wn5gvmkfDEYqoNhOjoYaC/E/gcqk9e/qQsAAA==");
31
+ DefaultFontsZip.set(DefaultFonts.Helvetica, "H4sIAAAAAAACA03Wd1zVVRgGcO5BGQKpZTtyi+DgIg7cW1FxoeIeBIgoLpZbi4YtS9uWlXsg7j1QadneZXuZTdtlWmad5+nzPnX/uJ/7ve8573nP+t0bLI1aHkyIjkzNyS/JKcrLyowOT8/JLc7PLPj/d/99DNZw7myOc1HLnDsf51zEuWC0c1UrnKuS6FxgaTDUBUKSSqNSgjVdIIDPkf7NBSJcIDZY3QWcf7VNCnOBai4Q47sGQvmF71UHqmKqC1X1OgHVg8L8GIVQfSjc1ACKcC48FmoIRfqKMqBGUDVf12IoDoryOcugxlC0KR6KcS6UWRKgi/wI5VATqLpV1hSqYf2aQTUt1hy62JQIXWJ1BqFapiToUlML6DJTMnS5qSV0hakVdKWpNXSVqQ10tSkFusbUFoq1ytpB15raQ7Vtth2gOqaOUF1TJ6ie5ewM1fdnoDbUBWpgK98VamjqBjXyOg51h+JMPaDG1rInFO9HOAn1ghKcC2OdvaEm1i8Vampz6AM18/1CoL5Qc8vZD0q0qtOgoM/J/esPJVnOAVALG28glGxZBkEtLTYYamX90qHW1nII1MbmMBRKsZbDoLbWMgNq58/uEmg41N5iI6AOppFQR8s5Cupkcx8NdTaNgbqYxkJd/bmuhMZB3WwlxkPd7SRPgHpYLBPqaboO6mWrmwX1tlg2lGrKgfrY6BOhvhbLhfqZJkFp/m5yXfKg/qbJ0AAbbwo00GL50CDbv6nQYMs5DUo3TYeGmGZAQ00zoWE29wIow8YrhIbbHIqgEdavGBppLUugUba3s6DRFpsNjTHNgcaa5kLj/Ai8VfOg8V61oPnQBIstgDLt/i0MxvjNYGX+SRmyEsziJMBVYDYrBVeDOeIacKK4FswV14GTWAO4HsxTdAM4WQNtBKf4aZ8iN4H5PnqGLAOnqu9mcBpnAJaD05VqCzhDqbaCMxXdBhb405tMbgcLfapscgdYpMY7wWJxF1gi7gZn+b4ryD3gbM80ci84Rwu7D5yrvvvBeeIBcL7nafIguEDzPQQu9Ofz3/keBheJFUH/sxJyvXyEvoEXGz5Kl/Law8foG+VK+ib5Cfpm+Un6FvkperH8NH2rf2iH0M/Qt/EIw8fp29X+WfoO+Tn6Tvl5eon8An2XVvJF+m75JXqp/DK9TH6Fvkf1vErfK79G38fHMPw6fb/8Bv2A/Cb9oPwW/ZD8Nr1cx/ME/bDi79CPaPx36RXye/Sj8vv0Y/IH9ONanw/plfJH9Crt/8f0ap2mT+g18qf0Wvkzep18kl4vf05vkE/RG/l3Cf6C3sQHE/wlXab2X9Gb5a/pcvkbeov8Lb1V+3ma3iZ/R2+Xv6d3yD/QO5XvR3qX/BO9W/6Z3iP/Qu+Vf6X3yb/R++Uz9AE9U36nD2o/ztKH1P4cfVj+g66Q/6SPyOfpo1rfv+hjil+gKxX/GzfTnz7/F+hC/D8h9PQ0nQsAAA==");
32
+ DefaultFontsZip.set(DefaultFonts.HelveticaBold, "H4sIAAAAAAACA13Wd1iWVRgGcL4DIgg42ovCiajoizhAxYEL98Y9CHCiqCBuK9rD9s4KtyLurTgbVmZ7Z9PMhu3Shlnnvrue+4/+4eL3Pec8zznPOe/7fUFpTFmQEhudlV9Qkl88KTcnNiKzsCAvtro+SPifk+GgpnNnjzsXs8i5c4nORXcLYp2rcti5iEznXGUQ7kJhKaUxaUEtFwrh/2j/x4WiXCg+qOFCfoxLT4l0oWouFOenhsL5gZ+VAEV4lUO1oSrOhR+F6kCRvkYRVBeqaqoHRTlXNR6qD0X7FR2BGkDVnAudghKhGKvQEIo1JUFxvh6zNIKq+woVUGOohq2zCVTT5iVDtSzWFLrA1Ay60NYZQBeZUqCLTc2hS0yp0KWmFtBlppbQ5aZW0BWm1tCVpjToKlM6FG+rbgNdbWoLXWO7bQclmDKg2qb2UB2vE1AHqK7v/DGoI1TPOt8Jqm/KhBqYOkOJpi5QQ69sqCuUZBVwuUKNnItkP7tDjW1eFtTEet0DSrbd9oSa2sheUDPL2RsKfE7uvQ+UYiP7Qs2tXj8o1VbWH2phsQFQS5s3EGplIwdBra3eYCjNRg6B0m1kNtTGd3AxNBRqa7FhUDvTcCjDco6A2tv5jYQ6WCdGQR0tNhrqZOc3Bsq0Lo2FOtvIcVAXi+VAXa3etVA3i+VC3S2WB2VZLB/qYTnHQz1t5ASol2ki1NtWPQnqY5oM9bWcU6B+FiuA+tvzPhUaYDmnQQNNhdAg03RosGkGNMSe95lQttUrgobaHoqhYTZvFjTcRpZAI+xOzIZGWmwONMo0FxrtFQbNg8ZY9fnQWF8vA1oAjbPYQijHzm9REOcPg53wb8qwMjCXCwWXgnmsCC4D88Xl4HhxBThBXAlO5BrAVeAkRVeDk1VoDTjFX82T5FqwwEfPkOXgVM1dB07jDsAKsFCp1oPTlWoDOEPRjeBM34tUchNY5FPlkZvBYg3eAs4St4Il4jZwtp+7hNwOztEid4Bz1did4DzN3QXOF3eDCzxPk3vAhUq1F/TfjpH/7bcSvE7cF/ivlbDr5f30Dbxe8AG6lK8L+CB9o3yIvkk+TN8sP0PfIj9L3yo/R9/mXFQY/Tx9u+JH6Dv42oFfoO+UX6Tvkl+iF8tH6bvVyZfpe+Rj9L3yK/R98qv0/VrPa/QD8uv0g3zk4Dfoh+Q36Yflt+hH5LfpR+V36Md0Pd+lH1f8PfoJ1X+fXiJ/QD8pf0g/JR+nn1Z/PqLL5I/ppTr/T+hluk2f0svlz+gV8uf0SvkEvUr+gl4tn6TX8PUJf0mvVfwUXS5/Ra+Tv6Yr5G/o9fK39Aad52l6o/wdvUn+nt4s/0BvUT9+pLfKP9Hb5J/p7fIv9A75V3qn/Bu9Sz5D79Y75Sy9R/Hf6b3yH3Sl/Ce9T/6L3i+fow+oP3/TBxU/Tx9S/B88mf72+Z9A55P+Be1tbgOkCwAA");
33
+ DefaultFontsZip.set(DefaultFonts.HelveticaBoldOblique, "H4sIAAAAAAACA1XWd3jNVxgH8Ps7kSU3RZUu0ZgRhN8VI0GMWDEjRuwRyUW4RGTY2qZ0615Ua6+IPYLE7NBWde9lVbVFdSgdRM/3277v8/SfPM/nvOec95z3nN+5cYsiytwUb3iKP1Doz8/OzPB6k3MCWdGp4wLZuQV+b00NRP+vvYa2x6H9v2a3qjFXK4zxlhpzLcaY8Amu15jgI8ZUSjPGlLuhJthz47LH4yuKSHCrGccxjscXbv8YJ8w4UW4V49h+JtEXYpzKxom0w50gNgQZJxqqZFUM1YGCjQk6BtWFQmyePKgeFCqqD4UZExoFNYDC7aqOQg2hysY456AYKEIyNIK8olgo0ubjLI2hm2yGEqgJVEXW2RSqKuPioGoSawbdLGoOVZd1utAtIh9UQ9QCqimKh24VtYRuE7WCbhe1hu4QtYHuFCVAtUSJUJSsui1UW9QOukt22x6KFiVBdUQdoLpWZ6COUD1b+eNQJ6i+VL4z1ECUDDUUdYFiRF2hRlbpUDcoVjJ0hxobE8J69oCayLgUqKnUuicUJ7vtBTWTnr2h5jJnH8i1c3LvfSGf9OwHtZB8qVC8rKw/1FJiaVArGTcAai09B0JtJN8gKEF6DoYSpWc61NZWcBE0BGonsaFQe9EwKEnmHA51kPMbAXWUSoyEOklsFNRZzm80lCxVGgN1kZ5joa4Sy4C6Sb5xUHeJZUI9JJYFpUjMD/WUOcdDvaQnngunt2gi1EdWnQ31FU2C+smck6FUiQWg/vK9T4HSZM6p0ABRDjRQNA0aJMqFBsv3Ph1Kl3x50BDZQz40VMYVQMOkZyE0XO7EDGiExGZCI0WzoFFWHmg2NFqyz4HG2HxJ0FxorMTmQRlyfvPdSHsYrIR9KT3LwUwuFFwBZjEjuBL0K1eB45WrwQnKNeBErgFcC2ZrdB04SROtByfbq3mW3AAGbPQKWQxO0bEbwancAVgC5uhUm8BpOtVmMFejW8Dpthbx5FYwz06VRW4D87XzdrBAuQMsVO4EZ9ixS8ld4Exd5G5wlha2FJytY/eAc5R7wbmWF8h94Dydqgycb+/Ev/stB+9W7nftz4rnHvUB+l5eL/ggXcTnAj5E36c+TC9QH6EXql+h71e/Sj+gfo1+0JgwD/06/ZDGj9IP89mB36AfUb9JP6p+i16kPkY/ppV8m35cfZx+Qv0O/aT6XfopXc979NPq9+ln+MnBH9DPqj+kn1N/RD+v/ph+Qf0JvViv56f0Eo1/Rr+o+T+nl6q/oF9Sf0m/rP6KXqb1+Zperv6GXqHnf4JeqbfpJL1KfYperT5Nr1Gfodeqv6XXqc/S6/l8wt/RGzR+ji5Wf09vVP9Al6h/pDepz9Ob9Twv0FvUF+mt6p/obepL9Hatx8/0DvUv9E71r/Qu9W/0bvVlulT9O71HfYXeq2/KVXqfxv+gy9R/0uXqv+j96r/pA+pr9EGtz3X6kMYr6MMav4Ev094++y9QRew/R/qZmL8LAAA=");
34
+ DefaultFontsZip.set(DefaultFonts.HelveticaOblique, "H4sIAAAAAAACA2XWd1yVVRgH8PseZMklJa00I3EiKvJecQDujYrixD0QroriQIbbkoZlWaaWI8u9ENxbUWnZUNtpWzObts1Rpp3fz57nn+4f9/P5vs85z3nOeu91C8NK3CRvaLI/u8Cfl5WR7g1OHZWdlZPv90bos6j/P4r975Fb0Zhr843xLjLmRrQxodVcrzGBpcaUizPGWegGm0DPrcsej68wLMGNMI5jHI8v1H4ZJ8Q4kW4F4xj7SfQFGae8ccJtdyeADwKMEwWVE9WAAq3OQDWhIDtOLlQLChbVhkKMCY6E6kChtqo0qC5U3tY2D4qGwmzOIqge5BXFQOHGBDBLfegOO0Ix1ACqIJU1hCpKv1goQmKNoDtFcVAlqdOFKot80F2ixtDdonjoHlETqIqoKVRV1Ay6V9QcqiZKgO4TJUKRUlkSdL+oBVRdZtsSihK1gmqIWkM1JWcbqJYxIdWhtlBtWfl2UB1Re6iu1QmoAxQt6gjVk5adoBg7wgWoM1TfmCDW2QVqIP2SoYYyh65QrO3ngbpBjSRndyhOqk6BXJuT+9cD8knOnlBjGS8VipcsvaAmEusNNZV+faBm0rIv1Fzm0A9KkJb9oURpmQYl2bO7ABoAtZDYQKilaBDUSnIOhlrL3IdAbURDobaiYVA7e67LoOFQe1mJEVAHOckjoY4SS4c6iUZBnWV1M6AuEsuEkkV+qKuMPhrqJrExUHfRWCjF3k2uSxbUQzQO6injjYdSJZYN9ZL9mwD1lpwToT6iSVBf0WSonygH6i9znwKlyXi50ACZQx40UPrlQ4OkZQE0WPZ2KjREYtOgoaLp0DDRDGi4HYG3aiY0wqoyNAsaKbHZULrcvzluuN0MVmbflJ7VYAYnAa4BM1kpuBb0K9eBo5XrwTHKDeBY1gBuBLM0ugkcpwNtBsfbaV8kt4DZNnqFLAInaN+t4ETOACwGJ2mqEnCyptoG5mh0OzjFnt54cgeYa1NlkjvBPG28C8xX7gYLlHvAqbbvSnIvOM0yhdwHTteF3Q/O0L4HwJnKg+Asy0vkIXC2zvcwOMeez9vzPQI+oCx17c+K50H1UXouLzZ8jC7ktYeP0w+py+iH1S/Rj6hfph9Vv0LPU79KP2Zf2h76NfpxHmH4BD1f279OP6F+g35S/Sa9QP0W/ZSu5En6afUpeqH6NP2M+m16kdbzDr1Y/S69hK9h+D36WfX79HPqD+il6g/pZeqP6OV6PM/QKzR+ln5ex/+YXqn+hH5B/Sn9ovozepWuz+f0avUX9Brd/y/ptXqaztHr1Ofp9eqv6A3qC/RG9df0JvVFejP/LsHf0Fv4YoK/pYu0/Xf0VvX3dLH6B7pE/SO9TffzEr1d/RO9Q/0zvVP9C71L8/1K71b/Ru9R/07vVf9B71Nfpver/6QPqK/QB/WdcpU+pPtxjT6s7a/TR9R/0aXqv+mj6hv0MV3ff+jjGr9Jl2n8Fm6mPX32L9DNmH8BjyAiG7ELAAA=");
35
+ DefaultFontsZip.set(DefaultFonts.Symbol, "H4sIAAAAAAACA0XX+VdVVRgG4Hv3kUG7qNCgqeg9l0AR03NBnHJogDKzCcsGNSfQBkzFrJzScGqyHEEBcQQFESccQJwlqp9MK/+AltloZaZmaX3vS/tjLdfyPO/eZ0/n7H0uXn6g2HMDkSNmTZkwNTcQlZUzeWbu+DwN/v/fa2vMrUpjoo8bc7PEmMhSr5Xx+/DP+Jd7jlyE8wOZXqzx+3HdkoXRxh/vtTF+Y4zvRjjS+OWeGC9g/A6SsNwVhFqIKiEXijCmBcsSoEjpi2WJUJSoP5QERdv7ukEtrZKhVtJKNpQC3Wb76wEFrHpCMSK22QtqbXv3oDZWYaitVSoUa5UGxVn1hm63SofusOoD3WnVF7rLqh/Uzqo/1N6ObAB0t9V9UAc7v4FQR6tBUCerwVC8Mc4yaAjU2a7SKKiL1RgoaHsfC7ly33loDhSS51wEzYUSbNk8L8b47xGlheUp+naDicJqMBgCkzgaYWgc2NWYiBqyM9jNlvr2gMlaORvsrswBU4QloFMP9pCLKyw14L3acizYU96VArIN2Ms25RwHPZl5mKUpYFgqJ7K0Aky1TfmqwDQdRgewN9dJ6F8JpmvpULCP8AKbWg32lU3DysEksJ/O9xrY304h8QtwgLQ5kpUzvNbypGVUWeEI4/iu/4vigdpTHDhI2zoPDtbS8eAQ4TnQXQXeb0wUh+UuBx9Qcg4PauUV4EMyaI7D5RwydGWjwUy7WKFk8GFld/ARqTwPTAiCQ5Uu+KiwkavDjoYJ2ZHDYTxmh+FwzMOF35JrwMeVBeAT2lQh+KTwErkWfIqvNrgOfForF4FZdlROMThCViOeLAGf0crrwWeFyWQpOFJLN4DP6auzEXxeBjmD3AS+IKwnt4Av6hS2gqOkqcVkGThamupIloNjtKNt4EtSOprcDo6V0gDJnTNO3++94Hi5GEbuAyfY98ypAScqD4DZuuwHwRxhCnkInCQruZmsBSdrR3Xgy8rD4Ct67xHwVbm4TB4FX9PKx8Bc5Qlwig7jFPi6XCwkT4JTlafBaXoWNIDTtd9PwTxtuRGcoY/7M/AN5efgTH4P8AI34AP2pmzCG2F8XGplI6YieouriahOojTc9LY8jUjclMSjaZZyIjhbOQmco+QZOFf3Uzy2+TyeJ9zmF1D8jp1pKAacr/trjdQ2vgXqQvpd3feZdL62vpBeqF5KL1Ln04vVS+gl6kX0Uj0bztHv6dFxhn5ffZb+QOt/SX+oh8lX9EfSfgbbL6OXaX8t6Y/t/aGu9CfqbvRynX+QXiG+SPemV+rBH+HJh9i3ik9bfh4kVGOJ/2Sl1baSm85Ka2TN41hpEypdYlig4RaEvzEs1HArwr8YrtWwHOHf7GOdTsxHF+mDcuhi+x0JtaNL7EbzmhZivTqaLtUd37SwG2z7zjf0Rt0/X9ObdMfspzfreKI46C066GIM+ieGWzVcj/AXhmUaliK8yrBcw40Ir7OPbfoytGel7TxpUGkbKv3OsELD7QgvM6zUsALhHwx3aFiJ8ArDKg13IPyH4U4NqxDeZFit4U6EtzjEXbJMV7ksZ1lpN5cNlc6g0ncM9/CzjXAXwosM9+qMSxD+zHCfhpsR/sqwRsMNCK8x3K9hGcIb8tPY+A40f+N/YHCwOfiewSFZ0i5NwY+cQC1r4LtfQdepq+nDYp79boiut8edG0sfsR8StxN9VN/LgfQxu0HdpvdGfvNH8GsRrKJP2PPS6ccBnqQ5wPkMTjUH0xicbg6mM2hoDvLYZqOMaTb7HI6Vlx5L8JfGf5iJKaSfDAAA");
36
+ DefaultFontsZip.set(DefaultFonts.TimesBold, "H4sIAAAAAAACA03Wd1RVRxAG8HeHIsLDkt6IWBBR0YtYQKzYuyJibxEQFETEXiOJpqgxxXSTWAAVC/aKojGJ6b33xPTeizEm+305Myf/vHN/b3Zn5u7du+/5pVHr/LhgWGZ+YU5JMDS9qCA7GEnE/u86Edd+PZEL5SJ10kTO14hEjvODImF5IiFVIlLth4gXSCqNSvHri+fhurb7EC9CvBi/rnhujASSwsWLFC/aTfVC+IWbFQuFOlVCDaEwkdBiqBEU7sSRjaFaqiZQhEgEFQfVFglnlqZQpMuZCsVDUVqhGRRUJUDRmrM5VMdpLdQCqqt9toTq6bxEqL7GWkEXab3W0MWa04cuUSVBl6raQJepkqHLVW2hK1TtoCtV7aGrVB2gq1Up0DWqVChGu+4IXatKgxro3XaCYlWdoYaqLlAjzdkVaixSi8+oG9TE7YUzUHcozikLSoeaaqwHFK/qCTXTkb2gBFfhLNQbau6eJtezD9RC1Rdq6fZdDNQPStTO+kOtdOQAqLVWGAj5rus10CAoSXsZDLXReUOgZO1lKNRWY8OgdjovA2rvRpZAw6EOWi8TStGRI6BUVRbUUffuSChNY6OgTqrRUGfNOQbqos9vLNRVdx1eSK+bxsZD3V1nFdAEKF1XaSLUQ0dOgnpqbDLUS+/oOqi3W2uu2RSoj8ayob4ay4H6ac5cqL/mnAoN0Hl50EDtOh8apPOmQYN15HRoiI4sgIbqG14IDdORM6AMrVcEDdfYTChTVQyN0K5nQVm6l0qgkdrLbGiUzpsDjdYKc6Ex+ozmQWM1Nh8ap1oAjdd6C6EJTvHQImiiiHcaWgxN0tgSaLLLkgAt9aPdw+Bp407KwAZwChsFN4LZrAhuAnOMm8FcYxk41VgO5rEHsALMt+gWcJoV2gpOd7d9jtwGFrhoLlkJFtrc7eAMniDgDrDIUu0EZ1qqXWCxRavAWW4tksndYIlLlU3uAWdb3b3gHOM+cK6l2g/Oc3PXkwfA+Y4Z5EFwgS3sIXChzT0MLrLMR8DFjmXkUXCJ3e8xcKnbn/+xGlxmPO67n5XA9eYT9HKbXUOXckvBJ+kbzKfoG82P0ivMp+mV5sfom8yP0zfzyIGfoG+x+Bn6Vh408JP0KvNT9Grz0/Qa8zP0bXyV4Gfptebn6NvNz9N3mF+g77R+XqTvMr9Er+MxDL9M321+hb7H/Cp9r/k1+j7z6/T9tj3foB+w+Jv0g1b/LXq9+W36IfM79MPmd+lHzO/RG/ijAr9Pb+TxAn9Ab7L98CG92fwRXWb+mC43n6UrzJ/QW8yf0lutn8/obTyY4M/pSvMX9Hbzl/QO81f0TvPX9C4e1vA3dJX5W3q3+Tt6j/l7eq/1+wO9z9bnR3q/xX+iD5h/pg+af6EPmX+lD5t/o4/YmfI7fdTif9DHrP6fdLX5HH3c/Bd9wnyerrF8f9MnLX6BPmXxf/Bm4nRwf7MD/wJjRXkFmAsAAA==");
37
+ DefaultFontsZip.set(DefaultFonts.TimesBoldItalic, "H4sIAAAAAAACA03Wd1iXVRQH8Pe9yBB+JJRaVhS4UdH3Jw5wixP3QFScxFAURAT3ptIW2bZhJU5E3LhxV2Z7mznKzPaynZl2v1+fc57+4Xk+99xzzn3vvVzwisMqvERfYEpOXlahLywpPzczOrkoPTcnwxfJsej/D0VwKA5D10e8CGOulhrju2jMleXGhMZ7PmMC04wJqDTGVHnBJtC5dslx/MVhCV6kcV3jOv7q9odxQ4wb5dUwrp1nHH+QcUONG27T3QAOBBg3Gqpma0VBMVCgMdUKoLpQkBVn1oOCRfWhEGOCyqEGUHWrRKghFGo7UI2gMCvObAz5RLFQuNRsAt1gtQxqCtWQdTaDIiQvDoqUWHPoRunXArpJanpQTZEfqiVqCdUWYVvdm0WtoFtEraE6ojbQraK20G2iBOh2USIUJatuB90hag/dKV/bAYoWdYRiRJ2gulKzM1TP7nUZ1AWqb+9DKtQVaiBKghqKukGNrI5D3aHGEusBxYp6Qk1kZi+oqZxtb6iZ3JdkKE5W1gdqLlX6Qi1s7ALUD/KMCWZef8gvHQZALUUDoXjJGwS1kthgqLV0GAK1sTMLoaFQW8lLgRIkbxiUKHmpUDtZy3CovcRGQB2kykiooygN6iTnNwrqLLduNNRFYmOgrnJ+Y6Ek2aVxUDeZOR7qLrF0qIfoLqin3esSKAPqJbFMqLfEsqBkqZkN9ZGZE6C+sksToX6y6hyov2gSNEDyJkMDJZYLDZJbkAcNlppToCGSlw8NFU2FUkQF0DC5PdOgVFEhNFz6FUEjpMN0aKR87QwoTU5sJjRKOsyCRsvM2dAY6TAHGms7nIDmQuOMcY9B86DxEpsPpcv5LfDC7WHwtbEvpbMSzGBRsBTMZH9wFZilXA1mK9eAE5RrwYlcA7gOzNHoenASTxUsAyfbz75MbgBzbTSGLAfzNHcjOMXyFFkB5mupTeBULbUZLNDoFnCa/cB4citYaEtlktvAIjs5m9wOTlfuAGdoqUpwps1dQe4EZ+kid4GzdWN3g3M0dw84VyvvBecp94HztdR+cIG9n9dZBS5UHvDsnxVnkfogvVizD9HFvFLwYfpu9RH6HvVR+l71MXqJ+iV6qfpl+j775JTQr9D3a/w4/YD6VfpB9Qn6IfVrdIn6dfphvZNv0MvUb9KPqN+iH1W/TT/G5xJ+h35c/S79hPo9+kn1+/RT6g/o5eoP6afVH9HP8BcMPkk/q/GP6efUp+gV6k/o59Wn6RfUZ+gX+XDDZ+mV6nN0qZ7/p/Qq9Wf0avV5eo36c3qt+gK9Tv0FvV59kS7T9X1Jb+AzBX9Fl6u/pjeqv6Er1N/Sm6zP09/Rm/l4wt/TW9Q/0FvVP9LbbH4s/RO9Xdf7M72Dzy98ia7U+C/0TvWv9C71b/Ru9e/0HvUf9F59U/6k92n8L3q/9v+brlJfpg+o/6EPqq/Qh3S//qUPa/2r9BGNXzMmxMHrYP/Vdv4Dl4kV7bALAAA=");
38
+ DefaultFontsZip.set(DefaultFonts.TimesItalic, "H4sIAAAAAAACA1XWd1iXVRQH8Pe9yJIfqTkaRuEeiLw/EQX3VtwDcaFCDEXBBU4cRakty2znyD1wo+LelqvS9k7NynaZszLtfr885zxP/MHzfDj3nnvu+V0OeIVhS7woX2BSdm5mni8oMT8tJzvd5yMj/6foUnnljbk925jwRGNuFRsTes7zGRMYb0zAAmPc+V6wCXTuXHYcf2FYvFfBuK5xHX+o/WbcEONGeOWMa+yX4w8yblnjhtvtbgB/EGDcSKiMVRFUDQq0mVOg6lCQMWW4sgYULKoJhRgTxH21oFCrBKg2VNbWVgLVgcLkhLqQT1QPCpec9aG77N2yoCionNTZACov+6KhChJrCN1txdNjoIqS04MqifxQZVEjqIooFrpH1Bi6VxQH3SdqAt0vagpVFcVDD4gSoAipuhn0oKg59JDctgUUKWoJVRO1gqpLztZQDWOC+Rm1gWra2EWoLVRL1A6qbbMkQ+2hOlbHoQ5QXVnZEaon6gTVl5WdoShRF6iB3CERirbvZR7UFWoo53WDYmzOPKg75Ml76QH5ZWVPqJGc0AuKlVp6Q40l1geKk1hfqIn0pR/UVM5LguJlX38oQfYlQ82klgFQc4kNhFpIlkFQS9FgqJW9bQQ0BGotry4FaiOxoVBbq1RoGNRO6hwOtZcOpkIdJJYGdRQ9DHWS7qZDnSWWAXWRWCaUKLVkQV1l5Qiom2gk1F1WZkM9RKOgnpJzNNRLYjlQb+lnLtRHco6B+orGQv1E46Ak0Xiov3RpApQsyoMGyHn50EDZNxEaJJVNggbL65kMDZHYFChFNBUaKidMg4ZZxUIF0HB7HjUdSpXYDCjNnp4EzfTC7YfBaWMnpbMUTGdScBmYwUrB5WCmcgWYpVwJjlCuAkeyBnA1mK3RNeAovhRwLTjaPttK5Dowx0bjyCIwV/euB8dwgoAbwLGaaiM4TlNtAsdrdDM4gb0At4B5NnMGuRXMt4tLMxeDE5XbwEmaajs42e5dRO4Ap1jGkCXgVG3sTnCa7t0FFmjm3eB0ywJyDzhD77sXnGlvVMp94Czlfs/+WXEeUR+gH9XdB+lCDgH4EP2Y+jD9uPoIPVt9lJ6jPkbPVb9JP2GHdumbeYt+kk8YPk4/petP0E+rT9LPqE/R89Sn6We1dW/Tz6nfoeer36WfV5+hF/DXGz5Lv6D1vUe/qPH36ZfUH9Avqz+kX1F/RL+q/ph+TZ/nJ/TrGv+UXqj+jF6k/pxerP6CXqL+kn6Dgxv+il6q/fqaXqaf/zl6ufo8vUJ9gV6p/oZepb5Ir1Z/S69Rf0ev1X5+T6/jmIIv0UXqH+j16h/pDeqf6I3qn+lNHJ7wL/Rm9a/0FvVv9Fb173Sx1vsHvU19md6u/pPeob5Cl6iv0jvV1+hd6uv0bp0pN+g9Gr9J71X/Re9T/03vV/9DH1Dfog9qf/6lD2n8Nn1Y43eMCXEwHey/2s5/rhWRJaILAAA=");
39
+ DefaultFontsZip.set(DefaultFonts.TimesRoman, "H4sIAAAAAAACAz3Wd1zWVRQG8Pd3kSEjtWxH4VYU/SGi4B44cSLiRkmGKENAXDgKS1uW2ZSswC3uvQct27tsL9t7T7PO89Q5/MGHL+fcc88d3Be/MmK1HxsZnJ5fmFMWGZqWk1dekFUaGUHHpBUXZhX9jzjCb+jc+VrnoqqcO7fKufB2fqRzwanOBdU45630g5wXiK+MSPIbOc/Dz/Xlm/PCnBftN3Cek69AfIjzwp0XJUO9IP5CRsVA9US1UBMoWKqmQE2hEOfqMbMZFKpqDoU5F8JxLaD6omSoJRQufZVAraAInaE1FKlqA0VpzVjoAtFSqC3UQPvEgr2GOi4OaqSx9tCFIs7eAbpIa/pQY1U8dLGqI3SJKgG6VNUJukyVCF2u6gxdoeoCXalKgq5SJUPR2llX6GpVN+gaXW13KEbVA2qi6gk1lVNZAfWCmjkXmgn1hprLXTgN9YFaiDKgvlBLVT+olWamQK1lhrNQf6iNqAwaAMVq5kCorWoQ1E7PYTAUJ51FQ0Og9pqZCnXQGYZCvnTNzGFQvGYOhzqqRkAJ2stIqJPGRkGJuqI0qLNmjoa66HzpUJKOGwMlqzKgrtIL93Ms1E1j46DuqvFQD605Aeqpa58I9dLTnAT11thkqI/sSx2UCfXVOzEF6qeZU6EUPdssqL9mXgsN0Ng0aKDGsqFBGsuBBmvNXGiIZuZBqarp0FDtOh8appoBDdfMmdAIjRVAI/UvvBAapZlFUJqqGBqtmgWlq0qgMdpnKZSht6cMGqvzzYbG6bhyaLxqDjRBz2guNFFj86BJqvnQZN2lBVCm6AxUAU2RV6oKWghN1dgiKEuqpEOL/Sg5DL428lIGqsFpXARYA2ZzRnAtmGNcB+Ya14N5xg3gdPYAbgTzLboJnGETbQZnyhE0JreABRJNJGvBQhu7FSziCwJuA4ut1HZwlpXaAZZYdCdYKnuRQO4Cy6RUNrkbnC3JueQesNy4F5xjpfaBc2XsGnI/OE8qV5MHwPm2sQfBBTb2EFhhlQ+DC4UV5BFwka33KLhYVvQfj4FLjMd9+VgJXGc+QV/PiwGfpCt5peBT9FJzHX2D+RH6RvOj9DLzY/Ry8+P0TXz+4Cfom/mQwafpW/jQwE/St5qfom8zP02vMD9D325b9yx9h/k5eqX5efpO8wv0Kuv3Rfou80v03eaX6XvMr9D3ml+l7zO/Rt9vfp1ebdfzDF1l8TfoB8xv0mvMb9EPmt+mHzK/Qz9sfpeu5kcF/B5dY7fnfXqt3YcP6HXmD+n15o/oDeaz9Ebzx/Qm8yf0ZjvvT+ktFv+MrjV/Tm81f0FvM39Jbzd/Re/g4wl/Te80f0PvMn9L7zZ/R++x/fie3mv+gd5n/pHeb/6JPmD+mT5o/oU+ZP6VPmxvym/0EYv/Th81/0EfM/9JHzf/RZ8wn6NPmv+mT5nP03Xmf5wLC+B1kH+zA/8CI6LPsZ0LAAA=");
40
+ DefaultFontsZip.set(DefaultFonts.ZapfDingbats, "H4sIAAAAAAACA13X11cVVxQGcO4gcDEgiNgbqDCx36ti770XYoxiiSBF7A27ImBv2GMXe8PeFU2M0cSYFR998CH/QB7ykIeslSxXvu876+6sFR5Y97f3OXvOzJxzZiZUnvB3qGdCYk7uksK0ocWLivJyVyxPiMsuKCpZkLvs//EkMqJRk4eEkrxAlOfFvfe8Tx89L7YiVJsBxgL7QtH4ES5PqAzV9QIB/o5XMugFmrOjh79e4VgvgD6JDERHAmiXFkr0ArVQ+l0Y//0AGQPeFj0y1rLRZBz4QaxFBj0v5iWZWYeMx+gmKhtL1gazxTjyM3CyGCQT0HeLGE8movJNlWpK1gErxBZkkufVylfjBDIZpdwwEsm6aDxa1DBSwFViElnPsslkKlgp1iXr2wmmkA1QubZYj2wIvhZTyUZgY7E+2RhsKDYgm2CQ+8WGZFOc4DyxEdkMjZuKjcnmYKrYhGwBpog6/ZZgUGxGpnle9J9iczIdB3KVdXFagWPFlmRr8LSo+9sGw9ghppMZqOyuRisyExwvtiZ9Yxvyc7uDGWRbcKqYSbYDc0SfbA9u0y2LITuAR5RtS3a0udGO7AQ+FduTna1xBzIEXhM7kuFIZb8T2QW8JHYmu+IO5okhshvO112rMJkFvhW7kN3BT2JXsoedYDeyJzhFzCJ7obGbKt3J3shmiT3IPmCG2JPsa317kf3shvYm+6PUFbEPOQB0J9iXHAiWiP3IQeBJsT85GKUcB5BDQLdwBpJD7cIOIocZB5PD7bhDyBFgqTiUHAm6GTuMHAVq0fnDydE2VUaQY0A3zUaSY9H4vjiKHGerezQ5HhwpjiEnRLIZ78mJ4D/KjiMnRdZRRhWZbatsAvmFcSI52S7sJPJLYzY5BZOhtUrdJb8y1pBTI9M74w05DRyuvlPIHKyyMmU/kNOxv7oFO5WcgY2zhziNnInGbubkkLNAHcifTn5tnEHOxrVyC2cmmWucFUr2Anlo3DIcp+Xmz2VkTiSCFecXs0s+ju5W8TyywDifG38hmBXGbuwv8LxQkKEiCy1EKJ6hudgYUhhKw8T2FzFUbCFMbn8xS8/Dsd2dW0LONy5lB9QP/Kayy1A2laGFFlqOUH2OfxEOXs3xr0N0BSOLI5ENiJSw8BJchI8qnEsuxUjcZpJHLjPOIVE5zo0in1yBvm6tFZAltpcWkiuNReSqyLLNVKnVqPxKVOM1KLVHVKm1oCfOJtdFJkwbcb1RY95g1Jg3GnWgUmN+CI+zqE3mArnMXCiXm4vkCvNcebO5WN5ie/VKeat5lbzNvFrebl4j7zCvlXea18m7zOvl3eYN8h7zRnmvuVSuNG+S95nL5P3mcvmAuUI+aN4sHzJvkQ+bt8pHzNvkb8zb5aPmHfIx8075uHmXfMK8Wz5p3iOfMu+VT5sr5TPmfXKVeb981nxAPmc+KJ/HnPflQ/IF5LXhprv2Fz0vmC67/CWsVD1T0g/LlzGV3SZ7VL6Ceu4d6ph81fLH5WvIu13phHwddm8ZJ+VqeKF8Sr5hPi3fxPiq5TPyLdvkq+TbcJV8Vr5j4zkn3zWfl+/BbpFfkO/DS+WL8gN4uXxJfojzdw+ky/Ij5JPlK/JjHN+92V6Vn5ivyU/hP+Tr8jNztVxjD8sb8nPzTfkF2rtXi1vyt+Y78ne2Ld2VX2J8rv89+Xvk28v35Vfw7/ID+QfLP5Rfo797Pj2S38A18mP5R8s/kX+y16an8lu7P8/kn+1+18jvYG2U/nP5F5sfL/Ah4UX9qi+JGC866q9SBd7/F8BGGYzitwq+WY78C/+AGgf/DAAA");
41
+
42
+ let FontGlyph = class FontGlyph {
43
+ constructor(params = {}) {
44
+ this.index = 0;
45
+ this.advanceWidth = 0;
46
+ this.unicode = [];
47
+ Object.assign(this, params);
48
+ }
49
+ };
50
+ __decorate([
51
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
52
+ ], FontGlyph.prototype, "index", void 0);
53
+ __decorate([
54
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
55
+ ], FontGlyph.prototype, "advanceWidth", void 0);
56
+ __decorate([
57
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer, repeated: "set" })
58
+ ], FontGlyph.prototype, "unicode", void 0);
59
+ FontGlyph = __decorate([
60
+ asn.AsnType({ type: asn.AsnTypeTypes.Sequence })
61
+ ], FontGlyph);
62
+
63
+ let FontHead = class FontHead {
64
+ constructor() {
65
+ this.xMin = 0;
66
+ this.xMax = 0;
67
+ this.yMin = 0;
68
+ this.yMax = 0;
69
+ }
70
+ };
71
+ __decorate([
72
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
73
+ ], FontHead.prototype, "xMin", void 0);
74
+ __decorate([
75
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
76
+ ], FontHead.prototype, "xMax", void 0);
77
+ __decorate([
78
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
79
+ ], FontHead.prototype, "yMin", void 0);
80
+ __decorate([
81
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
82
+ ], FontHead.prototype, "yMax", void 0);
83
+ FontHead = __decorate([
84
+ asn.AsnType({ type: asn.AsnTypeTypes.Sequence })
85
+ ], FontHead);
86
+
87
+ let FontName = class FontName {
88
+ constructor() {
89
+ this.fontFamily = "";
90
+ this.fontSubfamily = "";
91
+ this.fullName = "";
92
+ this.postScriptName = "";
93
+ }
94
+ };
95
+ __decorate([
96
+ asn.AsnProp({ type: asn.AsnPropTypes.Utf8String })
97
+ ], FontName.prototype, "fontFamily", void 0);
98
+ __decorate([
99
+ asn.AsnProp({ type: asn.AsnPropTypes.Utf8String })
100
+ ], FontName.prototype, "fontSubfamily", void 0);
101
+ __decorate([
102
+ asn.AsnProp({ type: asn.AsnPropTypes.Utf8String })
103
+ ], FontName.prototype, "fullName", void 0);
104
+ __decorate([
105
+ asn.AsnProp({ type: asn.AsnPropTypes.Utf8String })
106
+ ], FontName.prototype, "postScriptName", void 0);
107
+ FontName = __decorate([
108
+ asn.AsnType({ type: asn.AsnTypeTypes.Sequence })
109
+ ], FontName);
110
+
111
+ let FontOS2 = class FontOS2 {
112
+ constructor() {
113
+ this.sCapHeight = 0;
114
+ this.sxHeight = 0;
115
+ this.usWeightClass = 0;
116
+ }
117
+ };
118
+ __decorate([
119
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
120
+ ], FontOS2.prototype, "sCapHeight", void 0);
121
+ __decorate([
122
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
123
+ ], FontOS2.prototype, "sxHeight", void 0);
124
+ __decorate([
125
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
126
+ ], FontOS2.prototype, "usWeightClass", void 0);
127
+ FontOS2 = __decorate([
128
+ asn.AsnType({ type: asn.AsnTypeTypes.Sequence })
129
+ ], FontOS2);
130
+
131
+ let FontPost = class FontPost {
132
+ constructor() {
133
+ this.italicAngle = 0;
134
+ }
135
+ };
136
+ __decorate([
137
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
138
+ ], FontPost.prototype, "italicAngle", void 0);
139
+ FontPost = __decorate([
140
+ asn.AsnType({ type: asn.AsnTypeTypes.Sequence })
141
+ ], FontPost);
142
+
143
+ var FontInfo_1;
144
+ let FontInfo = FontInfo_1 = class FontInfo {
145
+ constructor() {
146
+ this.name = new FontName();
147
+ this.head = new FontHead();
148
+ this.os2 = new FontOS2();
149
+ this.post = new FontPost();
150
+ this.glyphs = [];
151
+ this.unitsPerEm = 0;
152
+ this.ascent = 0;
153
+ this.descent = 0;
154
+ }
155
+ findGlyph(code) {
156
+ for (const glyph of this.glyphs) {
157
+ if (glyph.unicode.includes(code)) {
158
+ return glyph;
159
+ }
160
+ }
161
+ return null;
162
+ }
163
+ getGlyphs(text) {
164
+ const res = [];
165
+ let unique = "";
166
+ for (const char of text) {
167
+ if (!unique.includes(char)) {
168
+ unique += char;
169
+ const code = char.charCodeAt(0);
170
+ const glyph = this.findGlyph(code);
171
+ if (glyph && !res.includes(glyph)) {
172
+ res.push(glyph);
173
+ }
174
+ }
175
+ }
176
+ res.sort(FontInfo_1.sortByIndex);
177
+ return res;
178
+ }
179
+ static sortByIndex(a, b) {
180
+ if (a.index < b.index) {
181
+ return -1;
182
+ }
183
+ if (a.index > b.index) {
184
+ return 1;
185
+ }
186
+ return 0;
187
+ }
188
+ };
189
+ __decorate([
190
+ asn.AsnProp({ type: FontName })
191
+ ], FontInfo.prototype, "name", void 0);
192
+ __decorate([
193
+ asn.AsnProp({ type: FontHead })
194
+ ], FontInfo.prototype, "head", void 0);
195
+ __decorate([
196
+ asn.AsnProp({ type: FontOS2 })
197
+ ], FontInfo.prototype, "os2", void 0);
198
+ __decorate([
199
+ asn.AsnProp({ type: FontPost })
200
+ ], FontInfo.prototype, "post", void 0);
201
+ __decorate([
202
+ asn.AsnProp({ type: FontGlyph, repeated: "set" })
203
+ ], FontInfo.prototype, "glyphs", void 0);
204
+ __decorate([
205
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
206
+ ], FontInfo.prototype, "unitsPerEm", void 0);
207
+ __decorate([
208
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
209
+ ], FontInfo.prototype, "ascent", void 0);
210
+ __decorate([
211
+ asn.AsnProp({ type: asn.AsnPropTypes.Integer })
212
+ ], FontInfo.prototype, "descent", void 0);
213
+ FontInfo = FontInfo_1 = __decorate([
214
+ asn.AsnType({ type: asn.AsnTypeTypes.Sequence })
215
+ ], FontInfo);
216
+
217
+ class FontFactory {
218
+ static { this.cache = new Map(); }
219
+ static create(source) {
220
+ if (BufferSourceConverter.isBufferSource(source)) {
221
+ return this.createFile(source);
222
+ }
223
+ return this.createDefault(source);
224
+ }
225
+ static createDefault(source) {
226
+ let font = this.cache.get(source);
227
+ if (font) {
228
+ return font;
229
+ }
230
+ const fontZip = DefaultFontsZip.get(source);
231
+ if (!fontZip) {
232
+ throw new Error(`Cannot get default font '${source}. ZIP cached value doesn't exist'`);
233
+ }
234
+ font = AsnConvert.parse(pako.ungzip(new Uint8Array(Convert.FromBase64(fontZip))), FontInfo);
235
+ this.cache.set(source, font);
236
+ return font;
237
+ }
238
+ static createFile(source) {
239
+ const buffer = BufferSourceConverter.toArrayBuffer(source);
240
+ const font = fontjs.Font.fromStream(new bs.SeqStream({ stream: new bs.ByteStream({ buffer }) }));
241
+ const fontInfo = new FontInfo();
242
+ const name = font.tables.get(fontjs.Tables.NAME.tag);
243
+ if (name) {
244
+ fontInfo.name.fontFamily =
245
+ name.getName(fontjs.Tables.NameIDs.fontFamilyName) || "";
246
+ fontInfo.name.fontSubfamily =
247
+ name.getName(fontjs.Tables.NameIDs.fontSubFamilyName) || "";
248
+ fontInfo.name.fullName =
249
+ name.getName(fontjs.Tables.NameIDs.fullFontName) || "";
250
+ fontInfo.name.postScriptName =
251
+ name.getName(fontjs.Tables.NameIDs.postScriptFontName) || "";
252
+ }
253
+ const head = font.tables.get(fontjs.Tables.HEAD.tag);
254
+ if (!head) {
255
+ throw new Error("Required HEAD table is missing");
256
+ }
257
+ fontInfo.head.xMin = head.xMin;
258
+ fontInfo.head.xMax = head.xMax;
259
+ fontInfo.head.yMin = head.yMin;
260
+ fontInfo.head.yMax = head.yMax;
261
+ fontInfo.unitsPerEm = font.unitsPerEm;
262
+ const os2 = font.tables.get(fontjs.Tables.OS2.tag);
263
+ fontInfo.os2.sCapHeight = os2.sCapHeight || 0;
264
+ fontInfo.os2.sxHeight = os2.sxHeight || 0;
265
+ fontInfo.os2.usWeightClass = os2.usWeightClass || 0;
266
+ const post = font.tables.get(fontjs.Tables.POST.tag);
267
+ if (post) {
268
+ fontInfo.post.italicAngle = post.italicAngle;
269
+ }
270
+ const hhea = font.tables.get(fontjs.Tables.HHEA.tag);
271
+ if (!hhea) {
272
+ throw new Error("Required HHEA table is missing");
273
+ }
274
+ fontInfo.ascent = hhea.ascent;
275
+ fontInfo.descent = hhea.descent;
276
+ for (let i = 0; i < font.glyphs.length; i++) {
277
+ const item = font.glyphs[i];
278
+ const glyph = new FontGlyph({
279
+ index: i,
280
+ advanceWidth: item.hAdvanceWidth || 0,
281
+ unicode: item.unicodes || []
282
+ });
283
+ fontInfo.glyphs.push(glyph);
284
+ }
285
+ return fontInfo;
286
+ }
287
+ static getIndexes(fontjs, text) {
288
+ const indexes = [0, 0];
289
+ for (const char of text) {
290
+ const glyph = fontjs.findUnicodeGlyph(char);
291
+ if (glyph && glyph.index) {
292
+ if (!glyph.unicodes) {
293
+ glyph.unicodes = [];
294
+ }
295
+ glyph.unicodes.push(char.charCodeAt(0));
296
+ if (!indexes.includes(glyph.index)) {
297
+ indexes.push(glyph.index);
298
+ }
299
+ }
300
+ }
301
+ return indexes;
302
+ }
303
+ static subsetFont(source, text) {
304
+ const buffer = BufferSourceConverter.toArrayBuffer(source);
305
+ const font = fontjs.Font.fromStream(new bs.SeqStream({ stream: new bs.ByteStream({ buffer }) }));
306
+ const gids = this.getIndexes(font, text);
307
+ const glyphs = font.glyphs;
308
+ const yMax = [];
309
+ const yMin = [];
310
+ for (const element of gids) {
311
+ const glyph = glyphs[element];
312
+ yMax.push(glyph.yMax);
313
+ yMin.push(glyph.yMin);
314
+ }
315
+ const post = font.tables.get(fontjs.Tables.POST.tag);
316
+ post.glyphNameIndex = [];
317
+ post.names = [];
318
+ const hhea = font.tables.get(fontjs.Tables.HHEA.tag);
319
+ const head = font.tables.get(fontjs.Tables.HEAD.tag);
320
+ const name = font.tables.get(fontjs.Tables.NAME.tag);
321
+ const name2 = new fontjs.Tables.NAME();
322
+ name2.nameRecords = [];
323
+ for (const nameRecord of name.nameRecords) {
324
+ if ([
325
+ fontjs.Tables.NameIDs.fontFamilyName,
326
+ fontjs.Tables.NameIDs.fontSubFamilyName,
327
+ fontjs.Tables.NameIDs.fullFontName,
328
+ fontjs.Tables.NameIDs.postScriptFontName
329
+ ].includes(nameRecord.nameID)) {
330
+ const newRecord = {
331
+ platformID: nameRecord.platformID,
332
+ platformSpecificID: nameRecord.platformSpecificID,
333
+ languageID: nameRecord.languageID,
334
+ nameID: nameRecord.nameID,
335
+ value: nameRecord.value
336
+ };
337
+ name2.nameRecords.push(newRecord);
338
+ }
339
+ }
340
+ const newFont = font.subset({
341
+ tables: new Map([
342
+ [fontjs.Tables.OS2.tag, font.tables.get(fontjs.Tables.OS2.tag)],
343
+ [fontjs.Tables.POST.tag, post],
344
+ [fontjs.Tables.NAME.tag, name2]
345
+ ]),
346
+ glyphIndexes: gids,
347
+ fontValues: {
348
+ unitsPerEm: head.unitsPerEm,
349
+ ascent: hhea.ascent,
350
+ descent: hhea.descent,
351
+ lineGap: hhea.lineGap
352
+ },
353
+ cmaps: [
354
+ {
355
+ format: 4,
356
+ language: 0,
357
+ platformID: 3,
358
+ platformSpecificID: 1
359
+ }
360
+ ],
361
+ cmapLanguage: 0
362
+ });
363
+ const newFontStream = new bs.SeqStream();
364
+ newFont.toStream(newFontStream);
365
+ return newFontStream.buffer;
366
+ }
367
+ }
368
+
369
+ export { DefaultFonts, DefaultFontsZip, FontFactory, FontGlyph, FontHead, FontInfo, FontName, FontOS2 };